diff options
author | davem <davem> | 2002-02-10 02:05:42 +0000 |
---|---|---|
committer | davem <davem> | 2002-02-10 02:05:42 +0000 |
commit | f5dea6e62a3e557d78412b139de0fad38d82741c (patch) | |
tree | 2ff27c50d9bd0499eb67c53b4efcab4116ed793a | |
parent | a049347b868bcbbf1e4c20ee9c1cb2624e598a17 (diff) | |
download | netdev-vger-cvs-f5dea6e62a3e557d78412b139de0fad38d82741c.tar.gz |
Merge mainline to 2.5.4-pre5
113 files changed, 1263 insertions, 1110 deletions
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt index 0b1f791c0..22014567a 100644 --- a/Documentation/oops-tracing.txt +++ b/Documentation/oops-tracing.txt @@ -219,6 +219,11 @@ characters, each representing a particular tainted value. 2: 'F' if any module was force loaded by insmod -f, ' ' if all modules were loaded normally. + 3: 'S' if the oops occured on an SMP kernel running on hardware that + hasn't been certified as safe to run multiprocessor. + Currently this occurs only on various Athlons that are not + SMP capable. + The primary reason for the 'Tainted: ' string is to tell kernel debuggers if this is a clean kernel or if anything unusual has occurred. Tainting is permanent, even if an offending module is @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 5 SUBLEVEL = 4 -EXTRAVERSION =-pre3 +EXTRAVERSION =-pre5 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) @@ -332,11 +332,13 @@ include/linux/version.h: ./Makefile @echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver @mv -f .ver $@ +comma := , + init/version.o: init/version.c include/linux/compile.h include/config/MARKER - $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c + $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(ARCH)"' -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o init/version.c init/main.o: init/main.c include/config/MARKER - $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $< + $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $*.o $< init/do_mounts.o: init/do_mounts.c include/config/MARKER $(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -c -o $*.o $< diff --git a/Rules.make b/Rules.make index d792a5cba..69af52710 100644 --- a/Rules.make +++ b/Rules.make @@ -31,6 +31,8 @@ unexport subdir-m unexport subdir-n unexport subdir- +comma := , + # # Get things started. # @@ -54,7 +56,7 @@ ALL_SUB_DIRS := $(sort $(subdir-y) $(subdir-m) $(subdir-n) $(subdir-)) $(CPP) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) $< > $@ %.o: %.c - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c -o $@ $< + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -c -o $@ $< @ ( \ echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@))))' ; \ echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \ @@ -270,7 +272,7 @@ endif # CONFIG_MODVERSIONS ifneq "$(strip $(export-objs))" "" $(export-objs): $(export-objs:.o=.c) $(TOPDIR)/include/linux/modversions.h - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -DEXPORT_SYMTAB -c $(@:.o=.c) + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -DEXPORT_SYMTAB -c $(@:.o=.c) @ ( \ echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -DEXPORT_SYMTAB)),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@) -DEXPORT_SYMTAB)))' ; \ echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \ diff --git a/arch/cris/cris.ld b/arch/cris/cris.ld index d0d2af1f8..f62b467f6 100644 --- a/arch/cris/cris.ld +++ b/arch/cris/cris.ld @@ -24,7 +24,6 @@ SECTIONS *(.fixup) *(.text.__*) } - .text.lock : { *(.text.lock) } /* out-of-line lock text */ _etext = . ; /* End of text section */ __etext = .; diff --git a/arch/i386/Config.help b/arch/i386/Config.help index 9b5b72e11..98b4c7542 100644 --- a/arch/i386/Config.help +++ b/arch/i386/Config.help @@ -386,7 +386,7 @@ CONFIG_M386 will run on a 386 class machine. - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or SL/SLC/SLC2/SLC3/SX/SX2 and UMC U5D or U5S. - - "586" for generic Pentium CPUs, possibly lacking the TSC + - "586" for generic Pentium CPUs lacking the TSC (time stamp counter) register. - "Pentium-Classic" for the Intel Pentium. - "Pentium-MMX" for the Intel Pentium MMX. @@ -413,12 +413,69 @@ CONFIG_M486 CONFIG_M586 Select this for an x586 or x686 processor such as the AMD K5, the Intel 5x86 or 6x86, or the Intel 6x86MX. This choice does not - assume the RDTSC instruction. + assume the RDTSC (Read Time Stamp Counter) instruction. CONFIG_M586TSC Select this for a Pentium Classic processor with the RDTSC (Read Time Stamp Counter) instruction for benchmarking. +CONFIG_M586MMX + Select this for a Pentium with the MMX graphics/multimedia + extended instructions. + +CONFIG_M686 + Select this for a Pro/Celeron/Pentium II. This enables the use of + Pentium Pro extended instructions, and disables the init-time guard + against the f00f bug found in earlier Pentiums. + +CONFIG_MPENTIUMIII + Select this for Intel chips based on the Pentium-III and + Celeron-Coppermine core. Enables use of some extended prefetch + instructions, in addition to the Pentium II extensions. + +CONFIG_MPENTIUM4 + Select this for Intel Pentium 4 chips. Presently these are + treated almost like Pentium IIIs, but with a different cache + shift. + +CONFIG_MCRUSOE + Select this for Transmeta Crusoe processor. Treats the processor + like a 586 with TSC, and sets some GCC optimization flags (like a + Pentium Pro with no alignment requirements). + +CONFIG_MK6 + Select this for an AMD K6-family processor. Enables use of + some extended instructions, and passes appropriate optimization + flags to GCC. + +CONFIG_MK7 + Select this for an AMD Athlon K7-family processor. Enables use of + some extended instructions, and passes appropriate optimization + flags to GCC. + +CONFIG_MCYRIXIII + Select this for a Cyrix III or C3 chip. Presently Linux and GCC + treat this chip as a generic 586. Whilst the CPU is 686 class, + it lacks the cmov extension which gcc assumes is present when + generating 686 code. + +CONFIG_MWINCHIPC6 + Select this for a IDT Winchip C6 chip. Linux and GCC + treat this chip as a 586TSC with some extended instructions + and alignment requirements. + +CONFIG_MWINCHIP2 + Select this for a IDT Winchip-2. Linux and GCC + treat this chip as a 586TSC with some extended instructions + and alignment requirements. + +CONFIG_MWINCHIP3D + Select this for a IDT Winchip-2A or 3. Linux and GCC + treat this chip as a 586TSC with some extended instructions + and alignment reqirements. Development kernels also enable + out of order memory stores for this CPU, which can increase + performance of some operations. + CONFIG_VGA_CONSOLE Saying Y here will allow you to use Linux in text mode through a display that complies with the generic VGA standard. Virtually diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile index 223277693..e323873c4 100644 --- a/arch/i386/boot/compressed/Makefile +++ b/arch/i386/boot/compressed/Makefile @@ -32,8 +32,10 @@ bvmlinux: piggy.o $(OBJECTS) head.o: head.S $(CC) $(AFLAGS) -traditional -c head.S +comma := , + misc.o: misc.c - $(CC) $(CFLAGS) -c misc.c + $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c misc.c piggy.o: $(SYSTEM) tmppiggy=_tmp_$$$$piggy; \ diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 4f292da94..0d33e70a9 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -436,6 +436,7 @@ CONFIG_EEPRO100=y # CONFIG_8139TOO_PIO is not set # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set +# CONFIG_8139_NEW_RX_RESET is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -581,7 +582,7 @@ CONFIG_AGP=y CONFIG_AGP_INTEL=y CONFIG_AGP_I810=y CONFIG_AGP_VIA=y -CONFIG_AGP_AMD=y +# CONFIG_AGP_AMD is not set CONFIG_AGP_SIS=y CONFIG_AGP_ALI=y # CONFIG_AGP_SWORKS is not set diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 0e8e46d76..16b69e8f6 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -95,6 +95,7 @@ static loff_t cpuid_seek(struct file *file, loff_t offset, int orig) case 1: file->f_pos += offset; ret = file->f_pos; + break; default: ret = -EINVAL; } diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 02e19533c..77d0323aa 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -456,12 +456,3 @@ ENTRY(gdt_table) .quad 0x0000000000000000 /* 0x98 not used */ /* Per CPU segments */ .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ - -/* - * This is to aid debugging, the various locking macros will be putting - * code fragments here. When an oops occurs we'd rather know that it's - * inside the .text.lock section rather than as some offset from whatever - * function happens to be last in the .text segment. - */ -.section .text.lock -ENTRY(stext_lock) diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index 0732feda4..a87a362c4 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -52,7 +52,7 @@ static inline void __save_init_fpu( struct task_struct *tsk ) asm volatile( "fnsave %0 ; fwait" : "=m" (tsk->thread.i387.fsave) ); } - clear_thread_flag(TIF_USEDFPU); + clear_tsk_thread_flag(tsk, TIF_USEDFPU); } void save_init_fpu( struct task_struct *tsk ) @@ -63,10 +63,8 @@ void save_init_fpu( struct task_struct *tsk ) void kernel_fpu_begin(void) { - struct task_struct *tsk = current; - if (test_thread_flag(TIF_USEDFPU)) { - __save_init_fpu(tsk); + __save_init_fpu(current); return; } clts(); diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index b955ff2bb..142915bd3 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -808,7 +808,7 @@ unsigned long get_wchan(struct task_struct *p) int count = 0; if (!p || p == current || p->state == TASK_RUNNING) return 0; - stack_page = (unsigned long)p; + stack_page = (unsigned long)p->thread_info; esp = p->thread.esp; if (!stack_page || esp < stack_page || esp > 8188+stack_page) return 0; diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index a6573e39d..4afb2afc6 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -278,10 +278,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if ((unsigned long) data > _NSIG) break; if (request == PTRACE_SYSCALL) { - set_thread_flag(TIF_SYSCALL_TRACE); + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } else { - clear_thread_flag(TIF_SYSCALL_TRACE); + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } child->exit_code = data; /* make sure the single step bit is not set. */ @@ -317,7 +317,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - clear_thread_flag(TIF_SYSCALL_TRACE); + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); if ((child->ptrace & PT_DTRACE) == 0) { /* Spurious delayed TF traps may occur */ child->ptrace |= PT_DTRACE; @@ -449,7 +449,7 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) { if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; - if (current->ptrace & PT_PTRACED) + if (!(current->ptrace & PT_PTRACED)) return; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 691cd19ae..d7f8e2a1e 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -2652,7 +2652,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* AMD-defined */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, "mmxext", NULL, + NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL, NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow", /* Transmeta-defined */ diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 66417cef4..b8774935f 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -30,10 +30,12 @@ * Tigran Aivazian : fixed "0.00 in /proc/uptime on SMP" bug. * Maciej W. Rozycki : Bits for genuine 82489DX APICs * Martin J. Bligh : Added support for multi-quad systems + * Dave Jones : Report invalid combinations of Athlon CPUs. */ #include <linux/config.h> #include <linux/init.h> +#include <linux/kernel.h> #include <linux/mm.h> #include <linux/kernel_stat.h> @@ -160,6 +162,35 @@ void __init smp_store_cpu_info(int id) * Remember we have B step Pentia with bugs */ smp_b_stepping = 1; + + /* + * Certain Athlons might work (for various values of 'work') in SMP + * but they are not certified as MP capable. + */ + if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) { + + /* Athlon 660/661 is valid. */ + if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1))) + goto valid_k7; + + /* Duron 670 is valid */ + if ((c->x86_model==7) && (c->x86_mask==0)) + goto valid_k7; + + /* Athlon 662, Duron 671, and Athlon >model 7 have capability bit */ + if (((c->x86_model==6) && (c->x86_mask>=2)) || + ((c->x86_model==7) && (c->x86_mask>=1)) || + (c->x86_model> 7)) + if (cpu_has_mp) + goto valid_k7; + + /* If we get here, it's not a certified SMP capable AMD system. */ + printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n"); + tainted |= TAINT_UNSAFE_SMP; + + } +valid_k7: + } /* diff --git a/arch/i386/vmlinux.lds b/arch/i386/vmlinux.lds index 1a7da033d..cd994f0b9 100644 --- a/arch/i386/vmlinux.lds +++ b/arch/i386/vmlinux.lds @@ -13,7 +13,6 @@ SECTIONS *(.fixup) *(.gnu.warning) } = 0x9090 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ _etext = .; /* End of text section */ diff --git a/arch/ia64/sn/fprom/Makefile b/arch/ia64/sn/fprom/Makefile index 0b2b212ab..4113f0666 100644 --- a/arch/ia64/sn/fprom/Makefile +++ b/arch/ia64/sn/fprom/Makefile @@ -18,10 +18,12 @@ obj-y=fprom fprom: $(OBJ) $(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB) +comma := , + .S.o: $(CC) -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< .c.o: - $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -c -o $*.o $< + $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_KERNEL) -c -o $*.o $< clean: rm -f *.o fprom diff --git a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile index f98e2d1f3..cdfa56f32 100644 --- a/arch/ia64/tools/Makefile +++ b/arch/ia64/tools/Makefile @@ -31,8 +31,10 @@ ifeq ($(CROSS_COMPILE),) offsets.h: print_offsets ./print_offsets > offsets.h +comma := , + print_offsets: print_offsets.c FORCE_RECOMPILE - $(CC) $(CFLAGS) print_offsets.c -o $@ + $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) print_offsets.c -o $@ FORCE_RECOMPILE: @@ -42,7 +44,7 @@ offsets.h: print_offsets.s $(AWK) -f print_offsets.awk $^ > $@ print_offsets.s: print_offsets.c - $(CC) $(CFLAGS) -S print_offsets.c -o $@ + $(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -S print_offsets.c -o $@ endif diff --git a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds index 164b11ac4..7894d47f4 100644 --- a/arch/m68k/vmlinux-sun3.lds +++ b/arch/m68k/vmlinux-sun3.lds @@ -10,7 +10,6 @@ SECTIONS *(.head) *(.text) *(.fixup) - *(.text.lock) /* out-of-line lock text */ *(.gnu.warning) } = 0x4e75 .kstrtab : { *(.kstrtab) } diff --git a/arch/m68k/vmlinux.lds b/arch/m68k/vmlinux.lds index 3b9eb25b5..aea08a896 100644 --- a/arch/m68k/vmlinux.lds +++ b/arch/m68k/vmlinux.lds @@ -9,7 +9,6 @@ SECTIONS .text : { *(.text) *(.fixup) - *(.text.lock) /* out-of-line lock text */ *(.gnu.warning) } = 0x4e75 .rodata : { *(.rodata) *(.rodata.*) } diff --git a/arch/s390/vmlinux-shared.lds b/arch/s390/vmlinux-shared.lds index 4956b7c7e..ad325713d 100644 --- a/arch/s390/vmlinux-shared.lds +++ b/arch/s390/vmlinux-shared.lds @@ -13,7 +13,6 @@ SECTIONS *(.fixup) *(.gnu.warning) } = 0x0700 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ .rodata : { *(.rodata) } .kstrtab : { *(.kstrtab) } diff --git a/arch/s390/vmlinux.lds b/arch/s390/vmlinux.lds index 1b53d5baf..c1dd3aec0 100644 --- a/arch/s390/vmlinux.lds +++ b/arch/s390/vmlinux.lds @@ -13,7 +13,6 @@ SECTIONS *(.fixup) *(.gnu.warning) } = 0x0700 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ .rodata : { *(.rodata) *(.rodata.*) } .kstrtab : { *(.kstrtab) } diff --git a/arch/s390x/vmlinux-shared.lds b/arch/s390x/vmlinux-shared.lds index 8f6d74e69..1d22a5ec5 100644 --- a/arch/s390x/vmlinux-shared.lds +++ b/arch/s390x/vmlinux-shared.lds @@ -13,7 +13,6 @@ SECTIONS *(.fixup) *(.gnu.warning) } = 0x0700 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ .rodata : { *(.rodata) } .kstrtab : { *(.kstrtab) } diff --git a/arch/s390x/vmlinux.lds b/arch/s390x/vmlinux.lds index 2cc3355c8..f3e7b069a 100644 --- a/arch/s390x/vmlinux.lds +++ b/arch/s390x/vmlinux.lds @@ -13,7 +13,6 @@ SECTIONS *(.fixup) *(.gnu.warning) } = 0x0700 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ .rodata : { *(.rodata) *(.rodata.*) } .kstrtab : { *(.kstrtab) } diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S index fcbc7bd32..0620024f6 100644 --- a/arch/sh/vmlinux.lds.S +++ b/arch/sh/vmlinux.lds.S @@ -23,7 +23,6 @@ SECTIONS *(.fixup) *(.gnu.warning) } = 0x0009 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ .rodata : { *(.rodata) *(.rodata.*) } .kstrtab : { *(.kstrtab) } diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 7cfcab034..3100e0fcd 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -3,6 +3,11 @@ # # +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# # General setup # CONFIG_NET=y @@ -11,11 +16,6 @@ CONFIG_SYSVIPC=y CONFIG_SYSCTL=y # -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# # Loadable module support # CONFIG_MODULES=y @@ -486,6 +486,7 @@ CONFIG_EEPRO100=m # CONFIG_LNE390 is not set CONFIG_FEALNX=m CONFIG_NATSEMI=m +# CONFIG_NATSEMI_CABLE_MAGIC is not set CONFIG_NE2K_PCI=m # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set @@ -669,7 +670,7 @@ CONFIG_UFS_FS_WRITE=y # Network File Systems # CONFIG_CODA_FS=m -CONFIG_INTERMEZZO_FS=m +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_ROOT_NFS is not set diff --git a/drivers/base/core.c b/drivers/base/core.c index 0cc155572..4a8b527c6 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -18,7 +18,10 @@ # define DBG(x...) #endif -static struct device * device_root; +static struct device device_root = { + bus_id: "root", + name: "System Root", +}; int (*platform_notify)(struct device * dev) = NULL; int (*platform_notify_remove)(struct device * dev) = NULL; @@ -49,9 +52,9 @@ int device_register(struct device *dev) spin_lock_init(&dev->lock); atomic_set(&dev->refcount,2); - if (dev != device_root) { + if (dev != &device_root) { if (!dev->parent) - dev->parent = device_root; + dev->parent = &device_root; get_device(dev->parent); list_add_tail(&dev->node,&dev->parent->children); } @@ -117,16 +120,10 @@ void put_device(struct device * dev) static int __init device_init_root(void) { - device_root = kmalloc(sizeof(*device_root),GFP_KERNEL); - if (!device_root) - return -ENOMEM; - memset(device_root,0,sizeof(*device_root)); - strcpy(device_root->bus_id,"root"); - strcpy(device_root->name,"System Root"); - return device_register(device_root); + return device_register(&device_root); } -static int __init device_driver_init(void) +static int __init device_init(void) { int error = 0; @@ -141,17 +138,12 @@ static int __init device_driver_init(void) return error; } - error = device_init_root(); - if (error) { + if ((error = device_init_root())) printk(KERN_ERR "%s: device root init failed!\n", __FUNCTION__); - return error; - } - - DBG("DEV: Done Initialising\n"); return error; } -subsys_initcall(device_driver_init); +subsys_initcall(device_init); EXPORT_SYMBOL(device_register); EXPORT_SYMBOL(put_device); diff --git a/drivers/char/Config.in b/drivers/char/Config.in index 6358b6aa8..3ed5efcfa 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -208,7 +208,7 @@ endmenu dep_tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP if [ "$CONFIG_AGP" != "n" ]; then - bool ' Intel 440LX/BX/GX and I815/I830M/I840/I850 support' CONFIG_AGP_INTEL + bool ' Intel 440LX/BX/GX and I815/I820/I830M/I840/I845/I850/I860 support' CONFIG_AGP_INTEL bool ' Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810 bool ' VIA chipset support' CONFIG_AGP_VIA bool ' AMD Irongate, 761, and 762 support' CONFIG_AGP_AMD diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index b6b2355e9..a2c4ed580 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -179,6 +179,9 @@ struct agp_bridge_data { #ifndef PCI_DEVICE_ID_INTEL_820_0 #define PCI_DEVICE_ID_INTEL_820_0 0x2500 #endif +#ifndef PCI_DEVICE_ID_INTEL_820_UP_0 +#define PCI_DEVICE_ID_INTEL_820_UP_0 0x2501 +#endif #ifndef PCI_DEVICE_ID_INTEL_840_0 #define PCI_DEVICE_ID_INTEL_840_0 0x1a21 #endif @@ -189,7 +192,7 @@ struct agp_bridge_data { #define PCI_DEVICE_ID_INTEL_850_0 0x2530 #endif #ifndef PCI_DEVICE_ID_INTEL_860_0 -#define PCI_DEVICE_ID_INTEL_860_0 0x2532 +#define PCI_DEVICE_ID_INTEL_860_0 0x2531 #endif #ifndef PCI_DEVICE_ID_INTEL_810_DC100_0 #define PCI_DEVICE_ID_INTEL_810_DC100_0 0x7122 @@ -276,6 +279,7 @@ struct agp_bridge_data { #define I830_RDRAM_ND(x) (((x) & 0x20) >> 5) #define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3) +/* This one is for I830MP w. an external graphic card */ #define INTEL_I830_ERRSTS 0x92 /* intel i820 registers */ diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c index 630ef9c4a..2f717b911 100644 --- a/drivers/char/agp/agpgart_be.c +++ b/drivers/char/agp/agpgart_be.c @@ -409,8 +409,18 @@ static void agp_generic_agp_enable(u32 mode) * AGP devices and collect their data. */ - while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, - device)) != NULL) { + + pci_for_each_dev(device) + { + /* + * Enable AGP devices. Most will be VGA display but + * some may be coprocessors on non VGA devices too + */ + + if((((device->class >> 16) & 0xFF) != PCI_BASE_CLASS_DISPLAY) && + (device->class != (PCI_CLASS_PROCESSOR_CO << 8))) + continue; + pci_read_config_dword(device, 0x04, &scratch); if (!(scratch & 0x00100000)) @@ -1826,7 +1836,7 @@ static int __init intel_820_setup (struct pci_dev *pdev) agp_bridge.needs_scratch_page = FALSE; agp_bridge.configure = intel_820_configure; agp_bridge.fetch_size = intel_8xx_fetch_size; - agp_bridge.cleanup = intel_cleanup; + agp_bridge.cleanup = intel_820_cleanup; agp_bridge.tlb_flush = intel_820_tlbflush; agp_bridge.mask_memory = intel_mask_memory; agp_bridge.agp_enable = agp_generic_agp_enable; @@ -1839,6 +1849,9 @@ static int __init intel_820_setup (struct pci_dev *pdev) agp_bridge.free_by_type = agp_generic_free_by_type; agp_bridge.agp_alloc_page = agp_generic_alloc_page; agp_bridge.agp_destroy_page = agp_generic_destroy_page; + agp_bridge.suspend = agp_generic_suspend; + agp_bridge.resume = agp_generic_resume; + agp_bridge.cant_use_aperture = 0; return 0; @@ -1869,6 +1882,9 @@ static int __init intel_830mp_setup (struct pci_dev *pdev) agp_bridge.free_by_type = agp_generic_free_by_type; agp_bridge.agp_alloc_page = agp_generic_alloc_page; agp_bridge.agp_destroy_page = agp_generic_destroy_page; + agp_bridge.suspend = agp_generic_suspend; + agp_bridge.resume = agp_generic_resume; + agp_bridge.cant_use_aperture = 0; return 0; @@ -3307,8 +3323,18 @@ static void serverworks_agp_enable(u32 mode) * AGP devices and collect their data. */ - while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, - device)) != NULL) { + + pci_for_each_dev(device) + { + /* + * Enable AGP devices. Most will be VGA display but + * some may be coprocessors on non VGA devices too + */ + + if((((device->class >> 16) & 0xFF) != PCI_BASE_CLASS_DISPLAY) && + (device->class != (PCI_CLASS_PROCESSOR_CO << 8))) + continue; + pci_read_config_dword(device, 0x04, &scratch); if (!(scratch & 0x00100000)) @@ -3611,6 +3637,12 @@ static struct { "Intel", "i820", intel_820_setup }, + { PCI_DEVICE_ID_INTEL_820_UP_0, + PCI_VENDOR_ID_INTEL, + INTEL_I820, + "Intel", + "i820", + intel_820_setup }, { PCI_DEVICE_ID_INTEL_830_M_0, PCI_VENDOR_ID_INTEL, INTEL_I830_M, diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c index 2c6b9f9a5..e603a9e5f 100644 --- a/drivers/char/agp/agpgart_fe.c +++ b/drivers/char/agp/agpgart_fe.c @@ -301,7 +301,7 @@ static agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type) agp_memory *memory; memory = agp_allocate_memory(pg_count, type); - printk(KERN_DEBUG "memory : %p\n", memory); + printk(KERN_DEBUG "agp_allocate_memory: %p\n", memory); if (memory == NULL) { return NULL; } diff --git a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c index ea67cd9f4..9b01255d6 100644 --- a/drivers/char/ftape/lowlevel/fdc-io.c +++ b/drivers/char/ftape/lowlevel/fdc-io.c @@ -928,18 +928,6 @@ static inline void fdc_setup_dma(char mode, set_dma_mode(fdc.dma, mode); set_dma_addr(fdc.dma, virt_to_bus((void*)addr)); set_dma_count(fdc.dma, count); -#ifdef GCC_2_4_5_BUG - /* This seemingly stupid construction confuses the gcc-2.4.5 - * code generator enough to create correct code. - */ - if (1) { - int i; - - for (i = 0; i < 1; ++i) { - ftape_udelay(1); - } - } -#endif enable_dma(fdc.dma); } diff --git a/drivers/char/serial.c b/drivers/char/serial.c index 9a9b3c565..34b09d3f7 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -3095,36 +3095,52 @@ static int get_async_struct(int line, struct async_struct **ret_info) sstate = rs_table + line; sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } + info = sstate->info; + + /* + * If the async_struct is already allocated, do the fastpath. + */ + if (info) + goto out; + info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); if (!info) { sstate->count--; return -ENOMEM; } + memset(info, 0, sizeof(struct async_struct)); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); init_waitqueue_head(&info->delta_msr_wait); info->magic = SERIAL_MAGIC; info->port = sstate->port; + info->hub6 = sstate->hub6; info->flags = sstate->flags; - info->io_type = sstate->io_type; - info->iomem_base = sstate->iomem_base; - info->iomem_reg_shift = sstate->iomem_reg_shift; info->xmit_fifo_size = sstate->xmit_fifo_size; + info->state = sstate; info->line = line; + info->iomem_base = sstate->iomem_base; + info->iomem_reg_shift = sstate->iomem_reg_shift; + info->io_type = sstate->io_type; info->tqueue.routine = do_softint; info->tqueue.data = info; - info->state = sstate; + if (sstate->info) { kfree(info); - *ret_info = sstate->info; - return 0; + info = sstate->info; + } else { + sstate->info = info; + } + +out: + /* + * If this is the first open, copy over some timeouts. + */ + if (sstate->count == 1) { + info->closing_wait = sstate->closing_wait; } - *ret_info = sstate->info = info; + *ret_info = info; return 0; } diff --git a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c index 108821563..f956de8d8 100644 --- a/drivers/hotplug/pci_hotplug_core.c +++ b/drivers/hotplug/pci_hotplug_core.c @@ -396,7 +396,7 @@ static struct super_block *pcihpfs_get_sb(struct file_system_type *fs_type, static struct file_system_type pcihpfs_type = { owner: THIS_MODULE, - name: "pchihpfs", + name: "pcihpfs", get_sb: pcihpfs_get_sb, fs_flags: FS_LITTER, }; diff --git a/drivers/ide/Config.help b/drivers/ide/Config.help index 04eff0669..7cf29240f 100644 --- a/drivers/ide/Config.help +++ b/drivers/ide/Config.help @@ -796,3 +796,61 @@ CONFIG_BLK_DEV_TIVO Enable vendor-specific code for TiVo IDE disks. Unless you are the IDE maintainer, you probably do not want to mess with this. +CONFIG_IDEDISK_STROKE + Should you have a system w/ an AWARD Bios and your drives are larger + than 32GB and it will not boot, one is required to perform a few OEM + operations first. The option is called "STROKE" because it allows + one to "soft clip" the drive to work around a barrier limit. For + Maxtor drives it is called "jumpon.exe". Please search Maxtor's + web-site for "JUMPON.EXE". IBM has a similar tool at: + <http://www.storage.ibm.com/hdd/support/download.htm>. + + If you are unsure, say N here. + +CONFIG_IDE_TASK_IOCTL + This is a direct raw access to the media. It is a complex but + elegant solution to test and validate the domain of the hardware and + perform below the driver data recovery if needed. This is the most + basic form of media-forensics. + + If you are unsure, say N here. + +CONFIG_BLK_DEV_IDEDMA_FORCED + This is an old piece of lost code from Linux 2.0 Kernels. + + Generally say N here. + +CONFIG_IDEDMA_ONLYDISK + This is used if you know your ATAPI Devices are going to fail DMA + Transfers. + + Generally say N here. + +CONFIG_BLK_DEV_IT8172 + Say Y here to support the on-board IDE controller on the Integrated + Technology Express, Inc. ITE8172 SBC. Vendor page at + <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the + board at <http://www.mvista.com/allies/semiconductor/ite.html>. + +CONFIG_IT8172_TUNING + Say Y here to support tuning the ITE8172's IDE interface. This makes + it possible to set DMA channel or PIO opration and the transfer rate. + +CONFIG_IT8172_REVC + Say Y here to support the older, Revision C version of the Integrated + Technology Express, Inc. ITE8172 SBC. Vendor page at + <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the + board at <http://www.mvista.com/allies/semiconductor/ite.html>. + +CONFIG_IT8172_SCR0 + Say Y here to support smart-card reader 0 (SCR0) on the Integrated + Technology Express, Inc. ITE8172 SBC. Vendor page at + <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the + board at <http://www.mvista.com/allies/semiconductor/ite.html>. + +CONFIG_IT8172_SCR1 + Say Y here to support smart-card reader 1 (SCR1) on the Integrated + Technology Express, Inc. ITE8172 SBC. Vendor page at + <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the + board at <http://www.mvista.com/allies/semiconductor/ite.html>. + diff --git a/drivers/media/video/Config.in b/drivers/media/video/Config.in index 4a4ed77a0..d6a2f9ee3 100644 --- a/drivers/media/video/Config.in +++ b/drivers/media/video/Config.in @@ -22,10 +22,8 @@ if [ "$CONFIG_PARPORT" != "n" ]; then fi fi if [ "$CONFIG_PARPORT" != "n" ]; then - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_PARPORT_1284" != "n" ]; then - dep_tristate ' Winbond W9966CF Webcam Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_W9966 $CONFIG_VIDEO_DEV $CONFIG_PARPORT - fi + if [ "$CONFIG_PARPORT_1284" != "n" ]; then + dep_tristate ' W9966CF Webcam (FlyCam Supra and others) Video For Linux' CONFIG_VIDEO_W9966 $CONFIG_VIDEO_DEV $CONFIG_PARPORT fi fi dep_tristate ' CPiA Video For Linux' CONFIG_VIDEO_CPIA $CONFIG_VIDEO_DEV diff --git a/drivers/net/Config.help b/drivers/net/Config.help index d34d5ca45..fe7ba7ec6 100644 --- a/drivers/net/Config.help +++ b/drivers/net/Config.help @@ -1154,6 +1154,17 @@ CONFIG_NATSEMI More specific information and updates are available from <http://www.scyld.com/network/natsemi.html>. +CONFIG_NATSEMI_CABLE_MAGIC + Some systems see lots of errors with NatSemi ethernet controllers + on certain cables. If you are seeing lots of errors, try turning + this option on. Some boards have incorrect values for supporting + resistors that can cause this change to break. If you turn this + option on and your network suddenly stops working, turn this + option off. + + Say N unless you are certain you need this option. + Vendors should not enable this option by default. + CONFIG_SK_G16 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from diff --git a/drivers/net/Config.in b/drivers/net/Config.in index eee781f4f..9fe05fbc1 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -171,6 +171,9 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then dep_tristate ' Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 $CONFIG_EISA $CONFIG_EXPERIMENTAL dep_tristate ' Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI dep_tristate ' National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI + if [ "$CONFIG_NATSEMI" = "y" -o "$CONFIG_NATSEMI" = "m" ]; then + bool ' NatSemi workaround for high errors' CONFIG_NATSEMI_CABLE_MAGIC + fi dep_tristate ' PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI dep_tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL dep_tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index f9d6cb7de..c670ba07f 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -833,6 +833,10 @@ static int speedo_found1(struct pci_dev *pdev, sp->phy[0] = eeprom[6]; sp->phy[1] = eeprom[7]; sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1; + if (((pdev->device > 0x1030 && (pdev->device < 0x1039))) + || (pdev->device == 0x2449)) { + sp->chip_id = 1; + } if (sp->rx_bug) printk(KERN_INFO " Receiver lock-up workaround activated.\n"); @@ -987,6 +991,11 @@ speedo_open(struct net_device *dev) if ((sp->phy[0] & 0x8000) == 0) sp->advertising = mdio_read(ioaddr, sp->phy[0] & 0x1f, 4); + if (mdio_read(ioaddr, sp->phy[0] & 0x1f, MII_BMSR) & BMSR_LSTATUS) + netif_carrier_on(dev); + else + netif_carrier_off(dev); + if (speedo_debug > 2) { printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n", dev->name, inw(ioaddr + SCBStatus)); @@ -1098,10 +1107,10 @@ static void speedo_timer(unsigned long data) /* Clear sticky bit. */ mdio_read(ioaddr, phy_num, 1); /* If link beat has returned... */ - if (mdio_read(ioaddr, phy_num, 1) & 0x0004) - dev->flags |= IFF_RUNNING; + if (mdio_read(ioaddr, phy_num, MII_BMSR) & BMSR_LSTATUS) + netif_carrier_on(dev); else - dev->flags &= ~IFF_RUNNING; + netif_carrier_off(dev); } } if (speedo_debug > 3) { @@ -1375,7 +1384,7 @@ speedo_start_xmit(struct sk_buff *skb, struct net_device *dev) /* workaround for hardware bug on 10 mbit half duplex */ - if ((sp->partner==0) && (sp->chip_id==1)) { + if ((sp->partner == 0) || (sp->chip_id == 1)) { wait_for_cmd_done(ioaddr + SCBCmd); outb(0 , ioaddr + SCBCmd); } diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index a94d69453..d3d57823a 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -394,7 +394,11 @@ enum register_offsets { SDCFG = 0xF8 }; /* the values for the 'magic' registers above (PGSEL=1) */ +#ifdef CONFIG_NATSEMI_CABLE_MAGIC +#define PMDCSR_VAL 0x1898 +#else #define PMDCSR_VAL 0x189C +#endif #define TSTDAT_VAL 0x0 #define DSPCFG_VAL 0x5040 #define SDCFG_VAL 0x008c @@ -1511,7 +1515,7 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs) if (intr_status == 0) break; - if (intr_status & (IntrRxDone | IntrRxIntr)) + if (intr_status & (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | IntrRxErr | IntrRxOverrun )) netdev_rx(dev); if (intr_status & (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr) ) { diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 25b86ec89..8dd2af654 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -65,15 +65,15 @@ static struct net_device *pcnet32_dev; static const int max_interrupt_work = 80; static const int rx_copybreak = 200; -#define PORT_AUI 0x00 -#define PORT_10BT 0x01 -#define PORT_GPSI 0x02 -#define PORT_MII 0x03 +#define PCNET32_PORT_AUI 0x00 +#define PCNET32_PORT_10BT 0x01 +#define PCNET32_PORT_GPSI 0x02 +#define PCNET32_PORT_MII 0x03 -#define PORT_PORTSEL 0x03 -#define PORT_ASEL 0x04 -#define PORT_100 0x40 -#define PORT_FD 0x80 +#define PCNET32_PORT_PORTSEL 0x03 +#define PCNET32_PORT_ASEL 0x04 +#define PCNET32_PORT_100 0x40 +#define PCNET32_PORT_FD 0x80 #define PCNET32_DMA_MASK 0xffffffff @@ -82,22 +82,22 @@ static const int rx_copybreak = 200; * to internal options */ static unsigned char options_mapping[] = { - PORT_ASEL, /* 0 Auto-select */ - PORT_AUI, /* 1 BNC/AUI */ - PORT_AUI, /* 2 AUI/BNC */ - PORT_ASEL, /* 3 not supported */ - PORT_10BT | PORT_FD, /* 4 10baseT-FD */ - PORT_ASEL, /* 5 not supported */ - PORT_ASEL, /* 6 not supported */ - PORT_ASEL, /* 7 not supported */ - PORT_ASEL, /* 8 not supported */ - PORT_MII, /* 9 MII 10baseT */ - PORT_MII | PORT_FD, /* 10 MII 10baseT-FD */ - PORT_MII, /* 11 MII (autosel) */ - PORT_10BT, /* 12 10BaseT */ - PORT_MII | PORT_100, /* 13 MII 100BaseTx */ - PORT_MII | PORT_100 | PORT_FD, /* 14 MII 100BaseTx-FD */ - PORT_ASEL /* 15 not supported */ + PCNET32_PORT_ASEL, /* 0 Auto-select */ + PCNET32_PORT_AUI, /* 1 BNC/AUI */ + PCNET32_PORT_AUI, /* 2 AUI/BNC */ + PCNET32_PORT_ASEL, /* 3 not supported */ + PCNET32_PORT_10BT | PCNET32_PORT_FD, /* 4 10baseT-FD */ + PCNET32_PORT_ASEL, /* 5 not supported */ + PCNET32_PORT_ASEL, /* 6 not supported */ + PCNET32_PORT_ASEL, /* 7 not supported */ + PCNET32_PORT_ASEL, /* 8 not supported */ + PCNET32_PORT_MII, /* 9 MII 10baseT */ + PCNET32_PORT_MII | PCNET32_PORT_FD, /* 10 MII 10baseT-FD */ + PCNET32_PORT_MII, /* 11 MII (autosel) */ + PCNET32_PORT_10BT, /* 12 10BaseT */ + PCNET32_PORT_MII | PCNET32_PORT_100, /* 13 MII 100BaseTx */ + PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD, /* 14 MII 100BaseTx-FD */ + PCNET32_PORT_ASEL /* 15 not supported */ }; #define MAX_UNITS 8 @@ -709,12 +709,12 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car lp->ltint = ltint; lp->mii = mii; if (options[card_idx] > sizeof (options_mapping)) - lp->options = PORT_ASEL; + lp->options = PCNET32_PORT_ASEL; else lp->options = options_mapping[options[card_idx]]; - if (fdx && !(lp->options & PORT_ASEL) && full_duplex[card_idx]) - lp->options |= PORT_FD; + if (fdx && !(lp->options & PCNET32_PORT_ASEL) && full_duplex[card_idx]) + lp->options |= PCNET32_PORT_FD; if (a == NULL) { printk(KERN_ERR "pcnet32: No access methods\n"); @@ -726,7 +726,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int car /* detect special T1/E1 WAN card by checking for MAC address */ if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 && dev->dev_addr[2] == 0x75) - lp->options = PORT_FD | PORT_GPSI; + lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI; lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */ lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS); @@ -829,16 +829,16 @@ pcnet32_open(struct net_device *dev) /* set/reset autoselect bit */ val = lp->a.read_bcr (ioaddr, 2) & ~2; - if (lp->options & PORT_ASEL) + if (lp->options & PCNET32_PORT_ASEL) val |= 2; lp->a.write_bcr (ioaddr, 2, val); /* handle full duplex setting */ if (lp->full_duplex) { val = lp->a.read_bcr (ioaddr, 9) & ~3; - if (lp->options & PORT_FD) { + if (lp->options & PCNET32_PORT_FD) { val |= 1; - if (lp->options == (PORT_FD | PORT_AUI)) + if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI)) val |= 2; } lp->a.write_bcr (ioaddr, 9, val); @@ -846,19 +846,19 @@ pcnet32_open(struct net_device *dev) /* set/reset GPSI bit in test register */ val = lp->a.read_csr (ioaddr, 124) & ~0x10; - if ((lp->options & PORT_PORTSEL) == PORT_GPSI) + if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI) val |= 0x10; lp->a.write_csr (ioaddr, 124, val); - if (lp->mii && !(lp->options & PORT_ASEL)) { + if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) { val = lp->a.read_bcr (ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */ - if (lp->options & PORT_FD) + if (lp->options & PCNET32_PORT_FD) val |= 0x10; - if (lp->options & PORT_100) + if (lp->options & PCNET32_PORT_100) val |= 0x08; lp->a.write_bcr (ioaddr, 32, val); } else { - if (lp->options & PORT_ASEL) { /* enable auto negotiate, setup, disable fd */ + if (lp->options & PCNET32_PORT_ASEL) { /* enable auto negotiate, setup, disable fd */ val = lp->a.read_bcr(ioaddr, 32) & ~0x98; val |= 0x20; lp->a.write_bcr(ioaddr, 32, val); @@ -878,7 +878,7 @@ pcnet32_open(struct net_device *dev) lp->a.write_csr (ioaddr, 5, val); } - lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7); + lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); lp->init_block.filter[0] = 0x00000000; lp->init_block.filter[1] = 0x00000000; if (pcnet32_init_ring(dev)) @@ -1465,9 +1465,9 @@ static void pcnet32_set_multicast_list(struct net_device *dev) if (dev->flags&IFF_PROMISC) { /* Log any net taps. */ printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name); - lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PORT_PORTSEL) << 7); + lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) << 7); } else { - lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7); + lp->init_block.mode = le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7); pcnet32_load_multicast (dev); } diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c index 3a88c4412..7e66f9034 100644 --- a/drivers/net/tulip/21142.c +++ b/drivers/net/tulip/21142.c @@ -39,8 +39,13 @@ void t21142_timer(unsigned long data) printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n", dev->name, csr12, medianame[dev->if_port]); if (tulip_media_cap[dev->if_port] & MediaIsMII) { - tulip_check_duplex(dev); - next_tick = 60*HZ; + if (tulip_check_duplex(dev) < 0) { + netif_carrier_off(dev); + next_tick = 3*HZ; + } else { + netif_carrier_on(dev); + next_tick = 60*HZ; + } } else if (tp->nwayset) { /* Don't screw up a negotiated session! */ if (tulip_debug > 1) diff --git a/drivers/net/tulip/ChangeLog b/drivers/net/tulip/ChangeLog index 8a1caaa28..3111685c2 100644 --- a/drivers/net/tulip/ChangeLog +++ b/drivers/net/tulip/ChangeLog @@ -1,3 +1,30 @@ +2002-01-28 Stefan Rompf <srompf@isg.de>, + Jeff Garzik <jgarzik@mandrakesoft.com> + + * 21142.c (t21142_timer): Use return value of + tulip_check_duplex() to indicate to system whether or not + carrier is present. Use carrier presence/absence to determine + when next the 21142 media timer should check for link beat. + + * timer (tulip_timer): Un-comment-out calls to + netif_carrier_{on,off}, as there is now value in + reporting link beta information to userspace. + +2002-01-28 Pavel Roskin <proski@gnu.org> + + * tulip_core.c (tulip_init_one): Use tp->eeprom instead of + allocating a buffer for EEPROM copy on the stack. + + * tulip_core.c: Add support for Conexant RS7112 (a.k.a. CN7112) + chip. + * tulip.h: Likewise. Increase EEPROM_SIZE to 512 bytes to + accomodate EEPROM on Conexant RS7112. + +2002-02-07 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> + + * tulip_core (tulip_pci_tbl[]): + Add PCI id for comet tulip clone. + 2001-12-11 Jeff Garzik <jgarzik@mandrakesoft.com> * eeprom.c, timer.c, media.c, tulip_core.c: diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c index 53c43912b..c67dd8531 100644 --- a/drivers/net/tulip/timer.c +++ b/drivers/net/tulip/timer.c @@ -83,10 +83,10 @@ void tulip_timer(unsigned long data) medianame[mleaf->media & MEDIA_MASK]); if ((p[2] & 0x61) == 0x01) /* Bogus Znyx board. */ goto actually_mii; - /* netif_carrier_on(dev); */ + netif_carrier_on(dev); break; } - /* netif_carrier_off(dev); */ + netif_carrier_off(dev); if (tp->medialock) break; select_next_media: @@ -110,11 +110,13 @@ void tulip_timer(unsigned long data) } case 1: case 3: /* 21140, 21142 MII */ actually_mii: - if (tulip_check_duplex(dev) < 0) - { /* netif_carrier_off(dev); */ } - else - { /* netif_carrier_on(dev); */ } - next_tick = 60*HZ; + if (tulip_check_duplex(dev) < 0) { + netif_carrier_off(dev); + next_tick = 3*HZ; + } else { + netif_carrier_on(dev); + next_tick = 60*HZ; + } break; case 2: /* 21142 serial block has no link beat. */ default: diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index 2171eb9dc..c39cb3cb2 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -84,6 +84,7 @@ enum chips { COMPEX9881, I21145, DM910X, + CONEXANT, }; @@ -290,7 +291,7 @@ enum t21143_csr6_bits { #define DESC_RING_WRAP 0x02000000 -#define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */ +#define EEPROM_SIZE 512 /* 2 << EEPROM_ADDRLEN */ #define RUN_AT(x) (jiffies + (x)) diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index b396f5ba8..9143debde 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -15,8 +15,8 @@ */ #define DRV_NAME "tulip" -#define DRV_VERSION "1.1.0" -#define DRV_RELDATE "Dec 11, 2001" +#define DRV_VERSION "1.1.11" +#define DRV_RELDATE "Feb 08, 2002" #include <linux/config.h> #include <linux/module.h> @@ -185,6 +185,10 @@ struct tulip_chip_table tulip_tbl[] = { { "Davicom DM9102/DM9102A", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, tulip_timer }, + + /* RS7112 */ + { "Conexant LANfinity", 256, 0x0001ebef, + HAS_MII | HAS_ACPI, tulip_timer }, }; @@ -202,6 +206,7 @@ static struct pci_device_id tulip_pci_tbl[] __devinitdata = { { 0x1317, 0x1985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x13D1, 0xAB02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x13D1, 0xAB03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, + { 0x13D1, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x104A, 0x0981, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x104A, 0x2774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, @@ -211,6 +216,7 @@ static struct pci_device_id tulip_pci_tbl[] __devinitdata = { { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, + { 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT }, { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, tulip_pci_tbl); @@ -417,7 +423,7 @@ media_picked: tp->csr6 = 0x01a80200; outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0); - } else if (tp->chip_id == COMET) { + } else if (tp->chip_id == COMET || tp->chip_id == CONEXANT) { /* Enable automatic Tx underrun recovery. */ outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88); dev->if_port = tp->mii_cnt ? 11 : 0; @@ -1253,7 +1259,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, u8 chip_rev; int i, irq; unsigned short sum; - u8 ee_data[EEPROM_SIZE]; + unsigned char *ee_data; struct net_device *dev; long ioaddr; static int board_idx = -1; @@ -1430,6 +1436,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, be polled, waiting for the value to be read bit serially from the EEPROM. */ + ee_data = tp->eeprom; sum = 0; if (chip_idx == LC82C168) { for (i = 0; i < 3; i++) { @@ -1452,17 +1459,22 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, int sa_offset = 0; int ee_addr_size = tulip_read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; - for (i = 0; i < sizeof(ee_data)/2; i++) + for (i = 0; i < sizeof(tp->eeprom)/2; i++) ((u16 *)ee_data)[i] = le16_to_cpu(tulip_read_eeprom(ioaddr, i, ee_addr_size)); /* DEC now has a specification (see Notes) but early board makers just put the address in the first EEPROM locations. */ - /* This does memcmp(eedata, eedata+16, 8) */ + /* This does memcmp(ee_data, ee_data+16, 8) */ for (i = 0; i < 8; i ++) if (ee_data[i] != ee_data[16+i]) sa_offset = 20; - if (ee_data[0] == 0xff && ee_data[1] == 0xff && ee_data[2] == 0) { + if (chip_idx == CONEXANT) { + /* Check that the tuple type and length is correct. */ + if (ee_data[0x198] == 0x04 && ee_data[0x199] == 6) + sa_offset = 0x19A; + } else if (ee_data[0] == 0xff && ee_data[1] == 0xff && + ee_data[2] == 0) { sa_offset = 2; /* Grrr, damn Matrox boards. */ multiport_cnt = 4; } @@ -1555,8 +1567,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, } if (tp->flags & HAS_MEDIA_TABLE) { - memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom)); - sprintf(dev->name, "tulip%d", board_idx); /* hack */ tulip_parse_eeprom(dev); strcpy(dev->name, "eth%d"); /* un-hack */ diff --git a/drivers/net/winbond-840.c b/drivers/net/winbond-840.c index 514b57d19..90055d168 100644 --- a/drivers/net/winbond-840.c +++ b/drivers/net/winbond-840.c @@ -347,7 +347,7 @@ struct netdev_private { struct w840_rx_desc *rx_ring; dma_addr_t rx_addr[RX_RING_SIZE]; struct w840_tx_desc *tx_ring; - dma_addr_t tx_addr[RX_RING_SIZE]; + dma_addr_t tx_addr[TX_RING_SIZE]; dma_addr_t ring_dma_addr; /* The addresses of receive-in-place skbuffs. */ struct sk_buff* rx_skbuff[RX_RING_SIZE]; diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 875160beb..7001c37d1 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -279,6 +279,11 @@ int cb_alloc(socket_info_t * s) pci_readw(dev, PCI_DEVICE_ID, &dev->device); dev->hdr_type = hdr & 0x7f; + dev->dev.parent = bus->dev; + strcpy(dev->dev.name, dev->name); + strcpy(dev->dev.bus_id, dev->slot_name); + device_register(&dev->dev); + pci_setup_device(dev); /* FIXME: Do we need to enable the expansion ROM? */ diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 1590354e8..f18bc7a18 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -130,6 +130,7 @@ static void idescsi_output_zeros (ide_drive_t *drive, unsigned int bcount) static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount) { int count; + char *buf; while (bcount) { if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { @@ -138,7 +139,8 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne return; } count = IDE_MIN (pc->sg->length - pc->b_count, bcount); - atapi_input_bytes (drive, pc->sg->address + pc->b_count, count); + buf = page_address(pc->sg->page) + pc->sg->offset; + atapi_input_bytes (drive, buf + pc->b_count, count); bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { pc->sg++; @@ -150,6 +152,7 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount) { int count; + char *buf; while (bcount) { if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { @@ -158,7 +161,8 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign return; } count = IDE_MIN (pc->sg->length - pc->b_count, bcount); - atapi_output_bytes (drive, pc->sg->address + pc->b_count, count); + buf = page_address(pc->sg->page) + pc->sg->offset; + atapi_output_bytes (drive, buf + pc->b_count, count); bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { pc->sg++; @@ -750,25 +754,11 @@ static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc) printk ("ide-scsi: %s: building DMA table, %d segments, %dkB total\n", drive->name, segments, pc->request_transfer >> 10); #endif /* IDESCSI_DEBUG_LOG */ while (segments--) { - struct page *page = sg->page; - int offset = sg->offset; - - if (!page) { - BUG_ON(!sg->address); - page = virt_to_page(sg->address); - offset = (unsigned long) sg->address & ~PAGE_MASK; - } - - bh->bi_io_vec[0].bv_page = page; + bh->bi_io_vec[0].bv_page = sg->page; bh->bi_io_vec[0].bv_len = sg->length; - bh->bi_io_vec[0].bv_offset = offset; + bh->bi_io_vec[0].bv_offset = sg->offset; bh->bi_size = sg->length; bh = bh->bi_next; - /* - * just until scsi_merge is fixed up... - */ - BUG_ON(PageHighMem(page)); - sg->address = page_address(page) + offset; sg++; } } else { diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 62263c59d..e59074258 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -76,8 +76,6 @@ static void sg_proc_cleanup(void); #include <linux/version.h> #endif /* LINUX_VERSION_CODE */ -#define SG_STILL_HAVE_ADDRESS_IN_SCATTERLIST - #define SG_ALLOW_DIO_DEF 0 #define SG_ALLOW_DIO_CODE /* compile out be commenting this define */ #ifdef SG_ALLOW_DIO_CODE @@ -1714,9 +1712,6 @@ static int sg_build_dir(Sg_request * srp, Sg_fd * sfp, int dxfer_len) rem_sz; sclp->page = kp->maplist[k]; sclp->offset = offset; -#ifdef SG_STILL_HAVE_ADDRESS_IN_SCATTERLIST - sclp->address = page_address(kp->maplist[k]) + offset; -#endif sclp->length = num; mem_src_arr[k] = SG_USER_MEM; rem_sz -= num; @@ -1804,9 +1799,6 @@ static int sg_build_indi(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size) } sclp->page = virt_to_page(p); sclp->offset = (unsigned long)p & ~PAGE_MASK; -#ifdef SG_STILL_HAVE_ADDRESS_IN_SCATTERLIST - sclp->address = p; -#endif sclp->length = ret_sz; mem_src_arr[k] = mem_src; @@ -1967,9 +1959,6 @@ static void sg_remove_scat(Sg_scatter_hold * schp) sg_free(sg_scatg2virt(sclp), sclp->length, mem_src); sclp->page = NULL; sclp->offset = 0; -#ifdef SG_STILL_HAVE_ADDRESS_IN_SCATTERLIST - sclp->address = 0; -#endif sclp->length = 0; } sg_free(schp->buffer, schp->sglist_len, schp->buffer_mem_src); diff --git a/drivers/sound/opl3sa2.c b/drivers/sound/opl3sa2.c index 9791d7a7c..d8b25ed3a 100644 --- a/drivers/sound/opl3sa2.c +++ b/drivers/sound/opl3sa2.c @@ -55,6 +55,7 @@ * sb_card.c and awe_wave.c. (Dec 12, 2000) * Scott Murray Some small cleanups to the init code output. * (Jan 7, 2001) + * Zwane Mwaikambo Added PM support. (Dec 4 2001) * */ @@ -62,13 +63,14 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/isapnp.h> - +#include <linux/pm.h> #include "sound_config.h" #include "ad1848.h" #include "mpu401.h" /* Useful control port indexes: */ +#define OPL3SA2_PM 0x01 #define OPL3SA2_SYS_CTRL 0x02 #define OPL3SA2_IRQ_CONFIG 0x03 #define OPL3SA2_DMA_CONFIG 0x06 @@ -86,6 +88,11 @@ #define DEFAULT_MIC 50 #define DEFAULT_TIMBRE 0 +/* Power saving modes */ +#define OPL3SA2_PM_MODE1 0x05 +#define OPL3SA2_PM_MODE2 0x04 +#define OPL3SA2_PM_MODE3 0x03 + /* For checking against what the card returns: */ #define VERSION_UNKNOWN 0 #define VERSION_YMF711 1 @@ -121,6 +128,10 @@ static int opl3sa2_mixer[OPL3SA2_CARDS_MAX] = { -1 }; typedef struct opl3sa2_mixerdata_tag { unsigned short cfg_port; unsigned short padding; + unsigned char reg; + unsigned int in_suspend; + struct pm_dev *pmdev; + unsigned int card; unsigned int volume_l; unsigned int volume_r; unsigned int mic; @@ -328,6 +339,20 @@ static void opl3sa2_mixer_reset(opl3sa2_mixerdata* devc, int card) } +static void opl3sa2_mixer_restore(opl3sa2_mixerdata* devc, int card) +{ + if (devc) { + opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r); + opl3sa2_set_mic(devc, devc->mic); + + if (chipset[card] == CHIPSET_OPL3SA3) { + opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r); + opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r); + } + } +} + + static inline void arg_to_vol_mono(unsigned int vol, int* value) { int left; @@ -892,6 +917,77 @@ static int __init opl3sa2_isapnp_probe(struct address_info* hw_cfg, /* End of component functions */ +/* Power Management support functions */ +static int opl3sa2_suspend(struct pm_dev *pdev, unsigned char pm_mode) +{ + unsigned long flags; + opl3sa2_mixerdata *p; + + if (!pdev) + return -EINVAL; + + save_flags(flags); + cli(); + + p = (opl3sa2_mixerdata *) pdev->data; + p->in_suspend = 1; + switch (pm_mode) { + case 1: + pm_mode = OPL3SA2_PM_MODE1; + break; + case 2: + pm_mode = OPL3SA2_PM_MODE2; + break; + case 3: + pm_mode = OPL3SA2_PM_MODE3; + break; + default: + pm_mode = OPL3SA2_PM_MODE3; + break; + } + + /* its supposed to automute before suspending, so we wont bother */ + opl3sa2_read(p->cfg_port, OPL3SA2_PM, &p->reg); + opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->reg | pm_mode); + + restore_flags(flags); + return 0; +} + +static int opl3sa2_resume(struct pm_dev *pdev) +{ + unsigned long flags; + opl3sa2_mixerdata *p; + + if (!pdev) + return -EINVAL; + + p = (opl3sa2_mixerdata *) pdev->data; + save_flags(flags); + cli(); + + /* I don't think this is necessary */ + opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->reg); + opl3sa2_mixer_restore(p, p->card); + p->in_suspend = 0; + + restore_flags(flags); + return 0; +} + +static int opl3sa2_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data) +{ + unsigned char mode = (unsigned char)data; + + switch (rqst) { + case PM_SUSPEND: + return opl3sa2_suspend(pdev, mode); + + case PM_RESUME: + return opl3sa2_resume(pdev); + } + return 0; +} /* * Install OPL3-SA2 based card(s). @@ -989,6 +1085,12 @@ static int __init init_opl3sa2(void) attach_opl3sa2_mss(&cfg_mss[card]); attach_opl3sa2_mixer(&cfg[card], card); + opl3sa2_data[card].card = card; + /* register our power management capabilities */ + opl3sa2_data[card].pmdev = pm_register(PM_ISA_DEV, card, opl3sa2_pm_callback); + if (opl3sa2_data[card].pmdev) + opl3sa2_data[card].pmdev->data = &opl3sa2_data[card]; + /* * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and * it's supported. @@ -1033,6 +1135,9 @@ static void __exit cleanup_opl3sa2(void) int card; for(card = 0; card < opl3sa2_cards_num; card++) { + if (opl3sa2_data[card].pmdev) + pm_unregister(opl3sa2_data[card].pmdev); + if(cfg_mpu[card].slots[1] != -1) { unload_opl3sa2_mpu(&cfg_mpu[card]); } diff --git a/drivers/usb/ibmcam.h b/drivers/usb/ibmcam.h deleted file mode 100644 index 6a5e1cd02..000000000 --- a/drivers/usb/ibmcam.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Header file for USB IBM C-It Video Camera driver. - * - * Supports IBM C-It Video Camera. - * - * This driver is based on earlier work of: - * - * (C) Copyright 1999 Johannes Erdfelt - * (C) Copyright 1999 Randy Dunlap - */ - -#ifndef __LINUX_IBMCAM_H -#define __LINUX_IBMCAM_H - -#include <linux/list.h> - -#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */ - -/* Video Size 384 x 288 x 3 bytes for RGB */ -/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */ -#define V4L_FRAME_WIDTH 384 -#define V4L_FRAME_WIDTH_USED 352 -#define V4L_FRAME_HEIGHT 288 -#define V4L_BYTES_PER_PIXEL 3 -#define MAX_FRAME_SIZE (V4L_FRAME_WIDTH * V4L_FRAME_HEIGHT * V4L_BYTES_PER_PIXEL) - -/* Camera capabilities (maximum) */ -#define CAMERA_IMAGE_WIDTH 352 -#define CAMERA_IMAGE_HEIGHT 288 -#define CAMERA_IMAGE_LINE_SZ ((CAMERA_IMAGE_WIDTH * 3) / 2) /* Bytes */ -#define CAMERA_URB_FRAMES 32 -#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */ - -#define IBMCAM_NUMFRAMES 2 -#define IBMCAM_NUMSBUF 2 - -#define FRAMES_PER_DESC (CAMERA_URB_FRAMES) -#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET) - -/* This macro restricts an int variable to an inclusive range */ -#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); } - -/* - * This macro performs bounds checking - use it when working with - * new formats, or else you may get oopses all over the place. - * If pixel falls out of bounds then it gets shoved back (as close - * to place of offence as possible) and is painted bright red. - */ -#define IBMCAM_PUTPIXEL(fr, ix, iy, vr, vg, vb) { \ - register unsigned char *pf; \ - int limiter = 0, mx, my; \ - mx = ix; \ - my = iy; \ - if (mx < 0) { \ - mx=0; \ - limiter++; \ - } else if (mx >= 352) { \ - mx=351; \ - limiter++; \ - } \ - if (my < 0) { \ - my = 0; \ - limiter++; \ - } else if (my >= V4L_FRAME_HEIGHT) { \ - my = V4L_FRAME_HEIGHT - 1; \ - limiter++; \ - } \ - pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*352 + (ix)); \ - if (limiter) { \ - *pf++ = 0; \ - *pf++ = 0; \ - *pf++ = 0xFF; \ - } else { \ - *pf++ = (vb); \ - *pf++ = (vg); \ - *pf++ = (vr); \ - } \ -} - -/* - * We use macros to do YUV -> RGB conversion because this is - * very important for speed and totally unimportant for size. - * - * YUV -> RGB Conversion - * --------------------- - * - * B = 1.164*(Y-16) + 2.018*(V-128) - * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128) - * R = 1.164*(Y-16) + 1.596*(U-128) - * - * If you fancy integer arithmetics (as you should), hear this: - * - * 65536*B = 76284*(Y-16) + 132252*(V-128) - * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128) - * 65536*R = 76284*(Y-16) + 104595*(U-128) - * - * Make sure the output values are within [0..255] range. - */ -#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x))) -#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \ - int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \ - mm_y = (my) - 16; \ - mm_u = (mu) - 128; \ - mm_v = (mv) - 128; \ - mm_yc= mm_y * 76284; \ - mm_b = (mm_yc + 132252*mm_v ) >> 16; \ - mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \ - mm_r = (mm_yc + 104595*mm_u ) >> 16; \ - mb = LIMIT_RGB(mm_b); \ - mg = LIMIT_RGB(mm_g); \ - mr = LIMIT_RGB(mm_r); \ -} - -/* Debugging aid */ -#define IBMCAM_SAY_AND_WAIT(what) { \ - wait_queue_head_t wq; \ - init_waitqueue_head(&wq); \ - printk(KERN_INFO "Say: %s\n", what); \ - interruptible_sleep_on_timeout (&wq, HZ*3); \ -} - -/* - * This macro checks if ibmcam is still operational. The 'ibmcam' - * pointer must be valid, ibmcam->dev must be valid, we are not - * removing the device and the device has not erred on us. - */ -#define IBMCAM_IS_OPERATIONAL(ibm_cam) (\ - (ibm_cam != NULL) && \ - ((ibm_cam)->dev != NULL) && \ - ((ibm_cam)->last_error == 0) && \ - (!(ibm_cam)->remove_pending)) - -enum { - STATE_SCANNING, /* Scanning for header */ - STATE_LINES, /* Parsing lines */ -}; - -enum { - FRAME_UNUSED, /* Unused (no MCAPTURE) */ - FRAME_READY, /* Ready to start grabbing */ - FRAME_GRABBING, /* In the process of being grabbed into */ - FRAME_DONE, /* Finished grabbing, but not been synced yet */ - FRAME_ERROR, /* Something bad happened while processing */ -}; - -struct usb_device; - -struct ibmcam_sbuf { - char *data; - struct urb *urb; -}; - -struct ibmcam_frame { - char *data; /* Frame buffer */ - int order_uv; /* True=UV False=VU */ - int order_yc; /* True=Yc False=cY ('c'=either U or V) */ - unsigned char hdr_sig; /* "00 FF 00 ??" where 'hdr_sig' is '??' */ - - int width; /* Width application is expecting */ - int height; /* Height */ - - int frmwidth; /* Width the frame actually is */ - int frmheight; /* Height */ - - volatile int grabstate; /* State of grabbing */ - int scanstate; /* State of scanning */ - - int curline; /* Line of frame we're working on */ - - long scanlength; /* uncompressed, raw data length of frame */ - long bytes_read; /* amount of scanlength that has been read from *data */ - - wait_queue_head_t wq; /* Processes waiting */ -}; - -#define IBMCAM_MODEL_1 1 /* XVP-501, 3 interfaces, rev. 0.02 */ -#define IBMCAM_MODEL_2 2 /* KSX-X9903, 2 interfaces, rev. 3.0a */ - -struct usb_ibmcam { - struct video_device vdev; - - /* Device structure */ - struct usb_device *dev; - - unsigned char iface; /* Video interface number */ - unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */ - - struct semaphore lock; - int user; /* user count for exclusive use */ - - int ibmcam_used; /* Is this structure in use? */ - int initialized; /* Had we already sent init sequence? */ - int camera_model; /* What type of IBM camera we got? */ - int streaming; /* Are we streaming Isochronous? */ - int grabbing; /* Are we grabbing? */ - int last_error; /* What calamity struck us? */ - - int compress; /* Should the next frame be compressed? */ - - char *fbuf; /* Videodev buffer area */ - int fbuf_size; /* Videodev buffer size */ - - int curframe; - struct ibmcam_frame frame[IBMCAM_NUMFRAMES]; /* Double buffering */ - - int cursbuf; /* Current receiving sbuf */ - struct ibmcam_sbuf sbuf[IBMCAM_NUMSBUF]; /* Double buffering */ - volatile int remove_pending; /* If set then about to exit */ - - /* - * Scratch space from the Isochronous pipe. - * Scratch buffer should contain at least one pair of lines - * (CAMERA_IMAGE_LINE_SZ). We set it to two pairs here. - * This will be approximately 2 KB. HOWEVER in reality this - * buffer must be as large as hundred of KB because otherwise - * you'll get lots of overflows because V4L client may request - * frames not as uniformly as USB sources them. - */ - unsigned char *scratch; - int scratchlen; - - struct video_picture vpic, vpic_old; /* Picture settings */ - struct video_capability vcap; /* Video capabilities */ - struct video_channel vchan; /* May be used for tuner support */ - unsigned char video_endp; /* 0x82 for IBM camera */ - int has_hdr; - int frame_num; - int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */ - - /* Statistics that can be overlayed on screen */ - unsigned long urb_count; /* How many URBs we received so far */ - unsigned long urb_length; /* Length of last URB */ - unsigned long data_count; /* How many bytes we received */ - unsigned long header_count; /* How many frame headers we found */ - unsigned long scratch_ovf_count;/* How many times we overflowed scratch */ - unsigned long iso_skip_count; /* How many empty ISO packets received */ - unsigned long iso_err_count; /* How many bad ISO packets received */ -}; - -#endif /* __LINUX_IBMCAM_H */ diff --git a/drivers/video/Config.in b/drivers/video/Config.in index 1d92c99c2..513ab3f82 100644 --- a/drivers/video/Config.in +++ b/drivers/video/Config.in @@ -121,14 +121,14 @@ if [ "$CONFIG_FB" = "y" ]; then if [ "$CONFIG_FB_MATROX" != "n" ]; then bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE - bool ' G100/G200/G400/G450 support' CONFIG_FB_MATROX_G100 + bool ' G100/G200/G400/G450/G550 support' CONFIG_FB_MATROX_G100 if [ "$CONFIG_I2C" != "n" ]; then dep_tristate ' Matrox I2C support' CONFIG_FB_MATROX_I2C $CONFIG_FB_MATROX $CONFIG_I2C_ALGOBIT if [ "$CONFIG_FB_MATROX_G100" = "y" ]; then dep_tristate ' G400 second head support' CONFIG_FB_MATROX_MAVEN $CONFIG_FB_MATROX_I2C fi fi - dep_tristate ' G450 second head support' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100 + dep_tristate ' G450/G550 second head support' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100 bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD fi tristate ' ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY diff --git a/fs/Config.in b/fs/Config.in index 23796bac7..ff385012f 100644 --- a/fs/Config.in +++ b/fs/Config.in @@ -8,9 +8,9 @@ bool 'Quota support' CONFIG_QUOTA tristate 'Kernel automounter support' CONFIG_AUTOFS_FS tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS -dep_tristate 'Reiserfs support' CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL -dep_mbool ' Have reiserfs do extra internal checking' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL -dep_mbool ' Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL +tristate 'Reiserfs support' CONFIG_REISERFS_FS +dep_mbool ' Have reiserfs do extra internal checking' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS +dep_mbool ' Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS dep_tristate 'ADFS file system support' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL dep_mbool ' ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL diff --git a/fs/adfs/super.c b/fs/adfs/super.c index adce0851c..8a0ce050c 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -346,7 +346,7 @@ static inline unsigned long adfs_discsize(struct adfs_discrecord *dr, int block_ return discsize; } -struct super_block *adfs_read_super(struct super_block *sb, void *data, int silent) +static int adfs_fill_super(struct super_block *sb, void *data, int silent) { struct adfs_discrecord *dr; struct buffer_head *bh; @@ -467,15 +467,26 @@ struct super_block *adfs_read_super(struct super_block *sb, void *data, int sile goto error; } else sb->s_root->d_op = &adfs_dentry_operations; - return sb; + return 0; error_free_bh: brelse(bh); error: - return NULL; + return -EINVAL; +} + +static struct super_block *adfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, adfs_fill_super); } -static DECLARE_FSTYPE_DEV(adfs_fs_type, "adfs", adfs_read_super); +static struct file_system_type adfs_fs_type = { + owner: THIS_MODULE, + name: "adfs", + get_sb: adfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_adfs_fs(void) { diff --git a/fs/affs/super.c b/fs/affs/super.c index e824a71af..ecf11f3de 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -265,8 +265,7 @@ out_inv_arg: * hopefully have the guts to do so. Until then: sorry for the mess. */ -static struct super_block * -affs_read_super(struct super_block *sb, void *data, int silent) +static int affs_fill_super(struct super_block *sb, void *data, int silent) { struct buffer_head *root_bh = NULL; struct buffer_head *boot_bh; @@ -294,7 +293,7 @@ affs_read_super(struct super_block *sb, void *data, int silent) &blocksize,&AFFS_SB->s_prefix, AFFS_SB->s_volume, &mount_flags)) { printk(KERN_ERR "AFFS: Error parsing options\n"); - return NULL; + return -EINVAL; } /* N.B. after this point s_prefix must be released */ @@ -462,7 +461,7 @@ got_root: sb->s_root->d_op = &affs_dentry_operations; pr_debug("AFFS: s_flags=%lX\n",sb->s_flags); - return sb; + return 0; /* * Begin the cascaded cleanup ... @@ -475,7 +474,7 @@ out_error: affs_brelse(root_bh); if (AFFS_SB->s_prefix) kfree(AFFS_SB->s_prefix); - return NULL; + return -EINVAL; } static int @@ -533,7 +532,18 @@ affs_statfs(struct super_block *sb, struct statfs *buf) return 0; } -static DECLARE_FSTYPE_DEV(affs_fs_type, "affs", affs_read_super); +static struct super_block *affs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super); +} + +static struct file_system_type affs_fs_type = { + owner: THIS_MODULE, + name: "affs", + get_sb: affs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_affs_fs(void) { diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index ee3a64beb..7c3f0d560 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -279,8 +279,7 @@ void dump_imap(const char *prefix, struct super_block * s) #endif } -static struct super_block * bfs_read_super(struct super_block * s, - void * data, int silent) +static int bfs_fill_super(struct super_block *s, void *data, int silent) { struct buffer_head * bh; struct bfs_super_block * bfs_sb; @@ -355,14 +354,25 @@ static struct super_block * bfs_read_super(struct super_block * s, s->s_dirt = 1; } dump_imap("read_super", s); - return s; + return 0; out: brelse(bh); - return NULL; + return -EINVAL; } -static DECLARE_FSTYPE_DEV(bfs_fs_type, "bfs", bfs_read_super); +static struct super_block *bfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super); +} + +static struct file_system_type bfs_fs_type = { + owner: THIS_MODULE, + name: "bfs", + get_sb: bfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_bfs_fs(void) { diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 2132104cd..66dcaa6f3 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -188,12 +188,11 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i } -static struct super_block * cramfs_read_super(struct super_block *sb, void *data, int silent) +static int cramfs_fill_super(struct super_block *sb, void *data, int silent) { int i; struct cramfs_super super; unsigned long root_offset; - struct super_block * retval = NULL; sb_set_blocksize(sb, PAGE_CACHE_SIZE); @@ -252,9 +251,9 @@ static struct super_block * cramfs_read_super(struct super_block *sb, void *data /* Set it all up.. */ sb->s_op = &cramfs_ops; sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root)); - retval = sb; + return 0; out: - return retval; + return -EINVAL; } static int cramfs_statfs(struct super_block *sb, struct statfs *buf) @@ -442,7 +441,18 @@ static struct super_operations cramfs_ops = { statfs: cramfs_statfs, }; -static DECLARE_FSTYPE_DEV(cramfs_fs_type, "cramfs", cramfs_read_super); +static struct super_block *cramfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super); +} + +static struct file_system_type cramfs_fs_type = { + owner: THIS_MODULE, + name: "cramfs", + get_sb: cramfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_cramfs_fs(void) { diff --git a/fs/driverfs/inode.c b/fs/driverfs/inode.c index 54e35bce8..9502dc7cd 100644 --- a/fs/driverfs/inode.c +++ b/fs/driverfs/inode.c @@ -245,6 +245,9 @@ driverfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos) if (!entry->show) return 0; + if (count > PAGE_SIZE) + count = PAGE_SIZE; + dev = list_entry(entry->parent,struct device, dir); page = (unsigned char*)__get_free_page(GFP_KERNEL); @@ -260,7 +263,8 @@ driverfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos) if (len < 0) retval = len; break; - } + } else if (len > count) + len = count; if (copy_to_user(buf,page,len)) { retval = -EFAULT; diff --git a/fs/efs/super.c b/fs/efs/super.c index 541d86f2c..7605c758d 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -14,7 +14,18 @@ #include <linux/efs_fs_sb.h> #include <linux/slab.h> -static DECLARE_FSTYPE_DEV(efs_fs_type, "efs", efs_read_super); +static struct super_block *efs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, efs_fill_super); +} + +static struct file_system_type efs_fs_type = { + owner: THIS_MODULE, + name: "efs", + get_sb: efs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static kmem_cache_t * efs_inode_cachep; @@ -188,7 +199,8 @@ static int efs_validate_super(struct efs_sb_info *sb, struct efs_super *super) { return 0; } -struct super_block *efs_read_super(struct super_block *s, void *d, int silent) { +int efs_fill_super(struct super_block *s, void *d, int silent) +{ struct efs_sb_info *sb; struct buffer_head *bh; @@ -246,11 +258,11 @@ struct super_block *efs_read_super(struct super_block *s, void *d, int silent) { goto out_no_fs; } - return(s); + return 0; out_no_fs_ul: out_no_fs: - return(NULL); + return -EINVAL; } int efs_statfs(struct super_block *s, struct statfs *buf) { diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 013bb132a..24ddd1d43 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -934,8 +934,7 @@ static loff_t ext3_max_size(int bits) return res; } -struct super_block * ext3_read_super (struct super_block * sb, void * data, - int silent) +static int ext3_fill_super (struct super_block *sb, void *data, int silent) { struct buffer_head * bh; struct ext3_super_block *es = 0; @@ -1054,7 +1053,7 @@ struct super_block * ext3_read_super (struct super_block * sb, void * data, if (!bh) { printk(KERN_ERR "EXT3-fs: Can't read superblock on 2nd try.\n"); - return NULL; + return -EINVAL; } es = (struct ext3_super_block *)(((char *)bh->b_data) + offset); sbi->s_es = es; @@ -1252,7 +1251,7 @@ struct super_block * ext3_read_super (struct super_block * sb, void * data, test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": "writeback"); - return sb; + return 0; failed_mount3: journal_destroy(sbi->s_journal); @@ -1264,7 +1263,7 @@ failed_mount: ext3_blkdev_remove(sbi); brelse(bh); out_fail: - return NULL; + return -EINVAL; } static journal_t *ext3_get_journal(struct super_block *sb, int journal_inum) @@ -1769,7 +1768,18 @@ int ext3_statfs (struct super_block * sb, struct statfs * buf) return 0; } -static DECLARE_FSTYPE_DEV(ext3_fs_type, "ext3", ext3_read_super); +static struct super_block *ext3_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super); +} + +static struct file_system_type ext3_fs_type = { + owner: THIS_MODULE, + name: "ext3", + get_sb: ext3_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_ext3_fs(void) { diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index 768e91bb3..8658b3ca6 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c @@ -135,8 +135,7 @@ vxfs_statfs(struct super_block *sbp, struct statfs *bufp) * Locking: * We are under the bkl and @sbp->s_lock. */ -static struct super_block * -vxfs_read_super(struct super_block *sbp, void *dp, int silent) +static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) { struct vxfs_sb_info *infp; struct vxfs_sb *rsbp; @@ -146,7 +145,7 @@ vxfs_read_super(struct super_block *sbp, void *dp, int silent) infp = kmalloc(sizeof(*infp), GFP_KERNEL); if (!infp) { printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n"); - return NULL; + return -ENOMEM; } memset(infp, 0, sizeof(*infp)); @@ -213,7 +212,7 @@ vxfs_read_super(struct super_block *sbp, void *dp, int silent) goto out_free_ilist; } - return (sbp); + return 0; out_free_ilist: vxfs_put_fake_inode(infp->vsi_fship); @@ -222,13 +221,24 @@ out_free_ilist: out: brelse(bp); kfree(infp); - return NULL; + return -EINVAL; } /* * The usual module blurb. */ -static DECLARE_FSTYPE_DEV(vxfs_fs_type, "vxfs", vxfs_read_super); +static struct super_block *vxfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super); +} + +static struct file_system_type vxfs_fs_type = { + owner: THIS_MODULE, + name: "vxfs", + get_sb: vxfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init vxfs_init(void) diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 9ac627bb1..2d2749451 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -95,7 +95,18 @@ static struct super_operations hfs_super_operations = { /*================ File-local variables ================*/ -static DECLARE_FSTYPE_DEV(hfs_fs, "hfs", hfs_read_super); +static struct super_block *hfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super); +} + +static struct file_system_type hfs_fs = { + owner: THIS_MODULE, + name: "hfs", + get_sb: hfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; /*================ File-local functions ================*/ @@ -429,8 +440,7 @@ done: * hfs_btree_init() to get the necessary data about the extents and * catalog B-trees and, finally, reading the root inode into memory. */ -struct super_block *hfs_read_super(struct super_block *s, void *data, - int silent) +int hfs_fill_super(struct super_block *s, void *data, int silent) { struct hfs_mdb *mdb; struct hfs_cat_key key; @@ -501,7 +511,7 @@ struct super_block *hfs_read_super(struct super_block *s, void *data, s->s_root->d_op = &hfs_dentry_operations; /* everything's okay */ - return s; + return 0; bail_no_root: hfs_warn("hfs_fs: get root inode failed.\n"); @@ -511,7 +521,7 @@ bail1: bail2: set_blocksize(dev, BLOCK_SIZE); bail3: - return NULL; + return -EINVAL; } static int __init init_hfs_fs(void) diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 3d59f27c8..4cc04ff72 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -405,8 +405,7 @@ int hpfs_remount_fs(struct super_block *s, int *flags, char *data) return 0; } -struct super_block *hpfs_read_super(struct super_block *s, void *options, - int silent) +static int hpfs_fill_super(struct super_block *s, void *options, int silent) { struct buffer_head *bh0, *bh1, *bh2; struct hpfs_boot_block *bootblock; @@ -598,7 +597,7 @@ struct super_block *hpfs_read_super(struct super_block *s, void *options, } if (de) hpfs_brelse4(&qbh); - return s; + return 0; bail4: brelse(bh2); bail3: brelse(bh1); @@ -607,10 +606,21 @@ bail1: bail0: if (s->s_hpfs_bmp_dir) kfree(s->s_hpfs_bmp_dir); if (s->s_hpfs_cp_table) kfree(s->s_hpfs_cp_table); - return NULL; + return -EINVAL; } -DECLARE_FSTYPE_DEV(hpfs_fs_type, "hpfs", hpfs_read_super); +static struct super_block *hpfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super); +} + +static struct file_system_type hpfs_fs_type = { + owner: THIS_MODULE, + name: "hpfs", + get_sb: hpfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_hpfs_fs(void) { diff --git a/fs/inflate_fs/infutil.h b/fs/inflate_fs/infutil.h index cc219ac46..5c90a2759 100644 --- a/fs/inflate_fs/infutil.h +++ b/fs/inflate_fs/infutil.h @@ -11,7 +11,7 @@ #ifndef _INFUTIL_H #define _INFUTIL_H -#include "zconf.h" +#include <linux/zconf.h> #include "inftrees.h" #include "infcodes.h" diff --git a/fs/inflate_fs/zconf.h b/fs/inflate_fs/zconf.h deleted file mode 100644 index 0b5ec8838..000000000 --- a/fs/inflate_fs/zconf.h +++ /dev/null @@ -1,90 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-1998 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef _ZCONF_H -#define _ZCONF_H - -#if defined(__GNUC__) || defined(__386__) || defined(i386) -# ifndef __32BIT__ -# define __32BIT__ -# endif -#endif - -#if defined(__STDC__) || defined(__cplusplus) -# ifndef STDC -# define STDC -# endif -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# define MAX_MEM_LEVEL 9 -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef FAR -# define FAR -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -typedef void FAR *voidpf; -typedef void *voidp; - -#include <linux/types.h> /* for off_t */ -#include <linux/unistd.h> /* for SEEK_* and off_t */ -#define z_off_t off_t - -#endif /* _ZCONF_H */ diff --git a/fs/intermezzo/super.c b/fs/intermezzo/super.c index a60d869f7..2b011f171 100644 --- a/fs/intermezzo/super.c +++ b/fs/intermezzo/super.c @@ -452,12 +452,13 @@ out_err: struct file_system_type presto_fs_type = { #ifdef PRESTO_DEVEL - name: "izofs", + "izofs", #else - name: "intermezzo", + "intermezzo", #endif - fs_flags: FS_REQUIRES_DEV, /* can use Ibaskets when ext2 does */ - read_super: presto_read_super + FS_REQUIRES_DEV, /* can use Ibaskets when ext2 does */ + presto_read_super, + NULL }; diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 939748cf7..66ea867e7 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -510,8 +510,7 @@ static unsigned int isofs_get_last_session(struct super_block *sb,s32 session ) * Note: a check_disk_change() has been done immediately prior * to this call, so we don't need to check again. */ -static struct super_block *isofs_read_super(struct super_block *s, void *data, - int silent) +static int isofs_fill_super(struct super_block *s, void *data, int silent) { struct buffer_head * bh = NULL, *pri_bh = NULL; struct hs_primary_descriptor * h_pri = NULL; @@ -843,16 +842,16 @@ root_found: if (opt.check == 'r') table++; s->s_root->d_op = &isofs_dentry_ops[table]; - return s; + return 0; /* * Display error messages and free resources. */ out_bad_root: - printk(KERN_WARNING "isofs_read_super: root inode not initialized\n"); + printk(KERN_WARNING "isofs_fill_super: root inode not initialized\n"); goto out_iput; out_no_root: - printk(KERN_WARNING "isofs_read_super: get root inode failed\n"); + printk(KERN_WARNING "isofs_fill_super: get root inode failed\n"); out_iput: iput(inode); #ifdef CONFIG_JOLIET @@ -861,7 +860,7 @@ out_iput: #endif goto out_unlock; out_no_read: - printk(KERN_WARNING "isofs_read_super: " + printk(KERN_WARNING "isofs_fill_super: " "bread failed, dev=%s, iso_blknum=%d, block=%d\n", s->s_id, iso_blknum, block); goto out_unlock; @@ -885,7 +884,7 @@ out_unknown_format: out_freebh: brelse(bh); out_unlock: - return NULL; + return -EINVAL; } static int isofs_statfs (struct super_block *sb, struct statfs *buf) @@ -1395,7 +1394,18 @@ void leak_check_brelse(struct buffer_head * bh){ #endif -static DECLARE_FSTYPE_DEV(iso9660_fs_type, "iso9660", isofs_read_super); +static struct super_block *isofs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super); +} + +static struct file_system_type iso9660_fs_type = { + owner: THIS_MODULE, + name: "iso9660", + get_sb: isofs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_iso9660_fs(void) { diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index db71f741b..2bc47cf04 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c @@ -71,8 +71,7 @@ kmem_cache_t *node_cache = NULL; kmem_cache_t *fm_cache = NULL; /* Called by the VFS at mount time to initialize the whole file system. */ -static struct super_block * -jffs_read_super(struct super_block *sb, void *data, int silent) +static int jffs_fill_super(struct super_block *sb, void *data, int silent) { kdev_t dev = sb->s_dev; struct inode *root_inode; @@ -84,7 +83,7 @@ jffs_read_super(struct super_block *sb, void *data, int silent) if (major(dev) != MTD_BLOCK_MAJOR) { printk(KERN_WARNING "JFFS: Trying to mount a " "non-mtd device.\n"); - return 0; + return -EINVAL; } sb->s_blocksize = PAGE_CACHE_SIZE; @@ -145,7 +144,7 @@ jffs_read_super(struct super_block *sb, void *data, int silent) D1(printk(KERN_NOTICE "JFFS: Successfully mounted device %s.\n", sb->s_id)); - return sb; + return 0; jffs_sb_err3: iput(root_inode); @@ -154,7 +153,7 @@ jffs_sb_err2: jffs_sb_err1: printk(KERN_WARNING "JFFS: Failed to mount device %s.\n", sb->s_id); - return 0; + return -EINVAL; } @@ -1730,8 +1729,18 @@ static struct super_operations jffs_ops = statfs: jffs_statfs, }; +static struct super_block *jffs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, jffs_fill_super); +} -static DECLARE_FSTYPE_DEV(jffs_fs_type, "jffs", jffs_read_super); +static struct file_system_type jffs_fs_type = { + owner: THIS_MODULE, + name: "jffs", + get_sb: jffs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_jffs_fs(void) diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 884bc8a30..05f1185aa 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -195,7 +195,7 @@ static int jffs2_statfs(struct super_block *sb, struct statfs *buf) return 0; } -static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent) +static int jffs2_fill_super(struct super_block *sb, void *data, int silent) { struct jffs2_sb_info *c; struct inode *root_i; @@ -206,7 +206,7 @@ static struct super_block *jffs2_read_super(struct super_block *sb, void *data, if (major(sb->s_dev) != MTD_BLOCK_MAJOR) { if (!silent) printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev)); - return NULL; + return -EINVAL; } c = JFFS2_SB_INFO(sb); @@ -215,7 +215,7 @@ static struct super_block *jffs2_read_super(struct super_block *sb, void *data, c->mtd = get_mtd_device(NULL, minor(sb->s_dev)); if (!c->mtd) { D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev))); - return NULL; + return -EINVAL; } c->sector_size = c->mtd->erasesize; c->free_size = c->flash_size = c->mtd->size; @@ -275,7 +275,7 @@ static struct super_block *jffs2_read_super(struct super_block *sb, void *data, sb->s_magic = JFFS2_SUPER_MAGIC; if (!(sb->s_flags & MS_RDONLY)) jffs2_start_garbage_collect_thread(c); - return sb; + return 0; out_root_i: iput(root_i); @@ -285,7 +285,7 @@ static struct super_block *jffs2_read_super(struct super_block *sb, void *data, kfree(c->blocks); out_mtd: put_mtd_device(c->mtd); - return NULL; + return -EINVAL; } void jffs2_put_super (struct super_block *sb) @@ -340,8 +340,18 @@ void jffs2_write_super (struct super_block *sb) jffs2_mark_erased_blocks(c); } +static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, jffs2_fill_super); +} -static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super); +static struct file_system_type jffs2_fs_type = { + owner: THIS_MODULE, + name: "jffs2", + get_sb: jffs2_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_jffs2_fs(void) { diff --git a/fs/msdos/msdosfs_syms.c b/fs/msdos/msdosfs_syms.c index 4dc34bf6e..a37c99fc8 100644 --- a/fs/msdos/msdosfs_syms.c +++ b/fs/msdos/msdosfs_syms.c @@ -25,7 +25,18 @@ EXPORT_SYMBOL(msdos_rmdir); EXPORT_SYMBOL(msdos_unlink); EXPORT_SYMBOL(msdos_put_super); -static DECLARE_FSTYPE_DEV(msdos_fs_type, "msdos", msdos_read_super); +static struct super_block *msdos_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super); +} + +static struct file_system_type msdos_fs_type = { + owner: THIS_MODULE, + name: "msdos", + get_sb: msdos_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_msdos_fs(void) { diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index 28d0caac9..6b136aad9 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -579,21 +579,21 @@ struct inode_operations msdos_dir_inode_operations = { setattr: fat_notify_change, }; -struct super_block *msdos_read_super(struct super_block *sb,void *data, int silent) +int msdos_fill_super(struct super_block *sb,void *data, int silent) { struct super_block *res; MSDOS_SB(sb)->options.isvfat = 0; res = fat_read_super(sb, data, silent, &msdos_dir_inode_operations); if (IS_ERR(res)) - return NULL; + return PTR_ERR(res); if (res == NULL) { if (!silent) printk(KERN_INFO "VFS: Can't find a valid" " MSDOS filesystem on dev %s.\n", sb->s_id); - return NULL; + return -EINVAL; } sb->s_root->d_op = &msdos_dentry_operations; - return res; + return 0; } diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 617f18282..51fbb9be0 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c @@ -453,7 +453,7 @@ static int __init root_nfs_get_handle(void) /* * Get the NFS port numbers and file handle, and return the prepared 'data' - * argument for ->read_super() if everything went OK. Return NULL otherwise. + * argument for mount() if everything went OK. Return NULL otherwise. */ void * __init nfs_root_data(void) { diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index a4a6d4ceb..03c7735c7 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -19,6 +19,7 @@ #include <linux/sched.h> #include <linux/stat.h> #include <linux/in.h> +#include <linux/seq_file.h> #include <linux/sunrpc/svc.h> #include <linux/nfsd/nfsd.h> @@ -32,10 +33,9 @@ typedef struct svc_client svc_client; typedef struct svc_export svc_export; -static svc_export * exp_find(svc_client *clp, kdev_t dev); -static svc_export * exp_parent(svc_client *clp, kdev_t dev, +static svc_export * exp_parent(svc_client *clp, struct super_block *sb, struct dentry *dentry); -static svc_export * exp_child(svc_client *clp, kdev_t dev, +static svc_export * exp_child(svc_client *clp, struct super_block *sb, struct dentry *dentry); static void exp_unexport_all(svc_client *clp); static void exp_do_unexport(svc_export *unexp); @@ -66,40 +66,43 @@ static int want_lock; static int hash_count; static DECLARE_WAIT_QUEUE_HEAD( hash_wait ); - /* - * Find a client's export for a device. + * Find the client's export entry matching xdev/xino. */ -static inline svc_export * -exp_find(svc_client *clp, kdev_t dev) +svc_export * +exp_get(svc_client *clp, kdev_t dev, ino_t ino) { - svc_export * exp; + struct list_head *head, *p; + svc_export *exp = NULL; + + if (!clp) + return NULL; - exp = clp->cl_export[EXPORT_HASH(dev)]; - while (exp && !kdev_same(exp->ex_dev, dev)) - exp = exp->ex_next; + head = &clp->cl_export[EXPORT_HASH(dev)]; + list_for_each(p, head) { + exp = list_entry(p, svc_export, ex_hash); + if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev)) + break; + } return exp; } -/* - * Find the client's export entry matching xdev/xino. - */ svc_export * -exp_get(svc_client *clp, kdev_t dev, ino_t ino) +exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry) { - svc_export * exp; + struct list_head *head, *p; + int hash = EXPORT_HASH(mnt->mnt_sb->s_dev); + svc_export *exp = NULL; if (!clp) return NULL; - exp = clp->cl_export[EXPORT_HASH(dev)]; - if (exp) - do { - if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev)) - goto out; - } while (NULL != (exp = exp->ex_next)); - exp = NULL; -out: + head = &clp->cl_export[hash]; + list_for_each(p, head) { + exp = list_entry(p, svc_export, ex_hash); + if (exp->ex_dentry == dentry && exp->ex_mnt == mnt) + break; + } return exp; } @@ -107,16 +110,17 @@ out: * Find the export entry for a given dentry. <gam3@acm.org> */ static svc_export * -exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry) +exp_parent(svc_client *clp, struct super_block *sb, struct dentry *dentry) { - svc_export *exp; - - if (clp == NULL) - return NULL; + struct list_head *head = &clp->cl_export[EXPORT_HASH(sb->s_dev)]; + struct list_head *p; + svc_export *exp = NULL; - for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) + list_for_each(p, head) { + exp = list_entry(p, svc_export, ex_hash); if (is_subdir(dentry, exp->ex_dentry)) break; + } return exp; } @@ -126,21 +130,35 @@ exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry) * <gam3@acm.org> */ static svc_export * -exp_child(svc_client *clp, kdev_t dev, struct dentry *dentry) +exp_child(svc_client *clp, struct super_block *sb, struct dentry *dentry) { - svc_export *exp; - - if (clp == NULL) - return NULL; - - for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) { - struct dentry *ndentry = exp->ex_dentry; + struct list_head *head = &clp->cl_export[EXPORT_HASH(sb->s_dev)]; + struct list_head *p; + svc_export *exp = NULL; + struct dentry *ndentry; + + list_for_each(p, head) { + exp = list_entry(p, svc_export, ex_hash); + ndentry = exp->ex_dentry; if (ndentry && is_subdir(ndentry->d_parent, dentry)) break; } return exp; } +/* Update parent pointers of all exports */ +static void exp_change_parents(svc_client *clp, svc_export *old, svc_export *new) +{ + struct list_head *head = &clp->cl_list; + struct list_head *p; + + list_for_each(p, head) { + svc_export *exp = list_entry(p, svc_export, ex_list); + if (exp->ex_parent == old) + exp->ex_parent = new; + } +} + /* * Export a file system. */ @@ -149,10 +167,9 @@ exp_export(struct nfsctl_export *nxp) { svc_client *clp; svc_export *exp, *parent; - svc_export **head; struct nameidata nd; struct inode *inode = NULL; - int i, err; + int err; kdev_t dev; ino_t ino; @@ -221,12 +238,12 @@ exp_export(struct nfsctl_export *nxp) goto finish; } - if ((parent = exp_child(clp, dev, nd.dentry)) != NULL) { + if ((parent = exp_child(clp, inode->i_sb, nd.dentry)) != NULL) { dprintk("exp_export: export not valid (Rule 3).\n"); goto finish; } /* Is this is a sub-export, must be a proper subset of FS */ - if ((parent = exp_parent(clp, dev, nd.dentry)) != NULL) { + if ((parent = exp_parent(clp, inode->i_sb, nd.dentry)) != NULL) { dprintk("exp_export: sub-export not valid (Rule 2).\n"); goto finish; } @@ -248,21 +265,11 @@ exp_export(struct nfsctl_export *nxp) exp->ex_anon_gid = nxp->ex_anon_gid; /* Update parent pointers of all exports */ - if (parent) { - for (i = 0; i < NFSCLNT_EXPMAX; i++) { - svc_export *temp = clp->cl_export[i]; - - while (temp) { - if (temp->ex_parent == parent) - temp->ex_parent = exp; - temp = temp->ex_next; - } - } - } + if (parent) + exp_change_parents(clp, parent, exp); - head = clp->cl_export + EXPORT_HASH(dev); - exp->ex_next = *head; - *head = exp; + list_add(&exp->ex_hash, clp->cl_export + EXPORT_HASH(dev)); + list_add_tail(&exp->ex_list, &clp->cl_list); err = 0; @@ -285,21 +292,12 @@ finish: static void exp_do_unexport(svc_export *unexp) { - svc_export *exp; - svc_client *clp; struct dentry *dentry; struct vfsmount *mnt; struct inode *inode; - int i; /* Update parent pointers. */ - clp = unexp->ex_client; - for (i = 0; i < NFSCLNT_EXPMAX; i++) { - for (exp = clp->cl_export[i]; exp; exp = exp->ex_next) - if (exp->ex_parent == unexp) - exp->ex_parent = unexp->ex_parent; - } - + exp_change_parents(unexp->ex_client, unexp, unexp->ex_parent); dentry = unexp->ex_dentry; mnt = unexp->ex_mnt; inode = dentry->d_inode; @@ -319,18 +317,15 @@ exp_do_unexport(svc_export *unexp) static void exp_unexport_all(svc_client *clp) { - svc_export *exp; - int i; + struct list_head *p = &clp->cl_list; dprintk("unexporting all fs's for clnt %p\n", clp); - for (i = 0; i < NFSCLNT_EXPMAX; i++) { - exp = clp->cl_export[i]; - clp->cl_export[i] = NULL; - while (exp) { - svc_export *next = exp->ex_next; - exp_do_unexport(exp); - exp = next; - } + + while (!list_empty(p)) { + svc_export *exp = list_entry(p->next, svc_export, ex_list); + list_del(&exp->ex_list); + list_del(&exp->ex_hash); + exp_do_unexport(exp); } } @@ -341,7 +336,6 @@ int exp_unexport(struct nfsctl_export *nxp) { svc_client *clp; - svc_export **expp, *exp = NULL; int err; /* Consistency check */ @@ -355,17 +349,12 @@ exp_unexport(struct nfsctl_export *nxp) clp = exp_getclientbyname(nxp->ex_client); if (clp) { kdev_t ex_dev = to_kdev_t(nxp->ex_dev); - expp = clp->cl_export + EXPORT_HASH(ex_dev); - while ((exp = *expp) != NULL) { - if (kdev_same(exp->ex_dev, ex_dev)) { - if (exp->ex_ino == nxp->ex_ino) { - *expp = exp->ex_next; - exp_do_unexport(exp); - err = 0; - break; - } - } - expp = &(exp->ex_next); + svc_export *exp = exp_get(clp, ex_dev, nxp->ex_ino); + if (exp) { + list_del(&exp->ex_hash); + list_del(&exp->ex_list); + exp_do_unexport(exp); + err = 0; } } @@ -380,55 +369,34 @@ out: * since its harder to fool a kernel module than a user space program. */ int -exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, - char *path, struct knfsd_fh *f, int maxsize) +exp_rootfh(struct svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) { struct svc_export *exp; struct nameidata nd; struct inode *inode; struct svc_fh fh; + kdev_t dev; int err; err = -EPERM; - if (path) { - if (path_init(path, LOOKUP_POSITIVE, &nd) && - path_walk(path, &nd)) { - printk("nfsd: exp_rootfh path not found %s", path); - return err; - } - dev = nd.dentry->d_inode->i_dev; - ino = nd.dentry->d_inode->i_ino; - - dprintk("nfsd: exp_rootfh(%s [%p] %s:%02x:%02x/%ld)\n", - path, nd.dentry, clp->cl_ident, - major(dev), minor(dev), (long) ino); - exp = exp_parent(clp, dev, nd.dentry); - } else { - dprintk("nfsd: exp_rootfh(%s:%02x:%02x/%ld)\n", - clp->cl_ident, major(dev), minor(dev), (long) ino); - if ((exp = exp_get(clp, dev, ino))) { - nd.mnt = mntget(exp->ex_mnt); - nd.dentry = dget(exp->ex_dentry); - } + /* NB: we probably ought to check that it's NUL-terminated */ + if (path_init(path, LOOKUP_POSITIVE, &nd) && + path_walk(path, &nd)) { + printk("nfsd: exp_rootfh path not found %s", path); + return err; } + inode = nd.dentry->d_inode; + dev = inode->i_dev; + + dprintk("nfsd: exp_rootfh(%s [%p] %s:%02x:%02x/%ld)\n", + path, nd.dentry, clp->cl_ident, + major(dev), minor(dev), (long) inode->i_ino); + exp = exp_parent(clp, inode->i_sb, nd.dentry); if (!exp) { dprintk("nfsd: exp_rootfh export not found.\n"); goto out; } - inode = nd.dentry->d_inode; - if (!inode) { - printk("exp_rootfh: Aieee, NULL d_inode\n"); - goto out; - } - if (!kdev_same(inode->i_dev, dev) || inode->i_ino != ino) { - printk("exp_rootfh: Aieee, ino/dev mismatch\n"); - printk("exp_rootfh: arg[dev(%02x:%02x):ino(%ld)]" - " inode[dev(%02x:%02x):ino(%ld)]\n", - major(dev), minor(dev), (long) ino, - major(inode->i_dev), minor(inode->i_dev), (long) inode->i_ino); - } - /* * fh must be initialized before calling fh_compose */ @@ -547,6 +515,67 @@ exp_getclientbyname(char *ident) return NULL; } +/* Iterator */ + +static void *e_start(struct seq_file *m, loff_t *pos) +{ + loff_t n = *pos; + unsigned client, export; + svc_client *clp; + struct list_head *p; + + exp_readlock(); + if (!n--) + return (void *)1; + client = n >> 32; + export = n & ((1LL<<32) - 1); + for (clp = clients; client && clp; clp = clp->cl_next, client--) + ; + if (!clp) + return NULL; + list_for_each(p, &clp->cl_list) + if (!export--) + return list_entry(p, svc_export, ex_list); + n &= ~((1LL<<32) - 1); + do { + clp = clp->cl_next; + n += 1LL<<32; + } while(clp && list_empty(&clp->cl_list)); + if (!clp) + return NULL; + *pos = n+1; + return list_entry(clp->cl_list.next, svc_export, ex_list); +} + +static void *e_next(struct seq_file *m, void *p, loff_t *pos) +{ + svc_export *exp = p; + svc_client *clp; + + if (p == (void *)1) + clp = clients; + else if (exp->ex_list.next == &exp->ex_client->cl_list) + clp = exp->ex_client->cl_next; + else { + ++*pos; + return list_entry(exp->ex_list.next, svc_export, ex_list); + } + *pos &= ~((1LL<<32) - 1); + while (clp && list_empty(&clp->cl_list)) { + clp = clp->cl_next; + *pos += 1LL<<32; + } + if (!clp) + return NULL; + ++*pos; + return list_entry(clp->cl_list.next, svc_export, ex_list); +} + +static void e_stop(struct seq_file *m, void *p) +{ + exp_unlock(); +} + struct flags { int flag; char *name[2]; @@ -569,128 +598,77 @@ struct flags { { 0, {"", ""}} }; -static int -exp_flags(char *buffer, int flag) +static void exp_flags(struct seq_file *m, int flag) { - int len = 0, first = 0; - struct flags *flg = expflags; - - for (;flg->flag;flg++) { - int state = (flg->flag & flag)?0:1; - if (!flg->flag) - break; - if (*flg->name[state]) { - len += sprintf(buffer + len, "%s%s", - first++?",":"", flg->name[state]); - } - } - return len; -} - - - -/* mangling borrowed from fs/super.c */ -/* Use octal escapes, like mount does, for embedded spaces etc. */ -static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' }; + int first = 0; + struct flags *flg; -static int -mangle(const unsigned char *s, char *buf, int len) { - char *sp; - int n; - - sp = buf; - while(*s && sp-buf < len-3) { - for (n = 0; n < sizeof(need_escaping); n++) { - if (*s == need_escaping[n]) { - *sp++ = '\\'; - *sp++ = '0' + ((*s & 0300) >> 6); - *sp++ = '0' + ((*s & 070) >> 3); - *sp++ = '0' + (*s & 07); - goto next; - } - } - *sp++ = *s; - next: - s++; - } - return sp - buf; /* no trailing NUL */ + for (flg = expflags; flg->flag; flg++) { + int state = (flg->flag & flag)?0:1; + if (*flg->name[state]) + seq_printf(m, "%s%s", first++?",":"", flg->name[state]); + } } -#define FREEROOM ((int)PAGE_SIZE-200-len) -#define MANGLE(s) len += mangle((s), buffer+len, FREEROOM); +static inline void mangle(struct seq_file *m, const char *s) +{ + seq_escape(m, s, " \t\n\\"); +} -int -exp_procfs_exports(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) +static int e_show(struct seq_file *m, void *p) { - struct svc_clnthash **hp, **head, *tmp; - struct svc_client *clp; - svc_export *exp; - off_t pos = 0; - off_t begin = 0; - int len = 0; - int i,j; + struct svc_export *exp = p; + struct svc_client *clp; + int j, first = 0; - len += sprintf(buffer, "# Version 1.1\n"); - len += sprintf(buffer+len, "# Path Client(Flags) # IPs\n"); + if (p == (void *)1) { + seq_puts(m, "# Version 1.1\n"); + seq_puts(m, "# Path Client(Flags) # IPs\n"); + return 0; + } - for (clp = clients; clp; clp = clp->cl_next) { - for (i = 0; i < NFSCLNT_EXPMAX; i++) { - exp = clp->cl_export[i]; - while (exp) { - int first = 0; - MANGLE(exp->ex_path); - buffer[len++]='\t'; - MANGLE(clp->cl_ident); - buffer[len++]='('; - - len += exp_flags(buffer+len, exp->ex_flags); - len += sprintf(buffer+len, ") # "); - for (j = 0; j < clp->cl_naddr; j++) { - struct in_addr addr = clp->cl_addr[j]; - - head = &clnt_hash[CLIENT_HASH(addr.s_addr)]; - for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) { - if (tmp->h_addr.s_addr == addr.s_addr) { - if (first++) len += sprintf(buffer+len, "%s", " "); - if (tmp->h_client != clp) - len += sprintf(buffer+len, "("); - len += sprintf(buffer+len, "%d.%d.%d.%d", - htonl(addr.s_addr) >> 24 & 0xff, - htonl(addr.s_addr) >> 16 & 0xff, - htonl(addr.s_addr) >> 8 & 0xff, - htonl(addr.s_addr) >> 0 & 0xff); - if (tmp->h_client != clp) - len += sprintf(buffer+len, ")"); - break; - } - } - } - exp = exp->ex_next; - - buffer[len++]='\n'; - - pos=begin+len; - if(pos<offset) { - len=0; - begin=pos; - } - if (pos > offset + length) - goto done; - } + clp = exp->ex_client; + + mangle(m, exp->ex_path); + seq_putc(m, '\t'); + mangle(m, clp->cl_ident); + seq_putc(m, '('); + exp_flags(m, exp->ex_flags); + seq_puts(m, ") # "); + for (j = 0; j < clp->cl_naddr; j++) { + struct svc_clnthash **hp, **head, *tmp; + struct in_addr addr = clp->cl_addr[j]; + + head = &clnt_hash[CLIENT_HASH(addr.s_addr)]; + for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) { + if (tmp->h_addr.s_addr == addr.s_addr) + break; + } + if (tmp) { + if (first++) + seq_putc(m, ' '); + if (tmp->h_client != clp) + seq_putc(m, '('); + seq_printf(m, "%d.%d.%d.%d", + htonl(addr.s_addr) >> 24 & 0xff, + htonl(addr.s_addr) >> 16 & 0xff, + htonl(addr.s_addr) >> 8 & 0xff, + htonl(addr.s_addr) >> 0 & 0xff); + if (tmp->h_client != clp) + seq_putc(m, ')'); } } - - *eof = 1; - -done: - *start = buffer + (offset - begin); - len -= (offset - begin); - if ( len > length ) - len = length; - return len; + seq_putc(m, '\n'); + return 0; } +struct seq_operations nfs_exports_op = { + start: e_start, + next: e_next, + stop: e_stop, + show: e_show, +}; + /* * Add or modify a client. * Change requests may involve the list of host addresses. The list of @@ -726,6 +704,9 @@ exp_addclient(struct nfsctl_client *ncp) if (!(clp = kmalloc(sizeof(*clp), GFP_KERNEL))) goto out_unlock; memset(clp, 0, sizeof(*clp)); + for (i = 0; i < NFSCLNT_EXPMAX; i++) + INIT_LIST_HEAD(&clp->cl_export[i]); + INIT_LIST_HEAD(&clp->cl_list); dprintk("created client %s (%p)\n", ncp->cl_ident, clp); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 25c4288bf..aad14fba7 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -20,6 +20,7 @@ #include <linux/unistd.h> #include <linux/slab.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/nfs.h> #include <linux/sunrpc/svc.h> @@ -37,7 +38,6 @@ static int nfsctl_addclient(struct nfsctl_client *data); static int nfsctl_delclient(struct nfsctl_client *data); static int nfsctl_export(struct nfsctl_export *data); static int nfsctl_unexport(struct nfsctl_export *data); -static int nfsctl_getfh(struct nfsctl_fhparm *, __u8 *); static int nfsctl_getfd(struct nfsctl_fdparm *, __u8 *); static int nfsctl_getfs(struct nfsctl_fsparm *, struct knfsd_fh *); #ifdef notyet @@ -46,17 +46,28 @@ static int nfsctl_ugidupdate(struct nfsctl_ugidmap *data); static int initialized; -int exp_procfs_exports(char *buffer, char **start, off_t offset, - int length, int *eof, void *data); +extern struct seq_operations nfs_exports_op; +static int exports_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &nfs_exports_op); +} +static struct file_operations exports_operations = { + open: exports_open, + read: seq_read, + llseek: seq_lseek, + release: seq_release, +}; void proc_export_init(void) { + struct proc_dir_entry *entry; if (!proc_mkdir("fs/nfs", 0)) return; - create_proc_read_entry("fs/nfs/exports", 0, 0, exp_procfs_exports,NULL); + entry = create_proc_entry("fs/nfs/exports", 0, NULL); + if (entry) + entry->proc_fops = &exports_operations; } - /* * Initialize nfsd */ @@ -125,7 +136,7 @@ nfsctl_getfs(struct nfsctl_fsparm *data, struct knfsd_fh *res) if (!(clp = exp_getclient(sin))) err = -EPERM; else - err = exp_rootfh(clp, NODEV, 0, data->gd_path, res, data->gd_maxlen); + err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen); exp_unlock(); return err; } @@ -148,40 +159,7 @@ nfsctl_getfd(struct nfsctl_fdparm *data, __u8 *res) if (!(clp = exp_getclient(sin))) err = -EPERM; else - err = exp_rootfh(clp, NODEV, 0, data->gd_path, &fh, NFS_FHSIZE); - exp_unlock(); - - if (err == 0) { - if (fh.fh_size > NFS_FHSIZE) - err = -EINVAL; - else { - memset(res,0, NFS_FHSIZE); - memcpy(res, &fh.fh_base, fh.fh_size); - } - } - - return err; -} - -static inline int -nfsctl_getfh(struct nfsctl_fhparm *data, __u8 *res) -{ - struct sockaddr_in *sin; - struct svc_client *clp; - int err = 0; - struct knfsd_fh fh; - - if (data->gf_addr.sa_family != AF_INET) - return -EPROTONOSUPPORT; - if (data->gf_version < 2 || data->gf_version > NFSSVC_MAXVERS) - return -EINVAL; - sin = (struct sockaddr_in *)&data->gf_addr; - - exp_readlock(); - if (!(clp = exp_getclient(sin))) - err = -EPERM; - else - err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, &fh, NFS_FHSIZE); + err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE); exp_unlock(); if (err == 0) { @@ -277,9 +255,6 @@ asmlinkage handle_sys_nfsservctl(int cmd, void *opaque_argp, void *opaque_resp) err = nfsctl_ugidupdate(&arg->ca_umap); break; #endif - case NFSCTL_GETFH: - err = nfsctl_getfh(&arg->ca_getfh, res->cr_getfh); - break; case NFSCTL_GETFD: err = nfsctl_getfd(&arg->ca_getfd, res->cr_getfh); break; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index af9bd34b2..245560649 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -114,35 +114,30 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, if (isdotent(name, len)) { if (len==1) dentry = dget(dparent); - else { /* must be ".." */ + else if (dparent != exp->ex_dentry) + dentry = dget(dparent->d_parent); + else if (!EX_CROSSMNT(exp)) + dentry = dget(dparent); /* .. == . just like at / */ + else { /* checking mountpoint crossing is very different when stepping up */ - if (dparent == exp->ex_dentry) { - if (!EX_CROSSMNT(exp)) - dentry = dget(dparent); /* .. == . just like at / */ - else - { - struct svc_export *exp2 = NULL; - struct dentry *dp; - struct vfsmount *mnt = mntget(exp->ex_mnt); - dentry = dget(dparent); - while(follow_up(&mnt, &dentry)) - ; - dp = dget(dentry->d_parent); - dput(dentry); - dentry = dp; - for ( ; exp2 == NULL && dp->d_parent != dp; - dp=dp->d_parent) - exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino); - if (exp2==NULL) { - dput(dentry); - dentry = dget(dparent); - } else { - exp = exp2; - } - mntput(mnt); - } - } else - dentry = dget(dparent->d_parent); + struct svc_export *exp2 = NULL; + struct dentry *dp; + struct vfsmount *mnt = mntget(exp->ex_mnt); + dentry = dget(dparent); + while(follow_up(&mnt, &dentry)) + ; + dp = dget(dentry->d_parent); + dput(dentry); + dentry = dp; + for ( ; !exp2 && dp->d_parent != dp; dp=dp->d_parent) + exp2 = exp_get_by_name(exp->ex_client, mnt, dp); + if (!exp2) { + dput(dentry); + dentry = dget(dparent); + } else { + exp = exp2; + } + mntput(mnt); } } else { fh_lock(fhp); @@ -159,9 +154,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, struct dentry *mounts = dget(dentry); while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts)) ; - exp2 = exp_get(rqstp->rq_client, - mounts->d_inode->i_dev, - mounts->d_inode->i_ino); + exp2 = exp_get_by_name(rqstp->rq_client, mnt, mounts); if (exp2 && EX_CROSSMNT(exp2)) { /* successfully crossed mount point */ exp = exp2; @@ -591,6 +584,7 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, mm_segment_t oldfs; int err; struct file file; + struct inode *inode; err = nfsd_open(rqstp, fhp, S_IFREG, MAY_READ, &file); if (err) @@ -598,14 +592,15 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, err = nfserr_perm; if (!file.f_op->read) goto out_close; + inode = file.f_dentry->d_inode; #ifdef MSNFS if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && - (!lock_may_read(file.f_dentry->d_inode, offset, *count))) + (!lock_may_read(inode, offset, *count))) goto out_close; #endif /* Get readahead parameters */ - ra = nfsd_get_raparms(fhp->fh_export->ex_dev, fhp->fh_dentry->d_inode->i_ino); + ra = nfsd_get_raparms(inode->i_dev, inode->i_ino); if (ra) { file.f_reada = ra->p_reada; file.f_ramax = ra->p_ramax; diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c index d28ea9408..56b85e1ed 100644 --- a/fs/ntfs/fs.c +++ b/fs/ntfs/fs.c @@ -1050,8 +1050,7 @@ not_ntfs: * * NOTE : A context switch can happen in kernel code only if the code blocks * (= calls schedule() in kernel/sched.c). */ -struct super_block *ntfs_read_super(struct super_block *sb, void *options, - int silent) +static int ntfs_fill_super(struct super_block *sb, void *options, int silent) { ntfs_volume *vol; struct buffer_head *bh; @@ -1142,19 +1141,28 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options, ntfs_error("Could not get root dir inode\n"); goto ntfs_read_super_mft; } -ntfs_read_super_ret: - ntfs_debug(DEBUG_OTHER, "read_super: done\n"); - return sb; + return 0; ntfs_read_super_mft: ntfs_free(vol->mft); ntfs_read_super_unl: ntfs_read_super_vol: - sb = NULL; - goto ntfs_read_super_ret; + ntfs_debug(DEBUG_OTHER, "read_super: done\n"); + return -EINVAL; } /* Define the filesystem */ -static DECLARE_FSTYPE_DEV(ntfs_fs_type, "ntfs", ntfs_read_super); +static struct super_block *ntfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, ntfs_fill_super); +} + +static struct file_system_type ntfs_fs_type = { + owner: THIS_MODULE, + name: "ntfs", + get_sb: ntfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_ntfs_fs(void) { diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 972fa8ed9..cd07c6652 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -119,7 +119,6 @@ static void qnx4_write_inode(struct inode *inode, int unused) #endif -static struct super_block *qnx4_read_super(struct super_block *, void *, int); static void qnx4_put_super(struct super_block *sb); static struct inode *qnx4_alloc_inode(struct super_block *sb); static void qnx4_destroy_inode(struct inode *inode); @@ -337,8 +336,7 @@ static const char *qnx4_checkroot(struct super_block *sb) return NULL; } -static struct super_block *qnx4_read_super(struct super_block *s, - void *data, int silent) +static int qnx4_fill_super(struct super_block *s, void *data, int silent) { struct buffer_head *bh; struct inode *root; @@ -396,7 +394,7 @@ static struct super_block *qnx4_read_super(struct super_block *s, brelse(bh); - return s; + return 0; outi: iput(root); @@ -404,7 +402,7 @@ static struct super_block *qnx4_read_super(struct super_block *s, brelse(bh); outnobh: - return NULL; + return -EINVAL; } static void qnx4_put_super(struct super_block *sb) @@ -541,7 +539,18 @@ static void destroy_inodecache(void) "qnx4_inode_cache: not all structures were freed\n"); } -static DECLARE_FSTYPE_DEV(qnx4_fs_type, "qnx4", qnx4_read_super); +static struct super_block *qnx4_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super); +} + +static struct file_system_type qnx4_fs_type = { + owner: THIS_MODULE, + name: "qnx4", + get_sb: qnx4_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_qnx4_fs(void) { diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index e1ac7050e..a9ae97dfc 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -965,7 +965,7 @@ int function2code (hashf_t func) // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // -static struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent) +static int reiserfs_fill_super(struct super_block *s, void *data, int silent) { int size; struct inode *root_inode; @@ -981,12 +981,12 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * memset (&s->u.reiserfs_sb, 0, sizeof (struct reiserfs_sb_info)); jdev_name = NULL; if (parse_options ((char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks, &jdev_name) == 0) { - return NULL; + return -EINVAL; } if (blocks) { printk("reserfs: resize option for remount only\n"); - return NULL; + return -EINVAL; } size = block_size(s->s_dev); @@ -997,14 +997,14 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * old_format = 1; /* try new format (64-th 1k block), which can contain reiserfs super block */ else if (read_super_block (s, REISERFS_DISK_OFFSET_IN_BYTES)) { - printk("sh-2021: reiserfs_read_super: can not find reiserfs on %s\n", s->s_id); + printk("sh-2021: reiserfs_fill_super: can not find reiserfs on %s\n", s->s_id); goto error; } s->u.reiserfs_sb.s_mount_state = SB_REISERFS_STATE(s); s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ; if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { - printk ("reiserfs_read_super: unable to read bitmap\n"); + printk ("reiserfs_fill_super: unable to read bitmap\n"); goto error; } #ifdef CONFIG_REISERFS_CHECK @@ -1014,7 +1014,7 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * // set_device_ro(s->s_dev, 1) ; if( journal_init(s, jdev_name, old_format) ) { - printk("sh-2022: reiserfs_read_super: unable to initialize journal space\n") ; + printk("sh-2022: reiserfs_fill_super: unable to initialize journal space\n") ; goto error ; } else { jinit_done = 1 ; /* once this is set, journal_release must be called @@ -1022,7 +1022,7 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * */ } if (reread_meta_blocks(s)) { - printk("reiserfs_read_super: unable to reread meta blocks after journal init\n") ; + printk("reiserfs_fill_super: unable to reread meta blocks after journal init\n") ; goto error ; } @@ -1036,7 +1036,7 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * args.objectid = REISERFS_ROOT_PARENT_OBJECTID ; root_inode = iget4 (s, REISERFS_ROOT_OBJECTID, 0, (void *)(&args)); if (!root_inode) { - printk ("reiserfs_read_super: get root inode failed\n"); + printk ("reiserfs_fill_super: get root inode failed\n"); goto error; } @@ -1115,7 +1115,7 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc ); init_waitqueue_head (&(s->u.reiserfs_sb.s_wait)); - return s; + return 0; error: if (jinit_done) { /* kill the commit thread, free journal ram */ @@ -1132,7 +1132,7 @@ static struct super_block * reiserfs_read_super (struct super_block * s, void * if (SB_BUFFER_WITH_SB (s)) brelse(SB_BUFFER_WITH_SB (s)); - return NULL; + return -EINVAL; } @@ -1159,7 +1159,18 @@ static int reiserfs_statfs (struct super_block * s, struct statfs * buf) return 0; } -static DECLARE_FSTYPE_DEV(reiserfs_fs_type,"reiserfs",reiserfs_read_super); +static struct super_block *reiserfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super); +} + +static struct file_system_type reiserfs_fs_type = { + owner: THIS_MODULE, + name: "reiserfs", + get_sb: reiserfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; // // this is exactly what 2.3.99-pre9's init_ext2_fs is diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index 0aa6ca89b..2f758e8bb 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -92,8 +92,7 @@ romfs_checksum(void *data, int size) static struct super_operations romfs_ops; -static struct super_block * -romfs_read_super(struct super_block *s, void *data, int silent) +static int romfs_fill_super(struct super_block *s, void *data, int silent) { struct buffer_head *bh; struct romfs_super_block *rsb; @@ -150,10 +149,10 @@ romfs_read_super(struct super_block *s, void *data, int silent) out: brelse(bh); outnobh: - s = NULL; + return -EINVAL; } - return s; + return 0; } /* That's simple too. */ @@ -529,7 +528,18 @@ static struct super_operations romfs_ops = { statfs: romfs_statfs, }; -static DECLARE_FSTYPE_DEV(romfs_fs_type, "romfs", romfs_read_super); +static struct super_block *romfs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, romfs_fill_super); +} + +static struct file_system_type romfs_fs_type = { + owner: THIS_MODULE, + name: "romfs", + get_sb: romfs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_romfs_fs(void) { diff --git a/fs/super.c b/fs/super.c index 2a4cb3259..2b4162e4b 100644 --- a/fs/super.c +++ b/fs/super.c @@ -597,11 +597,8 @@ static void put_anon_dev(kdev_t dev) * * Rather than duplicating all that logics every time when * we want something that doesn't fit "nodev" and "single" we pull - * the relevant code into common helper and let get_sb_...() call + * the relevant code into common helper and let ->get_sb() call * it. - * - * NB: get_sb_...() is going to become an fs type method, with - * current ->read_super() becoming a callback used by common instances. */ struct super_block *get_anon_super(struct file_system_type *type, int (*compare)(struct super_block *,void *), void *data) @@ -787,17 +784,6 @@ struct super_block *get_sb_single(struct file_system_type *fs_type, return s; } -/* Will go away */ -static int fill_super(struct super_block *sb, void *data, int verbose) -{ - return sb->s_type->read_super(sb, data, verbose) ? 0 : -EINVAL; -} -static struct super_block *__get_sb_bdev(struct file_system_type *fs_type, - int flags, char *dev_name, void * data) -{ - return get_sb_bdev(fs_type, flags, dev_name, data, fill_super); -} - struct vfsmount * do_kern_mount(const char *fstype, int flags, char *name, void *data) { @@ -811,10 +797,7 @@ do_kern_mount(const char *fstype, int flags, char *name, void *data) mnt = alloc_vfsmnt(name); if (!mnt) goto out; - if (type->get_sb) - sb = type->get_sb(type, flags, name, data); - else if (type->fs_flags & FS_REQUIRES_DEV) - sb = __get_sb_bdev(type, flags, name, data); + sb = type->get_sb(type, flags, name, data); if (IS_ERR(sb)) goto out_mnt; if (type->fs_flags & FS_NOMOUNT) diff --git a/fs/udf/super.c b/fs/udf/super.c index cf78cf53c..b9952e711 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -76,7 +76,7 @@ static char error_buf[1024]; /* These are the "meat" - everything else is stuffing */ -static struct super_block *udf_read_super(struct super_block *, void *, int); +static int udf_fill_super(struct super_block *, void *, int); static void udf_put_super(struct super_block *); static void udf_write_super(struct super_block *); static int udf_remount_fs(struct super_block *, int *, char *); @@ -96,7 +96,18 @@ static unsigned int udf_count_free(struct super_block *); static int udf_statfs(struct super_block *, struct statfs *); /* UDF filesystem type */ -static DECLARE_FSTYPE_DEV(udf_fstype, "udf", udf_read_super); +static struct super_block *udf_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super); +} + +static struct file_system_type udf_fstype = { + owner: THIS_MODULE, + name: "udf", + get_sb: udf_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static kmem_cache_t * udf_inode_cachep; @@ -1387,8 +1398,7 @@ static void udf_close_lvid(struct super_block *sb) * July 1, 1997 - Andrew E. Mileski * Written, tested, and released. */ -static struct super_block * -udf_read_super(struct super_block *sb, void *options, int silent) +static int udf_fill_super(struct super_block *sb, void *options, int silent) { int i; struct inode *inode=NULL; @@ -1545,7 +1555,7 @@ udf_read_super(struct super_block *sb, void *options, int silent) goto error_out; } sb->s_maxbytes = MAX_LFS_FILESIZE; - return sb; + return 0; error_out: if (UDF_SB_VAT(sb)) @@ -1588,7 +1598,7 @@ error_out: udf_close_lvid(sb); udf_release_data(UDF_SB_LVIDBH(sb)); UDF_SB_FREE(sb); - return NULL; + return -EINVAL; } void udf_error(struct super_block *sb, const char *function, diff --git a/fs/ufs/super.c b/fs/ufs/super.c index f62f97114..ef84557f1 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -434,8 +434,7 @@ void ufs_put_cylinder_structures (struct super_block * sb) { UFSD(("EXIT\n")) } -struct super_block * ufs_read_super (struct super_block * sb, void * data, - int silent) +static int ufs_fill_super(struct super_block *sb, void *data, int silent) { struct ufs_sb_private_info * uspi; struct ufs_super_block_first * usb1; @@ -807,7 +806,7 @@ magic_found: goto failed; UFSD(("EXIT\n")) - return(sb); + return 0; dalloc_failed: iput(inode); @@ -815,7 +814,7 @@ failed: if (ubh) ubh_brelse_uspi (uspi); if (uspi) kfree (uspi); UFSD(("EXIT (FAILED)\n")) - return(NULL); + return -EINVAL; } void ufs_write_super (struct super_block * sb) { @@ -1009,7 +1008,18 @@ static struct super_operations ufs_super_ops = { remount_fs: ufs_remount, }; -static DECLARE_FSTYPE_DEV(ufs_fs_type, "ufs", ufs_read_super); +static struct super_block *ufs_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super); +} + +static struct file_system_type ufs_fs_type = { + owner: THIS_MODULE, + name: "ufs", + get_sb: ufs_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; static int __init init_ufs_fs(void) { diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 86516399d..a761c31cb 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -1254,20 +1254,19 @@ struct inode_operations vfat_dir_inode_operations = { setattr: fat_notify_change, }; -struct super_block *vfat_read_super(struct super_block *sb,void *data, - int silent) +int vfat_fill_super(struct super_block *sb, void *data, int silent) { struct super_block *res; MSDOS_SB(sb)->options.isvfat = 1; res = fat_read_super(sb, data, silent, &vfat_dir_inode_operations); if (IS_ERR(res)) - return NULL; + return PTR_ERR(res); if (res == NULL) { if (!silent) printk(KERN_INFO "VFS: Can't find a valid" " VFAT filesystem on dev %s.\n", sb->s_id); - return NULL; + return -EINVAL; } if (parse_options((char *) data, &(MSDOS_SB(sb)->options))) { @@ -1281,6 +1280,5 @@ struct super_block *vfat_read_super(struct super_block *sb,void *data, sb->s_root->d_op = &vfat_dentry_ops[2]; } } - - return res; + return 0; } diff --git a/fs/vfat/vfatfs_syms.c b/fs/vfat/vfatfs_syms.c index 2feb1222d..f52faa7cb 100644 --- a/fs/vfat/vfatfs_syms.c +++ b/fs/vfat/vfatfs_syms.c @@ -11,14 +11,24 @@ #include <linux/mm.h> #include <linux/msdos_fs.h> -DECLARE_FSTYPE_DEV(vfat_fs_type, "vfat", vfat_read_super); +static struct super_block *vfat_get_sb(struct file_system_type *fs_type, + int flags, char *dev_name, void *data) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super); +} + +static struct file_system_type vfat_fs_type = { + owner: THIS_MODULE, + name: "vfat", + get_sb: vfat_get_sb, + fs_flags: FS_REQUIRES_DEV, +}; EXPORT_SYMBOL(vfat_create); EXPORT_SYMBOL(vfat_unlink); EXPORT_SYMBOL(vfat_mkdir); EXPORT_SYMBOL(vfat_rmdir); EXPORT_SYMBOL(vfat_rename); -EXPORT_SYMBOL(vfat_read_super); EXPORT_SYMBOL(vfat_lookup); static int __init init_vfat_fs(void) diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index 0cf51b706..3104bc340 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h @@ -47,6 +47,7 @@ /* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ /* Don't duplicate feature flags which are redundant with Intel! */ #define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */ +#define X86_FEATURE_MP (1*32+19) /* MP Capable. */ #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ #define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ #define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h index 3463340e4..462ec5a23 100644 --- a/include/asm-i386/i387.h +++ b/include/asm-i386/i387.h @@ -28,17 +28,17 @@ extern void kernel_fpu_begin(void); #define unlazy_fpu( tsk ) do { \ - if (test_thread_flag(TIF_USEDFPU)) \ + if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) \ save_init_fpu( tsk ); \ } while (0) -#define clear_fpu( tsk ) \ -do { \ - if (test_thread_flag(TIF_USEDFPU)) { \ - asm volatile("fwait"); \ - clear_thread_flag(TIF_USEDFPU); \ - stts(); \ - } \ +#define clear_fpu( tsk ) \ +do { \ + if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) { \ + asm volatile("fwait"); \ + clear_tsk_thread_flag(tsk, TIF_USEDFPU); \ + stts(); \ + } \ } while (0) /* diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 5ea17fb89..9fdc37660 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -90,6 +90,7 @@ extern struct cpuinfo_x86 cpu_data[]; #define cpu_has_xmm (test_bit(X86_FEATURE_XMM, boot_cpu_data.x86_capability)) #define cpu_has_fpu (test_bit(X86_FEATURE_FPU, boot_cpu_data.x86_capability)) #define cpu_has_apic (test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability)) +#define cpu_has_mp (test_bit(X86_FEATURE_MP, boot_cpu_data.x86_capability)) extern char ignore_irq13; diff --git a/include/asm-i386/rwlock.h b/include/asm-i386/rwlock.h index 9475419f9..5c2f47040 100644 --- a/include/asm-i386/rwlock.h +++ b/include/asm-i386/rwlock.h @@ -24,23 +24,23 @@ asm volatile(LOCK "subl $1,(%0)\n\t" \ "js 2f\n" \ "1:\n" \ - ".section .text.lock,\"ax\"\n" \ + LOCK_SECTION_START("") \ "2:\tcall " helper "\n\t" \ "jmp 1b\n" \ - ".previous" \ + LOCK_SECTION_END \ ::"a" (rw) : "memory") #define __build_read_lock_const(rw, helper) \ asm volatile(LOCK "subl $1,%0\n\t" \ "js 2f\n" \ "1:\n" \ - ".section .text.lock,\"ax\"\n" \ + LOCK_SECTION_START("") \ "2:\tpushl %%eax\n\t" \ "leal %0,%%eax\n\t" \ "call " helper "\n\t" \ "popl %%eax\n\t" \ "jmp 1b\n" \ - ".previous" \ + LOCK_SECTION_END \ :"=m" (*(volatile int *)rw) : : "memory") #define __build_read_lock(rw, helper) do { \ @@ -54,23 +54,23 @@ asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ "jnz 2f\n" \ "1:\n" \ - ".section .text.lock,\"ax\"\n" \ + LOCK_SECTION_START("") \ "2:\tcall " helper "\n\t" \ "jmp 1b\n" \ - ".previous" \ + LOCK_SECTION_END \ ::"a" (rw) : "memory") #define __build_write_lock_const(rw, helper) \ asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ "jnz 2f\n" \ "1:\n" \ - ".section .text.lock,\"ax\"\n" \ + LOCK_SECTION_START("") \ "2:\tpushl %%eax\n\t" \ "leal %0,%%eax\n\t" \ "call " helper "\n\t" \ "popl %%eax\n\t" \ "jmp 1b\n" \ - ".previous" \ + LOCK_SECTION_END \ :"=m" (*(volatile int *)rw) : : "memory") #define __build_write_lock(rw, helper) do { \ diff --git a/include/asm-i386/rwsem.h b/include/asm-i386/rwsem.h index 0d416f7ae..3cac14272 100644 --- a/include/asm-i386/rwsem.h +++ b/include/asm-i386/rwsem.h @@ -101,7 +101,7 @@ static inline void __down_read(struct rw_semaphore *sem) LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ " js 2f\n\t" /* jump if we weren't granted the lock */ "1:\n\t" - ".section .text.lock,\"ax\"\n" + LOCK_SECTION_START("") "2:\n\t" " pushl %%ecx\n\t" " pushl %%edx\n\t" @@ -109,7 +109,7 @@ LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value " popl %%edx\n\t" " popl %%ecx\n\t" " jmp 1b\n" - ".previous" + LOCK_SECTION_END "# ending down_read\n\t" : "+m"(sem->count) : "a"(sem) @@ -130,13 +130,13 @@ LOCK_PREFIX " xadd %0,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old " testl %0,%0\n\t" /* was the count 0 before? */ " jnz 2f\n\t" /* jump if we weren't granted the lock */ "1:\n\t" - ".section .text.lock,\"ax\"\n" + LOCK_SECTION_START("") "2:\n\t" " pushl %%ecx\n\t" " call rwsem_down_write_failed\n\t" " popl %%ecx\n\t" " jmp 1b\n" - ".previous\n" + LOCK_SECTION_END "# ending down_write" : "+d"(tmp), "+m"(sem->count) : "a"(sem) @@ -154,7 +154,7 @@ static inline void __up_read(struct rw_semaphore *sem) LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ " js 2f\n\t" /* jump if the lock is being waited upon */ "1:\n\t" - ".section .text.lock,\"ax\"\n" + LOCK_SECTION_START("") "2:\n\t" " decw %%dx\n\t" /* do nothing if still outstanding active readers */ " jnz 1b\n\t" @@ -162,7 +162,7 @@ LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old valu " call rwsem_wake\n\t" " popl %%ecx\n\t" " jmp 1b\n" - ".previous\n" + LOCK_SECTION_END "# ending __up_read\n" : "+m"(sem->count), "+d"(tmp) : "a"(sem) @@ -180,7 +180,7 @@ static inline void __up_write(struct rw_semaphore *sem) LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ " jnz 2f\n\t" /* jump if the lock is being waited upon */ "1:\n\t" - ".section .text.lock,\"ax\"\n" + LOCK_SECTION_START("") "2:\n\t" " decw %%dx\n\t" /* did the active count reduce to 0? */ " jnz 1b\n\t" /* jump back if not */ @@ -188,7 +188,7 @@ LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> " call rwsem_wake\n\t" " popl %%ecx\n\t" " jmp 1b\n" - ".previous\n" + LOCK_SECTION_END "# ending __up_write\n" : "+m"(sem->count) : "a"(sem), "i"(-RWSEM_ACTIVE_WRITE_BIAS) diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h index 76c738e73..a0ce1b8db 100644 --- a/include/asm-i386/semaphore.h +++ b/include/asm-i386/semaphore.h @@ -122,10 +122,10 @@ static inline void down(struct semaphore * sem) LOCK "decl %0\n\t" /* --sem->count */ "js 2f\n" "1:\n" - ".section .text.lock,\"ax\"\n" + LOCK_SECTION_START("") "2:\tcall __down_failed\n\t" "jmp 1b\n" - ".previous" + LOCK_SECTION_END :"=m" (sem->count) :"c" (sem) :"memory"); @@ -149,10 +149,10 @@ static inline int down_interruptible(struct semaphore * sem) "js 2f\n\t" "xorl %0,%0\n" "1:\n" - ".section .text.lock,\"ax\"\n" + LOCK_SECTION_START("") "2:\tcall __down_failed_interruptible\n\t" "jmp 1b\n" - ".previous" + LOCK_SECTION_END :"=a" (result), "=m" (sem->count) :"c" (sem) :"memory"); @@ -177,10 +177,10 @@ static inline int down_trylock(struct semaphore * sem) "js 2f\n\t" "xorl %0,%0\n" "1:\n" - ".section .text.lock,\"ax\"\n" + LOCK_SECTION_START("") "2:\tcall __down_failed_trylock\n\t" "jmp 1b\n" - ".previous" + LOCK_SECTION_END :"=a" (result), "=m" (sem->count) :"c" (sem) :"memory"); @@ -203,10 +203,11 @@ static inline void up(struct semaphore * sem) LOCK "incl %0\n\t" /* ++sem->count */ "jle 2f\n" "1:\n" - ".section .text.lock,\"ax\"\n" + LOCK_SECTION_START("") "2:\tcall __up_wakeup\n\t" "jmp 1b\n" - ".previous" + LOCK_SECTION_END + ".subsection 0\n" :"=m" (sem->count) :"c" (sem) :"memory"); diff --git a/include/asm-i386/softirq.h b/include/asm-i386/softirq.h index 254224411..b9f7796b2 100644 --- a/include/asm-i386/softirq.h +++ b/include/asm-i386/softirq.h @@ -33,12 +33,12 @@ do { \ "jnz 2f;" \ "1:;" \ \ - ".section .text.lock,\"ax\";" \ + LOCK_SECTION_START("") \ "2: pushl %%eax; pushl %%ecx; pushl %%edx;" \ "call %c1;" \ "popl %%edx; popl %%ecx; popl %%eax;" \ "jmp 1b;" \ - ".previous;" \ + LOCK_SECTION_END \ \ : /* no output */ \ : "r" (ptr), "i" (do_softirq) \ diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index dbdd68b41..89118fced 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -56,13 +56,13 @@ typedef struct { "\n1:\t" \ "lock ; decb %0\n\t" \ "js 2f\n" \ - ".section .text.lock,\"ax\"\n" \ + LOCK_SECTION_START("") \ "2:\t" \ "cmpb $0,%0\n\t" \ "rep;nop\n\t" \ "jle 2b\n\t" \ "jmp 1b\n" \ - ".previous" + LOCK_SECTION_END /* * This works. Despite all the confusion. diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h index e8515e012..61c7b4220 100644 --- a/include/asm-i386/thread_info.h +++ b/include/asm-i386/thread_info.h @@ -73,8 +73,8 @@ static inline struct thread_info *current_thread_info(void) #define THREAD_SIZE (2*PAGE_SIZE) #define alloc_thread_info() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) #define free_thread_info(ti) free_pages((unsigned long) (ti), 1) -#define get_thread_info(ti) get_task_struct((ti)->l_task) -#define put_thread_info(ti) put_task_struct((ti)->l_task) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) #else /* !__ASSEMBLY__ */ diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h index 4acf48cda..8581f361c 100644 --- a/include/asm-m68k/semaphore.h +++ b/include/asm-m68k/semaphore.h @@ -9,6 +9,7 @@ #include <linux/wait.h> #include <linux/spinlock.h> #include <linux/rwsem.h> +#include <linux/stringify.h> #include <asm/system.h> #include <asm/atomic.h> @@ -94,11 +95,10 @@ extern inline void down(struct semaphore * sem) "subql #1,%0@\n\t" "jmi 2f\n\t" "1:\n" - ".section .text.lock,\"ax\"\n" - ".even\n" + LOCK_SECTION_START(".even\n\t") "2:\tpea 1b\n\t" "jbra __down_failed\n" - ".previous" + LOCK_SECTION_END : /* no outputs */ : "a" (sem1) : "memory"); @@ -119,11 +119,10 @@ extern inline int down_interruptible(struct semaphore * sem) "jmi 2f\n\t" "clrl %0\n" "1:\n" - ".section .text.lock,\"ax\"\n" - ".even\n" + LOCK_SECTION_START(".even\n\t") "2:\tpea 1b\n\t" "jbra __down_failed_interruptible\n" - ".previous" + LOCK_SECTION_END : "=d" (result) : "a" (sem1) : "memory"); @@ -145,11 +144,10 @@ extern inline int down_trylock(struct semaphore * sem) "jmi 2f\n\t" "clrl %0\n" "1:\n" - ".section .text.lock,\"ax\"\n" - ".even\n" + LOCK_SECTION_START(".even\n\t") "2:\tpea 1b\n\t" "jbra __down_failed_trylock\n" - ".previous" + LOCK_SECTION_END : "=d" (result) : "a" (sem1) : "memory"); @@ -175,12 +173,11 @@ extern inline void up(struct semaphore * sem) "addql #1,%0@\n\t" "jle 2f\n" "1:\n" - ".section .text.lock,\"ax\"\n" - ".even\n" + LOCK_SECTION_START(".even\n\t") "2:\t" "pea 1b\n\t" "jbra __up_wakeup\n" - ".previous" + LOCK_SECTION_END : /* no outputs */ : "a" (sem1) : "memory"); diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h index 54a8d54b7..1434908ed 100644 --- a/include/asm-parisc/semaphore.h +++ b/include/asm-parisc/semaphore.h @@ -12,10 +12,6 @@ * */ -/* if you're going to use out-of-line slowpaths, use .section .lock.text, - * not .text.lock or the -ffunction-sections monster will eat you alive - */ - #include <linux/spinlock.h> #include <linux/rwsem.h> diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h index 7a59ed694..15c6d00fc 100644 --- a/include/asm-parisc/spinlock.h +++ b/include/asm-parisc/spinlock.h @@ -3,10 +3,6 @@ #include <asm/system.h> -/* if you're going to use out-of-line slowpaths, use .section .lock.text, - * not .text.lock or the -ffunction-sections monster will eat you alive - */ - /* we seem to be the only architecture that uses 0 to mean locked - but we * have to. prumpf */ diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h index 99d468975..c5cbc107c 100644 --- a/include/linux/efs_fs.h +++ b/include/linux/efs_fs.h @@ -47,7 +47,7 @@ extern struct inode_operations efs_dir_inode_operations; extern struct file_operations efs_dir_operations; extern struct address_space_operations efs_symlink_aops; -extern struct super_block *efs_read_super(struct super_block *, void *, int); +extern int efs_fill_super(struct super_block *, void *, int); extern int efs_statfs(struct super_block *, struct statfs *); extern void efs_read_inode(struct inode *); diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index c7fed24a7..14a44ec25 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -671,7 +671,6 @@ extern void ext3_write_super (struct super_block *); extern void ext3_write_super_lockfs (struct super_block *); extern void ext3_unlockfs (struct super_block *); extern int ext3_remount (struct super_block *, int *, char *); -extern struct super_block * ext3_read_super (struct super_block *,void *,int); extern int ext3_statfs (struct super_block *, struct statfs *); #define ext3_std_error(sb, errno) \ diff --git a/include/linux/fs.h b/include/linux/fs.h index 68902b1c4..28027aaaf 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -934,21 +934,10 @@ struct dquot_operations { int (*transfer) (struct inode *, struct iattr *); }; -/* - * NOTE NOTE NOTE - * - * ->read_super() is going to die. New method (->get_sb) should replace - * it. The only reason why ->read_super() is left for _SHORT_ transition - * period is to avoid a single patch touching every fs. They will be - * converted one-by-one and ONCE THAT IS DONE OR TWO WEEKS HAD PASSED - * (whatever sooner) ->read_super() WILL DISAPPEAR. - */ - struct file_system_type { const char *name; int fs_flags; struct super_block *(*get_sb) (struct file_system_type *, int, char *, void *); - struct super_block *(*read_super) (struct super_block *, void *, int); struct module *owner; struct file_system_type * next; struct list_head fs_supers; @@ -964,14 +953,6 @@ struct super_block *get_sb_nodev(struct file_system_type *fs_type, int flags, void *data, int (*fill_super)(struct super_block *, void *, int)); -#define DECLARE_FSTYPE_DEV(var,type,read) \ -struct file_system_type var = { \ - name: type, \ - read_super: read, \ - fs_flags: FS_REQUIRES_DEV, \ - owner: THIS_MODULE, \ -} - /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ (((fops) && (fops)->owner) \ diff --git a/include/linux/hfs_fs.h b/include/linux/hfs_fs.h index bd64f199b..d8549aedf 100644 --- a/include/linux/hfs_fs.h +++ b/include/linux/hfs_fs.h @@ -301,7 +301,7 @@ extern void hfs_nat_ifill(struct inode *, ino_t, const int); extern void hfs_sngl_ifill(struct inode *, ino_t, const int); /* super.c */ -extern struct super_block *hfs_read_super(struct super_block *,void *,int); +extern int hfs_fill_super(struct super_block *,void *,int); /* trans.c */ extern void hfs_colon2mac(struct hfs_name *, const char *, int); diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 8749f6f0c..220476061 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -91,6 +91,9 @@ extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in extern int tainted; extern const char *print_tainted(void); +#define TAINT_PROPRIETORY_MODULE (1<<0) +#define TAINT_FORCED_MODULE (1<<1) +#define TAINT_UNSAFE_SMP (1<<2) #if DEBUG #define pr_debug(fmt,arg...) \ diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index eff3797d6..4851d846d 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -330,8 +330,7 @@ extern int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode); extern int msdos_unlink(struct inode *dir, struct dentry *dentry); extern int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); -extern struct super_block *msdos_read_super(struct super_block *sb, - void *data, int silent); +extern int msdos_fill_super(struct super_block *sb, void *data, int silent); /* vfat/namei.c - these are for dmsdos */ extern struct dentry *vfat_lookup(struct inode *dir, struct dentry *); @@ -341,8 +340,7 @@ extern int vfat_unlink(struct inode *dir, struct dentry *dentry); extern int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode); extern int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry); -extern struct super_block *vfat_read_super(struct super_block *sb, void *data, - int silent); +extern int vfat_fill_super(struct super_block *sb, void *data, int silent); /* vfat/vfatfs_syms.c */ extern struct file_system_type vfat_fs_type; diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index db948a701..6f3e970f4 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h @@ -54,11 +54,13 @@ struct svc_client { int cl_naddr; struct in_addr cl_addr[NFSCLNT_ADDRMAX]; struct svc_uidmap * cl_umap; - struct svc_export * cl_export[NFSCLNT_EXPMAX]; + struct list_head cl_export[NFSCLNT_EXPMAX]; + struct list_head cl_list; }; struct svc_export { - struct svc_export * ex_next; + struct list_head ex_hash; + struct list_head ex_list; char ex_path[NFS_MAXPATHLEN+1]; struct svc_export * ex_parent; struct svc_client * ex_client; @@ -90,7 +92,10 @@ void exp_unlock(void); struct svc_client * exp_getclient(struct sockaddr_in *sin); void exp_putclient(struct svc_client *clp); struct svc_export * exp_get(struct svc_client *clp, kdev_t dev, ino_t ino); -int exp_rootfh(struct svc_client *, kdev_t, ino_t, +struct svc_export * exp_get_by_name(struct svc_client *clp, + struct vfsmount *mnt, + struct dentry *dentry); +int exp_rootfh(struct svc_client *, char *path, struct knfsd_fh *, int maxsize); int nfserrno(int errno); void exp_nlmdetach(void); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 904d4a406..e3d3e68ef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1486,6 +1486,9 @@ #define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400 #define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402 +#define PCI_VENDOR_ID_AFAVLAB 0x14db +#define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 + #define PCI_VENDOR_ID_BROADCOM 0x14e4 #define PCI_DEVICE_ID_TIGON3_5700 0x1644 #define PCI_DEVICE_ID_TIGON3_5701 0x1645 diff --git a/include/linux/proc_fs_i.h b/include/linux/proc_fs_i.h deleted file mode 100644 index d4bde0989..000000000 --- a/include/linux/proc_fs_i.h +++ /dev/null @@ -1,9 +0,0 @@ -struct proc_inode_info { - struct task_struct *task; - int type; - union { - int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); - int (*proc_read)(struct task_struct *task, char *page); - } op; - struct file *file; -}; diff --git a/include/linux/serialP.h b/include/linux/serialP.h index 9fff64fe6..40c5b9384 100644 --- a/include/linux/serialP.h +++ b/include/linux/serialP.h @@ -70,7 +70,7 @@ struct async_struct { int x_char; /* xon/xoff character */ int close_delay; unsigned short closing_wait; - unsigned short closing_wait2; + unsigned short closing_wait2; /* obsolete */ int IER; /* Interrupt Enable Register */ int MCR; /* Modem control register */ int LCR; /* Line control register */ diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 440ba7df4..dc27910a6 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -35,6 +35,23 @@ if (!__r) local_bh_enable(); \ __r; }) +/* Must define these before including other files, inline functions need them */ + +#include <linux/stringify.h> + +#define LOCK_SECTION_NAME \ + ".text.lock." __stringify(KBUILD_BASENAME) + +#define LOCK_SECTION_START(extra) \ + ".subsection 1\n\t" \ + extra \ + ".ifndef " LOCK_SECTION_NAME "\n\t" \ + LOCK_SECTION_NAME ":\n\t" \ + ".endif\n\t" + +#define LOCK_SECTION_END \ + ".previous\n\t" + #ifdef CONFIG_SMP #include <asm/spinlock.h> diff --git a/include/linux/stringify.h b/include/linux/stringify.h new file mode 100644 index 000000000..0b4388356 --- /dev/null +++ b/include/linux/stringify.h @@ -0,0 +1,12 @@ +#ifndef __LINUX_STRINGIFY_H +#define __LINUX_STRINGIFY_H + +/* Indirect stringification. Doing two levels allows the parameter to be a + * macro itself. For example, compile with -DFOO=bar, __stringify(FOO) + * converts to "bar". + */ + +#define __stringify_1(x) #x +#define __stringify(x) __stringify_1(x) + +#endif /* !__LINUX_STRINGIFY_H */ diff --git a/include/linux/swap.h b/include/linux/swap.h index b0ac23988..3535d0dba 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -50,8 +50,12 @@ union swap_header { #include <asm/atomic.h> -#define SWP_USED 1 -#define SWP_WRITEOK 3 +enum { + SWP_USED = (1 << 0), /* is slot in swap_info[] used? */ + SWP_WRITEOK = (1 << 1), /* ok to write to this swap? */ + SWP_BLOCKDEV = (1 << 2), /* is this swap a block device? */ + SWP_ACTIVE = (SWP_USED | SWP_WRITEOK), +}; #define SWAP_CLUSTER_MAX 32 @@ -63,7 +67,6 @@ union swap_header { */ struct swap_info_struct { unsigned int flags; - kdev_t swap_device; spinlock_t sdev_lock; struct file *swap_file; unsigned short * swap_map; diff --git a/init/Config.in b/init/Config.in index 64c26435f..5e225a782 100644 --- a/init/Config.in +++ b/init/Config.in @@ -1,16 +1,14 @@ mainmenu_option next_comment -comment 'General setup' +comment 'Code maturity level options' +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL +endmenu +mainmenu_option next_comment +comment 'General setup' bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT bool 'Sysctl support' CONFIG_SYSCTL - -endmenu - -mainmenu_option next_comment -comment 'Code maturity level options' -bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL endmenu mainmenu_option next_comment diff --git a/kernel/panic.c b/kernel/panic.c index 1eccb0e0c..84adabf00 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -103,6 +103,10 @@ NORET_TYPE void panic(const char * fmt, ...) /** * print_tainted - return a string to represent the kernel taint state. * + * 'P' - Proprietory module has been loaded. + * 'F' - Module has been forcibly loaded. + * 'S' - SMP with CPUs not designed for SMP. + * * The string is overwritten by the next call to print_taint(). */ @@ -110,9 +114,10 @@ const char *print_tainted() { static char buf[20]; if (tainted) { - snprintf(buf, sizeof(buf), "Tainted: %c%c", - tainted & 1 ? 'P' : 'G', - tainted & 2 ? 'F' : ' '); + snprintf(buf, sizeof(buf), "Tainted: %c%c%c", + tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G', + tainted & TAINT_FORCED_MODULE ? 'F' : ' ', + tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); } else snprintf(buf, sizeof(buf), "Not tainted"); diff --git a/lib/zlib_inflate/infutil.h b/lib/zlib_inflate/infutil.h index 7d1a8d396..f3f883eba 100644 --- a/lib/zlib_inflate/infutil.h +++ b/lib/zlib_inflate/infutil.h @@ -11,7 +11,7 @@ #ifndef _INFUTIL_H #define _INFUTIL_H -#include "zconf.h" +#include <linux/zconf.h> #include "inftrees.h" #include "infcodes.h" diff --git a/mm/swapfile.c b/mm/swapfile.c index 925286b4f..fbe389829 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -114,7 +114,7 @@ swp_entry_t get_swap_page(void) while (1) { p = &swap_info[type]; - if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) { + if ((p->flags & SWP_ACTIVE) == SWP_ACTIVE) { swap_device_lock(p); offset = scan_swap_map(p); swap_device_unlock(p); @@ -729,7 +729,7 @@ asmlinkage long sys_swapoff(const char * specialfile) swap_list_lock(); for (type = swap_list.head; type >= 0; type = swap_info[type].next) { p = swap_info + type; - if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) { + if ((p->flags & SWP_ACTIVE) == SWP_ACTIVE) { if (p->swap_file->f_dentry == nd.dentry) break; } @@ -752,7 +752,7 @@ asmlinkage long sys_swapoff(const char * specialfile) } nr_swap_pages -= p->pages; total_swap_pages -= p->pages; - p->flags = SWP_USED; + p->flags &= ~SWP_WRITEOK; swap_list_unlock(); unlock_kernel(); err = try_to_unuse(type); @@ -770,7 +770,7 @@ asmlinkage long sys_swapoff(const char * specialfile) swap_info[prev].next = p - swap_info; nr_swap_pages += p->pages; total_swap_pages += p->pages; - p->flags = SWP_WRITEOK; + p->flags |= SWP_WRITEOK; swap_list_unlock(); goto out_dput; } @@ -778,7 +778,6 @@ asmlinkage long sys_swapoff(const char * specialfile) swap_device_lock(p); swap_file = p->swap_file; p->swap_file = NULL; - p->swap_device = NODEV; p->max = 0; swap_map = p->swap_map; p->swap_map = NULL; @@ -822,7 +821,8 @@ int get_swaparea_info(char *buf) } len += sprintf(buf + len, "%-39s %s\t%d\t%d\t%d\n", path, - !kdev_none(ptr->swap_device) ? "partition" : "file\t", + (ptr->flags & SWP_BLOCKDEV) ? + "partition" : "file\t", ptr->pages << (PAGE_SHIFT - 10), usedswap << (PAGE_SHIFT - 10), ptr->prio); @@ -837,9 +837,10 @@ int is_swap_partition(kdev_t dev) { int i; for (i = 0 ; i < nr_swapfiles ; i++, ptr++) { - if (ptr->flags & SWP_USED) - if (kdev_same(ptr->swap_device, dev)) - return 1; + if ((ptr->flags & SWP_USED) && + (ptr->flags & SWP_BLOCKDEV) && + (kdev_same(ptr->swap_file->f_dentry->d_inode->i_rdev, dev))) + return 1; } return 0; } @@ -883,7 +884,6 @@ asmlinkage long sys_swapon(const char * specialfile, int swap_flags) nr_swapfiles = type+1; p->flags = SWP_USED; p->swap_file = NULL; - p->swap_device = NODEV; p->swap_map = NULL; p->lowest_bit = 0; p->highest_bit = 0; @@ -911,8 +911,10 @@ asmlinkage long sys_swapon(const char * specialfile, int swap_flags) error = -EINVAL; if (S_ISBLK(swap_file->f_dentry->d_inode->i_mode)) { - p->swap_device = swap_file->f_dentry->d_inode->i_rdev; - set_blocksize(p->swap_device, PAGE_SIZE); + error = set_blocksize(swap_file->f_dentry->d_inode->i_rdev, + PAGE_SIZE); + if (error < 0) + goto bad_swap; } else if (!S_ISREG(swap_file->f_dentry->d_inode->i_mode)) goto bad_swap; @@ -1035,7 +1037,9 @@ asmlinkage long sys_swapon(const char * specialfile, int swap_flags) swap_list_lock(); swap_device_lock(p); p->max = maxpages; - p->flags = SWP_WRITEOK; + p->flags = SWP_ACTIVE; + if (S_ISBLK(swap_file->f_dentry->d_inode->i_mode)) + p->flags |= SWP_BLOCKDEV; p->pages = nr_good_pages; nr_swap_pages += nr_good_pages; total_swap_pages += nr_good_pages; @@ -1064,7 +1068,6 @@ bad_swap: bad_swap_2: swap_list_lock(); swap_map = p->swap_map; - p->swap_device = NODEV; p->swap_file = NULL; p->swap_map = NULL; p->flags = 0; @@ -1090,7 +1093,7 @@ void si_swapinfo(struct sysinfo *val) swap_list_lock(); for (i = 0; i < nr_swapfiles; i++) { unsigned int j; - if (swap_info[i].flags != SWP_USED) + if (!(swap_info[i].flags & SWP_USED)) continue; for (j = 0; j < swap_info[i].max; ++j) { switch (swap_info[i].swap_map[j]) { |