Commit d0d4e162 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.80

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