Commit d0d4e162 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.80

parent 26265657
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 79
SUBLEVEL = 80
ARCH = i386
......@@ -68,16 +68,6 @@ endif
ROOT_DEV = CURRENT
#
# NFS_ROOT_NAME specifies the default name of the directory to mount
# as root via NFS, if the kernel does not get the "root=" option from
# the boot loader. The "%s" will be replaced by the IP-number of the
# local system. Use empty string for default root path provided by BOOTP.
#
#NFS_ROOT = -DNFS_ROOT="\"/tftpboot/%s\""
NFS_ROOT = -DNFS_ROOT="\"\""
#
# INSTALL_PATH specifies where to place the updated kernel and system map
# images. Uncomment if you want to place them anywhere other than root.
......@@ -242,7 +232,7 @@ init/version.o: init/version.c include/linux/compile.h
$(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c
init/main.o: init/main.c
$(CC) $(CFLAGS) $(PROFILING) $(NFS_ROOT) -c -o $*.o $<
$(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
fs: dummy
$(MAKE) linuxsubdirs SUBDIRS=fs
......
......@@ -114,6 +114,11 @@ start_of_setup:
mov dl,#0x81
int 0x13
! Reset the disk controller.
mov ax,#0x0000
mov dl,#0x80
int 0x13
! set DS=CS, we know that SETUPSEG == CS at this point
mov ax,cs ! aka #SETUPSEG
mov ds,ax
......
......@@ -270,11 +270,8 @@ ENTRY(lcall7)
ALIGN
handle_bottom_half:
pushfl
incl SYMBOL_NAME(intr_count)
sti
call SYMBOL_NAME(do_bottom_half)
popfl
decl SYMBOL_NAME(intr_count)
jmp 9f
ALIGN
......
......@@ -237,7 +237,7 @@ Summary of ide driver parameters for kernel "command line":
except the cmd640.
"idex=serialize" : do not overlap operations on idex and ide(x^1)
The following two are valid ONLY on ide0,
The following are valid ONLY on ide0,
and the defaults for the base,ctl ports must not be altered.
"ide0=dtc2278" : probe/support DTC2278 interface
......
/*
* linux/drivers/block/cmd640.c Version 0.08 Mar 15, 1996
* linux/drivers/block/cmd640.c Version 0.09 Mar 19, 1996
*
* Copyright (C) 1995-1996 Linus Torvalds & authors (see below)
*/
......@@ -43,6 +43,7 @@
* Version 0.08 Added autotune/noautotune support. -ml
*
* Version 0.09 Try to be smarter about 2nd port enabling. -ml
* Version 0.10 Be nice and don't reset 2nd port. -ml
*
*/
......@@ -272,12 +273,12 @@ static int probe_for_cmd640_vlb(void) {
return 1;
}
#if 0
/*
* Low level reset for controller, actually it has nothing specific for
* CMD640, but I don't know how to use standard reset routine before
* we recognized any drives.
*/
static void cmd640_reset_controller(int iface_no)
{
int retry_count = 600;
......@@ -294,12 +295,8 @@ static void cmd640_reset_controller(int iface_no)
if (retry_count == 0)
printk("cmd640: failed to reset controller %d\n", iface_no);
#if 0
else
printk("cmd640: controller %d reset [%d]\n",
iface_no, retry_count);
#endif
}
#endif /* 0 */
/*
* Returns 1 if an IDE interface/drive exists at 0x170,
......@@ -351,7 +348,6 @@ int ide_probe_for_cmd640x(void)
printk(" %2x%c", get_cmd640_reg(b),
((b&0xf) == 0xf) ? '\n' : ',');
}
#endif
/*
......@@ -394,7 +390,6 @@ int ide_probe_for_cmd640x(void)
*/
b = get_cmd640_reg(CNTRL);
if (!secondary_port_responding()) {
b ^= CNTRL_ENA_2ND; /* toggle the bit */
second_port_toggled = 1;
......@@ -428,38 +423,46 @@ int ide_probe_for_cmd640x(void)
ide_hwifs[1].drives[0].autotune = 1;
if (ide_hwifs[1].drives[1].autotune == 0)
ide_hwifs[1].drives[1].autotune = 1;
/* We reset timings, and disable read-ahead */
/* disable read-ahead for drives 2 & 3 */
put_cmd640_reg(ARTTIM23, (DIS_RA2 | DIS_RA3));
if (second_port_toggled) {
/* reset PIO timings for drives 2 & 3 */
put_cmd640_reg(DRWTIM23, 0);
}
#if 0
/* reset the secondary interface */
cmd640_reset_controller(1);
#endif
}
printk("ide: buggy CMD640%c interface at ",
printk("ide: buggy CMD640%c interface on ",
'A' - 1 + cmd640_chip_version);
switch (bus_type) {
case vlb :
printk("local bus, port 0x%x", cmd640_key);
printk("vlb (0x%x)", cmd640_key);
break;
case pci1:
printk("pci, (0x%x)", cmd640_key);
printk("pci (0x%x)", cmd640_key);
break;
case pci2:
printk("pci,(access method 2) (0x%x)", cmd640_key);
printk("pci (access method 2) (0x%x)", cmd640_key);
break;
}
/*
* Reset interface timings
*/
#if 0
/* reset PIO timings for drives 1 & 2 */
put_cmd640_reg(CMDTIM, 0);
#endif /* 0 */
/*
* Tell everyone what we did to their system
*/
printk("\n ... serialized, secondary port %s\n", second_port_toggled ? "toggled" : "untouched");
printk("; serialized, secondary port %s\n", second_port_toggled ? "toggled" : "untouched");
return 1;
}
#if 0 /* not used anywhere */
int cmd640_off(void) {
static int a = 0;
byte b;
......@@ -472,6 +475,7 @@ int cmd640_off(void) {
put_cmd640_reg(CNTRL, b);
return 1;
}
#endif /* 0 */
/*
* Sets readahead mode for specific drive
......
/*
* linux/drivers/block/ht6580.c Version 0.03 Feb 09, 1996
* linux/drivers/block/ht6580.c Version 0.04 Mar 19, 1996
*
* Copyright (C) 1995-1996 Linus Torvalds & author (see below)
*/
......@@ -44,9 +44,6 @@
* If I have booted to dos sometime after power on, I can get smaller
* timing values working. Perhaps I could soft-ice the initialization.
*
* OS/2 driver seems to use some kind of DMA. But that code is really
* messy to me to found out how.
*
* -=- malafoss@snakemail.hut.fi -=- searching the marvels of universe -=-
*/
......@@ -71,6 +68,7 @@
* silly sequence (below) whenever we switch between primary and secondary.
*
* This stuff is courtesy of malafoss@snakemail.hut.fi
* (or maf@nemesis.tky.hut.fi)
*
* At least one user has reported that this code can confuse the floppy
* controller and/or driver -- perhaps this should be changed to use
......@@ -152,9 +150,12 @@ static void ht6560b_selectproc (ide_drive_t *drive)
*/
outb (timing, IDE_SELECT_REG);
(void) inb (IDE_STATUS_REG);
OUT_BYTE(drive->select.all,IDE_SELECT_REG);
restore_flags (flags);
#ifdef DEBUG
printk("ht6560b: %s: select=%#x timing=%#x\n", drive->name, t, timing);
#endif
}
OUT_BYTE(drive->select.all,IDE_SELECT_REG);
}
/*
......@@ -229,6 +230,6 @@ void init_ht6560b (void)
ide_hwifs[0].serialized = 1;
ide_hwifs[1].serialized = 1;
} else
printk("ht6560b: not found\n");
printk("\nht6560b: not found\n");
}
}
/*
* linux/drivers/block/ide.c Version 5.34 Mar 16, 1996
* linux/drivers/block/ide.c Version 5.35 Mar 23, 1996
*
* Copyright (C) 1994-1996 Linus Torvalds & authors (see below)
*/
......@@ -221,6 +221,8 @@
* Version 5.33 improve handling of HDIO_DRIVE_CMDs that read data
* Version 5.34 fix irq-sharing problem from 5.33
* fix cdrom ioctl problem from 5.33
* Version 5.35 cosmetic changes
* fix cli() problem in try_to_identify()
*
* Some additional driver compile-time options are in ide.h
*
......@@ -1573,7 +1575,7 @@ static void timer_expiry (unsigned long data)
* This routine assumes cli() is in effect when called.
*
* If an unexpected interrupt happens on irq15 while we are handling irq14
* and if the two interfaces are "serialized" (CMD640B), then it looks like
* and if the two interfaces are "serialized" (CMD640), then it looks like
* we could screw up by interfering with a new request being set up for irq15.
*
* In reality, this is a non-issue. The new command is not sent unless the
......@@ -2371,6 +2373,8 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
delay_10ms(); /* wait for IRQ and DRQ_STAT */
if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) {
unsigned long flags;
save_flags(flags);
cli(); /* some systems need this */
do_identify(drive, cmd); /* drive returned ID */
if (drive->present && drive->media != ide_tape) {
......@@ -2379,6 +2383,8 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
tuneproc(drive, 255); /* auto-tune PIO mode */
}
rc = 0; /* drive responded with ID */
(void) GET_STAT(); /* clear drive IRQ */
restore_flags(flags);
} else
rc = 2; /* drive refused ID */
if (!HWIF(drive)->irq) {
......@@ -2638,7 +2644,7 @@ static int match_parm (char *s, const char *keywords[], int vals[], int max_vals
* except the cmd640.
* "idex=serialize" : do not overlap operations on idex and ide(x^1)
*
* The following two are valid ONLY on ide0,
* The following are valid ONLY on ide0,
* and the defaults for the base,ctl ports must not be altered.
*
* "ide0=dtc2278" : probe/support DTC2278 interface
......
......@@ -41,7 +41,7 @@ static struct ide_pio_info {
{ "WDC AC2120", 0 },
{ "WDC AC2850", 3 },
{ "WDC AC1270", 3 },
{ "WDC AC1170", 3 },
{ "WDC AC1170", 1 },
{ "WDC AC1210", 1 },
{ "WDC AC280", 0 },
/* { "WDC AC21000", 4 }, */
......
......@@ -96,20 +96,12 @@ static void unplug_device(void * data)
* force the transfer to start only after we have put all the requests
* on the list.
*
* Note! We can do the check without interrupts off, because interrupts
* will never add a new request to the queue, only take requests off..
* This is called with interrupts off and no requests on the queue.
*/
static inline void plug_device(struct blk_dev_struct * dev)
{
if (!dev->current_request) {
unsigned long flags;
save_flags(flags);
cli();
dev->current_request = &dev->plug;
queue_task_irq_off(&dev->plug_tq, &tq_scheduler);
restore_flags(flags);
}
}
/*
......@@ -340,63 +332,67 @@ static void make_request(int major,int rw, struct buffer_head * bh)
/* look for a free request. */
down (&request_lock);
cli();
/* The scsi disk and cdrom drivers completely remove the request
* from the queue when they start processing an entry. For this reason
* it is safe to continue to add links to the top entry for those devices.
/*
* Try to coalesce the new request with old requests
*/
cli();
req = blk_dev[major].current_request;
if (!req) {
plug_device(blk_dev + major);
} else switch (major) {
case IDE0_MAJOR: /* same as HD_MAJOR */
case IDE1_MAJOR:
case FLOPPY_MAJOR:
case IDE2_MAJOR:
case IDE3_MAJOR:
/*
* The scsi disk and cdrom drivers completely remove the request
* from the queue when they start processing an entry. For this
* reason it is safe to continue to add links to the top entry for
* those devices.
*
* All other drivers need to jump over the first entry, as that
* entry may be busy being processed and we thus can't change it.
*/
if (( major == IDE0_MAJOR /* same as HD_MAJOR */
|| major == IDE1_MAJOR
|| major == MD_MAJOR
|| major == FLOPPY_MAJOR
|| major == SCSI_DISK_MAJOR
|| major == SCSI_CDROM_MAJOR
|| major == IDE2_MAJOR
|| major == IDE3_MAJOR)
&& (req = blk_dev[major].current_request))
{
if (major != SCSI_DISK_MAJOR &&
major != SCSI_CDROM_MAJOR &&
major != MD_MAJOR)
req = req->next;
if (!req)
break;
/* fall through */
while (req) {
if (req->rq_dev == bh->b_dev &&
!req->sem &&
req->cmd == rw &&
req->sector + req->nr_sectors == sector &&
req->nr_sectors < 244)
{
case SCSI_DISK_MAJOR:
case SCSI_CDROM_MAJOR:
case MD_MAJOR:
do {
if (req->sem)
continue;
if (req->cmd != rw)
continue;
if (req->nr_sectors >= 244)
continue;
if (req->rq_dev != bh->b_dev)
continue;
/* Can we add it to the end of this request? */
if (req->sector + req->nr_sectors == sector) {
req->bhtail->b_reqnext = bh;
req->bhtail = bh;
req->nr_sectors += count;
mark_buffer_clean(bh);
up (&request_lock);
sti();
return;
}
if (req->rq_dev == bh->b_dev &&
!req->sem &&
req->cmd == rw &&
req->sector - count == sector &&
req->nr_sectors < 244)
{
req->nr_sectors += count;
/* or to the beginning? */
} else if (req->sector - count == sector) {
bh->b_reqnext = req->bh;
req->bh = bh;
req->buffer = bh->b_data;
req->current_nr_sectors = count;
req->sector = sector;
} else
continue;
req->nr_sectors += count;
mark_buffer_clean(bh);
req->bh = bh;
up (&request_lock);
sti();
return;
}
req = req->next;
}
} while ((req = req->next) != NULL);
}
up (&request_lock);
......@@ -524,12 +520,6 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
goto sorry;
}
/* If there are no pending requests for this device, then we insert
a dummy request for that device. This will prevent the request
from starting until we have shoved all of the blocks into the
queue, and then we let it rip. */
plug_device(dev);
for (i = 0; i < nr; i++) {
if (bh[i]) {
set_bit(BH_Req, &bh[i]->b_state);
......
/*
* linux/drivers/block/rz1000.c Version 0.02 Feb 08, 1996
* linux/drivers/block/rz1000.c Version 0.03 Mar 20, 1996
*
* Copyright (C) 1995-1996 Linus Torvalds & author (see below)
*/
......@@ -36,7 +36,7 @@ void init_rz1000 (byte bus, byte fn)
int rc;
unsigned short reg;
printk("ide: buggy RZ1000 interface: ");
printk("ide0: buggy RZ1000 interface: ");
if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &reg))) {
ide_pci_access_error (rc);
} else if (!(reg & 1)) {
......
......@@ -196,8 +196,8 @@ static const char *version =
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
......
......@@ -154,6 +154,8 @@ struct pci_dev_info dev_info[] = {
DEVICE( AL, AL_M1513, "M1513"),
DEVICE( AL, AL_M4803, "M4803"),
DEVICE( ASP, ASP_ABP940, "ABP940"),
DEVICE( CERN, CERN_SPSB_PMC, "STAR/RD24 SCI-PCI (PMC)"),
DEVICE( CERN, CERN_SPSB_PCI, "STAR/RD24 SCI-PCI (PMC)"),
DEVICE( IMS, IMS_8849, "8849"),
DEVICE( TEKRAM2, TEKRAM2_690c, "DC690c"),
DEVICE( AMCC, AMCC_MYRINET, "Myrinet PCI (M2-PCI-32)"),
......@@ -475,6 +477,7 @@ const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_3COM: return "3Com";
case PCI_VENDOR_ID_AL: return "Acer Labs";
case PCI_VENDOR_ID_ASP: return "Advanced System Products";
case PCI_VENDOR_ID_CERN: return "CERN";
case PCI_VENDOR_ID_IMS: return "IMS";
case PCI_VENDOR_ID_TEKRAM2: return "Tekram";
case PCI_VENDOR_ID_AMCC: return "AMCC";
......
/*
* linux/fs/nfs/nfsroot.c -- version 2.1
* linux/fs/nfs/nfsroot.c -- version 2.3
*
* Copyright (C) 1995 Gero Kuhlmann <gero@gkminix.han.de>
* Copyright (C) 1995, 1996 Gero Kuhlmann <gero@gkminix.han.de>
*
* For parts of this file:
* Copyright (C) 1996 Martin Mares <mj@k332.feld.cvut.cz>
*
* Allow an NFS filesystem to be mounted as root. The way this works is:
......@@ -16,6 +18,7 @@
*
* 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.
......@@ -30,27 +33,19 @@
* 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.
*
*
* Known bugs and caveats:
*
* - BOOTP code doesn't handle multiple network interfaces properly.
* For now, it uses the first one, trying to prefer ethernet-like
* devices. Not critical as diskless stations are usually single-homed.
* 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.
*
*/
/* Define this to allow debugging output */
#undef NFSROOT_DEBUG
#undef NFSROOT_MORE_DEBUG
#undef NFSROOT_BOOTP_DEBUG
/* Define the timeout for waiting for a RARP/BOOTP reply */
#define CONF_BASE_TIMEOUT (HZ*5) /* Initial timeout: 5 seconds */
#define CONF_RETRIES 10 /* 10 retries */
#define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */
#define CONF_TIMEOUT_MULT *5/4 /* Speed of timeout growth */
#define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */
#include <linux/config.h>
#include <linux/types.h>
......@@ -58,6 +53,8 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/random.h>
#include <linux/fcntl.h>
#include <asm/param.h>
#include <linux/utsname.h>
......@@ -79,8 +76,6 @@
#include <linux/in.h>
#include <net/route.h>
#include <net/sock.h>
#include <linux/random.h>
#include <linux/fcntl.h>
/* Range of privileged ports */
......@@ -89,6 +84,14 @@
#define NPORTS (ENDPORT - STARTPORT + 1)
/* Define the timeout for waiting for a RARP/BOOTP reply */
#define CONF_BASE_TIMEOUT (HZ*5) /* Initial timeout: 5 seconds */
#define CONF_RETRIES 10 /* 10 retries */
#define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */
#define CONF_TIMEOUT_MULT *5/4 /* Speed of timeout growth */
#define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */
/* List of open devices */
struct open_dev {
struct device *dev;
......@@ -98,6 +101,7 @@ struct open_dev {
static struct open_dev *open_base = NULL;
/* IP configuration */
static struct device *root_dev = NULL; /* Device selected for booting */
static char user_dev_name[IFNAMSIZ]; /* Name of user-selected boot device */
......@@ -106,8 +110,8 @@ static struct sockaddr_in server; /* Server IP address */
static struct sockaddr_in gateway; /* Gateway IP address */
static struct sockaddr_in netmask; /* Netmask for local subnet */
/* BOOTP/RARP variables */
/* BOOTP/RARP variables */
static int bootp_flag; /* User said: Use BOOTP! */
static int rarp_flag; /* User said: Use RARP! */
static int bootp_dev_count = 0; /* Number of devices allowing BOOTP */
......@@ -115,24 +119,24 @@ static int rarp_dev_count = 0; /* Number of devices allowing RARP */
#if defined(CONFIG_RNFS_BOOTP) || defined(CONFIG_RNFS_RARP)
#define CONFIG_RNFS_DYNAMIC /* Enable dynamic IP config */
volatile static int pkt_arrived; /* BOOTP/RARP packet detected */
static volatile int pkt_arrived; /* BOOTP/RARP packet detected */
#define ARRIVED_BOOTP 1
#define ARRIVED_RARP 2
#endif
/* NFS-related data */
static struct nfs_mount_data nfs_data; /* NFS mount info */
static char nfs_path[NFS_MAXPATHLEN]; /* Name of directory to mount */
static int nfs_port; /* Port to connect to for NFS service */
static char nfs_path[NFS_MAXPATHLEN] = ""; /* Name of directory to mount */
static int nfs_port; /* Port to connect to for NFS */
/* Macro for formatting of addresses in debug dumps */
#define IN_NTOA(x) (((x) == INADDR_NONE) ? "none" : in_ntoa(x))
/* Yes, we use sys_socket, but there's no include file for it */
extern asmlinkage int sys_socket(int family, int type, int protocol);
/***************************************************************************
Device Handling Subroutines
......@@ -212,6 +216,7 @@ static void root_dev_close(void)
}
/***************************************************************************
RARP Subroutines
......@@ -305,6 +310,13 @@ static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet
kfree_skb(skb, FREE_READ);
return 0;
}
/* Discard packets which are not from specified server. */
if (rarp_flag && !bootp_flag &&
server.sin_addr.s_addr != INADDR_NONE &&
server.sin_addr.s_addr != sip) {
kfree_skb(skb, FREE_READ);
return 0;
}
/*
* The packet is what we were looking for. Setup the global
......@@ -351,9 +363,10 @@ static void root_rarp_send(void)
}
}
}
#endif
/***************************************************************************
BOOTP Subroutines
......@@ -395,6 +408,7 @@ static struct bootp_pkt *recv_bootp; /* Packet being received */
static int bootp_have_route = 0; /* BOOTP route installed */
/*
* Free BOOTP packet buffers
*/
......@@ -665,7 +679,7 @@ static int root_bootp_open(void)
xmit_bootp->hlen = best_dev->addr_len;
memcpy(xmit_bootp->hw_addr, best_dev->dev_addr, best_dev->addr_len);
root_bootp_init_ext(xmit_bootp->vendor_area);
#ifdef NFSROOT_DEBUG
#ifdef NFSROOT_BOOTP_DEBUG
{
int x;
printk(KERN_NOTICE "BOOTP: XID=%08x, DE=%s, HT=%02x, HL=%02x, HA=",
......@@ -734,7 +748,7 @@ static void root_do_bootp_ext(u8 *ext)
u8 *c;
static int got_bootp_domain = 0;
#ifdef NFSROOT_MORE_DEBUG
#ifdef NFSROOT_BOOTP_DEBUG
printk("BOOTP: Got extension %02x",*ext);
for(c=ext+2; c<ext+2+ext[1]; c++)
printk(" %02x", *c);
......@@ -792,7 +806,7 @@ static void root_bootp_recv(void)
recv_bootp->htype != xmit_bootp->htype ||
recv_bootp->hlen != xmit_bootp->hlen ||
recv_bootp->xid != xmit_bootp->xid) {
#ifdef NFSROOT_DEBUG
#ifdef NFSROOT_BOOTP_DEBUG
printk("?");
#endif
return;
......@@ -831,9 +845,10 @@ static void root_bootp_recv(void)
}
}
}
#endif
/***************************************************************************
Dynamic configuration of IP.
......@@ -849,59 +864,51 @@ static void root_bootp_recv(void)
static int root_auto_config(void)
{
int retries;
u32 timeout, jiff;
u32 start_jiffies;
int selected = 0;
unsigned long timeout, jiff;
unsigned long start_jiffies;
/* Check devices */
/*
* If neither BOOTP nor RARP was selected, return with an error. This
* routine gets only called when some pieces of information are mis-
* sing, and without BOOTP and RARP we are not able to get that in-
* formation.
*/
if (!bootp_flag && !rarp_flag) {
printk(KERN_ERR "Root-NFS: Neither RARP nor BOOTP selected.\n");
return -1;
}
#ifdef CONFIG_RNFS_BOOTP
if (bootp_flag) {
if (bootp_dev_count)
selected = 1;
else {
printk(KERN_ERR "BOOTP: No suitable device found.\n");
if (bootp_flag && !bootp_dev_count) {
printk(KERN_ERR "Root-NFS: No suitable device for BOOTP found.\n");
bootp_flag = 0;
}
}
#else
bootp_flag = 0;
#endif
#ifdef CONFIG_RNFS_RARP
if (rarp_flag) {
if (rarp_dev_count)
selected = 1;
else {
printk(KERN_ERR "RARP: No suitable device found.\n");
if (rarp_flag && !rarp_dev_count) {
printk(KERN_ERR "Root-NFS: No suitable device for RARP found.\n");
rarp_flag = 0;
}
}
#else
rarp_flag = 0;
#endif
/* If neither BOOTP nor RARP was selected manually, use both of them */
if (!selected) {
#ifdef CONFIG_RNFS_BOOTP
if (bootp_dev_count)
bootp_flag = 1;
#endif
#ifdef CONFIG_RNFS_RARP
if (rarp_dev_count)
rarp_flag = 1;
#endif
if (!bootp_flag && !rarp_flag)
/* Error message already printed */
return -1;
}
/* Setup RARP and BOOTP protocols */
/*
* Setup RARP and BOOTP protocols
*/
#ifdef CONFIG_RNFS_RARP
if (rarp_flag)
root_rarp_open();
#endif
#ifdef CONFIG_RNFS_BOOTP
if (bootp_flag && root_bootp_open()) {
if (bootp_flag && root_bootp_open() < 0) {
root_bootp_close();
return -1;
}
......@@ -925,8 +932,8 @@ static int root_auto_config(void)
timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
for(;;) {
#ifdef CONFIG_RNFS_BOOTP
if (bootp_flag && root_bootp_send(jiffies - start_jiffies)) {
printk("...BOOTP failed!\n");
if (bootp_flag && root_bootp_send(jiffies - start_jiffies) < 0) {
printk(" BOOTP failed!\n");
root_bootp_close();
bootp_flag = 0;
if (!rarp_flag)
......@@ -948,7 +955,7 @@ static int root_auto_config(void)
if (pkt_arrived)
break;
if (! --retries) {
printk("timed out!\n");
printk(" timed out!\n");
break;
}
timeout = timeout CONF_TIMEOUT_MULT;
......@@ -968,7 +975,7 @@ static int root_auto_config(void)
if (!pkt_arrived)
return -1;
printk("OK\n");
printk(" OK\n");
printk(KERN_NOTICE "Root-NFS: Got %s answer from %s, ",
(pkt_arrived == ARRIVED_BOOTP) ? "BOOTP" : "RARP",
in_ntoa(server.sin_addr.s_addr));
......@@ -976,9 +983,10 @@ static int root_auto_config(void)
return 0;
}
#endif
/***************************************************************************
Parsing of options
......@@ -1029,9 +1037,10 @@ static struct nfs_bool_opts {
/*
* Prepare the NFS data structure and parse any options
* Prepare the NFS data structure and parse any options. This tries to
* set as many values in the nfs_data structure as known right now.
*/
static int root_nfs_parse(char *name)
static int root_nfs_name(char *name)
{
char buf[NFS_MAXPATHLEN];
char *cp, *options, *val;
......@@ -1043,13 +1052,20 @@ static int root_nfs_parse(char *name)
name = cp;
}
/* Clear the nfs_data structure and setup the server hostname */
memset(&nfs_data, 0, sizeof(nfs_data));
strncpy(nfs_data.hostname, in_ntoa(server.sin_addr.s_addr),
sizeof(nfs_data.hostname)-1);
/* Set the name of the directory to mount */
cp = in_ntoa(myaddr.sin_addr.s_addr);
strncpy(buf, name, 255);
if ((options = strchr(buf, ',')))
*options++ = '\0';
if (!strcmp(buf, "default"))
strcpy(buf, NFS_ROOT);
if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
printk(KERN_ERR "Root-NFS: Pathname for remote directory too long\n");
printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
return -1;
}
sprintf(nfs_path, buf, cp);
......@@ -1100,6 +1116,8 @@ static int root_nfs_parse(char *name)
#ifdef NFSROOT_DEBUG
static void root_nfs_print(void)
{
#define IN_NTOA(x) (((x) == INADDR_NONE) ? "none" : in_ntoa(x))
printk(KERN_NOTICE "Root-NFS: IP config: dev=%s, ",
root_dev ? root_dev->name : "none");
printk("local=%s, ", IN_NTOA(myaddr.sin_addr.s_addr));
......@@ -1118,19 +1136,32 @@ static void root_nfs_print(void)
nfs_data.acdirmin, nfs_data.acdirmax);
printk(KERN_NOTICE "Root-NFS: port = %d, flags = %08x\n",
nfs_port, nfs_data.flags);
#undef IN_NTOA
}
#endif
/*
* Parse any IP configuration options (the "nfsaddrs" parameter).
* The parameter consists of option fields separated by colons. It can start
* with device name and possibly with auto-config type ("bootp" or "rarp")
* followed by own IP address, IP address of the server, IP address of
* default gateway, local netmask and a host name. Any of the addresses can
* be blank to indicate that default value should be used.
* Decode any IP configuration options in the "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>:<bootp|rarp>
*
* 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 for RARP and the first
* one for BOOTP
* <bootp|rarp> - use both protocols to determine my own address
*/
static void root_nfs_ip_config(char *addrs)
static void root_nfs_addrs(char *addrs)
{
char *cp, *ip, *dp;
int num = 0;
......@@ -1143,31 +1174,29 @@ static void root_nfs_ip_config(char *addrs)
system_utsname.nodename[0] = '\0';
system_utsname.domainname[0] = '\0';
user_dev_name[0] = '\0';
bootp_flag = rarp_flag = 0;
bootp_flag = rarp_flag = 1;
/* Check for device name and BOOTP/RARP flags */
ip = addrs;
while (ip && *ip && (*ip < '0' || *ip > '9')) {
if ((cp = strchr(ip, ':')))
*cp++ = '\0';
if (*ip) {
if (!strcmp(ip, "rarp"))
rarp_flag = 1;
else if (!strcmp(ip, "bootp"))
bootp_flag = 1;
else if (!user_dev_name[0]) {
strncpy(user_dev_name, ip, IFNAMSIZ);
user_dev_name[IFNAMSIZ-1] = '\0';
}
}
ip = cp;
/* The following is just a shortcut for automatic IP configuration */
if (!strcmp(addrs, "bootp")) {
rarp_flag = 0;
return;
} else if (!strcmp(addrs, "rarp")) {
bootp_flag = 0;
return;
} else if (!strcmp(addrs, "both")) {
return;
}
/* Parse the IP addresses */
/* Parse the whole string */
ip = addrs;
while (ip && *ip) {
if ((cp = strchr(ip, ':')))
*cp++ = '\0';
if (strlen(ip) > 0 && strcmp(ip, "0.0.0.0")) {
if (strlen(ip) > 0) {
#ifdef NFSROOT_DEBUG
printk(KERN_NOTICE "Root-NFS: Config string num %d is \"%s\"\n",
num, ip);
#endif
switch (num) {
case 0:
myaddr.sin_addr.s_addr = in_aton(ip);
......@@ -1190,6 +1219,18 @@ static void root_nfs_ip_config(char *addrs)
strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
system_utsname.nodename[__NEW_UTS_LEN] = '\0';
break;
case 5:
strncpy(user_dev_name, ip, IFNAMSIZ);
user_dev_name[IFNAMSIZ-1] = '\0';
break;
case 6:
if (!strcmp(ip, "rarp"))
bootp_flag = 0;
else if (!strcmp(ip, "bootp"))
rarp_flag = 0;
else if (strcmp(ip, "both"))
bootp_flag = rarp_flag = 0;
break;
default:
break;
}
......@@ -1197,19 +1238,6 @@ static void root_nfs_ip_config(char *addrs)
ip = cp;
num++;
}
#ifdef NFSROOT_DEBUG
printk(KERN_NOTICE "Root-NFS: IP options: dev=%s, RARP=%d, BOOTP=%d, ",
user_dev_name[0] ? user_dev_name : "none",
rarp_flag,
bootp_flag);
printk("local=%s, ", IN_NTOA(myaddr.sin_addr.s_addr));
printk("server=%s, ", IN_NTOA(server.sin_addr.s_addr));
printk("gw=%s, ", IN_NTOA(gateway.sin_addr.s_addr));
printk("mask=%s, ", IN_NTOA(netmask.sin_addr.s_addr));
printk("host=%s, domain=%s\n",
system_utsname.nodename[0] ? system_utsname.nodename : "none",
system_utsname.domainname[0] ? system_utsname.domainname : "none");
#endif
}
......@@ -1226,9 +1254,6 @@ static int root_nfs_setup(void)
system_utsname.nodename[__NEW_UTS_LEN] = '\0';
}
/* Setup the server hostname */
strncpy(nfs_data.hostname, in_ntoa(server.sin_addr.s_addr), 255);
/* Set the correct netmask */
if (netmask.sin_addr.s_addr == INADDR_NONE)
netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
......@@ -1253,7 +1278,7 @@ static int root_nfs_setup(void)
route.rt_mss = root_dev->mtu;
route.rt_flags = RTF_UP;
*((struct sockaddr_in *) &(route.rt_dst)) = myaddr;
(((struct sockaddr_in *) &(route.rt_dst))) -> sin_addr.s_addr &= netmask.sin_addr.s_addr;
(((struct sockaddr_in *) &(route.rt_dst)))->sin_addr.s_addr &= netmask.sin_addr.s_addr;
*((struct sockaddr_in *) &(route.rt_genmask)) = netmask;
if (ip_rt_new(&route)) {
printk(KERN_ERR "Root-NFS: Adding of local route failed!\n");
......@@ -1261,8 +1286,8 @@ static int root_nfs_setup(void)
}
if (gateway.sin_addr.s_addr != INADDR_NONE) { /* Default route */
(((struct sockaddr_in *) &(route.rt_dst))) -> sin_addr.s_addr = 0;
(((struct sockaddr_in *) &(route.rt_genmask))) -> sin_addr.s_addr = 0;
(((struct sockaddr_in *) &(route.rt_dst)))->sin_addr.s_addr = INADDR_ANY;
(((struct sockaddr_in *) &(route.rt_genmask)))->sin_addr.s_addr = INADDR_ANY;
*((struct sockaddr_in *) &(route.rt_gateway)) = gateway;
route.rt_flags |= RTF_GATEWAY;
if ((gateway.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
......@@ -1289,16 +1314,15 @@ static int root_nfs_setup(void)
int nfs_root_init(char *nfsname, char *nfsaddrs)
{
/*
* Get local and server IP address. First check for network config
* parameters in the command line parameter.
* Decode IP addresses and other configuration info contained
* in the nfsaddrs string (which came from the kernel command
* line).
*/
root_nfs_ip_config(nfsaddrs);
/* Parse NFS options */
if (root_nfs_parse(nfsname))
return -1;
root_nfs_addrs(nfsaddrs);
/* Setup all network devices */
/*
* Setup all network devices
*/
if (root_dev_open() < 0)
return -1;
......@@ -1328,20 +1352,32 @@ int nfs_root_init(char *nfsname, char *nfsaddrs)
if (open_base != NULL && open_base->next == NULL) {
root_dev = open_base->dev;
} else {
/* I hope this cannot happen */
printk(KERN_ERR "Root-NFS: 1 == 0!\n");
printk(KERN_ERR "Root-NFS: Multiple devices and no server\n");
root_dev_close();
return -1;
}
}
/*
* Close all network devices except the device which connects to
* server
*/
root_dev_close();
/* Setup devices and routes */
if (root_nfs_setup())
/*
* 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(nfsname) < 0)
return -1;
/*
* Setup devices and routes. The server directory is actually
* mounted after init() has been started.
*/
if (root_nfs_setup() < 0)
return -1;
#ifdef NFSROOT_DEBUG
......@@ -1358,7 +1394,7 @@ int nfs_root_init(char *nfsname, char *nfsaddrs)
***************************************************************************/
static struct file *nfs_file;
static struct file *nfs_file; /* File descriptor pointing to inode */
static struct inode *nfs_sock_inode; /* Inode containing socket */
static int *rpc_packet = NULL; /* RPC packet */
......@@ -1370,14 +1406,11 @@ static int root_nfs_open(void)
{
/* Open the socket */
if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
printk(KERN_ERR "Root-NFS: Cannot open UDP socket!\n");
printk(KERN_ERR "Root-NFS: Cannot open UDP socket for NFS!\n");
return -1;
}
nfs_file = current->files->fd[nfs_data.fd];
nfs_sock_inode = nfs_file->f_inode;
/* keep socket open. Do we need really this ? */
/* nfs_file->f_count++; */
return 0;
}
......@@ -1387,8 +1420,18 @@ static int root_nfs_open(void)
* increases the reference count, so we can simply close the file, and
* the socket keeps open.
*/
static void root_nfs_close(int close_all)
static void root_nfs_close(void)
{
/*
* The following close doesn't touch the server structure, which
* now contains a file pointer pointing into nowhere. The system
* _should_ crash as soon as someone tries to select on the root
* filesystem. Haven't tried it yet - we can still change it back
* to the old way of keeping a static copy of all important data
* structures, including their pointers. At least this should be
* checked out _carefully_ before going into a public release
* kernel. - GK
*/
sys_close(nfs_data.fd);
}
......@@ -1409,14 +1452,14 @@ static int root_nfs_bind(void)
if (port > ENDPORT) {
port = STARTPORT;
}
res = nfs_sock_inode->u.socket_i.ops->bind
(&nfs_sock_inode->u.socket_i,
(struct sockaddr *)sin, sizeof(struct sockaddr_in));
res = nfs_sock_inode->u.socket_i.ops->bind(&nfs_sock_inode->u.socket_i,
(struct sockaddr *)sin,
sizeof(struct sockaddr_in));
}
}
if (res < 0) {
printk(KERN_ERR "Root-NFS: Cannot find a suitable listening port\n");
root_nfs_close(1);
root_nfs_close();
return -1;
}
#ifdef NFSROOT_DEBUG
......@@ -1451,7 +1494,7 @@ static int *root_nfs_call(int *end)
s.file = nfs_file;
sock = &((nfs_file->f_inode)->u.socket_i);
/* extract the other end of the socket into s->toaddr */
/* Extract the other end of the socket into s->toaddr */
sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
((struct sockaddr_in *) &s.toaddr)->sin_port = server.sin_port;
((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
......@@ -1470,8 +1513,7 @@ static int *root_nfs_call(int *end)
* packet out, and finally check wether the answer is OK.
*/
if (nfs_sock_inode->u.socket_i.ops->connect &&
nfs_sock_inode->u.socket_i.ops->connect
(&nfs_sock_inode->u.socket_i,
nfs_sock_inode->u.socket_i.ops->connect(&nfs_sock_inode->u.socket_i,
(struct sockaddr *) &server,
sizeof(struct sockaddr_in),
nfs_file->f_flags) < 0)
......@@ -1567,9 +1609,10 @@ static int root_nfs_get_handle(void)
/* Prepare header for mountd request */
p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
if (!p) {
root_nfs_close(1);
root_nfs_close();
return -1;
}
/* Set arguments for mountd */
len = strlen(nfs_path);
*p++ = htonl(len);
......@@ -1580,7 +1623,7 @@ static int root_nfs_get_handle(void)
/* Send request to server mountd */
if ((p = root_nfs_call(p)) == NULL) {
root_nfs_close(1);
root_nfs_close();
return -1;
}
status = ntohl(*p++);
......@@ -1590,7 +1633,7 @@ static int root_nfs_get_handle(void)
} else {
printk(KERN_ERR "Root-NFS: Server returned error %d while mounting %s\n",
status, nfs_path);
root_nfs_close(1);
root_nfs_close();
return -1;
}
......@@ -1607,17 +1650,17 @@ static int root_nfs_do_mount(struct super_block *sb)
server.sin_port = htons(nfs_port);
nfs_data.addr = server;
if (nfs_sock_inode->u.socket_i.ops->connect &&
nfs_sock_inode->u.socket_i.ops->connect
(&nfs_sock_inode->u.socket_i,
nfs_sock_inode->u.socket_i.ops->connect(&nfs_sock_inode->u.socket_i,
(struct sockaddr *) &server,
sizeof(struct sockaddr_in),
nfs_file->f_flags) < 0) {
root_nfs_close(1);
root_nfs_close();
return -1;
}
/* Now (finally ;-)) read the super block for mounting */
if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
root_nfs_close(1);
root_nfs_close();
return -1;
}
return 0;
......@@ -1640,6 +1683,6 @@ int nfs_root_mount(struct super_block *sb)
return -1;
if (root_nfs_do_mount(sb) < 0)
return -1;
root_nfs_close(0);
root_nfs_close();
return 0;
}
......@@ -128,6 +128,7 @@ extern int nfs_mmap(struct inode * inode, struct file * file, struct vm_area_str
/* NFS root */
#define NFS_ROOT "/tftpboot/%s"
#define NFS_ROOT_NAME_LEN 256
#define NFS_ROOT_ADDRS_LEN 128
......
......@@ -422,6 +422,10 @@
#define PCI_VENDOR_ID_ASP 0x10cd
#define PCI_DEVICE_ID_ASP_ABP940 0x1200
#define PCI_VENDOR_ID_CERN 0x10dc
#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001
#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002
#define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849
......
......@@ -165,7 +165,7 @@ int root_mountflags = MS_RDONLY;
char *execute_command = 0;
#ifdef CONFIG_ROOT_NFS
char nfs_root_name[NFS_ROOT_NAME_LEN] = { NFS_ROOT };
char nfs_root_name[NFS_ROOT_NAME_LEN] = { "default" };
char nfs_root_addrs[NFS_ROOT_ADDRS_LEN] = { "" };
#endif
......
......@@ -923,9 +923,8 @@ static void update_process_times(unsigned long ticks, unsigned long system)
p->counter = 0;
need_resched = 1;
}
update_one_process(p, ticks, ticks-system, system);
}
update_one_process(p, ticks, ticks-system, system);
#else
int cpu,j;
cpu = smp_processor_id();
......
......@@ -39,6 +39,7 @@ asmlinkage void do_bottom_half(void)
unsigned long mask, left;
void (**bh)(void);
sti();
bh = bh_base;
active = bh_active & bh_mask;
for (mask = 1, left = ~0 ; left & active ; bh++,mask += mask,left += left) {
......
......@@ -295,7 +295,7 @@ void __wait_on_page(struct page *page)
* This is really ugly. But the goto's actually try to clarify some
* of the logic when it comes to error handling etc.
*/
#define MAX_READAHEAD (PAGE_SIZE*4)
#define MAX_READAHEAD (PAGE_SIZE*8)
int generic_file_read(struct inode * inode, struct file * filp, char * buf, int count)
{
int error, read;
......
......@@ -96,6 +96,8 @@ static struct symbol_table net_syms = {
X(ip_options_compile),
X(ip_rt_put),
X(arp_send),
X(ip_id_count),
X(ip_send_check),
#ifdef CONFIG_IP_FORWARD
X(ip_forward),
#endif
......@@ -166,6 +168,8 @@ static struct symbol_table net_syms = {
X(kill_fasync),
#ifdef CONFIG_FIREWALL
X(call_in_firewall),
X(call_out_firewall),
X(call_fw_firewall),
#endif
#endif /* CONFIG_INET */
......
......@@ -1097,7 +1097,7 @@ then
# Activate the Linux compatible sound configuration.
# This may not work for all sound cards. (See sound docs)
#
make -C drivers/sound mkscript >>.menuconfig.log 2>&1
make -C drivers/sound mkscript kernelconfig >>.menuconfig.log 2>&1
echo "# $kernel_version" >.menuconfig
fi
......
......@@ -205,7 +205,7 @@ proc write_tristate { file1 file2 varname variable dep } {
elseif { $variable == 2 || ($dep == 2 && $variable == 1) } \
then { puts $file1 "$varname=m"; \
puts $file2 "#undef $varname"; \
puts $file2 "#define $varname_MODULE 1" } \
puts $file2 "#define ${varname}_MODULE 1" } \
elseif { $variable == 1 && $dep != 2 } \
then { puts $file1 "$varname=y"; \
puts $file2 "#define $varname 1" } \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment