From 3d2cce92c0fb1bf0353f70c0d143ff9f4da40d0b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:10:41 -0500 Subject: [PATCH] Import 1.3.76 --- CREDITS | 10 +- Documentation/Configure.help | 29 +- Documentation/svga.txt | 10 +- MAINTAINERS | 8 +- Makefile | 2 +- arch/alpha/defconfig | 1 + arch/i386/boot/setup.S | 11 +- arch/i386/boot/video.S | 35 ++- arch/i386/kernel/head.S | 1 + arch/i386/kernel/irq.c | 85 +++--- arch/i386/kernel/setup.c | 221 ++++++-------- arch/i386/kernel/smp.c | 1 + arch/i386/kernel/time.c | 6 +- arch/i386/math-emu/reg_constant.c | 51 ++-- arch/i386/math-emu/version.h | 8 +- drivers/block/floppy.c | 2 +- drivers/block/ide.c | 49 +-- drivers/block/promise.c | 10 +- drivers/char/ftape/kernel-interface.c | 2 +- drivers/net/eexpress.c | 7 +- drivers/scsi/scsi.c | 40 ++- drivers/scsi/sd.c | 8 +- drivers/scsi/sr.c | 33 ++- drivers/scsi/sr_ioctl.c | 38 +++ drivers/sound/configure.c | 2 +- fs/Config.in | 4 + fs/inode.c | 26 ++ fs/nfs/nfsroot.c | 89 ++++-- include/asm-i386/smp.h | 1 + include/asm-i386/string.h | 5 +- include/linux/fs.h | 1 - include/linux/module.h | 3 - include/linux/symtab_begin.h | 24 +- include/net/sock.h | 2 +- include/net/tcp.h | 13 +- kernel/ksyms.c | 1 - kernel/module.c | 56 ---- kernel/sched.c | 409 ++++++++++++++------------ mm/kmalloc.c | 6 +- net/ipv4/ip_fw.c | 11 +- scripts/Menuconfig | 22 +- scripts/README.Menuconfig | 41 +-- scripts/header.tk | 4 +- scripts/lxdialog/menubox.c | 139 +++++---- scripts/tkcond.c | 1 + scripts/tkgen.c | 32 +- scripts/tkparse.c | 9 +- scripts/tkparse.h | 3 +- 48 files changed, 909 insertions(+), 663 deletions(-) diff --git a/CREDITS b/CREDITS index a46010d1e3f6..972d041d0952 100644 --- a/CREDITS +++ b/CREDITS @@ -432,12 +432,13 @@ S: Atlanta, Georgia 30332 S: USA N: Kai Harrekilde-Petersen -E: khp@pip.dknet.dk +E: khp@dolphinics.no W: http://www.pip.dknet.dk/~pip93 D: ftape-HOWTO, i82078 fdc detection code, various ftape related stuff. -S: Studsgade 40, 2tv -S: DK-8000 Aarhus C -S: Denmark +S: Dolphin Interconnect Solutions A/S +S: P.O. Box 70, Borgerud +S: N-0621 Oslo +S: Norway N: Andrew Haylett E: ajh@primag.co.uk @@ -716,6 +717,7 @@ E: mj@k332.feld.cvut.cz D: BIOS video mode handling code D: Miscellaneous kernel fixes D: MOXA C-218 serial board driver +D: BOOTP support S: Kankovskeho 1241 S: 182 00 Praha 8 S: Czech Republic diff --git a/Documentation/Configure.help b/Documentation/Configure.help index e3fcfff2a073..ef32aa1cf939 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -168,6 +168,12 @@ CONFIG_BLK_DEV_IDETAPE or something similar. Be sure to consult the drivers/block/ide-tape.c and README.ide files for usage information. +Support removeable IDE interfaces (PCMCIA) +CONFIG_BLK_DEV_IDE_PCMCIA + This option adds code to the IDE driver to handle hot insertion + and removal of IDE interfaces and drives, under direction of an + external utility (?). Normally, just say N here. + CMD640 chipset bugfix/support CONFIG_BLK_DEV_CMD640 The CMD-Technologies CMD640 chip is used on many common 486 and @@ -248,7 +254,7 @@ CONFIG_BLK_DEV_PROMISE card. This driver is known to incur timeouts/retries during heavy I/O to drives attached to the secondary interface. CDROM and TAPE devices are not supported yet. - See the README.ide and ali14xx.c files for more info. + See the README.ide and promise.c files for more info. XT harddisk support CONFIG_BLK_DEV_XD @@ -2487,6 +2493,27 @@ CONFIG_ROOT_NFS the SCSI-HOWTO, available via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.) Most people say N here. +BOOTP support +CONFIG_RNFS_BOOTP + If you want your Linux box to mount its whole root filesystem from + some other computer over the net via NFS and you want the address + of your computer to be discovered automatically using the BOOTP + protocol (a special protocol designed for doing this job), say Y + here. In case the boot ROM of your network card was designed for + booting Linux and does BOOTP itself, providing all necessary + information on the kernel command line, you can say N here. + If unsure, say Y. Note that in case you want to use BOOTP, a BOOTP + server must be operating on your network. + +RARP support +CONFIG_RNFS_RARP + If you want your Linux box to mount its whole root filesystem from + some other computer over the net via NFS and you want the address + of your computer to be discovered automatically using the RARP + protocol (an older protocol which is being obsoleted by BOOTP), say + Y here. Note that in case you want to use RARP, a RARP server must be + operating on your network. + ISO9660 cdrom filesystem support CONFIG_ISO9660_FS This is the standard filesystem used on CDROMs. It was previously diff --git a/Documentation/svga.txt b/Documentation/svga.txt index 6f2cf5672b3d..bc3aaf68a196 100644 --- a/Documentation/svga.txt +++ b/Documentation/svga.txt @@ -1,4 +1,4 @@ - Video Mode Selection Support 2.2 + Video Mode Selection Support 2.4 (c) 1995, 1996 Martin Mares, -------------------------------------------------------------------------------- @@ -148,7 +148,8 @@ it's possible that the first variant doesn't work, while some of the others do -- in this case turn this switch off to see the rest. CONFIG_VIDEO_RETAIN - enables retaining of screen contents when switching -video modes. Useful and probably harmless. +video modes. Works only with some boot loaders leaving enough room for the +buffer. CONFIG_VIDEO_LOCAL - enables inclusion of "local modes" in the list. The local modes are added automatically to the beginning of the list not depending @@ -216,3 +217,8 @@ this must be done manually -- no autodetection mechanisms are available. flag, 0xffff and 0xfffe became aliases instead of real ID's. Screen contents retained during mode changes. 2.3 (15-Mar-96) Changed to work with 1.3.74 kernel. +2.4 (18-Mar-96) Added patches by Hans Lermen fixing a memory overwrite problem + with some boot loaders. Memory management rewritten to reflect + these changes. Unfortunately, screen contents retaining works + only with some loaders now. + Added a Tseng 132x60 mode. diff --git a/MAINTAINERS b/MAINTAINERS index 13a88beb86af..048ed2fd47d8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -97,7 +97,7 @@ S: Odd fixes (e.g., new signatures) FTAPE/QIC-117: P: Kai Harrekilde-Petersen -M: khp@pip.dknet.dk [from 960401: khp@dolphinics.no] +M: khp@@dolphinics.no L: linux-tape@vger.rutgers.edu S: Maintained @@ -167,6 +167,12 @@ M: davem@caip.rutgers.edu L: sparclinux@vger.rutgers.edu S: Maintained +SVGA HANDLING: +P: Martin Mares +M: mj@k332.feld.cvut.cz +L: linux-kernel@vger.rutgers.edu +S: Maintained + REST: P: Linus Torvalds S: Buried alive in email diff --git a/Makefile b/Makefile index ef268221d74d..dd87e1b58917 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 75 +SUBLEVEL = 76 ARCH = i386 diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 441b3d2d3139..06290a597399 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -121,6 +121,7 @@ CONFIG_SCSI_NCR53C7xx=y # CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_PPA is not set # CONFIG_SCSI_AM53C974 is not set # diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index b0acfe732bc6..4041d4acb2bd 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S @@ -61,7 +61,7 @@ start: ! SETUP-header, must start at CS:2 (old 0x9020:2) ! .ascii "HdrS" ! Signature for SETUP-header - .word 0x0200 ! Version number of header format + .word 0x0201 ! Version number of header format ! (must be >= 0x0105 ! else old loadlin-1.5 will fail) realmode_swtch: .word 0,0 ! default_switch,SETUPSEG @@ -80,6 +80,10 @@ type_of_loader: .byte 0 ! = 0, old one (LILO, Loadlin, loadflags: .byte 0 ! unused bits =0 (reserved for future development) LOADED_HIGH = 1 ! bit within loadflags, ! if set, then the kernel is loaded high +CAN_USE_HEAP = 0x80 ! if set, the loader also has set heap_end_ptr + ! to tell how much space behind setup.S + | can be used for heap purposes. + ! Only the loader knows what is free! setup_move_size: .word 0x8000 ! size to move, when we (setup) are not ! loaded at 0x90000. We will move ourselves ! to 0x90000 then just before jumping into @@ -97,6 +101,9 @@ ramdisk_image: .long 0 ! address of loaded ramdisk image ramdisk_size: .long 0 ! its size in bytes bootsect_kludge: .word bootsect_helper,SETUPSEG +heap_end_ptr: .word modelist+1024 ! space from here (exclusive) down to + ! end of setup code can be used by setup + ! for local heap purposes. ! ------------------------ end of header ---------------------------------- start_of_setup: @@ -229,7 +236,7 @@ loader_ok: ! Check for video adapter and its parameters and allow the ! user to browse video modes. - call video + call video ! NOTE: we need DS pointing to bootsector ! Get hd0 data diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index e0070fe53dc0..3bbe20c73841 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S @@ -1,5 +1,5 @@ ! -! Display adapter & video mode setup, version 2.3 (15-Mar-96) +! Display adapter & video mode setup, version 2.4 (18-Mar-96) ! ! Copyright (C) 1995, 1996 Martin Mares ! Based on the original setup.S code (C) Linus Torvalds @@ -66,6 +66,8 @@ ! ! This is the main entry point called by setup.S ! +! Input: +! DS pointing to the bootsector video: push ds ! We use different segments push ds ! FS contains original DS @@ -543,26 +545,35 @@ set_80x43: store_screen: cmpb [do_restore],#0 ! Already stored? jnz stsr + testb [loadflags],#CAN_USE_HEAP ! Have we space for storing? + jz stsr push ax push bx - incb [do_restore] ! Screen will be restored later mov al,[def_mode] ! "Default mode" flag overriden push ax movb [def_mode],#0 - call mode_params ! Obtain and store basic parameters + call mode_params ! Obtain params of current mode pop ax mov [def_mode],al - seg fs ! of the current mode. - mov ax,[PARAM_CURSOR_POS] - lea di,modelist+8192 - stosw + seg fs mov ah,[PARAM_VIDEO_LINES] seg fs mov al,[PARAM_VIDEO_COLS] - stosw + mov bx,ax ! BX=dimensions mul ah mov cx,ax ! CX=number of characters to store + add ax,ax ! Calculate image size + add ax,modelist+1024+4 + cmp ax,[heap_end_ptr] + jnc sts1 ! Unfortunately, out of memory + + seg fs ! Store mode params + mov ax,[PARAM_CURSOR_POS] + lea di,modelist+1024 + stosw + mov ax,bx + stosw push ds ! Store the screen mov ds,[video_segment] @@ -570,7 +581,8 @@ store_screen: rep movsw pop ds - pop bx + incb [do_restore] ! Screen will be restored later +sts1: pop bx pop ax stsr: ret @@ -586,7 +598,7 @@ restore_screen: mov cl,[PARAM_VIDEO_LINES] seg fs mov ch,[PARAM_VIDEO_COLS] - lea si,modelist+8192 ! Screen buffer + lea si,modelist+1024 ! Screen buffer lodsw ! Set cursor position mov dx,ax cmp dh,cl @@ -735,7 +747,7 @@ vesa_modes: cmpb [adapter],#2 ! VGA only jnz ret0 mov bp,di ! BP=original mode table end - add di,#0x400 ! Buffer space + add di,#0x200 ! Buffer space mov ax,#0x4f00 ! VESA Get card info call int #0x10 mov di,bp @@ -1423,6 +1435,7 @@ tseng_md: .byte 0x23, 0x19, 0x84 .byte 0x24, 0x1c, 0x84 .byte 0x22, 0x2c, 0x84 + .byte 0x21, 0x3c, 0x84 .byte 0 .ascii "Tseng" .byte 0 diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 96905629c4ac..ca5a16665863 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -133,6 +133,7 @@ checkCPUtype: je is486 isnew: pushl %ecx # restore original EFLAGS popfl + incl SYMBOL_NAME(have_cpuid) # we have CPUID /* get processor type */ movl $1, %eax # Use the CPUID instruction to .byte 0x0f, 0xa2 # check the processor type diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 7adc3512f555..b60390933756 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -212,16 +212,15 @@ static struct irqaction irq13 = { math_error_irq, 0, 0, "math error", NULL, NULL #endif /* - * IRQ0 is timer, IRQ2 is cascade interrupt to second interrupt controller + * IRQ2 is cascade interrupt to second interrupt controller */ -extern struct irqaction irq0; static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL}; static struct irqaction *irq_action[16] = { - &irq0, NULL, &irq2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, &irq13 , NULL, NULL + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL }; int get_irq_list(char *buf) @@ -385,59 +384,39 @@ asmlinkage void do_fast_IRQ(int irq) } } -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, - const char * devname, - void *dev_id) +int setup_x86_irq(int irq, struct irqaction * new) { int shared = 0; - struct irqaction * action, **p; + struct irqaction *old, **p; unsigned long flags; - if (irq > 15) - return -EINVAL; - if (!handler) - return -EINVAL; p = irq_action + irq; - action = *p; - if (action) { + if ((old = *p) != NULL) { /* Can't share interrupts unless both agree to */ - if (!(action->flags & irqflags & SA_SHIRQ)) + if (!(old->flags & new->flags & SA_SHIRQ)) return -EBUSY; /* Can't share interrupts unless both are same type */ - if ((action->flags ^ irqflags) & SA_INTERRUPT) + if ((old->flags ^ new->flags) & SA_INTERRUPT) return -EBUSY; /* add new interrupt at end of irq queue */ do { - p = &action->next; - action = *p; - } while (action); + p = &old->next; + old = *p; + } while (old); shared = 1; } - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - if (irqflags & SA_SAMPLE_RANDOM) + if (new->flags & SA_SAMPLE_RANDOM) rand_initialize_irq(irq); - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->next = NULL; - action->dev_id = dev_id; - save_flags(flags); cli(); - *p = action; + *p = new; if (!shared) { - if (action->flags & SA_INTERRUPT) + if (new->flags & SA_INTERRUPT) set_intr_gate(0x20+irq,fast_interrupt[irq]); else set_intr_gate(0x20+irq,interrupt[irq]); @@ -446,6 +425,38 @@ int request_irq(unsigned int irq, restore_flags(flags); return 0; } + +int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id) +{ + int retval; + struct irqaction * action; + + if (irq > 15) + return -EINVAL; + if (!handler) + return -EINVAL; + + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + if (!action) + return -ENOMEM; + + action->handler = handler; + action->flags = irqflags; + action->mask = 0; + action->name = devname; + action->next = NULL; + action->dev_id = dev_id; + + retval = setup_x86_irq(irq, action); + + if (retval) + kfree(action); + return retval; +} void free_irq(unsigned int irq, void *dev_id) { @@ -535,6 +546,6 @@ void init_IRQ(void) #endif request_region(0x20,0x20,"pic1"); request_region(0xa0,0x20,"pic2"); - enable_irq(2); - enable_irq(13); + setup_x86_irq(2, &irq2); + setup_x86_irq(13, &irq13); } diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index d6b353320f06..bedd563b7e1d 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -36,14 +36,15 @@ /* * Tell us the machine setup.. */ -char hard_math = 0; /* set by boot/head.S */ -char x86 = 0; /* set by boot/head.S to 3 or 4 */ -char x86_model = 0; /* set by boot/head.S */ -char x86_mask = 0; /* set by boot/head.S */ -int x86_capability = 0; /* set by boot/head.S */ +char hard_math = 0; /* set by kernel/head.S */ +char x86 = 0; /* set by kernel/head.S to 3..6 */ +char x86_model = 0; /* set by kernel/head.S */ +char x86_mask = 0; /* set by kernel/head.S */ +int x86_capability = 0; /* set by kernel/head.S */ int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */ +int have_cpuid = 0; /* set if CPUID instruction works */ -char x86_vendor_id[13] = "Unknown"; +char x86_vendor_id[13] = "unknown"; char ignore_irq13 = 0; /* set if exception 16 works */ char wp_works_ok = -1; /* set if paging hardware honours WP */ @@ -211,7 +212,7 @@ static const char * i486model(unsigned int nr) }; if (nr < sizeof(model)/sizeof(char *)) return model[nr]; - return "Unknown"; + return NULL; } static const char * i586model(unsigned int nr) @@ -221,144 +222,96 @@ static const char * i586model(unsigned int nr) }; if (nr < sizeof(model)/sizeof(char *)) return model[nr]; - return "Unknown"; + return NULL; } static const char * getmodel(int x86, int model) { + const char *p = NULL; + static char nbuf[12]; switch (x86) { case 4: - return i486model(model); + p = i486model(model); case 5: - return i586model(model); + p = i586model(model); } - return "Unknown"; + if (p) + return p; + + sprintf(nbuf, "%d", model); + return nbuf; } int get_cpuinfo(char * buffer) { - char mask[2]; -#ifndef __SMP__ - mask[0] = x86_mask+'@'; - mask[1] = '\0'; - return sprintf(buffer,"cpu\t\t: %c86\n" - "model\t\t: %s\n" - "mask\t\t: %s\n" - "vid\t\t: %s\n" - "fdiv_bug\t: %s\n" - "math\t\t: %s\n" - "hlt\t\t: %s\n" - "wp\t\t: %s\n" - "Integrated NPU\t: %s\n" - "Enhanced VM86\t: %s\n" - "IO Breakpoints\t: %s\n" - "4MB Pages\t: %s\n" - "TS Counters\t: %s\n" - "Pentium MSR\t: %s\n" - "Mach. Ch. Exep.\t: %s\n" - "CMPXCHGB8B\t: %s\n" - "BogoMips\t: %lu.%02lu\n", - x86+'0', - getmodel(x86, x86_model), - x86_mask ? mask : "Unknown", - x86_vendor_id, - fdiv_bug ? "yes" : "no", - hard_math ? "yes" : "no", - hlt_works_ok ? "yes" : "no", - wp_works_ok ? "yes" : "no", - x86_capability & 1 ? "yes" : "no", - x86_capability & 2 ? "yes" : "no", - x86_capability & 4 ? "yes" : "no", - x86_capability & 8 ? "yes" : "no", - x86_capability & 16 ? "yes" : "no", - x86_capability & 32 ? "yes" : "no", - x86_capability & 128 ? "yes" : "no", - x86_capability & 256 ? "yes" : "no", - loops_per_sec/500000, (loops_per_sec/5000) % 100 - ); + int i, len = 0; + static const char *x86_cap_flags[] = { + "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", + "cx8", "apic", "10", "11", "mtrr", "pge", "mca", "cmov", + "16", "17", "18", "19", "20", "21", "22", "mmx", + "24", "25", "26", "27", "28", "29", "30", "31" + }; + +#ifdef __SMP__ + int n; + +#define CD(X) (cpu_data[n].(X)) +#define CPUN n + + for ( n = 0 ; n < 32 ; n++ ) { + if ( cpu_present_map & (1<fdiv_bug=fdiv_bug; c->wp_works_ok=wp_works_ok; /* Always assumed the same currently */ c->hlt_works_ok=hlt_works_ok; + c->have_cpuid=have_cpuid; c->udelay_val=loops_per_sec; strcpy(c->x86_vendor_id, x86_vendor_id); } diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index f5a06513dc70..e9e1215ae18d 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -27,6 +27,8 @@ #include #include +extern int setup_x86_irq(int, struct irqaction *); + /* Cycle counter value at the previous timer interrupt.. */ static unsigned long long last_timer_cc = 0; static unsigned long long init_timer_cc = 0; @@ -353,7 +355,7 @@ unsigned long get_cmos_time(void) return mktime(year, mon, day, hour, min, sec); } -struct irqaction irq0 = { timer_interrupt, 0, 0, "timer", NULL, NULL}; +static struct irqaction irq0 = { timer_interrupt, 0, 0, "timer", NULL, NULL}; void time_init(void) { @@ -374,5 +376,5 @@ void time_init(void) irq0.handler = pentium_timer_interrupt; } #endif - enable_irq(0); + setup_x86_irq(0, &irq0); } diff --git a/arch/i386/math-emu/reg_constant.c b/arch/i386/math-emu/reg_constant.c index c1981ce24140..1b2458eea235 100644 --- a/arch/i386/math-emu/reg_constant.c +++ b/arch/i386/math-emu/reg_constant.c @@ -3,9 +3,9 @@ | | | All of the constant FPU_REGs | | | - | Copyright (C) 1992,1993,1994 | - | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | - | Australia. E-mail billm@vaxc.cc.monash.edu.au | + | Copyright (C) 1992,1993,1994,1996 | + | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | + | Australia. E-mail billm@jacobi.maths.monash.edu.au | | | | | +---------------------------------------------------------------------------*/ @@ -14,6 +14,7 @@ #include "fpu_emu.h" #include "status_w.h" #include "reg_constant.h" +#include "control_w.h" FPU_REG const CONST_1 = { SIGN_POS, TW_Valid, EXP_BIAS, @@ -56,7 +57,7 @@ FPU_REG const CONST_INF = { SIGN_POS, TW_Infinity, EXP_OVER, 0x00000000, 0x8000 -static void fld_const(FPU_REG const *c) +static void fld_const(FPU_REG const *c, int adj) { FPU_REG *st_new_ptr; @@ -67,50 +68,58 @@ static void fld_const(FPU_REG const *c) } push(); reg_move(c, st_new_ptr); + st_new_ptr->sigl += adj; /* For all our fldxxx constants, we don't need to + borrow or carry. */ clear_C1(); } +/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP + (and not one of RC_RND or RC_UP). + */ +#define DOWN_OR_CHOP(x) (x & RC_DOWN) -static void fld1(void) +static void fld1(int rc) { - fld_const(&CONST_1); + fld_const(&CONST_1, 0); } -static void fldl2t(void) +static void fldl2t(int rc) { - fld_const(&CONST_L2T); + fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0); } -static void fldl2e(void) +static void fldl2e(int rc) { - fld_const(&CONST_L2E); + fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0); } -static void fldpi(void) +static void fldpi(int rc) { - fld_const(&CONST_PI); + fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0); } -static void fldlg2(void) +static void fldlg2(int rc) { - fld_const(&CONST_LG2); + fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0); } -static void fldln2(void) +static void fldln2(int rc) { - fld_const(&CONST_LN2); + fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0); } -static void fldz(void) +static void fldz(int rc) { - fld_const(&CONST_Z); + fld_const(&CONST_Z, 0); } -static FUNC constants_table[] = { - fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, FPU_illegal +typedef void (*FUNC_RC)(int); + +static FUNC_RC constants_table[] = { + fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC)FPU_illegal }; void fconst(void) { - (constants_table[FPU_rm])(); + (constants_table[FPU_rm])(control_word & CW_RC); } diff --git a/arch/i386/math-emu/version.h b/arch/i386/math-emu/version.h index 4c75a4792d2c..e0bb665f8d10 100644 --- a/arch/i386/math-emu/version.h +++ b/arch/i386/math-emu/version.h @@ -2,11 +2,11 @@ | version.h | | | | | - | Copyright (C) 1992,1993,1994 | - | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | - | Australia. E-mail billm@vaxc.cc.monash.edu.au | + | Copyright (C) 1992,1993,1994,1996 | + | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | + | Australia. E-mail billm@jacobi.maths.monash.edu.au | | | | | +---------------------------------------------------------------------------*/ -#define FPU_VERSION "wm-FPU-emu version 1.20" +#define FPU_VERSION "wm-FPU-emu version 1.21" diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 2aab361ca9ca..1468b011fd6f 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -175,7 +175,7 @@ static inline int __get_order(unsigned long size) { int order; - size >>= (PAGE_SHIFT-1); + size = (size-1) >> (PAGE_SHIFT-1); order = -1; do { size >>= 1; diff --git a/drivers/block/ide.c b/drivers/block/ide.c index c0724a2d0097..ab406fcbd783 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide.c Version 5.33 Mar 15, 1996 + * linux/drivers/block/ide.c Version 5.34 Mar 16, 1996 * * Copyright (C) 1994-1996 Linus Torvalds & authors (see below) */ @@ -218,7 +218,9 @@ * add config option for PCMCIA baggage * try to make PCMCIA support safer to use * improve security on ioctls(): all are suser() only - * 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 + * fix cdrom ioctl problem from 5.33 * * Some additional driver compile-time options are in ide.h * @@ -1893,8 +1895,6 @@ static int ide_ioctl (struct inode *inode, struct file *file, unsigned long flags; struct request rq; - if (!suser()) - return -EACCES; if (!inode || !(inode->i_rdev)) return -EINVAL; if ((drive = get_info_ptr(inode->i_rdev)) == NULL) @@ -1915,11 +1915,13 @@ static int ide_ioctl (struct inode *inode, struct file *file, return 0; } case BLKFLSBUF: + if (!suser()) return -EACCES; fsync_dev(inode->i_rdev); invalidate_buffers(inode->i_rdev); return 0; case BLKRASET: + if (!suser()) return -EACCES; if(arg > 0xff) return -EINVAL; read_ahead[MAJOR(inode->i_rdev)] = arg; return 0; @@ -1930,6 +1932,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, case BLKGETSIZE: /* Return device size */ return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects); case BLKRRPART: /* Re-read partition tables */ + if (!suser()) return -EACCES; return revalidate_disk(inode->i_rdev); case HDIO_GET_KEEPSETTINGS: @@ -1961,6 +1964,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, return write_fs_long(arg, drive->bad_wstat == BAD_R_STAT); case HDIO_SET_DMA: + if (!suser()) return -EACCES; #ifdef CONFIG_BLK_DEV_IDECD if (drive->media == ide_cdrom) return -EPERM; @@ -1973,6 +1977,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, if (arg > 1) return -EINVAL; case HDIO_SET_32BIT: + if (!suser()) return -EACCES; if ((MINOR(inode->i_rdev) & PARTN_MASK)) return -EINVAL; save_flags(flags); @@ -2012,6 +2017,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, return 0; case HDIO_SET_MULTCOUNT: + if (!suser()) return -EACCES; if (MINOR(inode->i_rdev) & PARTN_MASK) return -EINVAL; if (drive->id && arg > drive->id->max_multsect) @@ -2032,6 +2038,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, { byte args[4], *argbuf = args; int argsize = 4; + if (!suser()) return -EACCES; if (NULL == (void *) arg) { err = ide_do_drive_cmd(drive, &rq, ide_wait); } else if (!(err = verify_area(VERIFY_READ,(void *)arg, 4))) { @@ -2057,6 +2064,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, return err; } case HDIO_SET_PIO_MODE: + if (!suser()) return -EACCES; if (MINOR(inode->i_rdev) & PARTN_MASK) return -EINVAL; if (!HWIF(drive)->tuneproc) @@ -2973,22 +2981,20 @@ static int init_irq (ide_hwif_t *hwif) * Handle serialization, regardless of init sequence */ mate_hwif = &ide_hwifs[hwif->index ^ 1]; - if (hwif->serialized && mate_hwif->present) { - hwgroup = mate_hwif->hwgroup; + if (hwif->serialized && mate_hwif->present) mate_irq = mate_hwif->irq; - } /* - * If another hwif is sharing our irq, then join its hwgroup. + * Group up with any other hwifs that share our irq(s) */ - if (hwgroup == NULL) { - for (index = 0; index < MAX_HWIFS; index++) { - if (index != hwif->index) { - ide_hwif_t *g = &ide_hwifs[index]; - if (g->irq == hwif->irq || g->irq == mate_irq) { - hwgroup = ide_hwifs[index].hwgroup; - break; - } + for (index = 0; index < MAX_HWIFS; index++) { + if (index != hwif->index) { + ide_hwif_t *g = &ide_hwifs[index]; + if (g->irq == hwif->irq || g->irq == mate_irq) { + if (hwgroup && !g->hwgroup) + g->hwgroup = hwgroup; + else if (!hwgroup) + hwgroup = g->hwgroup; } } } @@ -3001,7 +3007,10 @@ static int init_irq (ide_hwif_t *hwif) hwgroup->hwif = hwgroup->next_hwif = hwif->next = hwif; hwgroup->rq = NULL; hwgroup->handler = NULL; - hwgroup->drive = &hwif->drives[0]; + if (hwif->drives[0].present) + hwgroup->drive = &hwif->drives[0]; + else + hwgroup->drive = &hwif->drives[1]; hwgroup->poll_timeout = 0; init_timer(&hwgroup->timer); hwgroup->timer.function = &timer_expiry; @@ -3016,7 +3025,11 @@ static int init_irq (ide_hwif_t *hwif) restore_flags(flags); return 1; } - hwif->got_irq = 1; + for (index = 0; index < MAX_HWIFS; index++) { + ide_hwif_t *g = &ide_hwifs[index]; + if (g->irq == hwif->irq) + g->got_irq = 1; + } } /* diff --git a/drivers/block/promise.c b/drivers/block/promise.c index 78427e0435ec..296915645809 100644 --- a/drivers/block/promise.c +++ b/drivers/block/promise.c @@ -25,6 +25,7 @@ * Version 0.04 Updated for ide.c version 5.30 * Changed initialization strategy * Version 0.05 Kernel integration. -ml + * Version 0.06 Ooops. Add hwgroup to direct call of ide_intr() -ml */ @@ -58,6 +59,7 @@ #include #include #include +#include #include "ide.h" #include "promise.h" @@ -319,7 +321,13 @@ void do_promise_io (ide_drive_t *drive, struct request *rq) do { stat=GET_STAT(); if(stat & DRQ_STAT) { - ide_intr(HWIF(drive)->irq,NULL,NULL); + unsigned long flags; + save_flags(flags); + cli(); + disable_irq(HWIF(drive)->irq); + ide_intr(HWIF(drive)->irq,HWGROUP(drive),NULL); + enable_irq(HWIF(drive)->irq); + restore_flags(flags); return; } if(IN_BYTE(io_base+IDE_SELECT_OFFSET) & 0x01) diff --git a/drivers/char/ftape/kernel-interface.c b/drivers/char/ftape/kernel-interface.c index fc44c9656408..e9981dcadb79 100644 --- a/drivers/char/ftape/kernel-interface.c +++ b/drivers/char/ftape/kernel-interface.c @@ -89,7 +89,7 @@ static inline int __get_order(unsigned long size) { int order; - size >>= (PAGE_SHIFT-1); + size = (size-1) >> (PAGE_SHIFT-1); order = -1; do { size >>= 1; diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 705383dc4f51..50a46b12bb30 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -730,11 +730,14 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr) outb(0,ioaddr+SET_IRQ); } - eexp_hw_ASICrst(dev); - dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); + if (!dev->priv) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct net_local)); + eexp_hw_ASICrst(dev); + { unsigned short i586mso = 0x023e; unsigned short old_wp,old_rp,old_a0,old_a1; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 7ddc138983aa..f1258585fd6c 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -271,6 +271,7 @@ static struct dev_info device_list[] = {"INSITE","I325VM","*", BLIST_KEY}, {"PIONEER","CD-ROM DRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER","CD-ROM DRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN}, +{"EMULEX","MD21/S2 ESDI","*",BLIST_FORCELUN | BLIST_SINGLELUN}, /* * Must be at end of list... */ @@ -768,8 +769,10 @@ int scan_scsis_single (int channel, int dev, int lun, int *max_dev_lun, * If this device is known to support multiple units, override the other * settings, and scan all of them. */ - if (bflags & BLIST_FORCELUN) + if (bflags & BLIST_FORCELUN) { *max_dev_lun = 8; + return 1; + } /* * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1 @@ -1037,17 +1040,32 @@ Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device, restore_flags(flags); return NULL; } - if (!SCpnt || SCpnt->request.rq_status != RQ_INACTIVE) /* Might have changed */ + if (!SCpnt || SCpnt->request.rq_status != RQ_INACTIVE) /* Might have changed */ { - restore_flags(flags); - if(!wait) return NULL; - if (!SCwait) { - printk("Attempt to allocate device channel %d, target %d, " - "lun %d\n", device->channel, device->id, device->lun); - panic("No device found in allocate_device\n"); - } - SCSI_SLEEP(&device->device_wait, - (SCwait->request.rq_status != RQ_INACTIVE)); +#if 1 /* NEW CODE */ + if (wait && SCwait && SCwait->request.rq_status != RQ_INACTIVE) { + sleep_on(&device->device_wait); + restore_flags(flags); + } else { + restore_flags(flags); + if (!wait) return NULL; + if (!SCwait) { + printk("Attempt to allocate device target %d, lun %d\n", + device->id ,device->lun); + panic("No device found in allocate_device\n"); + } + } +#else /* ORIGINAL CODE */ + restore_flags(flags); + if(!wait) return NULL; + if (!SCwait) { + printk("Attempt to allocate device channel %d, target %d, " + "lun %d\n", device->channel, device->id, device->lun); + panic("No device found in allocate_device\n"); + } + SCSI_SLEEP(&device->device_wait, + (SCwait->request.rq_status != RQ_INACTIVE)); +#endif } else { if (req) { memcpy(&SCpnt->request, req, sizeof(struct request)); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 47bf2263700e..b527d5b4f0a7 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1126,10 +1126,10 @@ static int sd_init_onedisk(int i) */ rscsi_disks[i].ready = 1; - rscsi_disks[i].capacity = (buffer[0] << 24) | - (buffer[1] << 16) | - (buffer[2] << 8) | - buffer[3]; + rscsi_disks[i].capacity = 1 + ((buffer[0] << 24) | + (buffer[1] << 16) | + (buffer[2] << 8) | + buffer[3]); rscsi_disks[i].sector_size = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index dc15cf5895ef..6f760a584ae7 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -1020,18 +1020,27 @@ static void get_sectorsize(int i){ (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; scsi_CDs[i].sector_size = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; - if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048; - /* Work around bug/feature in HP 4020i CD-Recorder... */ - if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048; - if(scsi_CDs[i].sector_size != 2048 && - scsi_CDs[i].sector_size != 512) { - printk ("scd%d : unsupported sector size %d.\n", - i, scsi_CDs[i].sector_size); - scsi_CDs[i].capacity = 0; - scsi_CDs[i].needs_sector_size = 1; - }; - if(scsi_CDs[i].sector_size == 2048) - scsi_CDs[i].capacity *= 4; + switch (scsi_CDs[i].sector_size) { + /* + * HP 4020i CD-Recorder reports 2340 byte sectors + * Philips CD-Writers report 2352 byte sectors + * + * Use 2k sectors for them.. + */ + case 0: case 2340: case 2352: + scsi_CDs[i].sector_size = 2048; + /* fall through */ + case 2048: + scsi_CDs[i].capacity *= 4; + /* fall through */ + case 512: + break; + default: + printk ("scd%d : unsupported sector size %d.\n", + i, scsi_CDs[i].sector_size); + scsi_CDs[i].capacity = 0; + scsi_CDs[i].needs_sector_size = 1; + } scsi_CDs[i].needs_sector_size = 0; sr_sizes[i] = scsi_CDs[i].capacity; }; diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 2313cf8c807c..44b31ced6445 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -378,6 +378,44 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne return result; } + case CDROMVOLREAD: + { + char * buffer; + struct cdrom_volctrl volctrl; + + err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_volctrl)); + if (err) return err; + + /* Get the current params */ + + sr_cmd[0] = MODE_SENSE; + sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5; + sr_cmd[2] = 0xe; /* Want mode page 0xe, CDROM audio params */ + sr_cmd[3] = 0; + sr_cmd[4] = 28; + sr_cmd[5] = 0; + + buffer = (unsigned char *) scsi_malloc(512); + if(!buffer) return -ENOMEM; + + if ((result = do_ioctl (target, sr_cmd, buffer, 28))) { + printk ("(CDROMVOLREAD) Hosed while obtaining audio mode page\n"); + scsi_free(buffer, 512); + return result; + } + + volctrl.channel0 = buffer[21]; + volctrl.channel1 = buffer[23]; + volctrl.channel2 = buffer[25]; + volctrl.channel3 = buffer[27]; + + memcpy_tofs ((void *) arg, &volctrl, sizeof (struct cdrom_volctrl)); + + scsi_free(buffer, 512); + + return 0; + } + case CDROMSUBCHNL: { struct cdrom_subchnl subchnl; diff --git a/drivers/sound/configure.c b/drivers/sound/configure.c index ca9c9c9dea22..96b1d445b097 100644 --- a/drivers/sound/configure.c +++ b/drivers/sound/configure.c @@ -778,7 +778,7 @@ ask_parameters (void) "Check from manual of the card"); ask_int_choice (B (OPT_SB), "SB_MPU_IRQ", - "SB MPU401 IRQ (SB16, Jazz16 and ES1688)", + "SB MPU401 IRQ (Jazz16 and ES1688)", FMT_INT, -1, "Check from manual of the card"); diff --git a/fs/Config.in b/fs/Config.in index 2f83da32afd2..c425609bbb7c 100644 --- a/fs/Config.in +++ b/fs/Config.in @@ -21,6 +21,10 @@ if [ "$CONFIG_INET" = "y" ]; then tristate 'NFS filesystem support' CONFIG_NFS_FS if [ "$CONFIG_NFS_FS" = "y" ]; then bool 'Root file system on NFS' CONFIG_ROOT_NFS + if [ "$CONFIG_ROOT_NFS" = "y" ]; then + bool 'BOOTP support' CONFIG_RNFS_BOOTP + bool 'RARP support' CONFIG_RNFS_RARP + fi fi tristate 'SMB filesystem support (to mount WfW shares etc..)' CONFIG_SMB_FS fi diff --git a/fs/inode.c b/fs/inode.c index 330f72caa130..da8ed38dac67 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -12,6 +12,25 @@ #include +#define NR_IHASH 512 + +/* + * Be VERY careful when you access the inode hash table. There + * are some rather scary race conditions you need to take care of: + * - P1 tries to open file "xx", calls "iget()" with the proper + * inode number, but blocks because it's not on the list. + * - P2 deletes file "xx", gets the inode (which P1 has just read, + * but P1 hasn't woken up to the fact yet) + * - P2 iput()'s the inode, which now has i_nlink = 0 + * - P1 wakes up and has the inode, but now P2 has made that + * inode invalid (but P1 has no way of knowing that). + * + * The "updating" counter makes sure that when P1 blocks on the + * iget(), P2 can't delete the inode from under it because P2 + * will wait until P1 has been able to update the inode usage + * count so that the inode will stay in use until everybody has + * closed it.. + */ static struct inode_hash_entry { struct inode * inode; int updating; @@ -563,6 +582,13 @@ repeat: if (inode->i_dev == sb->s_dev && inode->i_ino == nr) goto found_it; if (!empty) { + /* + * If we sleep here before we have found an inode + * we need to make sure nobody does anything bad + * to the inode while we sleep, because otherwise + * we may return an inode that is not valid any + * more when we wake up.. + */ h->updating++; empty = get_empty_inode(); if (!--h->updating) diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index f044f73255b1..fa8d4bec3820 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c @@ -1,5 +1,5 @@ /* - * linux/fs/nfs/nfsroot.c -- version 2.0 + * linux/fs/nfs/nfsroot.c -- version 2.1 * * Copyright (C) 1995 Gero Kuhlmann * Copyright (C) 1996 Martin Mares @@ -25,6 +25,8 @@ * Martin Mares : Randomized timer with exponential backoff * installed to minimize network congestion. * Martin Mares : Code cleanup. + * Martin Mares : (2.1) BOOTP and RARP made configuration options. + * Martin Mares : Server hostname generation fixed. * * * Known bugs and caveats: @@ -40,10 +42,6 @@ #undef NFSROOT_DEBUG #undef NFSROOT_MORE_DEBUG -/* Choose default protocol(s) */ -#define CONFIG_USE_BOOTP -#define CONFIG_USE_RARP - /* 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 */ @@ -106,14 +104,19 @@ static struct sockaddr_in gateway; /* Gateway IP address */ static struct sockaddr_in netmask; /* Netmask for local subnet */ /* 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 */ 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 */ #define ARRIVED_BOOTP 1 #define ARRIVED_RARP 2 +#endif /* NFS-related data */ static struct nfs_mount_data nfs_data; /* NFS mount info */ @@ -212,6 +215,8 @@ static void root_dev_close(void) ***************************************************************************/ +#ifdef CONFIG_RNFS_RARP + extern void arp_send(int type, int ptype, unsigned long target_ip, struct device *dev, unsigned long src_ip, unsigned char *dest_hw, unsigned char *src_hw, @@ -350,6 +355,7 @@ static void root_rarp_send(void) } } +#endif /*************************************************************************** @@ -357,6 +363,8 @@ static void root_rarp_send(void) ***************************************************************************/ +#ifdef CONFIG_RNFS_BOOTP + static struct device *bootp_dev = NULL; /* Device selected as best BOOTP target */ static int bootp_xmit_fd = -1; /* Socket descriptor for transmit */ @@ -827,6 +835,7 @@ static void root_bootp_recv(void) } } +#endif /*************************************************************************** @@ -834,6 +843,8 @@ static void root_bootp_recv(void) ***************************************************************************/ +#ifdef CONFIG_RNFS_DYNAMIC + /* * Determine client and server IP numbers and appropriate device by using * the RARP and BOOTP protocols. @@ -843,24 +854,43 @@ static int root_auto_config(void) int retries; u32 timeout, jiff; u32 start_jiffies; + int selected = 0; /* Check devices */ - if (bootp_flag && !bootp_dev_count) { - printk(KERN_ERR "BOOTP: No suitable device found.\n"); - bootp_flag = 0; + +#ifdef CONFIG_RNFS_BOOTP + if (bootp_flag) { + if (bootp_dev_count) + selected = 1; + else { + printk(KERN_ERR "BOOTP: No suitable device found.\n"); + bootp_flag = 0; } - if (rarp_flag && !rarp_dev_count) { - printk(KERN_ERR "RARP: No suitable device found.\n"); - rarp_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"); + rarp_flag = 0; } + } +#else + rarp_flag = 0; +#endif /* If neither BOOTP nor RARP was selected manually, use both of them */ - if (!bootp_flag && !rarp_flag) { -#ifdef CONFIG_USE_BOOTP + if (!selected) { +#ifdef CONFIG_RNFS_BOOTP if (bootp_dev_count) bootp_flag = 1; #endif -#ifdef CONFIG_USE_RARP +#ifdef CONFIG_RNFS_RARP if (rarp_dev_count) rarp_flag = 1; #endif @@ -869,12 +899,16 @@ static int root_auto_config(void) } /* 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()) { root_bootp_close(); return -1; } +#endif /* * Send requests and wait, until we get an answer. This loop @@ -893,6 +927,7 @@ static int root_auto_config(void) get_random_bytes(&timeout, sizeof(timeout)); 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"); root_bootp_close(); @@ -900,12 +935,19 @@ static int root_auto_config(void) if (!rarp_flag) break; } +#endif +#ifdef CONFIG_RNFS_RARP if (rarp_flag) root_rarp_send(); +#endif printk("."); jiff = jiffies + timeout; while (jiffies < jiff && !pkt_arrived) +#ifdef CONFIG_RNFS_BOOTP root_bootp_recv(); +#else + ; +#endif if (pkt_arrived) break; if (! --retries) { @@ -917,10 +959,14 @@ static int root_auto_config(void) timeout = CONF_TIMEOUT_MAX; } +#ifdef CONFIG_RNFS_RARP if (rarp_flag) root_rarp_close(); +#endif +#ifdef CONFIG_RNFS_BOOTP if (bootp_flag) root_bootp_close(); +#endif if (!pkt_arrived) return -1; @@ -934,6 +980,7 @@ static int root_auto_config(void) return 0; } +#endif /*************************************************************************** @@ -999,10 +1046,6 @@ static int root_nfs_parse(char *name) name = cp; } - /* Setup the server hostname */ - cp = in_ntoa(server.sin_addr.s_addr); - strncpy(nfs_data.hostname, cp, 255); - /* Set the name of the directory to mount */ cp = in_ntoa(myaddr.sin_addr.s_addr); strncpy(buf, name, 255); @@ -1186,6 +1229,9 @@ 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); @@ -1273,8 +1319,11 @@ int nfs_root_init(char *nfsname, char *nfsaddrs) */ if ((myaddr.sin_addr.s_addr == INADDR_NONE || server.sin_addr.s_addr == INADDR_NONE || - (open_base != NULL && open_base->next != NULL)) && - root_auto_config() < 0) { + (open_base != NULL && open_base->next != NULL)) +#ifdef CONFIG_RNFS_DYNAMIC + && root_auto_config() < 0 +#endif + ) { root_dev_close(); return -1; } diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 00893f415da1..c2e40d685517 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -161,6 +161,7 @@ struct cpuinfo_x86 char x86_vendor_id[16]; int x86_capability; int fdiv_bug; + int have_cpuid; char wp_works_ok; char hlt_works_ok; unsigned long udelay_val; diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h index d4adc32895ff..e79720e5dd8f 100644 --- a/include/asm-i386/string.h +++ b/include/asm-i386/string.h @@ -6,8 +6,11 @@ * byte string operations. But on a 386 or a PPro the * byte string ops are faster than doing it by hand * (MUCH faster on a Pentium). + * + * Also, the byte strings actually work correctly. Forget + * the i486 routines for now as they may be broken.. */ -#if CPU == 486 || CPU == 586 +#if FIXED_486_STRING && (CPU == 486 || CPU == 586) #include #else diff --git a/include/linux/fs.h b/include/linux/fs.h index 669768503f9c..0fa1186fa25a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -30,7 +30,6 @@ #define NR_OPEN 256 #define NR_SUPER 64 -#define NR_IHASH 131 #define BLOCK_SIZE 1024 #define BLOCK_SIZE_BITS 10 diff --git a/include/linux/module.h b/include/linux/module.h index a91ad19b3cdf..ceecc3c0f80c 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -74,9 +74,6 @@ struct mod_routines { void (*cleanup)(void); /* cleanup routine */ }; -/* rename_module_symbol(old_name, new_name) WOW! */ -extern int rename_module_symbol(char *, char *); - /* insert new symbol table */ extern int register_symtab(struct symbol_table *); diff --git a/include/linux/symtab_begin.h b/include/linux/symtab_begin.h index 2729fc77684c..65a87008c537 100644 --- a/include/linux/symtab_begin.h +++ b/include/linux/symtab_begin.h @@ -3,19 +3,37 @@ #ifdef MODVERSIONS # undef _set_ver # undef X +/* + * These two macros _will_ get enough arguments from the X* macros + * since "sym" expands to "symaddr, symstr" from the #define in *.ver + */ +# define _basic_version(symaddr,symstr) symaddr, symstr +# define _alias_version(really,symaddr,symstr) (void *) & really , symstr # ifndef __GENKSYMS__ # ifdef MODULE # define _set_ver(sym,ver) \ - { (void *) & sym ## _R ## ver, SYMBOL_NAME_STR(sym) "_R" #ver } + (void *) & sym ## _R ## ver, SYMBOL_NAME_STR(sym) "_R" #ver # else /* !MODULE */ # define _set_ver(sym,ver) \ - { (void *) & sym, SYMBOL_NAME_STR(sym) "_R" #ver } + (void *) & sym, SYMBOL_NAME_STR(sym) "_R" #ver # endif /* !MODULE */ -# define X(a) a +# define X(sym) { _basic_version(sym) } +/* + * For _really_ stacked modules: + * + * Use "Xalias(local_symbol, symbol_from_other_module)" + * to make subsequent modules really use "local_symbol" + * when they think that they are using "symbol_from_other_module" + * + * The "aliasing" module can still use "symbol_from_other_module", + * but can now replace and/or modify the behaviour of that symbol. + */ +# define Xalias(really,sym) { _alias_version(really,sym) } # endif /* !__GENKSYMS__ */ #else /* !MODVERSIONS */ # define X(sym) { (void *) & sym, SYMBOL_NAME_STR(sym)} +# define Xalias(really,sym) { (void *) & really, SYMBOL_NAME_STR(sym)} #endif /* MODVERSIONS */ /* * Some symbols always need to be unversioned. This includes diff --git a/include/net/sock.h b/include/net/sock.h index dfe4ddfe6e71..193629d74235 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -236,7 +236,7 @@ struct sock 'timed out' */ unsigned char protocol; volatile unsigned char state; - volatile unsigned char ack_backlog; + unsigned char ack_backlog; unsigned char max_ack_backlog; unsigned char priority; unsigned char debug; diff --git a/include/net/tcp.h b/include/net/tcp.h index ae2ce3eddb43..c6ef1fec7baf 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -107,9 +107,16 @@ extern __inline int between(__u32 seq1, __u32 seq2, __u32 seq3) static __inline__ int min(unsigned int a, unsigned int b) { - if (a < b) - return(a); - return(b); + if (a > b) + a = b; + return a; +} + +static __inline__ int max(unsigned int a, unsigned int b) +{ + if (a < b) + a = b; + return a; } extern struct proto tcp_prot; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 81565e941064..e4c80aad2d68 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -116,7 +116,6 @@ struct symbol_table symbol_table = { #endif /* stackable module support */ - X(rename_module_symbol), X(register_symtab), #ifdef CONFIG_KERNELD X(kerneld_send), diff --git a/kernel/module.c b/kernel/module.c index 2eb13911ce81..992b2d23e2c2 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -81,62 +81,6 @@ void init_modules(void) { kernel_module.name = ""; } -int -rename_module_symbol(char *old_name, char *new_name) -{ - struct internal_symbol *sym; - int i = 0; /* keep gcc silent */ - - if (module_list->symtab) { - sym = module_list->symtab->symbol; - for (i = module_list->symtab->n_symbols; i > 0; ++sym, --i) { - if (strcmp(sym->name, old_name) == 0) { /* found it! */ - sym->name = new_name; /* done! */ - PRINTK(("renamed %s to %s\n", old_name, new_name)); - return 1; /* it worked! */ - } - } - } - printk("rename %s to %s failed!\n", old_name, new_name); - return 0; /* not there... */ - - /* - * This one will change the name of the first matching symbol! - * - * With this function, you can replace the name of a symbol defined - * in the current module with a new name, e.g. when you want to insert - * your own function instead of a previously defined function - * with the same name. - * - * "Normal" usage: - * - * bogus_function(int params) - * { - * do something "smart"; - * return real_function(params); - * } - * - * ... - * - * init_module() - * { - * if (rename_module_symbol("_bogus_function", "_real_function")) - * printk("yep!\n"); - * else - * printk("no way!\n"); - * ... - * } - * - * When loading this module, real_function will be resolved - * to the real function address. - * All later loaded modules that refer to "real_function()" will - * then really call "bogus_function()" instead!!! - * - * This feature will give you ample opportunities to get to know - * the taste of your foot when you stuff it into your mouth!!! - */ -} - /* * Allocate space for a module. */ diff --git a/kernel/sched.c b/kernel/sched.c index 9644d497ed23..cec5da6a0c7a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -581,6 +580,50 @@ int del_timer(struct timer_list * timer) #endif } +static inline void run_timer_list(void) +{ + struct timer_list * timer; + + while ((timer = timer_head.next) != &timer_head && timer->expires <= jiffies) { + void (*fn)(unsigned long) = timer->function; + unsigned long data = timer->data; + timer->next->prev = timer->prev; + timer->prev->next = timer->next; + timer->next = timer->prev = NULL; + sti(); + fn(data); + cli(); + } +} + +static inline void run_old_timers(void) +{ + struct timer_struct *tp; + unsigned long mask; + + for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) { + if (mask > timer_active) + break; + if (!(mask & timer_active)) + continue; + if (tp->expires > jiffies) + continue; + timer_active &= ~mask; + tp->fn(); + sti(); + } +} + +void tqueue_bh(void) +{ + run_task_queue(&tq_timer); +} + +void immediate_bh(void) +{ + run_task_queue(&tq_immediate); +} + unsigned long timer_active = 0; struct timer_struct timer_table[32]; @@ -611,18 +654,19 @@ static unsigned long count_active_tasks(void) return nr; } -static inline void calc_load(void) +static inline void calc_load(unsigned long ticks) { unsigned long active_tasks; /* fixed-point */ static int count = LOAD_FREQ; - if (count-- > 0) - return; - count = LOAD_FREQ; - active_tasks = count_active_tasks(); - CALC_LOAD(avenrun[0], EXP_1, active_tasks); - CALC_LOAD(avenrun[1], EXP_5, active_tasks); - CALC_LOAD(avenrun[2], EXP_15, active_tasks); + count -= ticks; + if (count < 0) { + count += LOAD_FREQ; + active_tasks = count_active_tasks(); + CALC_LOAD(avenrun[0], EXP_1, active_tasks); + CALC_LOAD(avenrun[1], EXP_5, active_tasks); + CALC_LOAD(avenrun[2], EXP_15, active_tasks); + } } /* @@ -749,71 +793,20 @@ static void second_overflow(void) #endif } -/* - * disregard lost ticks for now.. We don't care enough. - */ -static void timer_bh(void) -{ - unsigned long mask; - struct timer_struct *tp; - struct timer_list * timer; - - cli(); - while ((timer = timer_head.next) != &timer_head && timer->expires <= jiffies) { - void (*fn)(unsigned long) = timer->function; - unsigned long data = timer->data; - timer->next->prev = timer->prev; - timer->prev->next = timer->next; - timer->next = timer->prev = NULL; - sti(); - fn(data); - cli(); - } - sti(); - - for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) { - if (mask > timer_active) - break; - if (!(mask & timer_active)) - continue; - if (tp->expires > jiffies) - continue; - timer_active &= ~mask; - tp->fn(); - sti(); - } -} - -void tqueue_bh(void) +static void update_wall_time_one_tick(void) { - run_task_queue(&tq_timer); -} - -void immediate_bh(void) -{ - run_task_queue(&tq_immediate); -} - -void do_timer(struct pt_regs * regs) -{ - unsigned long mask; - struct timer_struct *tp; - long ltemp, psecs; -#ifdef __SMP__ - int cpu,i; -#endif - - /* Advance the phase, once it gets to one microsecond, then + /* + * Advance the phase, once it gets to one microsecond, then * advance the tick more. */ time_phase += time_adj; if (time_phase <= -FINEUSEC) { - ltemp = -time_phase >> SHIFT_SCALE; + long ltemp = -time_phase >> SHIFT_SCALE; time_phase += ltemp << SHIFT_SCALE; xtime.tv_usec += tick + time_adjust_step - ltemp; } else if (time_phase >= FINEUSEC) { - ltemp = time_phase >> SHIFT_SCALE; + long ltemp = time_phase >> SHIFT_SCALE; time_phase -= ltemp << SHIFT_SCALE; xtime.tv_usec += tick + time_adjust_step + ltemp; } else @@ -841,161 +834,203 @@ void do_timer(struct pt_regs * regs) } else time_adjust_step = 0; +} + +/* + * Using a loop looks inefficient, but "ticks" is + * usually just one (we shouldn't be losing ticks, + * we're doing this this way mainly for interrupt + * latency reasons, not because we think we'll + * have lots of lost timer ticks + */ +static void update_wall_time(unsigned long ticks) +{ + do { + ticks--; + update_wall_time_one_tick(); + } while (ticks); if (xtime.tv_usec >= 1000000) { xtime.tv_usec -= 1000000; xtime.tv_sec++; second_overflow(); } +} - jiffies++; - calc_load(); -#ifndef __SMP__ - if (user_mode(regs)) { - current->utime++; - if (current->pid) { - if (current->priority < DEF_PRIORITY) - kstat.cpu_nice++; - else - kstat.cpu_user++; - } - /* Update ITIMER_VIRT for current task if not in a system call */ - if (current->it_virt_value && !(--current->it_virt_value)) { - current->it_virt_value = current->it_virt_incr; - send_sig(SIGVTALRM,current,1); - } - } else { - current->stime++; - if(current->pid) - kstat.cpu_system++; - if (prof_buffer && current->pid) { - extern int _stext; - unsigned long ip = instruction_pointer(regs); - ip -= (unsigned long) &_stext; - ip >>= prof_shift; - if (ip < prof_len) - prof_buffer[ip]++; - } +static inline void do_process_times(struct task_struct *p, + unsigned long user, unsigned long system) +{ + long psecs; + + p->utime += user; + if (p->priority < DEF_PRIORITY) + kstat.cpu_nice += user; + else + kstat.cpu_user += user; + kstat.cpu_system += system; + p->stime += system; + + psecs = (p->stime + p->utime) / HZ; + if (psecs > p->rlim[RLIMIT_CPU].rlim_cur) { + /* Send SIGXCPU every second.. */ + if (psecs * HZ == p->stime + p->utime) + send_sig(SIGXCPU, p, 1); + /* and SIGKILL when we go over max.. */ + if (psecs > p->rlim[RLIMIT_CPU].rlim_max) + send_sig(SIGKILL, p, 1); } - /* - * check the cpu time limit on the process. - */ - if ((current->rlim[RLIMIT_CPU].rlim_max != RLIM_INFINITY) && - (((current->stime + current->utime) / HZ) >= current->rlim[RLIMIT_CPU].rlim_max)) - send_sig(SIGKILL, current, 1); - if ((current->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) && - (((current->stime + current->utime) % HZ) == 0)) { - psecs = (current->stime + current->utime) / HZ; - /* send when equal */ - if (psecs == current->rlim[RLIMIT_CPU].rlim_cur) - send_sig(SIGXCPU, current, 1); - /* and every five seconds thereafter. */ - else if ((psecs > current->rlim[RLIMIT_CPU].rlim_cur) && - ((psecs - current->rlim[RLIMIT_CPU].rlim_cur) % 5) == 0) - send_sig(SIGXCPU, current, 1); +} + +static inline void do_it_virt(struct task_struct * p, unsigned long ticks) +{ + unsigned long it_virt = p->it_virt_value; + + if (it_virt) { + if (it_virt < ticks) { + it_virt = ticks + p->it_virt_incr; + send_sig(SIGVTALRM, p, 1); + } + p->it_virt_value = it_virt - ticks; } +} - if (current->pid && 0 > --current->counter) { - current->counter = 0; - need_resched = 1; +static inline void do_it_prof(struct task_struct * p, unsigned long ticks) +{ + unsigned long it_prof = p->it_prof_value; + + if (it_prof) { + if (it_prof < ticks) { + it_prof = ticks + p->it_prof_incr; + send_sig(SIGPROF, p, 1); + } + p->it_prof_value = it_prof - ticks; } - /* Update ITIMER_PROF for the current task */ - if (current->it_prof_value && !(--current->it_prof_value)) { - current->it_prof_value = current->it_prof_incr; - send_sig(SIGPROF,current,1); +} + +static __inline__ void update_one_process(struct task_struct *p, + unsigned long ticks, unsigned long user, unsigned long system) +{ + do_process_times(p, user, system); + do_it_virt(p, user); + do_it_prof(p, ticks); +} + +static void update_process_times(unsigned long ticks, unsigned long system) +{ +#ifndef __SMP__ + struct task_struct * p = current; + if (p->pid) { + p->counter -= ticks; + if (p->counter < 0) { + p->counter = 0; + need_resched = 1; + } + + update_one_process(p, ticks, ticks-system, system); } #else + int cpu,i; cpu = smp_processor_id(); for (i=0;i<=smp_top_cpu;i++) { + struct task_struct *p; + if(cpu_number_map[i]==-1) continue; #ifdef __SMP_PROF__ if (test_bit(i,&smp_idle_map)) smp_idle_count[i]++; #endif - if (((cpu==i) && user_mode(regs)) || - ((cpu!=i) && 0==smp_proc_in_lock[i])) - { - current_set[i]->utime++; - if (current_set[i]->pid) - { - if (current_set[i]->priority < DEF_PRIORITY) - kstat.cpu_nice++; - else - kstat.cpu_user++; - } - /* Update ITIMER_VIRT for current task if not in a system call */ - if (current_set[i]->it_virt_value && !(--current_set[i]->it_virt_value)) { - current_set[i]->it_virt_value = current_set[i]->it_virt_incr; - send_sig(SIGVTALRM,current_set[i],1); - } - } else { - current_set[i]->stime++; - if(current_set[i]->pid) - kstat.cpu_system++; - if (prof_buffer && current_set[i]->pid) { - extern int _stext; - unsigned long ip = instruction_pointer(regs); - ip -= (unsigned long) &_stext; - ip >>= prof_shift; - if (ip < prof_len) - prof_buffer[ip]++; - } - } + p = current_set[i]; /* - * check the cpu time limit on the process. + * Do we have a real process? */ - if ((current_set[i]->rlim[RLIMIT_CPU].rlim_max != RLIM_INFINITY) && - (((current_set[i]->stime + current_set[i]->utime) / HZ) >= - current_set[i]->rlim[RLIMIT_CPU].rlim_max)) - send_sig(SIGKILL, current_set[i], 1); - if ((current_set[i]->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) && - (((current_set[i]->stime + current_set[i]->utime) % HZ) == 0)) { - psecs = (current_set[i]->stime + current_set[i]->utime) / HZ; - /* send when equal */ - if (psecs == current_set[i]->rlim[RLIMIT_CPU].rlim_cur) - send_sig(SIGXCPU, current_set[i], 1); - /* and every five seconds thereafter. */ - else if ((psecs > current_set[i]->rlim[RLIMIT_CPU].rlim_cur) && - ((psecs - current_set[i]->rlim[RLIMIT_CPU].rlim_cur) % 5) == 0) - send_sig(SIGXCPU, current_set[i], 1); - } - if (current_set[i]->pid && 0 > --current_set[i]->counter) { - current_set[i]->counter = 0; - if (i==cpu) - need_resched = 1; - else - smp_message_pass(i, MSG_RESCHEDULE, 0L, 0); - } else - if ((0==current_set[i]->pid) && (0x7fffffff & smp_process_available)){ - /* runnable process found; wakeup idle process */ - if (cpu==i) - need_resched = 1; - else - smp_message_pass(i, MSG_RESCHEDULE, 0L, 0); + if (p->pid) { + /* assume user-mode process */ + unsigned long utime = ticks; + unsigned long stime = 0; + if (cpu == i) { + utime = ticks-system; + stime = system; + } else if (smp_proc_in_lock[i]) { + utime = 0; + stime = ticks; } + update_one_process(p, ticks, utime, stime); - /* Update ITIMER_PROF for the current task */ - if (current_set[i]->it_prof_value && !(--current_set[i]->it_prof_value)) { - current_set[i]->it_prof_value = current_set[i]->it_prof_incr; - send_sig(SIGPROF,current_set[i],1); + p->counter -= ticks; + if (p->counter >= 0) + continue; + p->counter = 0; + } else { + /* + * Idle processor found, do we have anything + * we could run? + */ + if (!(0x7fffffff & smp_process_available)) + continue; } + /* Ok, we should reschedule, do the magic */ + if (i==cpu) + need_resched = 1; + else + smp_message_pass(i, MSG_RESCHEDULE, 0L, 0); } +#endif +} + +static unsigned long lost_ticks = 0; +static unsigned long lost_ticks_system = 0; + +static void timer_bh(void) +{ + unsigned long ticks, system; + + run_old_timers(); + cli(); + run_timer_list(); + ticks = lost_ticks; + lost_ticks = 0; + system = lost_ticks_system; + lost_ticks_system = 0; + sti(); + + if (ticks) { + calc_load(ticks); + update_wall_time(ticks); + update_process_times(ticks, system); + } +} + +/* + * Run the bottom half stuff only about 100 times a second, + * we'd just use up unnecessary CPU time for timer handling + * otherwise + */ +#if HZ > 100 +#define should_run_timers(x) ((x) >= HZ/100) +#else +#define should_run_timers(x) (1) #endif - for (mask = 1, tp = timer_table+0 ; mask ; tp++,mask += mask) { - if (mask > timer_active) - break; - if (!(mask & timer_active)) - continue; - if (tp->expires > jiffies) - continue; +void do_timer(struct pt_regs * regs) +{ + (*(unsigned long *)&jiffies)++; + lost_ticks++; + if (should_run_timers(lost_ticks)) mark_bh(TIMER_BH); + if (!user_mode(regs)) { + lost_ticks_system++; + if (prof_buffer && current->pid) { + extern int _stext; + unsigned long ip = instruction_pointer(regs); + ip -= (unsigned long) &_stext; + ip >>= prof_shift; + if (ip < prof_len) + prof_buffer[ip]++; + } } - if (timer_head.next->expires <= jiffies) - mark_bh(TIMER_BH); if (tq_timer != &tq_last) mark_bh(TQUEUE_BH); } diff --git a/mm/kmalloc.c b/mm/kmalloc.c index dae0dd963715..57a9ea0d7836 100644 --- a/mm/kmalloc.c +++ b/mm/kmalloc.c @@ -177,7 +177,7 @@ void *kmalloc(size_t size, int priority) { unsigned long flags; unsigned long type; - int order, i, sz; + int order, i, sz, dma; struct block_header *p; struct page_descriptor *page, **pg; @@ -187,9 +187,11 @@ void *kmalloc(size_t size, int priority) return (NULL); } + dma = 0; type = MF_USED; pg = &sizes[order].firstfree; if (priority & GFP_DMA) { + dma = 1; type = MF_DMA; pg = &sizes[order].dmafree; } @@ -227,7 +229,7 @@ void *kmalloc(size_t size, int priority) sz = BLOCKSIZE(order); page = (struct page_descriptor *) __get_free_pages(priority, - sizes[order].gfporder, priority & GFP_DMA); + sizes[order].gfporder, dma); if (!page) { static unsigned long last = 0; diff --git a/net/ipv4/ip_fw.c b/net/ipv4/ip_fw.c index d437f8d51961..aa77f7c0df2c 100644 --- a/net/ipv4/ip_fw.c +++ b/net/ipv4/ip_fw.c @@ -444,14 +444,16 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int pol if(opt != 1) { if(f->fw_flg&IP_FW_F_ACCEPT) { if(f->fw_flg&IP_FW_F_MASQ) - printk("Masquerade "); + printk("masq "); else - printk("Accept "); + printk("acc "); } else if(f->fw_flg&IP_FW_F_ICMPRPL) - printk("Reject "); + printk("rej "); else - printk("Deny "); + printk("deny "); } + if (rif) + printk("%s ", rif->name); switch(ip->protocol) { case IPPROTO_TCP: @@ -459,6 +461,7 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, struct ip_fw *chain, int pol break; case IPPROTO_UDP: printk("UDP "); + break; case IPPROTO_ICMP: printk("ICMP:%d ", icmp_type); break; diff --git a/scripts/Menuconfig b/scripts/Menuconfig index 061002e43bb4..8aa31eaf9189 100644 --- a/scripts/Menuconfig +++ b/scripts/Menuconfig @@ -78,10 +78,10 @@ function help () { if extract_help $1 >help.out then $DIALOG --backtitle "$backtitle" --title "$2"\ - --textbox help.out 20 75 + --textbox help.out $LINES $COLS else $DIALOG --backtitle "$backtitle" \ - --textbox help.out 20 75 + --textbox help.out $LINES $COLS fi rm help.out } @@ -91,7 +91,7 @@ function help () { # function show_readme() { $DIALOG --backtitle "$backtitle" \ - --textbox scripts/README.Menuconfig 21 75 + --textbox scripts/README.Menuconfig $LINES $COLS } # @@ -102,7 +102,8 @@ function menu_name () { echo -ne "$DIALOG --title '$1'\ --backtitle '$backtitle' \ --menu '$menu_instructions' \ - 21 75 11 '$default' " >MCmenu + $LINES $COLS $((LINES-10)) \ + '$default' " >MCmenu >MCradiolists } @@ -841,6 +842,19 @@ cleanup2 () { rm -f .tmpconfig .tmpconfig.h } +x=`stty -a` +case $x in +*\ rows\ *\;*) + LINES=${x##*rows} LINES=${LINES%%;*} LINES=$((${LINES:-25}-4)) + COLS=${x##*columns} COLS=${COLS%%;*} COLS=$((${COLS:-80}-5)) + ;; +*) + LINES=21 + COLS=75 + ;; +esac + + menu_instructions="\ Arrow keys navigate the menu. \ Highlighted letters are hotkeys. \ diff --git a/scripts/README.Menuconfig b/scripts/README.Menuconfig index 2184143f7a62..bb4d36c395c9 100644 --- a/scripts/README.Menuconfig +++ b/scripts/README.Menuconfig @@ -1,22 +1,8 @@ -This is the Linux kernel Menuconfig README file. - Menuconfig gives the Linux kernel configuration a long needed face lift. Featuring text based color menus and dialogs, it does not require X Windows. With this utility you can easily select a kernel option to modify without sifting through 100 other options. -The windowing support utility (lxdialog) is a VERY modified version of -the dialog utility by Savio Lam . Although lxdialog -is significantly different from dialog, I have left Savio's copyrights -intact. Please DO NOT contact Savio with questions about lxdialog. -He will not be able to assist. - -Please feel free to send any questions, comments or suggestions to -William Roadcap . - -READ ON! There are hints and notices below... - - Some Menuconfig keyboard hints: Menus @@ -27,6 +13,9 @@ o Use the Up/Down arrow keys (cursor keys) to highlight the item Pressing a hotkey more than once will sequence through all items which use that hotkey. + You may also use the and keys to scroll + unseen options into view. + o Use the cursor keys to highlight