From f6cce5dae53e5176e35ae26b2711755c52dc01ea Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:18:06 -0500 Subject: [PATCH] Linux 2.2.0 > Compile this code > > ---- cut here ---- > #include > void main( int argc, char *argv[] ) { > open( argv[ 1 ], O_WRONLY|O_CREAT|O_TRUNC, 0666 ); > } > ---- and here ---- > > and run it like this > > strace ./a.out >(cat - ) > > with 2.0.36 & 2.2.0-pre[67] you get: > > open("/dev/fd/63", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 > > with 2.2.0-pre[89] you get: > > open("/dev/fd/63", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 ENOENT (No > such file or directory) Ok, this seems to be due to pre9 removing some rather bogus code that happened to hide another problem in open_namei(). I haven't actually tested this, but it looks really obvious, so does this patch fix it for you? (This should also fix a potential performance bogosity - there's absolutely no reason why we should get the directory lock when we don't need to for a normal open of an existing file). Linus --- Makefile | 2 +- arch/alpha/Makefile | 9 +- arch/alpha/kernel/entry.S | 4 +- arch/alpha/kernel/sys_rx164.c | 2 - arch/alpha/kernel/sys_sio.c | 2 +- arch/alpha/lib/semaphore.S | 1 - arch/i386/kernel/setup.c | 7 ++ arch/i386/kernel/smp.c | 238 +++++++++++++++++++++++++-------------- arch/i386/mm/init.c | 33 ------ drivers/block/ide-pci.c | 17 +-- drivers/char/bttv.c | 20 +++- drivers/char/bttv.h | 7 +- drivers/char/mem.c | 1 + drivers/char/msp3400.c | 24 ++-- drivers/char/pc_keyb.c | 14 +-- drivers/net/ibmtr.c | 2 +- drivers/net/irda/irport.c | 1 - drivers/net/irda/uircc.c | 1 - drivers/net/ne2k-pci.c | 1 + drivers/scsi/megaraid.h | 2 + drivers/sound/ad1816.c | 45 +++++--- drivers/sound/sb_card.c | 2 + drivers/sound/sb_common.c | 5 - drivers/sound/sb_ess.c | 186 +++++++++++++++++++----------- drivers/sound/sb_mixer.c | 1 - fs/coda/cnode.c | 28 ++--- fs/coda/coda_linux.c | 13 ++- fs/coda/dir.c | 47 ++++++-- fs/dcache.c | 11 -- fs/inode.c | 91 +++++++-------- fs/namei.c | 8 +- fs/nfsd/nfscache.c | 4 +- fs/proc/array.c | 127 ++++++++++----------- fs/vfat/namei.c | 4 +- include/asm-alpha/core_polaris.h | 2 + include/asm-alpha/jensen.h | 3 + include/asm-alpha/unistd.h | 1 + include/asm-i386/cobalt.h | 1 + include/asm-i386/i82489.h | 4 +- include/asm-i386/lithium.h | 5 + include/asm-i386/smp.h | 2 +- include/linux/coda.h | 61 +++++++++- include/linux/coda_linux.h | 1 + include/linux/videodev.h | 1 + include/net/irda/irda.h | 1 + mm/filemap.c | 5 +- mm/page_alloc.c | 66 +++++------ mm/vmscan.c | 151 +++++++++++++++---------- net/decnet/README | 7 +- net/ipv4/fib_semantics.c | 2 +- net/ipv4/ip_masq_mfw.c | 3 +- net/ipv4/tcp_input.c | 2 +- net/irda/irlpt/irlpt_common.c | 1 - net/irda/irlpt/irlpt_srvr_fsm.c | 2 - net/irda/irsysctl.c | 1 + 55 files changed, 760 insertions(+), 522 deletions(-) diff --git a/Makefile b/Makefile index 7e51805fe..af68bb8a8 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 2 SUBLEVEL = 0 -EXTRAVERSION =-final +EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index 8ec15d610..d48c8e09f 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -49,7 +49,11 @@ ifeq ($(have_mcpu),y) ifeq ($(have_mcpu_ev6),y) CFLAGS := $(CFLAGS) -mcpu=ev6 else - CFLAGS := $(CFLAGS) -mcpu=pca56 + ifeq ($(have_mcpu_pca56),y) + CFLAGS := $(CFLAGS) -mcpu=pca56 + else + CFLAGS := $(CFLAGS) -mcpu=ev56 + endif endif endif endif @@ -72,6 +76,9 @@ else ifeq ($(CONFIG_ALPHA_POLARIS),y) CFLAGS := $(CFLAGS) -Wa,-m21164pc endif + ifeq ($(CONFIG_ALPHA_TSUNAMI),y) + CFLAGS := $(CFLAGS) -Wa,-mev6 + endif endif HEAD := arch/alpha/kernel/head.o diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 520eae7cd..380af2c9c 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -10,7 +10,7 @@ #define rti .long PAL_rti #define SIGCHLD 20 -#define NR_SYSCALLS 370 +#define NR_SYSCALLS 371 /* * These offsets must match with alpha_mv in . @@ -1138,4 +1138,4 @@ sys_call_table: .quad sys_getcwd .quad sys_capget .quad sys_capset - .quad sys_ni_syscall /* 370 */ + .quad sys_sendfile /* 370 */ diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index de0912e73..5d2cf5288 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c @@ -211,8 +211,6 @@ rx164_pci_fixup(void) * The System Vector */ -#define POLARIS_IACK_SC POLARIS_IACK_BASE /* hack, move to header */ - struct alpha_machine_vector rx164_mv __initmv = { vector_name: "RX164", DO_EV5_MMU, diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index bf7460e52..70d8720e9 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -232,7 +232,7 @@ noname_pci_fixup(void) * selected... :-( */ layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE); - sio_pci_fixup(noname_map_irq, 0x0b0a0f0e); + sio_pci_fixup(noname_map_irq, 0x0b0a0f0d); sio_fixup_irq_levels(sio_collect_irq_levels()); enable_ide(0x26e); } diff --git a/arch/alpha/lib/semaphore.S b/arch/alpha/lib/semaphore.S index 81b1c5a56..7ecddc2ec 100644 --- a/arch/alpha/lib/semaphore.S +++ b/arch/alpha/lib/semaphore.S @@ -77,7 +77,6 @@ __down_failed: .ent __down_failed_interruptible __down_failed_interruptible: ldgp $29,0($27) - ldgp $29,0($27) lda $30, -20*8($30) stq $28, 0*8($30) stq $0, 1*8($30) diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 222c4a148..c3f34270a 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -341,6 +341,13 @@ __initfunc(void setup_arch(char **cmdline_p, *memory_start_p = memory_start; *memory_end_p = memory_end; +#ifdef __SMP__ + /* + * Save possible boot-time SMP configuration: + */ + init_smp_config(); +#endif + #ifdef CONFIG_BLK_DEV_INITRD if (LOADER_TYPE) { initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0; diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 05e2af7b8..2960d521c 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -37,19 +37,8 @@ #include #include #include -#include #include -#include -#include -#include -#include - -#ifdef CONFIG_MTRR -# include -#endif - -#define __KERNEL_SYSCALLS__ -#include +#include #include "irq.h" @@ -100,21 +89,6 @@ extern void update_one_process( struct task_struct *p, spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; /* - * Why isn't this somewhere standard ?? - * - * Maybe because this procedure is horribly buggy, and does - * not deserve to live. Think about signedness issues for five - * seconds to see why. - Linus - */ - -extern __inline int max(int a,int b) -{ - if (a>b) - return a; - return b; -} - -/* * function prototypes: */ static void cache_APIC_registers (void); @@ -168,6 +142,11 @@ int skip_ioapic_setup = 0; /* 1 if "noapic" boot option passed */ #endif /* + * IA s/w dev Vol 3, Section 7.4 + */ +#define APIC_DEFAULT_PHYS_BASE 0xfee00000 + +/* * Setup routine for controlling SMP activation * * Command-line option of "nosmp" or "maxcpus=0" will disable SMP @@ -197,19 +176,11 @@ void ack_APIC_irq(void) apic_write(APIC_EOI, 0); } -#ifdef CONFIG_X86_VISWS_APIC /* - * hacky! + * Intel MP BIOS table parsing routines: */ -int __init smp_scan_config(unsigned long base, unsigned long length) -{ - cpu_present_map |= 2; /* or in id 1 */ - apic_version[1] |= 0x10; /* integrated APIC */ - num_processors = 2; - return 1; -} -#else +#ifndef CONFIG_X86_VISWS_APIC /* * Checksum an MP configuration block. */ @@ -429,7 +400,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) * Scan the memory blocks for an SMP configuration block. */ -int __init smp_scan_config(unsigned long base, unsigned long length) +static int __init smp_scan_config(unsigned long base, unsigned long length) { unsigned long *bp=phys_to_virt(base); struct intel_mp_floating *mpf; @@ -463,7 +434,7 @@ int __init smp_scan_config(unsigned long base, unsigned long length) unsigned long cfg; /* local APIC has default address */ - mp_lapic_addr = 0xFEE00000; + mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; /* * We need to know what the local * APIC id of the boot CPU is! @@ -579,7 +550,76 @@ int __init smp_scan_config(unsigned long base, unsigned long length) return 0; } + +void __init init_intel_smp (void) +{ + /* + * FIXME: Linux assumes you have 640K of base ram.. + * this continues the error... + * + * 1) Scan the bottom 1K for a signature + * 2) Scan the top 1K of base RAM + * 3) Scan the 64K of bios + */ + if (!smp_scan_config(0x0,0x400) && + !smp_scan_config(639*0x400,0x400) && + !smp_scan_config(0xF0000,0x10000)) { + /* + * If it is an SMP machine we should know now, unless the + * configuration is in an EISA/MCA bus machine with an + * extended bios data area. + * + * there is a real-mode segmented pointer pointing to the + * 4K EBDA area at 0x40E, calculate and scan it here. + * + * NOTE! There are Linux loaders that will corrupt the EBDA + * area, and as such this kind of SMP config may be less + * trustworthy, simply because the SMP table may have been + * stomped on during early boot. These loaders are buggy and + * should be fixed. + */ + unsigned int address; + + address = *(unsigned short *)phys_to_virt(0x40E); + address<<=4; + smp_scan_config(address, 0x1000); + if (smp_found_config) + printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.rutgers.edu if you experience SMP problems!\n"); + } +} + +#else + +/* + * The Visual Workstation is Intel MP compliant in the hardware + * sense, but it doesnt have a BIOS(-configuration table). + * No problem for Linux. + */ +void __init init_visws_smp(void) +{ + smp_found_config = 1; + + cpu_present_map |= 2; /* or in id 1 */ + apic_version[1] |= 0x10; /* integrated APIC */ + apic_version[0] |= 0x10; + + mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; +} + +#endif + +/* + * - Intel MP Configuration Table + * - or SGI Visual Workstation configuration + */ +void __init init_smp_config (void) +{ +#ifndef CONFIG_VISWS + init_intel_smp(); +#else + init_visws_smp(); #endif +} /* * Trampoline 80x86 program as an array. @@ -674,6 +714,26 @@ void __init enable_local_APIC(void) value &= ~APIC_TPRI_MASK; /* Set Task Priority to 'accept all' */ apic_write(APIC_TASKPRI,value); + /* + * Set arbitrarion priority to 0 + */ + value = apic_read(APIC_ARBPRI); + value &= ~APIC_ARBPRI_MASK; + apic_write(APIC_ARBPRI, value); + + /* + * Set the logical destination ID to 'all', just to be safe. + * also, put the APIC into flat delivery mode. + */ + value = apic_read(APIC_LDR); + value &= ~APIC_LDR_MASK; + value |= SET_APIC_LOGICAL_ID(0xff); + apic_write(APIC_LDR,value); + + value = apic_read(APIC_DFR); + value |= SET_APIC_DFR(0xf); + apic_write(APIC_DFR, value); + udelay(100); /* B safe */ ack_APIC_irq(); udelay(100); @@ -681,14 +741,11 @@ void __init enable_local_APIC(void) unsigned long __init init_smp_mappings(unsigned long memory_start) { - unsigned long apic_phys, ioapic_phys; + unsigned long apic_phys; memory_start = PAGE_ALIGN(memory_start); if (smp_found_config) { apic_phys = mp_lapic_addr; -#ifdef CONFIG_X86_IO_APIC - ioapic_phys = mp_ioapic_addr; -#endif } else { /* * set up a fake all zeroes page to simulate the @@ -697,17 +754,27 @@ unsigned long __init init_smp_mappings(unsigned long memory_start) * this way if some buggy code writes to this page ... */ apic_phys = __pa(memory_start); - ioapic_phys = __pa(memory_start+PAGE_SIZE); - memset((void *)memory_start, 0, 2*PAGE_SIZE); - memory_start += 2*PAGE_SIZE; + memset((void *)memory_start, 0, PAGE_SIZE); + memory_start += PAGE_SIZE; } - -#ifdef CONFIG_X86_IO_APIC set_fixmap(FIX_APIC_BASE,apic_phys); - set_fixmap(FIX_IO_APIC_BASE,ioapic_phys); - printk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys); - printk("mapped IOAPIC to %08lx (%08lx)\n", fix_to_virt(FIX_IO_APIC_BASE), ioapic_phys); + +#ifdef CONFIG_X86_IO_APIC + { + unsigned long ioapic_phys; + + if (smp_found_config) { + ioapic_phys = mp_ioapic_addr; + } else { + ioapic_phys = __pa(memory_start); + memset((void *)memory_start, 0, PAGE_SIZE); + memory_start += PAGE_SIZE; + } + set_fixmap(FIX_IO_APIC_BASE,ioapic_phys); + printk("mapped IOAPIC to %08lx (%08lx)\n", + fix_to_virt(FIX_IO_APIC_BASE), ioapic_phys); + } #endif return memory_start; @@ -925,8 +992,7 @@ static void __init do_boot_cpu(int i) apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ cfg=apic_read(APIC_ICR); cfg&=~0xCDFFF; /* Clear bits */ - cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG - | APIC_DEST_ASSERT | APIC_DEST_DM_INIT); + cfg |= (APIC_DEST_LEVELTRIG | APIC_DEST_ASSERT | APIC_DEST_DM_INIT); apic_write(APIC_ICR, cfg); /* Send IPI */ udelay(200); @@ -937,8 +1003,7 @@ static void __init do_boot_cpu(int i) apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ cfg=apic_read(APIC_ICR); cfg&=~0xCDFFF; /* Clear bits */ - cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG - | APIC_DEST_DM_INIT); + cfg |= (APIC_DEST_LEVELTRIG | APIC_DEST_DM_INIT); apic_write(APIC_ICR, cfg); /* Send IPI */ /* @@ -974,9 +1039,7 @@ static void __init do_boot_cpu(int i) apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ cfg=apic_read(APIC_ICR); cfg&=~0xCDFFF; /* Clear bits */ - cfg |= (APIC_DEST_FIELD - | APIC_DEST_DM_STARTUP - | (start_eip >> 12)); /* Boot on the stack */ + cfg |= (APIC_DEST_DM_STARTUP | (start_eip >> 12)); /* Boot on the stack */ SMP_PRINTK(("Before start apic_write.\n")); apic_write(APIC_ICR, cfg); /* Kick the second */ @@ -1099,7 +1162,6 @@ unsigned int prof_counter[NR_CPUS]; void __init smp_boot_cpus(void) { int i; - unsigned long cfg; #ifdef CONFIG_MTRR /* Must be done before other processors booted */ @@ -1134,20 +1196,20 @@ void __init smp_boot_cpus(void) cpu_number_map[boot_cpu_id] = 0; -#ifdef CONFIG_X86_IO_APIC /* - * If we don't conform to the Intel MPS standard, get out - * of here now! + * If we couldnt find an SMP configuration at boot time, + * get out of here now! */ if (!smp_found_config) { printk(KERN_NOTICE "SMP motherboard not detected. Using dummy APIC emulation.\n"); +#ifndef CONFIG_VISWS io_apic_irqs = 0; +#endif cpu_online_map = cpu_present_map; goto smp_done; } -#endif /* * If SMP should be disabled, then really disable it! @@ -1246,29 +1308,34 @@ void __init smp_boot_cpus(void) * Cleanup possible dangling ends... */ - /* - * Install writable page 0 entry. - */ - - cfg = pg0[0]; - pg0[0] = 3; /* writeable, present, addr 0 */ - local_flush_tlb(); +#ifndef CONFIG_VISWS + { + unsigned long cfg; - /* - * Paranoid: Set warm reset code and vector here back - * to default values. - */ + /* + * Install writable page 0 entry. + */ + cfg = pg0[0]; + pg0[0] = 3; /* writeable, present, addr 0 */ + local_flush_tlb(); + + /* + * Paranoid: Set warm reset code and vector here back + * to default values. + */ - CMOS_WRITE(0, 0xf); + CMOS_WRITE(0, 0xf); - *((volatile long *) phys_to_virt(0x467)) = 0; + *((volatile long *) phys_to_virt(0x467)) = 0; - /* - * Restore old page 0 entry. - */ + /* + * Restore old page 0 entry. + */ - pg0[0] = cfg; - local_flush_tlb(); + pg0[0] = cfg; + local_flush_tlb(); + } +#endif /* * Allow the user to impress friends. @@ -1301,15 +1368,16 @@ void __init smp_boot_cpus(void) SMP_PRINTK(("Boot done.\n")); cache_APIC_registers(); -#ifdef CONFIG_X86_IO_APIC +#ifndef CONFIG_VISWS /* * Here we can be sure that there is an IO-APIC in the system. Let's * go and set it up: */ if (!skip_ioapic_setup) setup_IO_APIC(); -smp_done: #endif + +smp_done: } @@ -1393,7 +1461,7 @@ static inline int __prepare_ICR (unsigned int shortcut, int vector) unsigned int cfg; cfg = __get_ICR(); - cfg |= APIC_DEST_FIELD|APIC_DEST_DM_FIXED|shortcut|vector; + cfg |= APIC_DEST_DM_FIXED|shortcut|vector; return cfg; } @@ -1903,7 +1971,7 @@ int __init calibrate_APIC_clock(void) ((long)(t2-t1)/LOOPS)/(1000000/HZ), ((long)(t2-t1)/LOOPS)%(1000000/HZ) ); - printk("..... APIC bus clock speed is %ld.%04ld MHz.\n", + printk("..... system bus clock speed is %ld.%04ld MHz.\n", calibration_result/(1000000/HZ), calibration_result%(1000000/HZ) ); #undef LOOPS diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index c3cf3e288..dc96ad4bb 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -279,39 +279,6 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_ * kernel. * It may also hold the MP configuration table when we are booting SMP. */ -#ifdef __SMP__ - /* - * FIXME: Linux assumes you have 640K of base ram.. - * this continues the error... - * - * 1) Scan the bottom 1K for a signature - * 2) Scan the top 1K of base RAM - * 3) Scan the 64K of bios - */ - if (!smp_scan_config(0x0,0x400) && - !smp_scan_config(639*0x400,0x400) && - !smp_scan_config(0xF0000,0x10000)) { - /* - * If it is an SMP machine we should know now, unless the - * configuration is in an EISA/MCA bus machine with an - * extended bios data area. - * - * there is a real-mode segmented pointer pointing to the - * 4K EBDA area at 0x40E, calculate and scan it here. - * - * NOTE! There are Linux loaders that will corrupt the EBDA - * area, and as such this kind of SMP config may be less - * trustworthy, simply because the SMP table may have been - * stomped on during early boot. These loaders are buggy and - * should be fixed. - */ - address = *(unsigned short *)phys_to_virt(0x40E); - address<<=4; - smp_scan_config(address, 0x1000); - if (smp_found_config) - printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.rutgers.edu if you experience SMP problems!\n"); - } -#endif start_mem = PAGE_ALIGN(start_mem); address = PAGE_OFFSET; pg_dir = swapper_pg_dir; diff --git a/drivers/block/ide-pci.c b/drivers/block/ide-pci.c index 36b2cc0b0..df9c715e1 100644 --- a/drivers/block/ide-pci.c +++ b/drivers/block/ide-pci.c @@ -150,22 +150,15 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { */ __initfunc(static unsigned int ide_special_settings (struct pci_dev *dev, const char *name)) { - unsigned int addressbios = 0; - - pci_read_config_dword(dev, PCI_ROM_ADDRESS, &addressbios); - switch(dev->device) { case PCI_DEVICE_ID_ARTOP_ATP850UF: case PCI_DEVICE_ID_PROMISE_20246: - pci_write_config_byte(dev, PCI_ROM_ADDRESS, PCI_ROM_ADDRESS_ENABLE); - printk("%s: ROM enabled ", name); - - if (!addressbios) { - printk("but no address\n"); - } else { - printk("at 0x%08x\n", addressbios); + if (dev->rom_address) { + pci_write_config_byte(dev, PCI_ROM_ADDRESS, + dev->rom_address | PCI_ROM_ADDRESS_ENABLE); + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->rom_address); } - + if ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID) { unsigned char irq1 = 0, irq2 = 0; diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c index 1735778f4..90c117467 100644 --- a/drivers/char/bttv.c +++ b/drivers/char/bttv.c @@ -535,6 +535,8 @@ static struct tvcard tvcards[] = { 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0}, /* AVerMedia TVCapture 98 */ { 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0}, + /* Aimslab VHX */ + { 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}}, }; #define TVCARDS (sizeof(tvcards)/sizeof(tvcard)) @@ -764,7 +766,7 @@ static struct tvnorm tvnorms[] = { /* NTSC */ { 28636363, 768, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0), - 910, 128, 754, 0x1a, 144}, + 910, 128, 910, 0x1a, 144}, /* { 28636363, 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0), @@ -815,10 +817,6 @@ static void make_vbitab(struct bttv *btv) DEBUG(printk(KERN_DEBUG "po: 0x%08x\n",(int)po)); DEBUG(printk(KERN_DEBUG "pe: 0x%08x\n",(int)pe)); - /* setup proper VBI capture length for given video mode */ - btwrite(tvnorms[btv->win.norm].vbipack, BT848_VBI_PACK_SIZE); - btwrite(1, BT848_VBI_PACK_DEL); - *(po++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(po++)=0; for (i=0; i<16; i++) { @@ -1281,6 +1279,8 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt) btwrite(tvn->adelay, BT848_ADELAY); btwrite(tvn->bdelay, BT848_BDELAY); btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM); + btwrite(tvn->vbipack, BT848_VBI_PACK_SIZE); + btwrite(1, BT848_VBI_PACK_DEL); btv->pll.pll_ofreq = tvn->Fsc; set_pll(btv); @@ -2880,7 +2880,9 @@ static void idcard(int i) } else if (I2CRead(&(btv->i2c), I2C_STBEE)>=0) { btv->type=BTTV_STB; - + } else + if (I2CRead(&(btv->i2c), I2C_VHX)>=0) { + btv->type=BTTV_VHX; } else { if (I2CRead(&(btv->i2c), 0x80)>=0) /* check for msp34xx */ btv->type = BTTV_MIROPRO; @@ -2938,6 +2940,9 @@ static void idcard(int i) case TDA9850: init_tda9850(&(btv->i2c)); break; + case TDA9840: + init_tda9840(&(btv->i2c)); + break; case TDA8425: init_tda8425(&(btv->i2c)); break; @@ -2977,6 +2982,9 @@ static void idcard(int i) case BTTV_AVERMEDIA98: strcat(btv->video_dev.name,"(AVerMedia TVCapture 98)"); break; + case BTTV_VHX: + strcpy(btv->video_dev.name,"BT848(Aimslab-VHX)"); + break; } printk("%s\n",btv->video_dev.name); audio(btv, AUDIO_MUTE); diff --git a/drivers/char/bttv.h b/drivers/char/bttv.h index 7327f3a94..ba6c52af4 100644 --- a/drivers/char/bttv.h +++ b/drivers/char/bttv.h @@ -21,7 +21,7 @@ #ifndef _BTTV_H_ #define _BTTV_H_ -#define BTTV_VERSION_CODE 0x000520 +#define BTTV_VERSION_CODE 0x000523 #include #include @@ -37,8 +37,7 @@ #define MAX_GBUFFERS 2 #define RISCMEM_LEN (32744*2) -#define VBI_MAXLINES 19 -#define VBIBUF_SIZE (2048*VBI_MAXLINES*2) +#define VBIBUF_SIZE 65536 /* maximum needed buffer size for extended VBI frame mode capturing */ #define BTTV_MAX_FBUF 0x190000 @@ -207,6 +206,7 @@ struct bttv #define BTTV_MIROPRO 0x0b #define BTTV_ADSTECH_TV 0x0c #define BTTV_AVERMEDIA98 0x0d +#define BTTV_VHX 0x0e #define AUDIO_TUNER 0x00 #define AUDIO_RADIO 0x01 @@ -227,6 +227,7 @@ struct bttv #define I2C_TDA8425 0x82 #define I2C_HAUPEE 0xa0 #define I2C_STBEE 0xae +#define I2C_VHX 0xc0 #define TDA9840_SW 0x00 #define TDA9840_LVADJ 0x02 diff --git a/drivers/char/mem.c b/drivers/char/mem.c index f8548fea9..6eaa07d23 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -4,6 +4,7 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ +#include #include #include #include diff --git a/drivers/char/msp3400.c b/drivers/char/msp3400.c index 80729ea85..abf08764d 100644 --- a/drivers/char/msp3400.c +++ b/drivers/char/msp3400.c @@ -83,7 +83,7 @@ struct msp3400c { /* thread */ struct task_struct *thread; - struct semaphore *wait; + struct wait_queue *wq; struct semaphore *notify; int active,restart,rmmod; @@ -500,14 +500,12 @@ static void msp3400c_stereo_wake(unsigned long data) { struct msp3400c *msp = (struct msp3400c*)data; /* XXX alpha ??? */ - if (!msp->active) - up(msp->wait); + wake_up_interruptible(&msp->wq); } static int msp3400c_thread(void *data) { struct msp3400c *msp = data; - struct semaphore sem = MUTEX_LOCKED; struct CARRIER_DETECT *cd; int count, max1,max2,val1,val2, val,this; @@ -525,7 +523,7 @@ static int msp3400c_thread(void *data) current->fs->umask = 0; strcpy(current->comm,"msp3400"); - msp->wait = &sem; + msp->wq = NULL; msp->thread = current; #ifdef __SMP__ @@ -541,7 +539,7 @@ static int msp3400c_thread(void *data) goto done; if (debug > 1) printk("msp3400: thread: sleep\n"); - down_interruptible(&sem); + interruptible_sleep_on(&msp->wq); if (debug > 1) printk("msp3400: thread: wakeup\n"); if (msp->rmmod || signal_pending(current)) @@ -735,7 +733,6 @@ static int msp3400c_thread(void *data) done: dprintk("msp3400: thread: exit\n"); - msp->wait = NULL; msp->active = 0; msp->thread = NULL; @@ -777,6 +774,7 @@ static int msp3410d_thread(void *data) goto done; dprintk("msp3410: thread: sleep\n"); down_interruptible(&sem); + sem.owner = 0; dprintk("msp3410: thread: wakeup\n"); if (msp->rmmod) goto done; @@ -1072,12 +1070,12 @@ static int msp3400c_attach(struct i2c_device *device) /* startup control thread */ MOD_INC_USE_COUNT; + msp->wq = NULL; msp->notify = &sem; kernel_thread(msp3400c_thread, (void *)msp, 0); down(&sem); msp->notify = NULL; - if (!msp->active) - up(msp->wait); + wake_up_interruptible(&msp->wq); printk(KERN_INFO "msp3400: init: chip=%s",device->name); if (msp->nicam) @@ -1109,8 +1107,7 @@ static int msp3400c_detach(struct i2c_device *device) { msp->notify = &sem; msp->rmmod = 1; - if (!msp->active) - up(msp->wait); + wake_up_interruptible(&msp->wq); down(&sem); msp->notify = NULL; } @@ -1158,10 +1155,9 @@ static int msp3400c_command(struct i2c_device *device, /* channels switching step two -- trigger sound carrier scan */ msp->watch_stereo=0; del_timer(&msp->wake_stereo); - if (!msp->active) - up(msp->wait); - else + if (msp->active) msp->restart = 1; + wake_up_interruptible(&msp->wq); break; case MSP_GET_VOLUME: diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c index 47d5c208f..b20d517b6 100644 --- a/drivers/char/pc_keyb.c +++ b/drivers/char/pc_keyb.c @@ -79,11 +79,11 @@ static int aux_count = 0; #define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT) #define MAX_RETRIES 60 /* some aux operations take long time*/ -#if defined(__alpha__) && !defined(CONFIG_PCI) -# define AUX_IRQ 9 /* Jensen is odd indeed */ -#else + +#ifndef AUX_IRQ # define AUX_IRQ 12 #endif + #endif /* CONFIG_PSMOUSE */ /* @@ -811,7 +811,7 @@ static int release_aux(struct inode * inode, struct file * file) if (--aux_count) return 0; kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */ - kbd_write(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); + kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE); free_irq(AUX_IRQ, AUX_DEV); return 0; } @@ -831,7 +831,7 @@ static int open_aux(struct inode * inode, struct file * file) aux_count--; return -EBUSY; } - kbd_write(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable the + kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on controller. */ aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */ @@ -950,14 +950,14 @@ static int __init psaux_init(void) queue->proc_list = NULL; #ifdef INITIALIZE_MOUSE - kbd_write(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable Aux. */ + kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */ aux_write_dev(AUX_SET_SAMPLE); aux_write_dev(100); /* 100 samples/sec */ aux_write_dev(AUX_SET_RES); aux_write_dev(3); /* 8 counts per mm */ aux_write_dev(AUX_SET_SCALE21); /* 2:1 scaling */ #endif /* INITIALIZE_MOUSE */ - kbd_write(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable aux device. */ + kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */ kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */ return 0; diff --git a/drivers/net/ibmtr.c b/drivers/net/ibmtr.c index 6290ac882..990610648 100644 --- a/drivers/net/ibmtr.c +++ b/drivers/net/ibmtr.c @@ -801,10 +801,10 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) struct tok_info *ti; struct device *dev; + dev = dev_id; #if TR_VERBOSE DPRINTK("Int from tok_driver, dev : %p\n",dev); #endif - dev = dev_id; ti = (struct tok_info *) dev->priv; /* Disable interrupts till processing is finished */ diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 66d069faf..ae8bcb27b 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include diff --git a/drivers/net/irda/uircc.c b/drivers/net/irda/uircc.c index 7f5f08bb7..05da78a00 100644 --- a/drivers/net/irda/uircc.c +++ b/drivers/net/irda/uircc.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index 8f152673c..1b48abd36 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -70,6 +70,7 @@ pci_clone_list[] __initdata = { {0x4a14, 0x5000, "NetVin NV5000SC"}, {0x1106, 0x0926, "Via 82C926"}, {0x10bd, 0x0e34, "SureCom NE34"}, + {0x1050, 0x5a5a, "Winbond"}, {0,} }; diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 544240732..b020d1b78 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -1,6 +1,8 @@ #ifndef __MEGARAID_H__ #define __MEGARAID_H__ +#include + #define IN_ISR 0x80000000L #define NO_INTR 0x40000000L #define IN_TIMEOUT 0x20000000L diff --git a/drivers/sound/ad1816.c b/drivers/sound/ad1816.c index 70af92ce7..6d7c2e13e 100644 --- a/drivers/sound/ad1816.c +++ b/drivers/sound/ad1816.c @@ -1,6 +1,6 @@ /* -AD1816 lowlevel sound driver for Linux 2.1.128 (and above) +AD1816 lowlevel sound driver for Linux 2.2.0 and above Copyright (C) 1998 by Thorsten Knabe Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996 @@ -32,16 +32,18 @@ Please report any bugs to: tek@rbg.informatik.tu-darmstadt.de ------------------------------------------------------------------------------- -version: 1.1 -cvs: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.24.2.8 1998/12/04 16:39:46 tek Exp $ +version: 1.2 +cvs: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.28 1999/01/16 19:01:36 tek Exp $ status: experimental -date: 1998/12/04 +date: 1999/01/16 Changes: Oleg Drokin: Some cleanup of load/unload functions. 1998/11/24 Thorsten Knabe: attach and unload rewritten, some argument checks added 1998/11/30 + + Thorsten Knabe: Buggy isa bridge workaround added 1999/01/16 */ #include @@ -164,7 +166,9 @@ static void ad1816_halt_input (int dev) save_flags (flags); cli (); - disable_dma(audio_devs[dev]->dmap_in->dma); + if(!isa_dma_bridge_buggy) { + disable_dma(audio_devs[dev]->dmap_in->dma); + } buffer=inb(devc->base+9); if (buffer & 0x01) { @@ -172,8 +176,10 @@ static void ad1816_halt_input (int dev) outb(buffer & ~0x01,devc->base+9); } - enable_dma(audio_devs[dev]->dmap_in->dma); - + if(!isa_dma_bridge_buggy) { + enable_dma(audio_devs[dev]->dmap_in->dma); + } + /* Clear interrupt status */ outb (~0x40, devc->base+1); @@ -195,15 +201,20 @@ static void ad1816_halt_output (int dev) /* Mute pcm output */ ad_write(devc, 4, ad_read(devc,4)|0x8080); - disable_dma(audio_devs[dev]->dmap_out->dma); - + if(!isa_dma_bridge_buggy) { + disable_dma(audio_devs[dev]->dmap_out->dma); + } + buffer=inb(devc->base+8); if (buffer & 0x01) { /* disable capture */ outb(buffer & ~0x01,devc->base+8); } - enable_dma(audio_devs[dev]->dmap_out->dma); - + + if(!isa_dma_bridge_buggy) { + enable_dma(audio_devs[dev]->dmap_out->dma); + } + /* Clear interrupt status */ outb ((unsigned char)~0x80, devc->base+1); @@ -707,11 +718,11 @@ MIX_ENT(SOUND_MIXER_LINE3, 39, 0, 9, 4, 39, 1, 0, 5) static unsigned short default_mixer_levels[SOUND_MIXER_NRDEVICES] = { - 0x6464, /* Master Volume */ + 0x4343, /* Master Volume */ 0x3232, /* Bass */ 0x3232, /* Treble */ 0x0000, /* FM */ - 0x6464, /* PCM */ + 0x4343, /* PCM */ 0x0000, /* PC Speaker */ 0x0000, /* Ext Line */ 0x0000, /* Mic */ @@ -1080,7 +1091,13 @@ int probe_ad1816 ( struct address_info *hw_config ) int tmp; printk("ad1816: AD1816 sounddriver Copyright (C) 1998 by Thorsten Knabe\n"); - printk("ad1816: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.24.2.8 1998/12/04 16:39:46 tek Exp $\n"); + printk("ad1816: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.28 1999/01/16 19:01:36 tek Exp $\n"); + printk("ad1816: io=0x%x, irq=%d, dma=%d, dma2=%d, isadmabug=%d\n", + hw_config->io_base, + hw_config->irq, + hw_config->dma, + hw_config->dma2, + isa_dma_bridge_buggy); if (check_region (io_base, 16)) { printk ("ad1816: I/O port 0x%03x not free\n", io_base); diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c index 24a3aa829..158108442 100644 --- a/drivers/sound/sb_card.c +++ b/drivers/sound/sb_card.c @@ -136,6 +136,7 @@ int trix = 0; /* Set trix=1 to load this as support for trix */ int pas2 = 0; /* Set pas2=1 to load this as support for pas2 */ int sm_games = 0; /* Mixer - see sb_mixer.c */ int acer = 0; /* Do acer notebook init */ +int esstype = 0; /* ESS chip type */ MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); @@ -147,6 +148,7 @@ MODULE_PARM(mad16, "i"); MODULE_PARM(trix, "i"); MODULE_PARM(pas2, "i"); MODULE_PARM(sm_games, "i"); +MODULE_PARM(esstype, "i"); void *smw_free = NULL; diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c index 6655ebd6d..907250981 100644 --- a/drivers/sound/sb_common.c +++ b/drivers/sound/sb_common.c @@ -645,10 +645,6 @@ int sb_dsp_init(struct address_info *hw_config) } } } -#if defined(__SMP__) - /* Skip IRQ detection if SMP (doesn't work) */ - devc->irq_ok = 1; -#else if (devc->major == 4 && devc->minor <= 11 ) /* Won't work */ devc->irq_ok = 1; else @@ -671,7 +667,6 @@ int sb_dsp_init(struct address_info *hw_config) DDB(printk("IRQ test OK (IRQ%d)\n", devc->irq)); } } -#endif /* __SMP__ */ } /* IRQ setup */ request_region(hw_config->io_base, 16, "soundblaster"); diff --git a/drivers/sound/sb_ess.c b/drivers/sound/sb_ess.c index cb23ac9aa..d1fdd4ccb 100644 --- a/drivers/sound/sb_ess.c +++ b/drivers/sound/sb_ess.c @@ -2,8 +2,6 @@ * Created: 9-Jan-1999 * * TODO: consistency speed calculations!! - * what's the sample rate when duplex? Docs contradict. - * I broke IRQ detection for non-SMP machines * ????: Did I break MIDI support? * * This files contains ESS chip specifics. It's based on the existing ESS @@ -19,6 +17,10 @@ * be one of 0, 1 or 3, dma16 can be one of 0, 1, 3 or 5. DMA 5 is a 16 bit * DMA channel, while the others are 8 bit.. * + * ESS detection isn't full proof (yet). If it fails an additional module + * parameter esstype can be specified to be one of the following: + * 688, 1688, 1868, 1869, 1788, 1887, 1888 + * * History: * * Rolf Fokkens (Dec 20 1998): ES188x recording level support on a per @@ -77,6 +79,9 @@ * Oh, and this is another trap: in ES1887 docs mixer register 0x70 is decribed * as if it's exactly the same as register 0xa1. This is *NOT* true. The * description of 0x70 in ES1869 docs is accurate however. + * Well, the assumption about ES1869 was wrong: register 0x70 is very much + * like register 0xa1, except that bit 7 is allways 1, whatever you want + * it to be. * * When using audio 2 mixer register 0x72 seems te be meaningless. Only 0xa2 * has effect. @@ -85,6 +90,16 @@ * the fact that register 0x78 isn't reset is great when you wanna change back * to single dma operation (simplex): audio 2 is still operation, and uses the * same dma as audio 1: your ess changes into a funny echo machine. + * + * Received the new that ES1688 is detected as a ES1788. Did some thinking: + * the ES1887 detection scheme suggests in step 2 to try if bit 3 of register + * 0x64 can be changed. This is inaccurate, first I inverted the * check: "If + * can be modified, it's a 1688", which lead to a correct detection + * of my ES1887. It resulted however in bad detection of 1688 (reported by mail) + * and 1868 (if no PnP detection first): they result in a 1788 being detected. + * I don't have docs on 1688, but I do have docs on 1868: The documentation is + * probably inaccurate in the fact that I should check bit 2, not bit 3. This + * is what I do now. */ /* @@ -141,14 +156,14 @@ * ES1946 yes This is a PCI chip; not handled by this driver */ -#include - #include "sound_config.h" #include "sb_mixer.h" #include "sb.h" #include "sb_ess.h" +extern int esstype; /* module parameter in sb_card.c */ + #ifdef FKS_LOGGING static void ess_show_mixerregs (sb_devc *devc); #endif @@ -255,10 +270,10 @@ static int ess_calc_div (int clock, int revert, int *speedp, int *diffp) int retval; speed = *speedp; - divider = (clock + speed / 2) / *speedp; + divider = (clock + speed / 2) / speed; retval = revert - divider; - if (retval > 127) { - retval = 127; + if (retval > revert - 1) { + retval = revert - 1; divider = revert - retval; } /* This line is suggested. Must be wrong I think @@ -299,60 +314,59 @@ static int ess_calc_best_speed /* * Depending on the audiochannel ESS devices can - * have different clock settings. + * have different clock settings. These are made consistent for duplex + * however. * callers of ess_speed only do an audionum suggestion, which means * input suggests 1, output suggests 2. This suggestion is only true * however when doing duplex. */ -static void ess_speed (sb_devc *devc, int audionum) +static void ess_common_speed (sb_devc *devc, int *speedp, int *divp) { - int choice; - int speed = devc->speed; - int clock1, clock2; - int rev1, rev2; - int div; - - if (!devc->duplex) audionum = 1; + int diff = 0, div, choice; - if (audionum == 1) { - rev1 = 128; - clock1 = 397700; - rev2 = 256; - clock2 = 795500; + if (devc->duplex) { + /* + * The 0x80 is important for the first audio channel + */ + div = 0x80 | ess_calc_div (795500, 128, speedp, &diff); } else { - rev1 = 128; - clock1 = 793800; - rev2 = 128; - clock2 = 768000; + choice = ess_calc_best_speed (397700, 128, 795500, 256, &div, speedp); + if (choice == 2) div |= 0x80; } - choice = ess_calc_best_speed - (clock1, rev1, clock2, rev2, &div, &speed); + *divp = div; +} + +static void ess_speed (sb_devc *devc, int audionum) +{ + int speed; + int div, div2; + + ess_common_speed (devc, &(devc->speed), &div); #ifdef FKS_REG_LOGGING -printk (KERN_INFO "FKS: ess_speed (%d) b speed = %d, div=%x\n", audionum, speed, div); +printk (KERN_INFO "FKS: ess_speed (%d) b speed = %d, div=%x\n", audionum, devc->speed, div); #endif - if (choice == 2) div |= 0x80; + /* Set filter roll-off to 90% of speed/2 */ + speed = (devc->speed * 9) / 20; + + div2 = 256 - 7160000 / (speed * 82); + + if (!devc->duplex) audionum = 1; if (audionum == 1) { /* Change behaviour of register A1 * sb_chg_mixer(devc, 0x71, 0x20, 0x20) * For ES1869 only??? */ ess_write (devc, 0xa1, div); + ess_write (devc, 0xa2, div2); } else { ess_setmixer (devc, 0x70, div); - } - - /* Set filter roll-off to 90% of speed/2 */ - speed = (speed * 9) / 20; - - div = 256 - 7160000 / (speed * 82); - - if (audionum == 1) { - ess_write (devc, 0xa2, div); - } else { - ess_write (devc, 0xa2, div); - ess_setmixer (devc, 0x72, div); + /* + * FKS: fascinating: 0x72 doesn't seem to work. + */ + ess_write (devc, 0xa2, div2); + ess_setmixer (devc, 0x72, div2); } } @@ -442,7 +456,9 @@ static int ess_audio_prepare_for_output_audio2 (int dev, int bsize, int bcount) sb_devc *devc = audio_devs[dev]->devc; unsigned char bits; +/* FKS: qqq sb_dsp_reset(devc); +*/ /* * Auto-Initialize: @@ -626,31 +642,19 @@ static void ess_audio_trigger(int dev, int bits) devc->trigger_bits = bits | bits_16; } -/* - * FKS: Change this!! it's the old routine! - */ static int ess_audio_set_speed(int dev, int speed) { sb_devc *devc = audio_devs[dev]->devc; - int divider; + int minspeed, maxspeed, dummydiv; - if (speed > 0) - { - if (speed < 5000) - speed = 5000; - if (speed > 48000) - speed = 48000; + if (speed > 0) { + minspeed = (devc->duplex ? 6215 : 5000 ); + maxspeed = (devc->duplex ? 44100 : 48000); + if (speed < minspeed) speed = minspeed; + if (speed > maxspeed) speed = maxspeed; + + ess_common_speed (devc, &speed, &dummydiv); - if (speed > 22000) - { - divider = (795500 + speed / 2) / speed; - speed = (795500 + divider / 2) / divider; - } - else - { - divider = (397700 + speed / 2) / speed; - speed = (397700 + divider / 2) / divider; - } devc->speed = speed; } return devc->speed; @@ -972,7 +976,7 @@ int ess_init(sb_devc * devc, struct address_info *hw_config) unsigned char cfg; int ess_major = 0, ess_minor = 0; int i; - static char name[100]; + static char name[100], modelname[10]; /* * Try to detect ESS chips. @@ -1022,13 +1026,42 @@ int ess_init(sb_devc * devc, struct address_info *hw_config) if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) { char *chip = NULL; - if ((ess_minor & 0x0f) < 8) { + if (esstype) { + int submodel = -1; + + switch (esstype) { + case 688: + submodel = 0x00; + break; + case 1688: + submodel = 0x08; + break; + case 1868: + submodel = SUBMDL_ES1868; + break; + case 1869: + submodel = SUBMDL_ES1869; + break; + case 1788: + submodel = SUBMDL_ES1788; + break; + case 1887: + submodel = SUBMDL_ES1887; + break; + case 1888: + submodel = SUBMDL_ES1888; + break; + }; + if (submodel != -1) { + devc->submodel = submodel; + sprintf (modelname, "ES%d", esstype); + chip = modelname; + }; + }; + if (chip == NULL && (ess_minor & 0x0f) < 8) { chip = "ES688"; }; -#ifdef FKS_LOGGING -printk(KERN_INFO "FKS: mixer_reset\n"); - ess_setmixer (devc, 0x00, 0x00); -#endif + if (chip == NULL) { int type; @@ -1049,7 +1082,24 @@ printk(KERN_INFO "FKS: mixer_reset\n"); break; }; }; - if (chip == NULL && !ess_probe(devc, 0x64, (1 << 3))) { +#if 0 + /* + * this one failed: + * the probing of bit 4 is another thought: from ES1788 and up, all + * chips seem to have hardware volume control. Bit 4 is readonly to + * check if a hardware volume interrupt has fired. + * Cause ES688/ES1688 don't have this feature, bit 4 might be writeable + * for these chips. + */ + if (chip == NULL && !ess_probe(devc, 0x64, (1 << 4))) { +#endif + /* + * the probing of bit 2 is my idea. The ES1887 docs want me to probe + * bit 3. This results in ES1688 being detected as ES1788. + * Bit 2 is for "Enable HWV IRQE", but as ES(1)688 chips don't have + * HardWare Volume, I think they don't have this IRQE. + */ + if (chip == NULL && ess_probe(devc, 0x64, (1 << 2))) { if (ess_probe (devc, 0x70, 0x7f)) { if (ess_probe (devc, 0x64, (1 << 5))) { chip = "ES1887"; diff --git a/drivers/sound/sb_mixer.c b/drivers/sound/sb_mixer.c index dca68c929..97ce1b39d 100644 --- a/drivers/sound/sb_mixer.c +++ b/drivers/sound/sb_mixer.c @@ -425,7 +425,6 @@ static int set_recmask(sb_devc * devc, int mask) if (devc->model == MDL_ESS && ess_set_recmask (devc, &devmask)) { break; }; -printk (KERN_INFO "FKS: set_recmask not handled by ess_set_recmask\n"); if (devmask != SOUND_MASK_MIC && devmask != SOUND_MASK_LINE && devmask != SOUND_MASK_CD) diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c index 22f791df5..2a099d865 100644 --- a/fs/coda/cnode.c +++ b/fs/coda/cnode.c @@ -83,19 +83,21 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb) } cnp = ITOC(*inode); - if ( cnp->c_magic == 0 ) { - memset(cnp, 0, (int) sizeof(struct coda_inode_info)); - cnp->c_fid = *fid; - cnp->c_magic = CODA_CNODE_MAGIC; - cnp->c_flags = 0; - cnp->c_vnode = *inode; - INIT_LIST_HEAD(&(cnp->c_cnhead)); - INIT_LIST_HEAD(&(cnp->c_volrootlist)); - } else { - cnp->c_flags = 0; - printk("coda_cnode make on initialized inode %ld, %s!\n", - (*inode)->i_ino, coda_f2s(&cnp->c_fid)); - } + if ( cnp->c_magic != 0 ) { + printk("coda_cnode make on initialized inode %ld, old %s new +%s!\n", + (*inode)->i_ino, coda_f2s(&cnp->c_fid), coda_f2s2(fid)); + iput(*inode); + return -ENOENT; + } + + memset(cnp, 0, (int) sizeof(struct coda_inode_info)); + cnp->c_fid = *fid; + cnp->c_magic = CODA_CNODE_MAGIC; + cnp->c_flags = 0; + cnp->c_vnode = *inode; + INIT_LIST_HEAD(&(cnp->c_cnhead)); + INIT_LIST_HEAD(&(cnp->c_volrootlist)); /* fill in the inode attributes */ if ( coda_f2i(fid) != ino ) { diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c index 5344baaea..f684f3a78 100644 --- a/fs/coda/coda_linux.c +++ b/fs/coda/coda_linux.c @@ -30,7 +30,7 @@ int coda_debug = 0; int coda_print_entry = 0; int coda_access_cache = 1; -/* caller must allocate 36 byte string ! */ +/* print a fid */ char * coda_f2s(ViceFid *f) { static char s[60]; @@ -41,6 +41,17 @@ char * coda_f2s(ViceFid *f) return s; } +/* print another fid */ +char * coda_f2s2(ViceFid *f) +{ + static char s[60]; + if ( f ) { + sprintf(s, "(%-#lx,%-#lx,%-#lx)", + f->Volume, f->Vnode, f->Unique); + } + return s; +} + /* recognize special .CONTROL name */ int coda_iscontrol(const char *name, size_t length) { diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 5f13d8ca9..7ba943cd6 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -1,3 +1,4 @@ + /* * Directory operations for Coda filesystem * Original version: (C) 1996 P. Braam and M. Callahan @@ -834,12 +835,19 @@ CDEBUG(D_FILE, "entry %d: ino %ld, namlen %d, reclen %d, type %d, pos %d, string if ( !vdirent->d_reclen ) { printk("CODA: Invalid directory, cfino: %ld\n", filp->f_dentry->d_inode->i_ino); + result = -EINVAL; break; } pos += (unsigned int) vdirent->d_reclen; i++; } + if ( i >= 1024 ) { + printk("Repeating too much in readdir %ld\n", + filp->f_dentry->d_inode->i_ino); + result = -EINVAL; + } + exit: CODA_FREE(buff, DIR_BUFSIZE); return result; @@ -853,18 +861,35 @@ static int coda_dentry_revalidate(struct dentry *de) struct coda_inode_info *cii; ENTRY; - if (inode) { - if (is_bad_inode(inode)) - return 0; - cii = ITOC(de->d_inode); - if (cii->c_flags & C_PURGE) - valid = 0; - if (cii->c_flags & C_FLUSH) { - coda_flag_inode_children(inode, C_FLUSH); - valid = 0; - } + if (!inode) + return 1; + + cii = ITOC(de->d_inode); + if (coda_isroot(inode)) + return 1; + if (is_bad_inode(inode)) + return 0; + + if (! (cii->c_flags & (C_PURGE | C_FLUSH)) ) + return valid; + + shrink_dcache_parent(de); + + if (de->d_count > 1) { + /* pretend it's valid, but don't change the flags */ + CDEBUG(D_DOWNCALL, "BOOM for: ino %ld, %s\n", + de->d_inode->i_ino, coda_f2s(&cii->c_fid)); + return 1; } - return valid || coda_isroot(de->d_inode); + + /* propagate for a flush */ + if (cii->c_flags & C_FLUSH) + coda_flag_inode_children(inode, C_FLUSH); + + /* clear the flags. */ + cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); + + return 0; } /* diff --git a/fs/dcache.c b/fs/dcache.c index 75fe40969..51c7869b3 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -480,17 +480,6 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name) char * str; struct dentry *dentry; - /* - * Prune the dcache if there are too many unused dentries. - */ - if (dentry_stat.nr_unused > 3*(nr_inodes >> 1)) { -#ifdef DCACHE_DEBUG -printk("d_alloc: %d unused, pruning dcache\n", dentry_stat.nr_unused); -#endif - prune_dcache(8); - free_inode_memory(8); - } - dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); if (!dentry) return NULL; diff --git a/fs/inode.c b/fs/inode.c index 1a9bd3456..72a23f858 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -354,36 +354,28 @@ static int free_inodes(int goal) return found; } +static void shrink_dentry_inodes(int goal) +{ + int found; + + spin_unlock(&inode_lock); + found = select_dcache(goal, 0); + if (found < goal) + found = goal; + prune_dcache(found); + spin_lock(&inode_lock); +} + /* * Searches the inodes list for freeable inodes, - * possibly shrinking the dcache before or after. + * shrinking the dcache before (and possible after, + * if we're low) */ static void try_to_free_inodes(int goal) { - int retry = 1, found; - - /* - * Check whether to preshrink the dcache ... - */ - if (inodes_stat.preshrink) - goto preshrink; - - retry = 0; - do { - if (free_inodes(goal)) - break; - /* - * If we didn't free any inodes, do a limited - * pruning of the dcache to help the next time. - */ - preshrink: - spin_unlock(&inode_lock); - found = select_dcache(goal, 0); - if (found < goal) - found = goal; - prune_dcache(found); - spin_lock(&inode_lock); - } while (retry--); + shrink_dentry_inodes(goal); + if (!free_inodes(goal)) + shrink_dentry_inodes(goal); } /* @@ -408,6 +400,21 @@ static struct inode * grow_inodes(void) { struct inode * inode; + /* + * Check whether to restock the unused list. + */ + if (inodes_stat.preshrink) { + struct list_head *tmp; + try_to_free_inodes(8); + tmp = inode_unused.next; + if (tmp != &inode_unused) { + inodes_stat.nr_free_inodes--; + list_del(tmp); + inode = list_entry(tmp, struct inode, i_list); + return inode; + } + } + spin_unlock(&inode_lock); inode = (struct inode *)__get_free_page(GFP_KERNEL); if (inode) { @@ -512,6 +519,12 @@ static inline void read_inode(struct inode *inode, struct super_block *sb) sb->s_op->read_inode(inode); } +/* + * This is called by things like the networking layer + * etc that want to get an inode without any inode + * number, or filesystems that allocate new inodes with + * no pre-existing information. + */ struct inode * get_empty_inode(void) { static unsigned long last_ino = 0; @@ -519,11 +532,6 @@ struct inode * get_empty_inode(void) struct list_head * tmp; spin_lock(&inode_lock); - /* - * Check whether to restock the unused list. - */ - if (inodes_stat.nr_free_inodes < 16) - try_to_free_inodes(8); tmp = inode_unused.next; if (tmp != &inode_unused) { list_del(tmp); @@ -629,25 +637,18 @@ struct inode *iget(struct super_block *sb, unsigned long ino) struct inode * inode; spin_lock(&inode_lock); - if (!inodes_stat.nr_free_inodes) - goto restock; -search: inode = find_inode(sb, ino, head); - if (!inode) { - return get_new_inode(sb, ino, head); + if (inode) { + spin_unlock(&inode_lock); + wait_on_inode(inode); + return inode; } - spin_unlock(&inode_lock); - wait_on_inode(inode); - return inode; - /* - * We restock the freelist before calling find, - * in order to avoid repeating the search. - * (The unused list usually won't be empty.) + * get_new_inode() will do the right thing, releasing + * the inode lock and re-trying the search in case it + * had to block at any point. */ -restock: - try_to_free_inodes(8); - goto search; + return get_new_inode(sb, ino, head); } void insert_inode_hash(struct inode *inode) diff --git a/fs/namei.c b/fs/namei.c index fff6ea917..d89d6d64c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -678,9 +678,12 @@ struct dentry * open_namei(const char * pathname, int flag, int mode) if (flag & O_CREAT) { struct dentry *dir; - error = -EEXIST; - if (dentry->d_inode && (flag & O_EXCL)) + if (dentry->d_inode) { + if (!(flag & O_EXCL)) + goto nocreate; + error = -EEXIST; goto exit; + } dir = lock_parent(dentry); if (!check_parent(dir, dentry)) { @@ -723,6 +726,7 @@ struct dentry * open_namei(const char * pathname, int flag, int mode) goto exit; } +nocreate: error = -ENOENT; inode = dentry->d_inode; if (!inode) diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 88d7cd1cd..370411d7c 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -268,8 +268,10 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, u32 *statp) if (!(rp = rqstp->rq_cacherep) || cache_disabled) return; + len = resp->len - (statp - resp->base); + /* Don't cache excessive amounts of data and XDR failures */ - if (!statp || (len = resp->buf - statp) > (256 >> 2)) { + if (!statp || len > (256 >> 2)) { rp->c_state = RC_UNUSED; return; } diff --git a/fs/proc/array.c b/fs/proc/array.c index f7f28e0e6..4188ebc09 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -14,7 +14,7 @@ * EVERY character on the current page. * * - * Danny ter Haar : added cpuinfo + * Danny ter Haar : added cpuinfo * * * Alessandro Rubini : profile extension. @@ -33,13 +33,13 @@ * and /proc//cpu extension * * - Incorporation and non-SMP safe operation - * of forissier patch in 2.1.78 by + * of forissier patch in 2.1.78 by * Hans Marcus * * aeb@cwi.nl : /proc/partitions * * - * Alan Cox : security fixes. + * Alan Cox : security fixes. * * * Andi Kleen : Race Fixes. @@ -142,7 +142,7 @@ static struct file_operations proc_kcore_operations = { }; struct inode_operations proc_kcore_inode_operations = { - &proc_kcore_operations, + &proc_kcore_operations, }; /* @@ -198,7 +198,7 @@ static ssize_t write_profile(struct file * file, const char * buf, return -EINVAL; } #endif - + memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer)); return count; } @@ -210,7 +210,7 @@ static struct file_operations proc_profile_operations = { }; struct inode_operations proc_profile_inode_operations = { - &proc_profile_operations, + &proc_profile_operations, }; @@ -388,29 +388,29 @@ static int get_cmdline(char * buffer) return sprintf(buffer, "%s\n", saved_command_line); } -/* +/* * Caller must release_mm the mm_struct later. - * You don't get any access to init_mm. - */ -static struct mm_struct *get_mm_and_lock(int pid) -{ - struct mm_struct *mm = NULL; - struct task_struct *tsk; - - read_lock(&tasklist_lock); - tsk = find_task_by_pid(pid); + * You don't get any access to init_mm. + */ +static struct mm_struct *get_mm_and_lock(int pid) +{ + struct mm_struct *mm = NULL; + struct task_struct *tsk; + + read_lock(&tasklist_lock); + tsk = find_task_by_pid(pid); if (tsk && tsk->mm && tsk->mm != &init_mm) - mmget(mm = tsk->mm); + mmget(mm = tsk->mm); read_unlock(&tasklist_lock); - if (mm != NULL) - down(&mm->mmap_sem); - return mm; + if (mm != NULL) + down(&mm->mmap_sem); + return mm; } static void release_mm(struct mm_struct *mm) { - up(&mm->mmap_sem); - mmput(mm); + up(&mm->mmap_sem); + mmput(mm); } static unsigned long get_phys_addr(struct mm_struct *mm, unsigned long ptr) @@ -423,7 +423,7 @@ static unsigned long get_phys_addr(struct mm_struct *mm, unsigned long ptr) return 0; /* Check for NULL pgd .. shouldn't happen! */ if (!mm->pgd) { - printk(KERN_DEBUG "missing pgd for mm %p\n", mm); + printk(KERN_DEBUG "missing pgd for mm %p\n", mm); return 0; } @@ -480,12 +480,12 @@ static int get_array(struct mm_struct *mm, unsigned long start, unsigned long en static int get_env(int pid, char * buffer) { - struct mm_struct *mm; - int res = 0; + struct mm_struct *mm; + int res = 0; - mm = get_mm_and_lock(pid); - if (mm) { - res = get_array(mm, mm->env_start, mm->env_end, buffer); + mm = get_mm_and_lock(pid); + if (mm) { + res = get_array(mm, mm->env_start, mm->env_end, buffer); release_mm(mm); } return res; @@ -493,14 +493,14 @@ static int get_env(int pid, char * buffer) static int get_arg(int pid, char * buffer) { - struct mm_struct *mm; - int res = 0; + struct mm_struct *mm; + int res = 0; - mm = get_mm_and_lock(pid); + mm = get_mm_and_lock(pid); if (mm) { - res = get_array(mm, mm->arg_start, mm->arg_end, buffer); - release_mm(mm); - } + res = get_array(mm, mm->arg_start, mm->arg_end, buffer); + release_mm(mm); + } return res; } @@ -754,14 +754,14 @@ static inline char * task_mem(struct task_struct *p, char *buffer) { struct mm_struct * mm = p->mm; - if (!mm) + if (!mm) return buffer; if (mm != &init_mm) { struct vm_area_struct * vma; unsigned long data = 0, stack = 0; unsigned long exec = 0, lib = 0; - down(&mm->mmap_sem); + down(&mm->mmap_sem); for (vma = mm->mmap; vma; vma = vma->vm_next) { unsigned long len = (vma->vm_end - vma->vm_start) >> 10; if (!vma->vm_file) { @@ -779,7 +779,7 @@ static inline char * task_mem(struct task_struct *p, char *buffer) lib += len; } } - up(&mm->mmap_sem); + up(&mm->mmap_sem); buffer += sprintf(buffer, "VmSize:\t%8lu kB\n" "VmLck:\t%8lu kB\n" @@ -849,35 +849,31 @@ extern inline char *task_cap(struct task_struct *p, char *buffer) cap_t(p->cap_effective)); } -static struct task_struct *grab_task(int pid, struct task_struct *dst) +static struct task_struct *grab_task(int pid) { - struct task_struct *tsk = current; - if (pid != tsk->pid) { + struct task_struct *tsk = current; + if (pid != tsk->pid) { read_lock(&tasklist_lock); tsk = find_task_by_pid(pid); - if (tsk) { - memcpy(dst, tsk, sizeof(struct task_struct)); - tsk = dst; - if (tsk->mm && tsk->mm != &init_mm) - mmget(tsk->mm); - } + if (tsk && tsk->mm && tsk->mm != &init_mm) + mmget(tsk->mm); read_unlock(&tasklist_lock); } - return tsk; + return tsk; } static void release_task(struct task_struct *tsk) { if (tsk != current && tsk->mm && tsk->mm != &init_mm) - mmput(tsk->mm); + mmput(tsk->mm); } static int get_status(int pid, char * buffer) { char * orig = buffer; - struct task_struct *tsk, mytask; + struct task_struct *tsk; - tsk = grab_task(pid, &mytask); + tsk = grab_task(pid); if (!tsk) return 0; buffer = task_name(tsk, buffer); @@ -885,13 +881,13 @@ static int get_status(int pid, char * buffer) buffer = task_mem(tsk, buffer); buffer = task_sig(tsk, buffer); buffer = task_cap(tsk, buffer); - release_task(tsk); + release_task(tsk); return buffer - orig; } static int get_stat(int pid, char * buffer) { - struct task_struct *tsk, mytask; + struct task_struct *tsk; unsigned long vsize, eip, esp, wchan; long priority, nice; int tty_pgrp; @@ -899,8 +895,8 @@ static int get_stat(int pid, char * buffer) char state; int res; - tsk = grab_task(pid, &mytask); - if (!tsk) + tsk = grab_task(pid); + if (!tsk) return 0; state = *get_task_state(tsk); vsize = eip = esp = 0; @@ -908,10 +904,10 @@ static int get_stat(int pid, char * buffer) struct vm_area_struct *vma; down(&tsk->mm->mmap_sem); - for (vma = tsk->mm->mmap; vma; vma = vma->vm_next) { + for (vma = tsk->mm->mmap; vma; vma = vma->vm_next) { vsize += vma->vm_end - vma->vm_start; } - up(&tsk->mm->mmap_sem); + up(&tsk->mm->mmap_sem); eip = KSTK_EIP(tsk); esp = KSTK_ESP(tsk); @@ -1061,8 +1057,8 @@ static int get_statm(int pid, char * buffer) int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0; struct mm_struct *mm; - mm = get_mm_and_lock(pid); - if (mm) { + mm = get_mm_and_lock(pid); + if (mm) { struct vm_area_struct * vma = mm->mmap; while (vma) { @@ -1084,7 +1080,7 @@ static int get_statm(int pid, char * buffer) drs += pages; vma = vma->vm_next; } - release_mm(mm); + release_mm(mm); } return sprintf(buffer,"%d %d %d %d %d %d %d\n", size, resident, share, trs, lrs, drs, dt); @@ -1122,7 +1118,7 @@ static int get_statm(int pid, char * buffer) #define MAPS_LINE_MAX MAPS_LINE_MAX8 -/* FIXME: this does not do proper mm locking */ +/* FIXME: this does not do proper mm locking */ static ssize_t read_maps (int pid, struct file * file, char * buf, size_t count, loff_t *ppos) { @@ -1170,7 +1166,7 @@ static ssize_t read_maps (int pid, struct file * file, char * buf, int flags; kdev_t dev; unsigned long ino; - int maxlen = (sizeof(void*) == 4) ? + int maxlen = (sizeof(void*) == 4) ? MAPS_LINE_MAX4 : MAPS_LINE_MAX8; int len; @@ -1254,10 +1250,10 @@ out: #ifdef __SMP__ static int get_pidcpu(int pid, char * buffer) { - struct task_struct * tsk, mytask; + struct task_struct * tsk; int i, len; - tsk = grab_task(pid, &mytask); + tsk = grab_task(pid); if (!tsk) return 0; @@ -1272,7 +1268,7 @@ static int get_pidcpu(int pid, char * buffer) tsk->per_cpu_utime[cpu_logical_map(i)], tsk->per_cpu_stime[cpu_logical_map(i)]); - release_task(tsk); + release_task(tsk); return len; } #endif @@ -1399,10 +1395,9 @@ static int process_unauthorized(int type, int pid) read_lock(&tasklist_lock); /* - * Grab the lock, find the task, save the uid and + * Grab the lock, find the task, save the uid and * check it has an mm still (ie its not dead) */ - p = find_task_by_pid(pid); if(p) { diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 244b7513e..d832bd99c 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -1657,9 +1657,9 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry, drop_aliases(new_dentry); } res = vfat_remove_entry(new_dir,&sinfo,new_inode); + if (res) + goto rename_done; } - if (res) - goto rename_done; /* Serious lossage here. FAT uses braindead inode numbers scheme, * so we can't simply cannibalize the entry. It means that we have diff --git a/include/asm-alpha/core_polaris.h b/include/asm-alpha/core_polaris.h index 9a75efb4a..8caf50622 100644 --- a/include/asm-alpha/core_polaris.h +++ b/include/asm-alpha/core_polaris.h @@ -27,6 +27,8 @@ #define POLARIS_DENSE_IO_BASE (IDENT_ADDR + 0xf9fc000000) #define POLARIS_DENSE_CONFIG_BASE (IDENT_ADDR + 0xf9fe000000) +#define POLARIS_IACK_SC POLARIS_IACK_BASE + /* The Polaris command/status registers live in PCI Config space for * bus 0/device 0. As such, they may be bytes, words, or doublewords. */ diff --git a/include/asm-alpha/jensen.h b/include/asm-alpha/jensen.h index 75f99ea33..874511e94 100644 --- a/include/asm-alpha/jensen.h +++ b/include/asm-alpha/jensen.h @@ -7,6 +7,9 @@ * Defines for the AlphaPC EISA IO and memory address space. */ +/* The Jensen is strange */ +#define AUX_IRQ (9) + /* * NOTE! The memory operations do not set any memory barriers, as it's * not needed for cases like a frame buffer that is essentially memory-like. diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index 0acbdf93a..df20edc7f 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -307,6 +307,7 @@ #define __NR_getcwd 367 #define __NR_capget 368 #define __NR_capset 369 +#define __NR_sendfile 370 #if defined(__LIBRARY__) && defined(__GNUC__) diff --git a/include/asm-i386/cobalt.h b/include/asm-i386/cobalt.h index 5bd5520f9..02c3b4ab3 100644 --- a/include/asm-i386/cobalt.h +++ b/include/asm-i386/cobalt.h @@ -1,3 +1,4 @@ +#include #ifndef __I386_COBALT_H #define __I386_COBALT_H diff --git a/include/asm-i386/i82489.h b/include/asm-i386/i82489.h index c804b70f7..76f580bde 100644 --- a/include/asm-i386/i82489.h +++ b/include/asm-i386/i82489.h @@ -14,12 +14,15 @@ #define APIC_TASKPRI 0x80 #define APIC_TPRI_MASK 0xFF #define APIC_ARBPRI 0x90 +#define APIC_ARBPRI_MASK 0xFF #define APIC_PROCPRI 0xA0 #define APIC_EOI 0xB0 #define APIC_EIO_ACK 0x0 /* Write this to the EOI register */ #define APIC_RRR 0xC0 #define APIC_LDR 0xD0 +#define APIC_LDR_MASK (0xFF<<24) #define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF) +#define SET_APIC_LOGICAL_ID(x) (((x)<<24)) #define APIC_DFR 0xE0 #define GET_APIC_DFR(x) (((x)>>28)&0x0F) #define SET_APIC_DFR(x) ((x)<<28) @@ -36,7 +39,6 @@ #define APIC_ESR_RECVILL 0x00040 #define APIC_ESR_ILLREGA 0x00080 #define APIC_ICR 0x300 -#define APIC_DEST_FIELD 0x00000 #define APIC_DEST_SELF 0x40000 #define APIC_DEST_ALLINC 0x80000 #define APIC_DEST_ALLBUT 0xC0000 diff --git a/include/asm-i386/lithium.h b/include/asm-i386/lithium.h index 1ee53a462..253472ee1 100644 --- a/include/asm-i386/lithium.h +++ b/include/asm-i386/lithium.h @@ -1,6 +1,8 @@ #ifndef __I386_LITHIUM_H #define __I386_LITHIUM_H +#include + /* * Lithium is the I/O ASIC on the SGI 320 and 540 Visual Workstations */ @@ -16,6 +18,7 @@ #define LI_PCI_BUSNUM 0x44 /* lo8: primary, hi8: sub */ #define LI_PCI_INTEN 0x46 +#ifdef CONFIG_X86_VISWS_APIC /* More special purpose macros... */ extern __inline void li_pcia_write16(unsigned long reg, unsigned short v) { @@ -36,5 +39,7 @@ extern __inline unsigned short li_pcib_read16(unsigned long reg) { return *((volatile unsigned short *)(LI_PCIB_VADDR+reg)); } +#endif #endif + diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index eaf2882be..ec24476ae 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -163,7 +163,7 @@ struct mpc_config_intlocal */ extern int smp_found_config; -extern int smp_scan_config(unsigned long, unsigned long); +extern void init_smp_config(void); extern unsigned long smp_alloc_memory(unsigned long mem_base); extern unsigned char boot_cpu_id; extern unsigned long cpu_present_map; diff --git a/include/linux/coda.h b/include/linux/coda.h index 800ff8266..ac3301c8a 100644 --- a/include/linux/coda.h +++ b/include/linux/coda.h @@ -1,8 +1,59 @@ +/* + You may distribute this file under either of the two licenses that + follow at your discretion. +*/ + +/* BLURB lgpl + + Coda File System + Release 5 + + Copyright (c) 1987-1999 Carnegie Mellon University + Additional copyrights listed below + +This code is distributed "AS IS" without warranty of any kind under +the terms of the GNU Library General Public Licence Version 2, as +shown in the file LICENSE, or under the license shown below. The +technical and financial contributors to Coda are listed in the file +CREDITS. + + Additional copyrights +*/ + +/* + + Coda: an Experimental Distributed File System + Release 4.0 + + Copyright (c) 1987-1999 Carnegie Mellon University + All Rights Reserved + +Permission to use, copy, modify and distribute this software and its +documentation is hereby granted, provided that both the copyright +notice and this permission notice appear in all copies of the +software, derivative works or modified versions, and any portions +thereof, and that both notices appear in supporting documentation, and +that credit is given to Carnegie Mellon University in all documents +and publicity pertaining to direct or indirect use of this code or its +derivatives. + +CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS, +SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS +FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON +DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER +RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF +ANY DERIVATIVE WORK. + +Carnegie Mellon encourages users of this software to return any +improvements or extensions that they make, and to grant Carnegie +Mellon the rights to redistribute these changes without encumbrance. +*/ /* * * Based on cfs.h from Mach, but revamped for increased simplicity. - * Linux modifications by Peter Braam, Aug 1996 + * Linux modifications by + * Peter Braam, Aug 1996 */ #ifndef _CODA_HEADER_ @@ -178,8 +229,12 @@ typedef u_int32_t vgid_t; #ifndef _CODACRED_T_ #define _CODACRED_T_ struct coda_cred { - vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/ - vgid_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */ + vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; + vgid_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; +#if defined(CODA_SUPPORTS_SUPPLEMENTARY_GROUPS) + int cr_nsupgps; + vgid_t cr_supgps[NGROUPS]; +#endif /* defined(CODA_SUPPORTS_SUPPLEMENTARY_GROUPS) */ }; #endif diff --git a/include/linux/coda_linux.h b/include/linux/coda_linux.h index 05d9c0e98..82ace8e27 100644 --- a/include/linux/coda_linux.h +++ b/include/linux/coda_linux.h @@ -46,6 +46,7 @@ extern int coda_access_cache; /* this file: heloers */ static __inline__ struct ViceFid *coda_i2f(struct inode *); char *coda_f2s(ViceFid *f); +char *coda_f2s2(ViceFid *f); int coda_isroot(struct inode *i); int coda_fid_is_volroot(struct ViceFid *); int coda_fid_is_weird(struct ViceFid *fid); diff --git a/include/linux/videodev.h b/include/linux/videodev.h index dea2806b0..ab04f1fee 100644 --- a/include/linux/videodev.h +++ b/include/linux/videodev.h @@ -2,6 +2,7 @@ #define __LINUX_VIDEODEV_H #include +#include #ifdef __KERNEL__ diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h index 7cd977510..22458aa0b 100644 --- a/include/net/irda/irda.h +++ b/include/net/irda/irda.h @@ -25,6 +25,7 @@ #ifndef IRDA_H #define IRDA_H +#include #include #ifndef TRUE diff --git a/mm/filemap.c b/mm/filemap.c index d3d3b4287..3c15ea63b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -125,7 +125,7 @@ int shrink_mmap(int priority, int gfp_mask) struct page * page; int count; - count = (limit << 1) >> priority; + count = limit >> priority; page = mem_map + clock; do { @@ -147,7 +147,6 @@ int shrink_mmap(int priority, int gfp_mask) clock = page - mem_map; } - count--; referenced = test_and_clear_bit(PG_referenced, &page->flags); if (PageLocked(page)) @@ -160,6 +159,8 @@ int shrink_mmap(int priority, int gfp_mask) if (atomic_read(&page->count) != 1) continue; + count--; + /* * Is it a page swap page? If so, we want to * drop it if it is no longer used, even if it diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a4b62cf9f..4a956c085 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -155,12 +155,12 @@ void free_pages(unsigned long addr, unsigned long order) change_bit((index) >> (1+(order)), (area)->map) #define CAN_DMA(x) (PageDMA(x)) #define ADDRESS(x) (PAGE_OFFSET + ((x) << PAGE_SHIFT)) -#define RMQUEUE(order, dma) \ +#define RMQUEUE(order, gfp_mask) \ do { struct free_area_struct * area = free_area+order; \ unsigned long new_order = order; \ do { struct page *prev = memory_head(area), *ret = prev->next; \ while (memory_head(area) != ret) { \ - if (!dma || CAN_DMA(ret)) { \ + if (!(gfp_mask & __GFP_DMA) || CAN_DMA(ret)) { \ unsigned long map_nr; \ (prev->next = ret->next)->prev = prev; \ map_nr = ret - mem_map; \ @@ -198,45 +198,45 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order) if (order >= NR_MEM_LISTS) goto nopage; - if (gfp_mask & __GFP_WAIT) { - if (in_interrupt()) { - static int count = 0; - if (++count < 5) { - printk("gfp called nonatomically from interrupt %p\n", - __builtin_return_address(0)); - } - goto nopage; +#ifdef ATOMIC_MEMORY_DEBUGGING + if ((gfp_mask & __GFP_WAIT) && in_interrupt()) { + static int count = 0; + if (++count < 5) { + printk("gfp called nonatomically from interrupt %p\n", + __builtin_return_address(0)); } + goto nopage; + } +#endif - /* - * If this is a recursive call, we'd better - * do our best to just allocate things without - * further thought. - */ - if (!(current->flags & PF_MEMALLOC)) { - int freed; - - if (nr_free_pages > freepages.min) { - if (!low_on_memory) - goto ok_to_allocate; - if (nr_free_pages >= freepages.high) { - low_on_memory = 0; - goto ok_to_allocate; - } + /* + * If this is a recursive call, we'd better + * do our best to just allocate things without + * further thought. + */ + if (!(current->flags & PF_MEMALLOC)) { + int freed; + + if (nr_free_pages > freepages.min) { + if (!low_on_memory) + goto ok_to_allocate; + if (nr_free_pages >= freepages.high) { + low_on_memory = 0; + goto ok_to_allocate; } + } - low_on_memory = 1; - current->flags |= PF_MEMALLOC; - freed = try_to_free_pages(gfp_mask); - current->flags &= ~PF_MEMALLOC; + low_on_memory = 1; + current->flags |= PF_MEMALLOC; + freed = try_to_free_pages(gfp_mask); + current->flags &= ~PF_MEMALLOC; - if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH))) - goto nopage; - } + if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH))) + goto nopage; } ok_to_allocate: spin_lock_irqsave(&page_alloc_lock, flags); - RMQUEUE(order, (gfp_mask & GFP_DMA)); + RMQUEUE(order, gfp_mask); spin_unlock_irqrestore(&page_alloc_lock, flags); /* diff --git a/mm/vmscan.c b/mm/vmscan.c index cec1ab0be..116096153 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -368,6 +368,54 @@ out: } /* + * We need to make the locks finer granularity, but right + * now we need this so that we can do page allocations + * without holding the kernel lock etc. + * + * We want to try to free "count" pages, and we need to + * cluster them so that we get good swap-out behaviour. See + * the "free_memory()" macro for details. + */ +static int do_try_to_free_pages(unsigned int gfp_mask) +{ + int priority; + int count = SWAP_CLUSTER_MAX; + + lock_kernel(); + + /* Always trim SLAB caches when memory gets low. */ + kmem_cache_reap(gfp_mask); + + priority = 6; + do { + while (shrink_mmap(priority, gfp_mask)) { + if (!--count) + goto done; + } + + /* Try to get rid of some shared memory pages.. */ + if (gfp_mask & __GFP_IO) { + while (shm_swap(priority, gfp_mask)) { + if (!--count) + goto done; + } + } + + /* Then, try to page stuff out.. */ + while (swap_out(priority, gfp_mask)) { + if (!--count) + goto done; + } + + shrink_dcache_memory(priority, gfp_mask); + } while (--priority >= 0); +done: + unlock_kernel(); + + return priority >= 0; +} + +/* * Before we start the kernel thread, print out the * kswapd initialization message (otherwise the init message * may be printed in the middle of another driver's init @@ -388,6 +436,8 @@ void __init kswapd_setup(void) printk ("Starting kswapd v%.*s\n", i, s); } +static struct task_struct *kswapd_process; + /* * The background pageout daemon, started as a kernel thread * from the init process. @@ -404,10 +454,13 @@ void __init kswapd_setup(void) */ int kswapd(void *unused) { - current->session = 1; - current->pgrp = 1; - strcpy(current->comm, "kswapd"); - sigfillset(¤t->blocked); + struct task_struct *tsk = current; + + kswapd_process = tsk; + tsk->session = 1; + tsk->pgrp = 1; + strcpy(tsk->comm, "kswapd"); + sigfillset(&tsk->blocked); /* * Tell the memory management that we're a "memory allocator", @@ -421,78 +474,52 @@ int kswapd(void *unused) * us from recursively trying to free more memory as we're * trying to free the first piece of memory in the first place). */ - current->flags |= PF_MEMALLOC; + tsk->flags |= PF_MEMALLOC; while (1) { - int tmo; - /* * Wake up once a second to see if we need to make - * more memory available. When we get into a low - * memory situation, we start waking up more often. + * more memory available. * - * We consider "freepages.low" to be low on memory, - * but we also try to be aggressive if other processes - * are low on memory and would otherwise block when - * calling __get_free_page(). + * If we actually get into a low-memory situation, + * the processes needing more memory will wake us + * up on a more timely basis. */ - tmo = HZ; - if (nr_free_pages < freepages.high) { - if (nr_free_pages < freepages.low || low_on_memory) { - if (try_to_free_pages(GFP_KSWAPD)) - tmo = (HZ+9)/10; - } - } + do { + if (nr_free_pages >= freepages.high) + break; + + if (!do_try_to_free_pages(GFP_KSWAPD)) + break; + } while (!tsk->need_resched); run_task_queue(&tq_disk); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(tmo); + tsk->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ); } } /* - * We need to make the locks finer granularity, but right - * now we need this so that we can do page allocations - * without holding the kernel lock etc. + * Called by non-kswapd processes when they want more + * memory. * - * We want to try to free "count" pages, and we need to - * cluster them so that we get good swap-out behaviour. See - * the "free_memory()" macro for details. + * In a perfect world, this should just wake up kswapd + * and return. We don't actually want to swap stuff out + * from user processes, because the locking issues are + * nasty to the extreme (file write locks, and MM locking) + * + * One option might be to let kswapd do all the page-out + * and VM page table scanning that needs locking, and this + * process thread could do just the mmap shrink stage that + * can be done by just dropping cached pages without having + * any deadlock issues. */ int try_to_free_pages(unsigned int gfp_mask) { - int priority; - int count = SWAP_CLUSTER_MAX; - - lock_kernel(); - - /* Always trim SLAB caches when memory gets low. */ - kmem_cache_reap(gfp_mask); - - priority = 6; - do { - while (shrink_mmap(priority, gfp_mask)) { - if (!--count) - goto done; - } - - /* Try to get rid of some shared memory pages.. */ - if (gfp_mask & __GFP_IO) { - while (shm_swap(priority, gfp_mask)) { - if (!--count) - goto done; - } - } - - /* Then, try to page stuff out.. */ - while (swap_out(priority, gfp_mask)) { - if (!--count) - goto done; - } - - shrink_dcache_memory(priority, gfp_mask); - } while (--priority >= 0); -done: - unlock_kernel(); + int retval = 1; - return priority >= 0; + wake_up_process(kswapd_process); + if (gfp_mask & __GFP_WAIT) + retval = do_try_to_free_pages(gfp_mask); + return retval; } + diff --git a/net/decnet/README b/net/decnet/README index c62e29323..316435d29 100644 --- a/net/decnet/README +++ b/net/decnet/README @@ -4,9 +4,12 @@ For information on the Linux DECnet Project and the latest progress, look at the project home page: -http://www-sigproc.eng.cam.ac.uk/~sjw44/ +http://www.sucs.swan.ac.uk/~rohan/DECnet/ To contribute either mail or post on one of the Linux -mailing lists (either linux-net or netdev). +mailing lists (either linux-net or netdev). DECnet for Linux will not +be distributed as part of the 2.2.xx kernel series. It is available as a +patch from the above site. Expect DECnet to arrive as part of the standard +kernel distribution early in the 2.3.xx series. Steve Whitehouse diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index c77ecc251..7bff36095 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -984,7 +984,7 @@ void fib_node_get_info(int type, int dead, struct fib_info *fi, u32 prefix, u32 flags, 0, 0, 0, mask, 0, 0, 0); } - memset(buffer+len, 0, 127-len); + memset(buffer+len, ' ', 127-len); buffer[127] = '\n'; } diff --git a/net/ipv4/ip_masq_mfw.c b/net/ipv4/ip_masq_mfw.c index 0dfbba528..e3903c0cb 100644 --- a/net/ipv4/ip_masq_mfw.c +++ b/net/ipv4/ip_masq_mfw.c @@ -79,7 +79,7 @@ struct ip_masq_mfw { }; -static struct semaphore mfw_sema; +static struct semaphore mfw_sema = MUTEX; #ifdef __SMP__ static rwlock_t mfw_lock = RW_LOCK_UNLOCKED; #endif @@ -748,7 +748,6 @@ static struct ip_masq_mod mfw_mod = { __initfunc(int ip_mfw_init(void)) { - sema_init(&mfw_sema, 1); return register_ip_masq_mod ((mmod_self=&mfw_mod)); } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c33292a58..aca7026b9 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1691,7 +1691,7 @@ static int prune_queue(struct sock *sk) do { net_statistics.OfoPruned += skb->len; kfree_skb(skb); skb = __skb_dequeue_tail(&tp->out_of_order_queue); - } while((skb = __skb_dequeue_tail(&tp->out_of_order_queue)) != NULL); + } while(skb != NULL); /* Reset SACK state. A conforming SACK implementation will * do the same at a timeout based retransmit. When a connection diff --git a/net/irda/irlpt/irlpt_common.c b/net/irda/irlpt/irlpt_common.c index 342f1a13f..886eb30a0 100644 --- a/net/irda/irlpt/irlpt_common.c +++ b/net/irda/irlpt/irlpt_common.c @@ -24,7 +24,6 @@ * ********************************************************************/ -#include #include #include diff --git a/net/irda/irlpt/irlpt_srvr_fsm.c b/net/irda/irlpt/irlpt_srvr_fsm.c index 0d71d6c81..3640a9677 100644 --- a/net/irda/irlpt/irlpt_srvr_fsm.c +++ b/net/irda/irlpt/irlpt_srvr_fsm.c @@ -17,8 +17,6 @@ * ********************************************************************/ -#include - #include #include #include diff --git a/net/irda/irsysctl.c b/net/irda/irsysctl.c index 6349829d5..e8a3f9910 100644 --- a/net/irda/irsysctl.c +++ b/net/irda/irsysctl.c @@ -22,6 +22,7 @@ * ********************************************************************/ +#include #include #include #include -- 2.11.4.GIT