diff options
| author | Patrick Mochel <mochel@osdl.org> | 2002-11-20 00:15:08 -0600 |
|---|---|---|
| committer | Patrick Mochel <mochel@osdl.org> | 2002-11-20 00:15:08 -0600 |
| commit | 95ca3c33e70332572251de4eb60eb0c628cc5aa2 (patch) | |
| tree | ce3a52dcc0423f9a3b6bf3e7ba042fc53143d36a | |
| parent | 3c31f49e8830d17e3cff6a727b0e4c8821078766 (diff) | |
| parent | 37256d28aacf841a25c62910abf586bd271e9632 (diff) | |
Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin
into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-kobject
97 files changed, 1103 insertions, 827 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 9ed995b75fbf..2351591b275c 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -35,7 +35,7 @@ prototypes: int (*symlink) (struct inode *,struct dentry *,const char *); int (*mkdir) (struct inode *,struct dentry *,int); int (*rmdir) (struct inode *,struct dentry *); - int (*mknod) (struct inode *,struct dentry *,int,int); + int (*mknod) (struct inode *,struct dentry *,int,dev_t); int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); int (*readlink) (struct dentry *, char *,int); diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index d14db016e09d..09c219cfb284 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -258,7 +258,7 @@ struct inode_operations { int (*symlink) (struct inode *,struct dentry *,const char *); int (*mkdir) (struct inode *,struct dentry *,int); int (*rmdir) (struct inode *,struct dentry *); - int (*mknod) (struct inode *,struct dentry *,int,int); + int (*mknod) (struct inode *,struct dentry *,int,dev_t); int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); int (*readlink) (struct dentry *, char *,int); diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 793e02ff040a..431ef90e5b6c 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -1314,6 +1314,17 @@ config BOOT_LOAD depends on BOOT_LOAD_BOOL default "0x00400000" +# If we don't have a custom load, we define one here depending. +config BOOT_LOAD + hex + depends on !BOOT_LOAD_BOOL && (40x || 8xx || 8260) + default "0x00400000" + +config BOOT_LOAD + hex + depends on !BOOT_LOAD_BOOL + default "0x00800000" + endmenu source "drivers/mtd/Kconfig" diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 297487d2e6bc..5a49a7fe2c84 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -36,19 +36,13 @@ ifdef CONFIG_MORE_COMPILE_OPTIONS CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') endif -ifdef CONFIG_4xx - HEAD := arch/ppc/kernel/head_4xx.o -else - ifdef CONFIG_8xx - HEAD := arch/ppc/kernel/head_8xx.o - else - ifdef CONFIG_PPC_ISERIES - HEAD := arch/ppc/kernel/iSeries_head.o - else - HEAD := arch/ppc/kernel/head.o - endif - endif -endif +head-y := head.o +head-$(CONFIG_PPC_ISERIES) := iSeries_head.o +head-$(CONFIG_8xx) := head_8xx.o +head-$(CONFIG_4xx) := head_4xx.o +head-$(CONFIG_440) := head_44x.o + +HEAD := arch/ppc/kernel/$(head-y) core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ @@ -80,7 +74,7 @@ $(BOOT_TARGETS): vmlinux cp -f arch/ppc/configs/$(@:config=defconfig) .config archclean: - $(MAKE) -f scripts/Makefile.clean obj=arch/ppc/boot + +$(MAKE) -f scripts/Makefile.clean obj=arch/ppc/boot archmrproper: diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 87c83cbbf35b..939b3bd75b49 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -10,19 +10,17 @@ # modified by Cort (cort@cs.nmt.edu) # -CFLAGS += -fno-builtin -D__BOOTER__ -I$(TOPDIR)/arch/$(ARCH)/boot/include +CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include -AFLAGS += -D__BOOTER__ -OBJCOPY_ARGS = -O elf32-powerpc +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd bootdir-y := simple bootdir-$(CONFIG_ALL_PPC) := openfirmware prep +subdir-y := lib common images +subdir-$(CONFIG_ALL_PPC) += of1275 -# for cleaning... -subdir- := images simple openfirmware prep \ - lib common of1275 - -HOSTCFLAGS += -Iarch/$(ARCH)/boot/include +# for cleaning +subdir- += simple openfirmware prep tools-$(CONFIG_ALL_PPC) := addnote mknote hack-coff mkprep tools-$(CONFIG_PPLUS) := mkbugboot mkprep @@ -39,15 +37,9 @@ all-tools := addnote mknote hack-coff mkprep mkbugboot mktree host-progs := $(addprefix utils/,$(tools-y)) -zImage zImage.initrd znetboot znetboot.initrd: $(addprefix $(obj)/,$(bootdir-y)) - -.PHONY: FORCE - -$(obj)/simple $(obj)/openfirmware $(obj)/prep: $(obj)/lib $(obj)/common $(obj)/images -$(obj)/openfirmware $(obj)/prep: $(obj)/of1275 +.PHONY: $(BOOT_TARGETS) $(bootdir-y) -$(obj)/lib $(obj)/common $(obj)/of1275 $(obj)/images: FORCE - +@$(call descend,$@,) +$(BOOT_TARGETS): $(bootdir-y) -$(obj)/openfirmware $(obj)/prep $(obj)/simple: FORCE - +@$(call descend,$@,$(MAKECMDGOALS)) +$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) + +$(call descend,$(obj)/$@,$(MAKECMDGOALS)) diff --git a/arch/ppc/boot/common/Makefile b/arch/ppc/boot/common/Makefile index 0b882179eef6..e8722218588b 100644 --- a/arch/ppc/boot/common/Makefile +++ b/arch/ppc/boot/common/Makefile @@ -15,5 +15,3 @@ obj-$(CONFIG_ALL_PPC) += mpc10x_memory.o obj-$(CONFIG_LOPEC) += mpc10x_memory.o obj-$(CONFIG_PAL4) += cpc700_memory.o obj-$(CONFIG_SERIAL_8250_CONSOLE) += ns16550.o - -include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile index e5938ff364ea..e64447c760f0 100644 --- a/arch/ppc/boot/images/Makefile +++ b/arch/ppc/boot/images/Makefile @@ -10,6 +10,5 @@ $(obj)/vmlinux.gz: vmlinux $(OBJCOPY) -O binary $< $(@:.gz=) gzip $(GZIP_FLAGS) $(@:.gz=) -clean: - rm -f $(obj)/sImage $(obj)/vmapus $(obj)/vmlinux* $(obj)/miboot* - rm -f $(obj)/zImage* z$(obj)/vmlinux* +# Files generated that shall be removed upon make clean +clean-files := sImage vmapus vmlinux* miboot* zImage* diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile index 4984baf0ff96..cfed956de87d 100644 --- a/arch/ppc/boot/lib/Makefile +++ b/arch/ppc/boot/lib/Makefile @@ -5,5 +5,3 @@ L_TARGET := lib.a obj-y := zlib.o div64.o - -include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/of1275/Makefile b/arch/ppc/boot/of1275/Makefile index 1d3a1f8bef49..e4f150348199 100644 --- a/arch/ppc/boot/of1275/Makefile +++ b/arch/ppc/boot/of1275/Makefile @@ -6,5 +6,3 @@ L_TARGET := lib.a obj-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \ ofstdio.o read.o release.o write.o - -include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile index 210f162442e4..0f21866db17c 100644 --- a/arch/ppc/boot/openfirmware/Makefile +++ b/arch/ppc/boot/openfirmware/Makefile @@ -10,13 +10,10 @@ # Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the # rules. -EXTRA_TARGETS := start.o misc.o crt0.o coffcrt0.o coffmain.o chrpmain.o \ - newworldmain.o common.o +clean-files := note coffboot coffboot.initrd boot: zImage -include $(TOPDIR)/Rules.make - boot := arch/ppc/boot common := $(boot)/common utils := $(boot)/utils @@ -38,8 +35,6 @@ LIBS = lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a ADDNOTE := $(utils)/addnote MKNOTE := $(utils)/mknote -SIZE := $(utils)/size -OFFSET := $(utils)/offset HACKCOFF := $(utils)/hack-coff ifdef CONFIG_SMP @@ -109,12 +104,12 @@ $(obj)/coffboot.initrd: $(COFFOBJS) $(obj)/image-initrd.o $(LIBS) $(LD) -o $@ $(COFF_LD_ARGS) $^ $(OBJCOPY) $@ $@ -R .comment -$(images)/vmlinux.coff: $(obj)/coffboot +$(images)/vmlinux.coff: $(obj)/coffboot $(HACKCOFF) $(OBJCOPY) $(OBJCOPY_ARGS) $(obj)/coffboot $@ $(HACKCOFF) $@ ln -sf vmlinux.coff $(images)/zImage.pmac -$(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd +$(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd $(HACKCOFF) $(OBJCOPY) $(OBJCOPY_ARGS) $(obj)/coffboot.initrd $@ $(HACKCOFF) $@ ln -sf vmlinux.initrd.coff $(images)/zImage.initrd.pmac @@ -139,11 +134,11 @@ $(images)/zImage.initrd.chrp: $(CHRPOBJS) $(obj)/image-initrd.o $(LIBS) $(LD) $(CHRP_LD_ARGS) -o $@ $^ $(OBJCOPY) $@ $@ -R .comment -$(images)/zImage.chrp-rs6k: $(images)/zImage.chrp +$(images)/zImage.chrp-rs6k: $(images)/zImage.chrp $(ADDNOTE) cp $(images)/zImage.chrp $@ $(ADDNOTE) $@ -$(images)/zImage.initrd.chrp-rs6k: $(images)/zImage.initrd.chrp +$(images)/zImage.initrd.chrp-rs6k: $(images)/zImage.initrd.chrp $(ADDNOTE) cp $(images)/zImage.initrd.chrp $@ $(ADDNOTE) $@ @@ -152,6 +147,3 @@ zImage: $(images)/vmlinux.coff $(images)/vmlinux.elf-pmac \ zImage.initrd: $(images)/vmlinux.initrd.coff $(images)/vmlinux.initrd.elf-pmac\ $(images)/zImage.initrd.chrp $(images)/miboot.initrd.image - -clean: - rm -f $(obj)/note $(obj)/image.o $(obj)/coffboot $(obj)/coffboot.initrd diff --git a/arch/ppc/boot/prep/Makefile b/arch/ppc/boot/prep/Makefile index b472f2bce21d..6eda4f8fa5a8 100644 --- a/arch/ppc/boot/prep/Makefile +++ b/arch/ppc/boot/prep/Makefile @@ -27,10 +27,6 @@ LIBS = $(common)/lib.a $(bootlib)/lib.a boot-y := head.o misc.o boot-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o -EXTRA_TARGETS := $(boot-y) ../simple/legacy.o - -include $(TOPDIR)/Rules.make - boot := arch/ppc/boot common := $(boot)/common utils := $(boot)/utils @@ -43,8 +39,6 @@ OBJS := $(addprefix $(obj)/,$(boot-y)) $(simple)/legacy.o # Tools MKPREP := $(utils)/mkprep -SIZE := $(utils)/size -OFFSET := $(utils)/offset # Extra include search dirs CFLAGS_kbd.o += -Idrivers/char @@ -55,8 +49,8 @@ zImage.initrd: $(images)/zImage.initrd.prep $(obj)/dummy.o: $(common)/dummy.c $(CC) -c -o $@ $(common)/dummy.c -$(images)/zImage.prep: $(OBJS) $(LIBS) $(boot)/ld.script \ - $(images)/vmlinux.gz $(obj)/dummy.o +$(images)/zImage.prep: $(OBJS) $(LIBS) $(boot)/ld.script $(images)/vmlinux.gz \ + $(obj)/dummy.o $(MKPREP) $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ --add-section=.image=$(images)/vmlinux.gz \ --set-section-flags=.image=contents,alloc,load,readonly,data \ @@ -68,7 +62,7 @@ $(images)/zImage.prep: $(OBJS) $(LIBS) $(boot)/ld.script \ rm -f $(obj)/zImage $(images)/zImage.initrd.prep: $(OBJS) $(LIBS) $(boot)/ld.script \ - $(images)/vmlinux.gz $(obj)/dummy.o + $(images)/vmlinux.gz $(obj)/dummy.o $(MKPREP) $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ --add-section=.ramdisk=$(images)/ramdisk.image.gz \ --set-section-flags=.ramdisk=contents,alloc,load,readonly,data \ diff --git a/arch/ppc/boot/prep/misc.c b/arch/ppc/boot/prep/misc.c index 7f6680036cea..66dab65ac9e5 100644 --- a/arch/ppc/boot/prep/misc.c +++ b/arch/ppc/boot/prep/misc.c @@ -8,6 +8,7 @@ */ #include <linux/types.h> +#include <linux/string.h> #include <asm/residual.h> #include <linux/config.h> #include <linux/threads.h> diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile index 509be73cd226..c8a9b37d3f41 100644 --- a/arch/ppc/boot/simple/Makefile +++ b/arch/ppc/boot/simple/Makefile @@ -132,23 +132,9 @@ EXTRA_AFLAGS := -Wa,-m405 EXTRA := rw4/rw4_init.o rw4/rw4_init_brd.o endif -# Default linker args. Link at 0x00800000 or 0x00400000 by default, but -# allow it to be overridden. -ifeq ($(CONFIG_BOOT_LOAD_BOOL),y) -LD_ARGS := -T $(boot)/ld.script \ - -Ttext $(CONFIG_BOOT_LOAD) -Bstatic -else +# Linker args. This specifies where the image will be run at. LD_ARGS = -T $(boot)/ld.script \ - -Ttext 0x00800000 -Bstatic -ifeq ($(CONFIG_8260)$(CONFIG_40x)$(CONFIG_8xx),y) -LD_ARGS := -T $(boot)/ld.script -Ttext 0x00400000 \ - -Bstatic -endif -ifeq ($(CONFIG_440),y) -LD_ARGS := -T $(boot)/ld.script -Ttext 0x01000000 \ - -Bstatic -endif -endif + -Ttext $(CONFIG_BOOT_LOAD) -Bstatic OBJCOPY_ARGS := -O elf32-powerpc # head.o and relocate.o must be at the start. @@ -167,8 +153,7 @@ boot-$(CONFIG_8260) += m8260_tty.o boot-$(CONFIG_GT64260_CONSOLE) += gt64260_tty.o endif -EXTRA_TARGETS := $(boot-y) -LIBS := $(common)/lib.a $(bootlib)/lib.a +LIBS := $(common)/lib.a $(bootlib)/lib.a OBJS := $(addprefix $(obj)/,$(boot-y)) @@ -181,7 +166,7 @@ $(obj)/dummy.o: $(common)/dummy.c $(CC) -c -o $@ $(common)/dummy.c $(obj)/zvmlinux: $(OBJS) $(LIBS) $(boot)/ld.script $(images)/vmlinux.gz \ - $(obj)/dummy.o + $(obj)/dummy.o $(OBJCOPY) $(OBJCOPY_ARGS) \ --add-section=.image=$(images)/vmlinux.gz \ --set-section-flags=.image=contents,alloc,load,readonly,data \ diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c index 74693dc19a0a..7cae431215a3 100644 --- a/arch/ppc/boot/simple/misc.c +++ b/arch/ppc/boot/simple/misc.c @@ -21,6 +21,7 @@ #include <linux/types.h> #include <linux/elf.h> #include <linux/config.h> +#include <linux/string.h> #include <asm/page.h> #include <asm/processor.h> diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 1005dd2d85b2..7447a109fac9 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -25,7 +25,7 @@ obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ cputable.o ppc_htab.o obj-$(CONFIG_6xx) += l2cr.o ppc6xx_idle.o obj-$(CONFIG_ALL_PPC) += ppc6xx_idle.o -obj-$(CONFIG_MODULES) += ppc_ksyms.o +obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o obj-$(CONFIG_PCI) += pci.o ifneq ($(CONFIG_PPC_ISERIES),y) obj-$(CONFIG_PCI) += pci-dma.o diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index bcd49bd0f735..480f941794b1 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1182,10 +1182,10 @@ _GLOBAL(sys_call_table) .long sys_adjtimex .long sys_mprotect /* 125 */ .long sys_sigprocmask - .long sys_create_module + .long sys_ni_syscall /* old sys_create_module */ .long sys_init_module .long sys_delete_module - .long sys_get_kernel_syms /* 130 */ + .long sys_ni_syscall /* old sys_get_kernel_syms */ /* 130 */ .long sys_quotactl .long sys_getpgid .long sys_fchdir @@ -1221,7 +1221,7 @@ _GLOBAL(sys_call_table) .long sys_mremap .long sys_setresuid .long sys_getresuid /* 165 */ - .long sys_query_module + .long sys_ni_syscall /* old sys_query_module */ .long sys_poll .long sys_nfsservctl .long sys_setresgid diff --git a/arch/ppc/kernel/module.c b/arch/ppc/kernel/module.c new file mode 100644 index 000000000000..480495f45289 --- /dev/null +++ b/arch/ppc/kernel/module.c @@ -0,0 +1,260 @@ +/* Kernel module help for PPC. + Copyright (C) 2001 Rusty Russell. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include <linux/module.h> +#include <linux/elf.h> +#include <linux/vmalloc.h> +#include <linux/fs.h> +#include <linux/string.h> +#include <linux/kernel.h> + +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(fmt , ...) +#endif + +void *module_alloc(unsigned long size) +{ + if (size == 0) + return NULL; + return vmalloc(size); +} + +/* Free memory returned from module_alloc */ +void module_free(struct module *mod, void *module_region) +{ + vfree(module_region); + /* FIXME: If module_region == mod->init_region, trim exception + table entries. */ +} + +/* Count how many different relocations (different symbol, different + addend) */ +static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num) +{ + unsigned int i, j, ret = 0; + + /* Sure, this is order(n^2), but it's usually short, and not + time critical */ + for (i = 0; i < num; i++) { + for (j = 0; j < i; j++) { + /* If this addend appeared before, it's + already been counted */ + if (ELF32_R_SYM(rela[i].r_info) + == ELF32_R_SYM(rela[j].r_info) + && rela[i].r_addend == rela[j].r_addend) + break; + } + if (j == i) ret++; + } + return ret; +} + +/* Get the potential trampolines size required of the init and + non-init sections */ +static unsigned long get_plt_size(const Elf32_Ehdr *hdr, + const Elf32_Shdr *sechdrs, + const char *secstrings, + int is_init) +{ + unsigned long ret = 0; + unsigned i; + + /* Everything marked ALLOC (this includes the exported + symbols) */ + for (i = 1; i < hdr->e_shnum; i++) { + /* If it's called *.init*, and we're not init, we're + not interested */ + if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) + != is_init) + continue; + + if (sechdrs[i].sh_type == SHT_RELA) { + DEBUGP("Found relocations in section %u\n", i); + DEBUGP("Ptr: %p. Number: %u\n", + (void *)hdr + sechdrs[i].sh_offset, + sechdrs[i].sh_size / sizeof(Elf32_Rela)); + ret += count_relocs((void *)hdr + + sechdrs[i].sh_offset, + sechdrs[i].sh_size + / sizeof(Elf32_Rela)) + * sizeof(struct ppc_plt_entry); + } + } + + return ret; +} + +long module_core_size(const Elf32_Ehdr *hdr, + const Elf32_Shdr *sechdrs, + const char *secstrings, + struct module *module) +{ + module->arch.core_plt_offset = module->core_size; + return module->core_size + get_plt_size(hdr, sechdrs, secstrings, 0); +} + +long module_init_size(const Elf32_Ehdr *hdr, + const Elf32_Shdr *sechdrs, + const char *secstrings, + struct module *module) +{ + module->arch.init_plt_offset = module->init_size; + return module->init_size + get_plt_size(hdr, sechdrs, secstrings, 1); +} + +int apply_relocate(Elf32_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *module) +{ + printk(KERN_ERR "%s: Non-ADD RELOCATION unsupported\n", + module->name); + return -ENOEXEC; +} + +static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) +{ + if (entry->jump[0] == 0x3d600000 + ((val + 0x8000) >> 16) + && entry->jump[1] == 0x396b0000 + (val & 0xffff)) + return 1; + return 0; +} + +/* Set up a trampoline in the PLT to bounce us to the distant function */ +static uint32_t do_plt_call(void *location, Elf32_Addr val, struct module *mod) +{ + struct ppc_plt_entry *entry; + + DEBUGP("Doing plt for %u\n", (unsigned int)location); + /* Init, or core PLT? */ + if (location >= mod->module_core + && location < mod->module_core + mod->arch.core_plt_offset) + entry = mod->module_core + mod->arch.core_plt_offset; + else + entry = mod->module_init + mod->arch.init_plt_offset; + + /* Find this entry, or if that fails, the next avail. entry */ + while (entry->jump[0]) { + if (entry_matches(entry, val)) return (uint32_t)entry; + entry++; + } + + /* Stolen from Paul Mackerras as well... */ + entry->jump[0] = 0x3d600000+((val+0x8000)>>16); /* lis r11,sym@ha */ + entry->jump[1] = 0x396b0000 + (val&0xffff); /* addi r11,r11,sym@l*/ + entry->jump[2] = 0x7d6903a6; /* mtctr r11 */ + entry->jump[3] = 0x4e800420; /* bctr */ + + return (uint32_t)entry; +} + +int apply_relocate_add(Elf32_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *module) +{ + unsigned int i; + Elf32_Rela *rela = (void *)sechdrs[relsec].sh_offset; + Elf32_Sym *sym; + uint32_t *location; + uint32_t value; + + DEBUGP("Applying ADD relocate section %u to %u\n", relsec, + sechdrs[relsec].sh_info); + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { + /* This is where to make the change */ + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_offset + + rela[i].r_offset; + /* This is the symbol it is referring to */ + sym = (Elf32_Sym *)sechdrs[symindex].sh_offset + + ELF32_R_SYM(rela[i].r_info); + if (!sym->st_value) { + printk(KERN_WARNING "%s: Unknown symbol %s\n", + module->name, strtab + sym->st_name); + return -ENOENT; + } + /* `Everything is relative'. */ + value = sym->st_value + rela[i].r_addend; + + switch (ELF32_R_TYPE(rela[i].r_info)) { + case R_PPC_ADDR32: + /* Simply set it */ + *(uint32_t *)location = value; + break; + + case R_PPC_ADDR16_LO: + /* Low half of the symbol */ + *(uint16_t *)location = value; + break; + + case R_PPC_ADDR16_HA: + /* Sign-adjusted lower 16 bits: PPC ELF ABI says: + (((x >> 16) + ((x & 0x8000) ? 1 : 0))) & 0xFFFF. + This is the same, only sane. + */ + *(uint16_t *)location = (value + 0x8000) >> 16; + break; + + case R_PPC_REL24: + if ((int)(value - (uint32_t)location) < -0x02000000 + || (int)(value - (uint32_t)location) >= 0x02000000) + value = do_plt_call(location, value, module); + + /* Only replace bits 2 through 26 */ + DEBUGP("REL24 value = %08X. location = %08X\n", + value, (uint32_t)location); + DEBUGP("Location before: %08X.\n", + *(uint32_t *)location); + *(uint32_t *)location + = (*(uint32_t *)location & ~0x03fffffc) + | ((value - (uint32_t)location) + & 0x03fffffc); + DEBUGP("Location after: %08X.\n", + *(uint32_t *)location); + DEBUGP("ie. jump to %08X+%08X = %08X\n", + *(uint32_t *)location & 0x03fffffc, + (uint32_t)location, + (*(uint32_t *)location & 0x03fffffc) + + (uint32_t)location); + break; + + case R_PPC_REL32: + /* 32-bit relative jump. */ + *(uint32_t *)location = value - (uint32_t)location; + break; + + default: + printk("%s: unknown ADD relocation: %u\n", + module->name, + ELF32_R_TYPE(rela[i].r_info)); + return -ENOEXEC; + } + } + return 0; +} + +/* FIXME: Sort exception table --RR */ +int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *me) +{ + return 0; +} diff --git a/arch/ppc/mm/extable.c b/arch/ppc/mm/extable.c index 971afb36045f..aee3118d18d2 100644 --- a/arch/ppc/mm/extable.c +++ b/arch/ppc/mm/extable.c @@ -70,24 +70,29 @@ search_one_table(const struct exception_table_entry *first, unsigned long search_exception_table(unsigned long addr) { - unsigned long ret; + unsigned long ret = 0; #ifndef CONFIG_MODULES /* There is only the kernel to search. */ ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); - if (ret) return ret; #else - /* The kernel is the last "module" -- no need to treat it special. */ - struct module *mp; - for (mp = module_list; mp != NULL; mp = mp->next) { - if (mp->ex_table_start == NULL) + unsigned long flags; + struct list_head *i; + + /* The kernel is the last "module" -- no need to treat it special. */ + spin_lock_irqsave(&modlist_lock, flags); + list_for_each(i, &extables) { + struct exception_table *ex + = list_entry(i, struct exception_table, list); + if (ex->num_entries == 0) continue; - ret = search_one_table(mp->ex_table_start, - mp->ex_table_end - 1, addr); + ret = search_one_table(ex->entry, + ex->entry + ex->num_entries - 1, addr); if (ret) - return ret; + break; } + spin_unlock_irqrestore(&modlist_lock, flags); #endif - return 0; + return ret; } diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c index aaaf01f70ded..5fd3c4caa43d 100644 --- a/arch/ppc/platforms/pmac_pic.c +++ b/arch/ppc/platforms/pmac_pic.c @@ -21,6 +21,7 @@ #include <linux/sched.h> #include <linux/signal.h> #include <linux/pci.h> +#include <linux/interrupt.h> #include <asm/sections.h> #include <asm/io.h> diff --git a/arch/ppc/syslib/i8259.c b/arch/ppc/syslib/i8259.c index 44324c5cc3ee..ba1f46074821 100644 --- a/arch/ppc/syslib/i8259.c +++ b/arch/ppc/syslib/i8259.c @@ -1,9 +1,6 @@ -#include <linux/stddef.h> #include <linux/init.h> -#include <linux/irq.h> #include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/signal.h> +#include <linux/interrupt.h> #include <asm/io.h> #include <asm/i8259.h> diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 7d22bc5f96eb..a6efd2c9a611 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -14,6 +14,7 @@ #include <linux/sched.h> #include <linux/init.h> #include <linux/irq.h> +#include <linux/interrupt.h> #include <asm/ptrace.h> #include <asm/signal.h> #include <asm/io.h> diff --git a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c index 9ada504c26a7..b6ab87135c30 100644 --- a/drivers/hotplug/pci_hotplug_core.c +++ b/drivers/hotplug/pci_hotplug_core.c @@ -121,7 +121,7 @@ static struct proc_dir_entry *slotdir = NULL; static const char *slotdir_name = "slots"; #endif -static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, int dev) +static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, dev_t dev) { struct inode *inode = new_inode(sb); @@ -153,7 +153,7 @@ static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, int de } /* SMP-safe */ -static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, int dev) +static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev); int error = -ENOSPC; diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c index a0b4282dae01..6954b99388bb 100644 --- a/drivers/isdn/hisax/bkm_a8.c +++ b/drivers/isdn/hisax/bkm_a8.c @@ -278,8 +278,6 @@ sct_alloc_io(u_int adr, u_int len) static struct pci_dev *dev_a8 __initdata = NULL; static u16 sub_vendor_id __initdata = 0; static u16 sub_sys_id __initdata = 0; -static u_char pci_bus __initdata = 0; -static u_char pci_device_fn __initdata = 0; static u_char pci_irq __initdata = 0; #endif /* CONFIG_PCI */ @@ -328,8 +326,6 @@ setup_sct_quadro(struct IsdnCard *card) return(0); pci_ioaddr1 = pci_resource_start(dev_a8, 1); pci_irq = dev_a8->irq; - pci_bus = dev_a8->bus->number; - pci_device_fn = dev_a8->devfn; found = 1; break; } @@ -342,20 +338,17 @@ setup_sct_quadro(struct IsdnCard *card) } #ifdef ATTEMPT_PCI_REMAPPING /* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */ - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_REVISION_ID, &pci_rev_id); + pci_read_config_byte(dev_a8, PCI_REVISION_ID, &pci_rev_id); if ((pci_ioaddr1 & 0x80) && (pci_rev_id == 1)) { printk(KERN_WARNING "HiSax: %s (%s): PLX rev 1, remapping required!\n", CardType[card->typ], sct_quadro_subtypes[cs->subtyp]); /* Restart PCI negotiation */ - pcibios_write_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, (u_int) - 1); + pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, (u_int) - 1); /* Move up by 0x80 byte */ pci_ioaddr1 += 0x80; pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK; - pcibios_write_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, pci_ioaddr1); + pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, pci_ioaddr1); dev_a8->resource[ 1].start = pci_ioaddr1; } #endif /* End HACK */ @@ -366,11 +359,11 @@ setup_sct_quadro(struct IsdnCard *card) sct_quadro_subtypes[cs->subtyp]); return (0); } - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &pci_ioaddr1); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &pci_ioaddr2); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_3, &pci_ioaddr3); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_4, &pci_ioaddr4); - pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_5, &pci_ioaddr5); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_1, &pci_ioaddr1); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_2, &pci_ioaddr2); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_3, &pci_ioaddr3); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_4, &pci_ioaddr4); + pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_5, &pci_ioaddr5); if (!pci_ioaddr1 || !pci_ioaddr2 || !pci_ioaddr3 || !pci_ioaddr4 || !pci_ioaddr5) { printk(KERN_WARNING "HiSax: %s (%s): No IO base address(es)\n", CardType[card->typ], diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 39322fec9a8f..2749c3ccd859 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,10 +3,10 @@ # export-objs := access.o hotplug.o pci-driver.o pci.o pool.o \ - probe.o proc.o search.o compat.o setup-bus.o + probe.o proc.o search.o setup-bus.o obj-y += access.o probe.o pci.o pool.o quirks.o \ - compat.o names.o pci-driver.o search.o hotplug.o + names.o pci-driver.o search.o hotplug.o obj-$(CONFIG_PM) += power.o obj-$(CONFIG_PROC_FS) += proc.o diff --git a/drivers/pci/compat.c b/drivers/pci/compat.c deleted file mode 100644 index 048c610a9e62..000000000000 --- a/drivers/pci/compat.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * $Id: compat.c,v 1.1 1998/02/16 10:35:50 mj Exp $ - * - * PCI Bus Services -- Function For Backward Compatibility - * - * Copyright 1998--2000 Martin Mares <mj@ucw.cz> - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pci.h> - -/* Obsolete functions, these will be going away... */ - -#define PCI_OP(rw,size,type) \ -int pcibios_##rw##_config_##size (unsigned char bus, unsigned char dev_fn, \ - unsigned char where, unsigned type val) \ -{ \ - struct pci_dev *dev = pci_find_slot(bus, dev_fn); \ - if (!dev) return PCIBIOS_DEVICE_NOT_FOUND; \ - return pci_##rw##_config_##size(dev, where, val); \ -} - -PCI_OP(read, byte, char *) -PCI_OP(read, word, short *) -PCI_OP(read, dword, int *) -PCI_OP(write, byte, char) -PCI_OP(write, word, short) -PCI_OP(write, dword, int) - -EXPORT_SYMBOL(pcibios_read_config_byte); -EXPORT_SYMBOL(pcibios_read_config_word); -EXPORT_SYMBOL(pcibios_read_config_dword); -EXPORT_SYMBOL(pcibios_write_config_byte); -EXPORT_SYMBOL(pcibios_write_config_word); -EXPORT_SYMBOL(pcibios_write_config_dword); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 620f9ff944ec..6ad18c0eebbd 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -182,7 +182,7 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) int i; struct resource *best = NULL; - for(i=0; i<4; i++) { + for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { struct resource *r = bus->resource[i]; if (!r) continue; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 5dfb1af81376..5135fdde0d4d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -384,7 +384,7 @@ int pci_setup_device(struct pci_dev * dev) /* The PCI-to-PCI bridge spec requires that subtractive decoding (i.e. transparent) bridge must have programming interface code of 0x01. */ - dev->transparent = ((class & 0xff) == 1); + dev->transparent = ((dev->class & 0xff) == 1); pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); break; diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 9684e68d4042..5a3d7ebc213d 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -36,21 +36,20 @@ int __init pci_claim_resource(struct pci_dev *dev, int resource) { - struct resource *res = &dev->resource[resource]; + struct resource *res = &dev->resource[resource]; struct resource *root = pci_find_parent_resource(dev, res); + char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; int err; err = -EINVAL; - if (root != NULL) { + if (root != NULL) err = request_resource(root, res); - if (err) { - printk(KERN_ERR "PCI: Address space collision on " - "region %d of device %s [%lx:%lx]\n", - resource, dev->dev.name, res->start, res->end); - } - } else { - printk(KERN_ERR "PCI: No parent found for region %d " - "of device %s\n", resource, dev->dev.name); + + if (err) { + printk(KERN_ERR "PCI: %s region %d of %s %s [%lx:%lx]\n", + root ? "Address space collision on" : + "No parent found for", + resource, dtype, dev->slot_name, res->start, res->end); } return err; @@ -131,13 +130,13 @@ pci_assign_resource(struct pci_dev *dev, int i) } DBGC((KERN_ERR " got res[%lx:%lx] for resource %d of %s\n", res->start, - res->end, i, dev->name)); + res->end, i, dev->dev.name)); return 0; } /* Sort resources by alignment */ -void __init +void __devinit pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) { int i; diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index d8ab8d3aa1e7..cc4d817c6dee 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -430,7 +430,10 @@ int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple) #ifdef CONFIG_CARDBUS if (s->state & SOCKET_CARDBUS) { u_int ptr; - pcibios_read_config_dword(s->cap.cb_dev->subordinate->number, 0, 0x28, &ptr); + struct pci_dev *dev = pci_find_slot (s->cap.cb_dev->subordinate->number, 0); + if (!dev) + return CS_BAD_HANDLE; + pci_read_config_dword(dev, 0x28, &ptr); tuple->CISOffset = ptr & ~7; SPACE(tuple->Flags) = (ptr & 7); } else diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 0a50a9d232fb..895466b94129 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -29,24 +29,26 @@ #define BusLogic_DriverVersion "2.1.16" #define BusLogic_DriverDate "18 July 2002" +#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> -#include <linux/config.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/types.h> #include <linux/blk.h> #include <linux/blkdev.h> #include <linux/delay.h> #include <linux/ioport.h> #include <linux/mm.h> -#include <linux/sched.h> #include <linux/stat.h> #include <linux/pci.h> #include <linux/spinlock.h> +/* #include <scsi/scsicam.h> This include file is currently busted */ + #include <asm/dma.h> #include <asm/io.h> #include <asm/system.h> -/* #include <scsi/scsicam.h> This include file is currently busted */ + #include "scsi.h" #include "hosts.h" #include "BusLogic.h" diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index d712e99bd728..0b71788947bc 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -93,25 +93,25 @@ #define NCR_D700_VERSION "2.2" #include <linux/config.h> +#include <linux/blk.h> +#include <linux/interrupt.h> #include <linux/version.h> #include <linux/kernel.h> +#include <linux/module.h> #include <linux/types.h> #include <linux/string.h> #include <linux/spinlock.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/sched.h> #include <linux/proc_fs.h> #include <linux/init.h> #include <linux/mca.h> + #include <asm/dma.h> #include <asm/system.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/byteorder.h> -#include <linux/blk.h> -#include <linux/module.h> - #include "scsi.h" #include "hosts.h" diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index ed4537d792a3..cf648b97736f 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -789,25 +789,23 @@ #endif /* CONFIG_X86 && !CONFIG_ISA */ #include <linux/string.h> -#include <linux/sched.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/ioport.h> +#include <linux/interrupt.h> #include <linux/delay.h> #include <linux/slab.h> #include <linux/mm.h> #include <linux/proc_fs.h> #include <linux/init.h> -#include <asm/io.h> -#include <asm/system.h> -#include <asm/dma.h> #include <linux/blk.h> #include <linux/stat.h> -#if ASC_LINUX_KERNEL24 #include <linux/spinlock.h> -#elif ASC_LINUX_KERNEL22 -#include <asm/spinlock.h> -#endif + +#include <asm/io.h> +#include <asm/system.h> +#include <asm/dma.h> + #include "scsi.h" #include "hosts.h" #include "advansys.h" diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index d7dcee22d753..5b6593f6a259 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -27,28 +27,26 @@ #include <linux/config.h> #include <linux/module.h> - +#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/sched.h> #include <linux/proc_fs.h> #include <linux/init.h> #include <linux/spinlock.h> #include <linux/pci.h> #include <linux/isapnp.h> +#include <linux/blk.h> +#include <linux/mca.h> + #include <asm/dma.h> #include <asm/system.h> #include <asm/io.h> -#include <linux/blk.h> -#include <linux/mca.h> #include "scsi.h" #include "hosts.h" - - #include "aha1542.h" #define SCSI_BUF_PA(address) isa_virt_to_bus(address) diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 38c6e632392d..f159bb58c1d9 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -30,23 +30,23 @@ * are deemed to be part of the source code. */ +#include <linux/blk.h> +#include <linux/interrupt.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> #include <linux/ioport.h> #include <linux/proc_fs.h> -#include <linux/sched.h> -#include <asm/dma.h> +#include <linux/stat.h> +#include <asm/dma.h> #include <asm/system.h> #include <asm/io.h> -#include <linux/blk.h> + #include "scsi.h" #include "hosts.h" - #include "aha1740.h" -#include<linux/stat.h> /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH IT WORK, THEN: diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index c367ed85f290..73538537f682 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -17,27 +17,25 @@ */ #include <linux/module.h> - +#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/sched.h> #include <linux/proc_fs.h> #include <linux/spinlock.h> -#include <asm/system.h> -#include <asm/io.h> #include <linux/pci.h> #include <linux/blk.h> -#include "scsi.h" -#include "hosts.h" +#include <linux/stat.h> +#include <asm/system.h> +#include <asm/io.h> +#include "scsi.h" +#include "hosts.h" #include "atp870u.h" -#include<linux/stat.h> - /* * static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/atp870u.c,v 1.0 1997/05/07 15:22:00 root Exp root $"; */ diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c index 3ae04dce0928..36b3a7154bdc 100644 --- a/drivers/scsi/cpqfcTSinit.c +++ b/drivers/scsi/cpqfcTSinit.c @@ -31,20 +31,21 @@ #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) +#include <linux/config.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/version.h> #include <linux/blk.h> #include <linux/kernel.h> #include <linux/string.h> -#include <linux/sched.h> #include <linux/types.h> #include <linux/pci.h> #include <linux/delay.h> #include <linux/timer.h> #include <linux/init.h> #include <linux/ioport.h> // request_region() prototype -#include <linux/vmalloc.h> // ioremap() -//#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) #include <linux/completion.h> -//#endif + #ifdef __alpha__ #define __KERNEL_SYSCALLS__ #endif @@ -62,10 +63,6 @@ #include "cpqfcTS.h" -#include <linux/config.h> -#include <linux/module.h> -#include <linux/version.h> - /* Embedded module documentation macros - see module.h */ MODULE_AUTHOR("Compaq Computer Corporation"); MODULE_DESCRIPTION("Driver for Compaq 64-bit/66Mhz PCI Fibre Channel HBA v. 2.5.4"); diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index f4a108567ac4..7267ef8d6d03 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c @@ -78,8 +78,7 @@ **************************************************************************/ #include <linux/module.h> - -#include <linux/sched.h> +#include <linux/interrupt.h> #include <linux/blk.h> #include <linux/errno.h> #include <linux/string.h> @@ -88,6 +87,7 @@ #include <linux/delay.h> #include <linux/mca.h> #include <linux/spinlock.h> + #include <asm/io.h> #include <asm/system.h> diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 2120a570c9e6..2007b99f675d 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -277,14 +277,10 @@ #undef MODULE #endif +#include <linux/config.h> /* for CONFIG_PCI */ #include <linux/init.h> -#include <linux/sched.h> -#include <asm/io.h> +#include <linux/interrupt.h> #include <linux/blk.h> -#include "scsi.h" -#include "hosts.h" -#include "fdomain.h" -#include <asm/system.h> #include <linux/spinlock.h> #include <linux/errno.h> #include <linux/string.h> @@ -294,7 +290,12 @@ #include <linux/stat.h> #include <linux/delay.h> -#include <linux/config.h> /* for CONFIG_PCI */ +#include <asm/io.h> +#include <asm/system.h> + +#include "scsi.h" +#include "hosts.h" +#include "fdomain.h" #define VERSION "$Revision: 5.50 $" diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index d383253d1f27..6a8fb9ebf7ac 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c @@ -17,6 +17,7 @@ */ +#include <linux/config.h> #ifndef LINUX_VERSION_CODE #include <linux/version.h> #endif @@ -28,22 +29,23 @@ #include <linux/types.h> #include <linux/ctype.h> #include <linux/string.h> +#include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/sched.h> #include <linux/blk.h> #include <linux/proc_fs.h> #include <linux/stat.h> #include <linux/mca.h> #include <linux/string.h> -#include <asm/system.h> #include <linux/spinlock.h> -#include <asm/io.h> #include <linux/init.h> + +#include <asm/system.h> +#include <asm/io.h> + #include "scsi.h" #include "hosts.h" #include "ibmmca.h" -#include <linux/config.h> /* current version of this driver-source: */ #define IBMMCA_SCSI_DRIVER_VERSION "4.0b-ac" @@ -1396,9 +1398,8 @@ static void internal_ibmmca_scsi_setup(char *str, int *ints) io_base = 0; id_base = 0; if (str) { - token = strtok(str, ","); j = 0; - while (token) { + while ((token = strsep(&str, ",")) != NULL) { if (!strcmp(token, "activity")) display_mode |= LED_ACTIVITY; if (!strcmp(token, "display")) @@ -1422,7 +1423,6 @@ static void internal_ibmmca_scsi_setup(char *str, int *ints) scsi_id[id_base++] = simple_strtoul(token, NULL, 0); j++; } - token = strtok(NULL, ","); } } else if (ints) { for (i = 0; i < IM_MAX_HOSTS && 2 * i + 2 < ints[0]; i++) { diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index c58f495fb2da..4a1f9be57dc8 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -114,19 +114,18 @@ */ #include <linux/module.h> - -#include <asm/system.h> -#include <linux/sched.h> +#include <linux/blk.h> +#include <linux/blkdev.h> +#include <linux/interrupt.h> #include <linux/string.h> #include <linux/delay.h> #include <linux/proc_fs.h> -#include <asm/io.h> #include <linux/ioport.h> -#include <linux/blkdev.h> - -#include <linux/blk.h> #include <linux/stat.h> +#include <asm/io.h> +#include <asm/system.h> + #include "scsi.h" #include "hosts.h" diff --git a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c index ba58ea9dfc81..553782833f48 100644 --- a/drivers/scsi/inia100.c +++ b/drivers/scsi/inia100.c @@ -75,9 +75,9 @@ #include <linux/module.h> -#include <asm/irq.h> #include <linux/errno.h> #include <linux/delay.h> +#include <linux/interrupt.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/blk.h> @@ -86,12 +86,15 @@ #include <linux/kernel.h> #include <linux/string.h> #include <linux/ioport.h> -#include <linux/sched.h> +//#include <linux/sched.h> +#include <linux/slab.h> #include <linux/proc_fs.h> + #include <asm/io.h> +#include <asm/irq.h> + #include "scsi.h" #include "hosts.h" -#include <linux/slab.h> #include "inia100.h" static Scsi_Host_Template driver_template = INIA100; diff --git a/drivers/scsi/mca_53c9x.c b/drivers/scsi/mca_53c9x.c index 3e4bcaec167f..cbadd79b29ce 100644 --- a/drivers/scsi/mca_53c9x.c +++ b/drivers/scsi/mca_53c9x.c @@ -30,8 +30,10 @@ * look. */ -#include <linux/kernel.h> #include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/mca.h> #include <linux/types.h> #include <linux/string.h> #include <linux/slab.h> @@ -45,10 +47,8 @@ #include "mca_53c9x.h" #include <asm/dma.h> -#include <linux/mca.h> #include <asm/irq.h> #include <asm/mca_dma.h> - #include <asm/pgtable.h> static int dma_bytes_sent(struct NCR_ESP *, int); diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index 522a601d90b7..55f6f8d224a9 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c @@ -26,26 +26,26 @@ #include <linux/module.h> +#include <linux/blk.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/sched.h> +#include <linux/interrupt.h> #include <linux/proc_fs.h> #include <linux/spinlock.h> +#include <linux/stat.h> + #include <asm/dma.h> #include <asm/system.h> #include <asm/io.h> -#include <linux/blk.h> #include "scsi.h" #include "hosts.h" #include "psi240i.h" #include "psi_chip.h" -#include<linux/stat.h> - //#define DEBUG 1 #ifdef DEBUG diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c index f6abeeaeaf42..ec1d109ae7a2 100644 --- a/drivers/scsi/qlogicfas.c +++ b/drivers/scsi/qlogicfas.c @@ -136,17 +136,19 @@ #include <linux/kernel.h> #include <linux/string.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/ioport.h> -#include <linux/sched.h> #include <linux/proc_fs.h> #include <linux/unistd.h> #include <linux/spinlock.h> +#include <linux/stat.h> + #include <asm/io.h> #include <asm/irq.h> + #include "scsi.h" #include "hosts.h" #include "qlogicfas.h" -#include <linux/stat.h> /*----------------------------------------------------------------*/ /* driver state info, local to driver */ diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 524557766a1e..8d195b1c6e84 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -88,22 +88,24 @@ */ #include <linux/module.h> - -#include <asm/io.h> -#include <asm/system.h> +#include <linux/interrupt.h> #include <linux/spinlock.h> #include <linux/signal.h> -#include <linux/sched.h> #include <linux/string.h> #include <linux/proc_fs.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/blk.h> +#include <linux/stat.h> + +#include <asm/io.h> +#include <asm/system.h> +#include <asm/uaccess.h> + #include "scsi.h" #include "hosts.h" #include "seagate.h" -#include <linux/stat.h> -#include <asm/uaccess.h> + #include <scsi/scsi_ioctl.h> #ifdef DEBUG diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index 90512cb1250f..233eb0f59ae1 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -393,7 +393,7 @@ MODULE_AUTHOR("Dario Ballabio"); #endif #include <linux/string.h> -#include <linux/sched.h> +#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/delay.h> @@ -402,11 +402,6 @@ MODULE_AUTHOR("Dario Ballabio"); #include <asm/byteorder.h> #include <linux/proc_fs.h> #include <linux/blk.h> -#include "scsi.h" -#include "hosts.h" -#include <asm/dma.h> -#include <asm/irq.h> -#include "u14-34f.h" #include <linux/stat.h> #include <linux/config.h> #include <linux/pci.h> @@ -415,6 +410,13 @@ MODULE_AUTHOR("Dario Ballabio"); #include <linux/spinlock.h> #include <scsi/scsicam.h> +#include <asm/dma.h> +#include <asm/irq.h> + +#include "scsi.h" +#include "hosts.h" +#include "u14-34f.h" + #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD) #error "Adjust your <asm/byteorder.h> defines" #endif diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index 970cd28ada0b..f081216dd914 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c @@ -128,25 +128,25 @@ */ #include <linux/module.h> - +#include <linux/blk.h> +#include <linux/interrupt.h> #include <linux/stddef.h> #include <linux/string.h> -#include <linux/sched.h> #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/proc_fs.h> #include <linux/spinlock.h> +#include <linux/stat.h> + #include <asm/io.h> #include <asm/bitops.h> #include <asm/system.h> #include <asm/dma.h> #define ULTRASTOR_PRIVATE /* Get the private stuff from ultrastor.h */ -#include <linux/blk.h> #include "scsi.h" #include "hosts.h" #include "ultrastor.h" -#include<linux/stat.h> #define FALSE 0 #define TRUE 1 diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index e7ac9a833730..01bedce1f4b1 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -161,24 +161,25 @@ */ #include <linux/module.h> - -#include <stdarg.h> +#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> -#include <linux/sched.h> #include <linux/slab.h> #include <linux/spinlock.h> -#include <asm/system.h> -#include <asm/dma.h> -#include <asm/io.h> #include <linux/ioport.h> #include <linux/proc_fs.h> #include <linux/blk.h> #include <linux/version.h> #include <linux/init.h> + +#include <asm/system.h> +#include <asm/dma.h> +#include <asm/io.h> + #include "scsi.h" #include "hosts.h" + #include <scsi/scsicam.h> #define ANY2SCSI_INLINE /* undef this to use old macros */ diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index cdc0c665c63a..3a3dfdc54e97 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -109,7 +109,8 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b interface->num_altsetting = 0; interface->max_altsetting = USB_ALTSETTINGALLOC; - interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL); + interface->altsetting = kmalloc(sizeof(*interface->altsetting) * interface->max_altsetting, + GFP_KERNEL); if (!interface->altsetting) { err("couldn't kmalloc interface->altsetting"); @@ -118,29 +119,27 @@ static int usb_parse_interface(struct usb_interface *interface, unsigned char *b while (size > 0) { struct usb_interface_descriptor *d; - + if (interface->num_altsetting >= interface->max_altsetting) { - void *ptr; + struct usb_host_interface *ptr; int oldmas; oldmas = interface->max_altsetting; interface->max_altsetting += USB_ALTSETTINGALLOC; if (interface->max_altsetting > USB_MAXALTSETTING) { - warn("too many alternate settings (max %d)", - USB_MAXALTSETTING); + warn("too many alternate settings (incr %d max %d)\n", + USB_ALTSETTINGALLOC, USB_MAXALTSETTING); return -1; } - ptr = interface->altsetting; - interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL); - if (!interface->altsetting) { + ptr = kmalloc(sizeof(*ptr) * interface->max_altsetting, GFP_KERNEL); + if (ptr == NULL) { err("couldn't kmalloc interface->altsetting"); - interface->altsetting = ptr; return -1; } - memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas); - - kfree(ptr); + memcpy(ptr, interface->altsetting, sizeof(*interface->altsetting) * oldmas); + kfree(interface->altsetting); + interface->altsetting = ptr; } ifp = interface->altsetting + interface->num_altsetting; diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index a7306cf26a35..ee5900f3969f 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -143,7 +143,7 @@ static int parse_options(struct super_block *s, char *data) /* --------------------------------------------------------------------- */ -static struct inode *usbfs_get_inode (struct super_block *sb, int mode, int dev) +static struct inode *usbfs_get_inode (struct super_block *sb, int mode, dev_t dev) { struct inode *inode = new_inode(sb); @@ -176,7 +176,7 @@ static struct inode *usbfs_get_inode (struct super_block *sb, int mode, int dev) /* SMP-safe */ static int usbfs_mknod (struct inode *dir, struct dentry *dentry, int mode, - int dev) + dev_t dev) { struct inode *inode = usbfs_get_inode(dir->i_sb, mode, dev); int error = -EPERM; diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 4b41945f2b6c..1f7138f93133 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c @@ -1,6 +1,7 @@ /* * USB ViCam WebCam driver - * Copyright (c) 2002 Joe Burks (jburks@wavicle.org) + * Copyright (c) 2002 Joe Burks (jburks@wavicle.org), + * John Tyner (fill in email address) * * Supports 3COM HomeConnect PC Digital WebCam * @@ -43,14 +44,6 @@ // #define VICAM_DEBUG -#ifndef MODULE_LICENSE -#define MODULE_LICENSE(a) -#endif - -#ifndef bool -#define bool int -#endif - #ifdef VICAM_DEBUG #define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __FUNCTION__, lineno, ##args) #define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args) @@ -403,26 +396,27 @@ static void rvfree(void *mem, unsigned long size) } vfree(mem); } - + struct vicam_camera { u16 shutter_speed; // capture shutter speed u16 gain; // capture gain u8 *raw_image; // raw data captured from the camera u8 *framebuf; // processed data in RGB24 format + u8 *cntrlbuf; // area used to send control msgs struct video_device vdev; // v4l video device struct usb_device *udev; // usb device struct semaphore busy_lock; // guard against SMP multithreading - bool is_initialized; + int is_initialized; u8 open_count; u8 bulkEndpoint; - bool needsDummyRead; + int needsDummyRead; -#ifdef CONFIG_PROC_FS - struct proc_dir_entry *proc_entry; +#if defined(CONFIG_VIDEO_PROC_FS) + struct proc_dir_entry *proc_dir; #endif }; @@ -437,22 +431,16 @@ send_control_msg(struct usb_device *udev, u8 request, u16 value, u16 index, { int status; - // for reasons not yet known to me, you can't send USB control messages - // with data in the module (if you are compiled as a module). Whatever - // the reason, copying it to memory allocated as kernel memory then - // doing the usb control message fixes the problem. - - unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL); - memcpy(transfer_buffer, cp, size); + /* cp must be memory that has been allocated by kmalloc */ status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, - transfer_buffer, size, HZ); + cp, size, HZ); - kfree(transfer_buffer); + status = min(status, 0); if (status < 0) { printk(KERN_INFO "Failed sending control message, error %d.\n", @@ -465,29 +453,30 @@ send_control_msg(struct usb_device *udev, u8 request, u16 value, u16 index, static int initialize_camera(struct vicam_camera *cam) { + const struct { + u8 *data; + u32 size; + } firmware[] = { + { .data = setup1, .size = sizeof(setup1) }, + { .data = setup2, .size = sizeof(setup2) }, + { .data = setup3, .size = sizeof(setup3) }, + { .data = setup4, .size = sizeof(setup4) }, + { .data = setup5, .size = sizeof(setup5) }, + { .data = setup3, .size = sizeof(setup3) }, + { .data = NULL, .size = 0 } + }; + struct usb_device *udev = cam->udev; - int status; + int err, i; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup1, sizeof (setup1))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup2, sizeof (setup2))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup3, sizeof (setup3))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup4, sizeof (setup4))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup5, sizeof (setup5))) < 0) - return status; - if ((status = - send_control_msg(udev, 0xff, 0, 0, setup3, sizeof (setup3))) < 0) - return status; + for (i = 0, err = 0; firmware[i].data && !err; i++) { + memcpy(cam->cntrlbuf, firmware[i].data, firmware[i].size); - return 0; + err = send_control_msg(udev, 0xff, 0, 0, + cam->cntrlbuf, firmware[i].size); + } + + return err; } static int @@ -752,7 +741,8 @@ vicam_open(struct inode *inode, struct file *file) "vicam video_device improperly initialized"); } - down_interruptible(&cam->busy_lock); + if ( down_interruptible(&cam->busy_lock) ) + return -EINTR; if (cam->open_count > 0) { printk(KERN_INFO @@ -774,6 +764,14 @@ vicam_open(struct inode *inode, struct file *file) return -ENOMEM; } + cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!cam->cntrlbuf) { + kfree(cam->raw_image); + rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); + up(&cam->busy_lock); + return -ENOMEM; + } + // First upload firmware, then turn the camera on if (!cam->is_initialized) { @@ -803,6 +801,7 @@ vicam_close(struct inode *inode, struct file *file) kfree(cam->raw_image); rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); + kfree(cam->cntrlbuf); cam->open_count--; @@ -831,7 +830,7 @@ inline void writepixel(char *rgb, int Y, int Cr, int Cb) // Copyright (C) 2002 Monroe Williams (monroe@pobox.com) // -------------------------------------------------------------------------------- -void vicam_decode_color( char *data, char *rgb) +static void vicam_decode_color( char *data, char *rgb) { int x,y; int Cr, Cb; @@ -915,7 +914,7 @@ void vicam_decode_color( char *data, char *rgb) static void read_frame(struct vicam_camera *cam, int framenum) { - unsigned char request[16]; + unsigned char *request = cam->cntrlbuf; int realShutter; int n; int actual_length; @@ -984,7 +983,8 @@ vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos ) DBG("read %d bytes.\n", (int) count); - down_interruptible(&cam->busy_lock); + if ( down_interruptible(&cam->busy_lock) ) + return -EINTR; if (*ppos >= VICAM_MAX_FRAME_SIZE) { *ppos = 0; @@ -1057,24 +1057,17 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -#ifdef CONFIG_PROC_FS +#if defined(CONFIG_VIDEO_PROC_FS) static struct proc_dir_entry *vicam_proc_root = NULL; -static int -vicam_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int vicam_read_helper(char *page, char **start, off_t off, + int count, int *eof, int value) { char *out = page; int len; - struct vicam_camera *cam = (struct vicam_camera *) data; - out += - sprintf(out, "Vicam-based WebCam Linux Driver.\n"); - out += sprintf(out, "(c) 2002 Joe Burks (jburks@wavicle.org)\n"); - out += sprintf(out, "vicam stats:\n"); - out += sprintf(out, " Shutter Speed: 1/%d\n", cam->shutter_speed); - out += sprintf(out, " Gain: %d\n", cam->gain); + out += sprintf(out, "%d",value); len = out - page; len -= off; @@ -1089,38 +1082,43 @@ vicam_read_proc(char *page, char **start, off_t off, return len; } -static int -vicam_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) +static int vicam_read_proc_shutter(char *page, char **start, off_t off, + int count, int *eof, void *data) { - char *in; - char *start; - struct vicam_camera *cam = (struct vicam_camera *) data; - - in = kmalloc(count + 1, GFP_KERNEL); - if (!in) - return -ENOMEM; + return vicam_read_helper(page,start,off,count,eof, + ((struct vicam_camera *)data)->shutter_speed); +} - in[count] = 0; // I'm not sure buffer is gauranteed to be null terminated - // so I do this to make sure I have a null in there. +static int vicam_read_proc_gain(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + return vicam_read_helper(page,start,off,count,eof, + ((struct vicam_camera *)data)->gain); +} - strncpy(in, buffer, count); +static int vicam_write_proc_shutter(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct vicam_camera *cam = (struct vicam_camera *)data; + + cam->shutter_speed = simple_strtoul(buffer, NULL, 10); - start = strstr(in, "gain="); - if (start - && (start == in || *(start - 1) == ' ' || *(start - 1) == ',')) - cam->gain = simple_strtoul(start + 5, NULL, 10); + return count; +} - start = strstr(in, "shutter="); - if (start - && (start == in || *(start - 1) == ' ' || *(start - 1) == ',')) - cam->shutter_speed = simple_strtoul(start + 8, NULL, 10); +static int vicam_write_proc_gain(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + struct vicam_camera *cam = (struct vicam_camera *)data; + + cam->gain = simple_strtoul(buffer, NULL, 10); - kfree(in); return count; } -void + + +static void vicam_create_proc_root(void) { vicam_proc_root = create_proc_entry("video/vicam", S_IFDIR, 0); @@ -1132,19 +1130,17 @@ vicam_create_proc_root(void) "could not create /proc entry for vicam!"); } -void +static void vicam_destroy_proc_root(void) { if (vicam_proc_root) remove_proc_entry("video/vicam", 0); } -void -vicam_create_proc_entry(void *ptr) +static void +vicam_create_proc_entry(struct vicam_camera *cam) { - struct vicam_camera *cam = (struct vicam_camera *) ptr; - - char name[7]; + char name[64]; struct proc_dir_entry *ent; DBG(KERN_INFO "vicam: creating proc entry\n"); @@ -1158,46 +1154,54 @@ vicam_create_proc_entry(void *ptr) sprintf(name, "video%d", cam->vdev.minor); + cam->proc_dir = create_proc_entry(name, S_IFDIR, vicam_proc_root); + + if ( !cam->proc_dir ) return; // We should probably return an error here + ent = - create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, - vicam_proc_root); - if (!ent) - return; + create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR, + cam->proc_dir); + if (ent) { + ent->data = cam; + ent->read_proc = vicam_read_proc_shutter; + ent->write_proc = vicam_write_proc_shutter; + ent->size = 64; + } - ent->data = cam; - ent->read_proc = vicam_read_proc; - ent->write_proc = vicam_write_proc; - ent->size = 512; - cam->proc_entry = ent; + ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR, + cam->proc_dir); + if ( ent ) { + ent->data = cam; + ent->read_proc = vicam_read_proc_gain; + ent->write_proc = vicam_write_proc_gain; + ent->size = 64; + } } -void +static void vicam_destroy_proc_entry(void *ptr) { struct vicam_camera *cam = (struct vicam_camera *) ptr; - char name[7]; + char name[16]; - if (!cam || !cam->proc_entry) + if ( !cam->proc_dir ) return; sprintf(name, "video%d", cam->vdev.minor); - remove_proc_entry(name, vicam_proc_root); - cam->proc_entry = NULL; + remove_proc_entry("shutter", cam->proc_dir); + remove_proc_entry("gain", cam->proc_dir); + remove_proc_entry(name,vicam_proc_root); + cam->proc_dir = NULL; } +#else +static inline void vicam_create_proc_root(void) { } +static inline void vicam_destroy_proc_root(void) { } +static inline void vicam_create_proc_entry(struct vicam_camera *cam) { } +static inline void vicam_destroy_proc_entry(void *ptr) { } #endif -int -vicam_video_init(struct video_device *vdev) -{ - // This would normally create the proc entry for this camera -#ifdef CONFIG_PROC_FS - vicam_create_proc_entry(vdev->priv); -#endif - return 0; -} - static struct file_operations vicam_fops = { .owner = THIS_MODULE, .open = vicam_open, @@ -1296,6 +1300,8 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) return -EIO; } + vicam_create_proc_entry(cam); + printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor); dev_set_drvdata(&intf->dev, cam); @@ -1314,9 +1320,7 @@ vicam_disconnect(struct usb_interface *intf) video_unregister_device(&cam->vdev); -#ifdef CONFIG_PROC_FS vicam_destroy_proc_entry(cam); -#endif kfree(cam); @@ -1329,9 +1333,7 @@ static int __init usb_vicam_init(void) { DBG(KERN_INFO "ViCam-based WebCam driver startup\n"); -#ifdef CONFIG_PROC_FS vicam_create_proc_root(); -#endif if (usb_register(&vicam_driver) != 0) printk(KERN_WARNING "usb_register failed!\n"); return 0; @@ -1344,9 +1346,7 @@ usb_vicam_exit(void) "ViCam-based WebCam driver shutdown\n"); usb_deregister(&vicam_driver); -#ifdef CONFIG_PROC_FS vicam_destroy_proc_root(); -#endif } module_init(usb_vicam_init); diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 34ed89241550..94ec69af89f1 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -28,7 +28,6 @@ * is out of the interrupt routine. */ - #include <linux/sched.h> #include <linux/slab.h> #include <linux/init.h> @@ -46,7 +45,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.5.6 (2002/06/23)" +#define DRIVER_VERSION "v0.5.7 (2002/11/18)" #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" @@ -119,16 +118,9 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, void *data) { int ret; - unsigned char *buffer; + unsigned char buffer[256]; DECLARE_WAITQUEUE(wait, current); - buffer = kmalloc(size, GFP_KERNEL); - if (!buffer) { - err("unable to allocate memory for configuration descriptors"); - return 0; - } - memcpy(buffer, data, size); - add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); while (pegasus->flags & ETH_REGS_CHANGED) @@ -144,9 +136,9 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, pegasus->ctrl_urb->transfer_buffer_length = size; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, - usb_rcvctrlpipe(pegasus->usb, 0), - (char *) &pegasus->dr, - buffer, size, ctrl_callback, pegasus); + usb_rcvctrlpipe(pegasus->usb, 0), + (char *) &pegasus->dr, + buffer, size, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -161,7 +153,6 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, out: remove_wait_queue(&pegasus->ctrl_wait, &wait); memcpy(data, buffer, size); - kfree(buffer); return ret; } @@ -170,14 +161,9 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, void *data) { int ret; - unsigned char *buffer; + unsigned char buffer[256]; DECLARE_WAITQUEUE(wait, current); - buffer = kmalloc(size, GFP_KERNEL); - if (!buffer) { - err("unable to allocate memory for configuration descriptors"); - return 0; - } memcpy(buffer, data, size); add_wait_queue(&pegasus->ctrl_wait, &wait); @@ -195,9 +181,9 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, pegasus->ctrl_urb->transfer_buffer_length = size; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, - usb_sndctrlpipe(pegasus->usb, 0), - (char *) &pegasus->dr, - buffer, size, ctrl_callback, pegasus); + usb_sndctrlpipe(pegasus->usb, 0), + (char *) &pegasus->dr, + buffer, size, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -210,7 +196,6 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, schedule(); out: remove_wait_queue(&pegasus->ctrl_wait, &wait); - kfree(buffer); return ret; } @@ -218,17 +203,9 @@ out: static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) { int ret; - unsigned char *buffer; - __u16 dat = data; + __u16 tmp = data; DECLARE_WAITQUEUE(wait, current); - buffer = kmalloc(1, GFP_KERNEL); - if (!buffer) { - err("unable to allocate memory for configuration descriptors"); - return 0; - } - memcpy(buffer, &data, 1); - add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); while (pegasus->flags & ETH_REGS_CHANGED) @@ -238,15 +215,15 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) pegasus->dr.bRequestType = PEGASUS_REQT_WRITE; pegasus->dr.bRequest = PEGASUS_REQ_SET_REG; - pegasus->dr.wValue = cpu_to_le16p(&dat); + pegasus->dr.wValue = cpu_to_le16p(&tmp); pegasus->dr.wIndex = cpu_to_le16p(&indx); pegasus->dr.wLength = cpu_to_le16(1); pegasus->ctrl_urb->transfer_buffer_length = 1; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, - usb_sndctrlpipe(pegasus->usb, 0), - (char *) &pegasus->dr, - buffer, 1, ctrl_callback, pegasus); + usb_sndctrlpipe(pegasus->usb, 0), + (char *) &pegasus->dr, + &data, 1, ctrl_callback, pegasus); add_wait_queue(&pegasus->ctrl_wait, &wait); set_current_state(TASK_UNINTERRUPTIBLE); @@ -259,7 +236,6 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) schedule(); out: remove_wait_queue(&pegasus->ctrl_wait, &wait); - kfree(buffer); return ret; } @@ -276,9 +252,9 @@ static int update_eth_regs_async(pegasus_t * pegasus) pegasus->ctrl_urb->transfer_buffer_length = 3; usb_fill_control_urb(pegasus->ctrl_urb, pegasus->usb, - usb_sndctrlpipe(pegasus->usb, 0), - (char *) &pegasus->dr, - pegasus->eth_regs, 3, ctrl_callback, pegasus); + usb_sndctrlpipe(pegasus->usb, 0), + (char *) &pegasus->dr, + pegasus->eth_regs, 3, ctrl_callback, pegasus); if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) err("%s: BAD CTRL %d, flgs %x", __FUNCTION__, ret, @@ -294,7 +270,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) __u16 regdi; set_register(pegasus, PhyCtrl, 0); - set_registers(pegasus, PhyAddr, sizeof(data), data); + set_registers(pegasus, PhyAddr, sizeof (data), data); set_register(pegasus, PhyCtrl, (indx | PHY_READ)); for (i = 0; i < REG_TIMEOUT; i++) { get_registers(pegasus, PhyCtrl, 1, data); @@ -311,6 +287,15 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) return 1; } +static int mdio_read(struct net_device *dev, int phy_id, int loc) +{ + pegasus_t *pegasus = (pegasus_t *) dev->priv; + int res; + + read_mii_word(pegasus, phy_id, loc, (u16 *) & res); + return res & 0xffff; +} + static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) { int i; @@ -332,6 +317,13 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) return 1; } +static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) +{ + pegasus_t *pegasus = (pegasus_t *) dev->priv; + + write_mii_word(pegasus, phy_id, loc, val); +} + static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) { int i; @@ -415,8 +407,8 @@ static void set_ethernet_addr(pegasus_t * pegasus) __u8 node_id[6]; get_node_id(pegasus, node_id); - set_registers(pegasus, EthID, sizeof(node_id), node_id); - memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id)); + set_registers(pegasus, EthID, sizeof (node_id), node_id); + memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); } static inline int reset_mac(pegasus_t * pegasus) @@ -473,7 +465,7 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) data[1] = 0; data[2] = (loopback & 1) ? 0x09 : 0x01; - memcpy(pegasus->eth_regs, data, sizeof(data)); + memcpy(pegasus->eth_regs, data, sizeof (data)); set_registers(pegasus, EthCtrl0, 3, data); if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS || @@ -486,18 +478,18 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) return 0; } -static void fill_skb_pool(pegasus_t *pegasus) +static void fill_skb_pool(pegasus_t * pegasus) { int i; - for (i=0; i < RX_SKBS; i++) { + for (i = 0; i < RX_SKBS; i++) { if (pegasus->rx_pool[i]) continue; pegasus->rx_pool[i] = dev_alloc_skb(PEGASUS_MTU + 2); /* - ** we give up if the allocation fail. the tasklet will be - ** rescheduled again anyway... - */ + ** we give up if the allocation fail. the tasklet will be + ** rescheduled again anyway... + */ if (pegasus->rx_pool[i] == NULL) return; pegasus->rx_pool[i]->dev = pegasus->net; @@ -505,11 +497,11 @@ static void fill_skb_pool(pegasus_t *pegasus) } } -static void free_skb_pool(pegasus_t *pegasus) +static void free_skb_pool(pegasus_t * pegasus) { int i; - for (i=0; i < RX_SKBS; i++) { + for (i = 0; i < RX_SKBS; i++) { if (pegasus->rx_pool[i]) { dev_kfree_skb(pegasus->rx_pool[i]); pegasus->rx_pool[i] = NULL; @@ -517,12 +509,12 @@ static void free_skb_pool(pegasus_t *pegasus) } } -static inline struct sk_buff *pull_skb(pegasus_t *pegasus) +static inline struct sk_buff *pull_skb(pegasus_t * pegasus) { int i; struct sk_buff *skb; - for (i=0; i < RX_SKBS; i++) { + for (i = 0; i < RX_SKBS; i++) { if (likely(pegasus->rx_pool[i] != NULL)) { skb = pegasus->rx_pool[i]; pegasus->rx_pool[i] = NULL; @@ -563,7 +555,7 @@ static void read_bulk_callback(struct urb *urb) if (!count) goto goon; - rx_status = le32_to_cpu(*(int *)(urb->transfer_buffer + count - 4)); + rx_status = le32_to_cpu(*(int *) (urb->transfer_buffer + count - 4)); if (rx_status & 0x000e0000) { dbg("%s: RX packet error %x", net->name, rx_status & 0xe0000); pegasus->stats.rx_errors++; @@ -575,20 +567,24 @@ static void read_bulk_callback(struct urb *urb) pegasus->stats.rx_frame_errors++; goto goon; } - pkt_len = (rx_status & 0xfff) - 8; + if (pegasus->chip == 0x8513) { + pkt_len = le32_to_cpu(*(int *)urb->transfer_buffer); + pkt_len &= 0x0fff; + pegasus->rx_skb->data += 2; + } else { + pkt_len = (rx_status & 0xfff) - 8; + } - if (pegasus->rx_skb == NULL) - printk("%s: rx_skb == NULL\n", __FUNCTION__); /* - ** we are sure at this point pegasus->rx_skb != NULL - ** so we go ahead and pass up the packet. - */ + * at this point we are sure pegasus->rx_skb != NULL + * so we go ahead and pass up the packet. + */ skb_put(pegasus->rx_skb, pkt_len); pegasus->rx_skb->protocol = eth_type_trans(pegasus->rx_skb, net); netif_rx(pegasus->rx_skb); pegasus->stats.rx_packets++; pegasus->stats.rx_bytes += pkt_len; - + spin_lock(&pegasus->rx_pool_lock); pegasus->rx_skb = pull_skb(pegasus); spin_unlock(&pegasus->rx_pool_lock); @@ -597,19 +593,19 @@ static void read_bulk_callback(struct urb *urb) goto tl_sched; goon: usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, - read_bulk_callback, pegasus); + usb_rcvbulkpipe(pegasus->usb, 1), + pegasus->rx_skb->data, PEGASUS_MTU + 8, + read_bulk_callback, pegasus); if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { pegasus->flags |= PEGASUS_RX_URB_FAIL; goto tl_sched; } else { pegasus->flags &= ~PEGASUS_RX_URB_FAIL; } - + return; - -tl_sched: + + tl_sched: tasklet_schedule(&pegasus->rx_tl); } @@ -617,7 +613,7 @@ static void rx_fixup(unsigned long data) { pegasus_t *pegasus; - pegasus = (pegasus_t *)data; + pegasus = (pegasus_t *) data; spin_lock_irq(&pegasus->rx_pool_lock); fill_skb_pool(pegasus); @@ -636,9 +632,9 @@ static void rx_fixup(unsigned long data) return; } usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, - read_bulk_callback, pegasus); + usb_rcvbulkpipe(pegasus->usb, 1), + pegasus->rx_skb->data, PEGASUS_MTU + 8, + read_bulk_callback, pegasus); try_again: if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { pegasus->flags |= PEGASUS_RX_URB_FAIL; @@ -704,10 +700,9 @@ static void intr_callback(struct urb *urb) } } - status = usb_submit_urb (urb, SLAB_ATOMIC); + status = usb_submit_urb(urb, SLAB_ATOMIC); if (status) - err ("%s: can't resubmit interrupt urb, %d", - net->name, status); + err("%s: can't resubmit interrupt urb, %d", net->name, status); } static void pegasus_tx_timeout(struct net_device *net) @@ -735,9 +730,9 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net) ((__u16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16); memcpy(pegasus->tx_buff + 2, skb->data, skb->len); usb_fill_bulk_urb(pegasus->tx_urb, pegasus->usb, - usb_sndbulkpipe(pegasus->usb, 2), - pegasus->tx_buff, count, - write_bulk_callback, pegasus); + usb_sndbulkpipe(pegasus->usb, 2), + pegasus->tx_buff, count, + write_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) { warn("failed tx_urb %d", res); pegasus->stats.tx_errors++; @@ -794,7 +789,7 @@ static void set_carrier(struct net_device *net) } -static void free_all_urbs(pegasus_t *pegasus) +static void free_all_urbs(pegasus_t * pegasus) { usb_free_urb(pegasus->intr_urb); usb_free_urb(pegasus->tx_urb); @@ -802,7 +797,7 @@ static void free_all_urbs(pegasus_t *pegasus) usb_free_urb(pegasus->ctrl_urb); } -static void unlink_all_urbs(pegasus_t *pegasus) +static void unlink_all_urbs(pegasus_t * pegasus) { usb_unlink_urb(pegasus->intr_urb); usb_unlink_urb(pegasus->tx_urb); @@ -810,7 +805,7 @@ static void unlink_all_urbs(pegasus_t *pegasus) usb_unlink_urb(pegasus->ctrl_urb); } -static int alloc_urbs(pegasus_t *pegasus) +static int alloc_urbs(pegasus_t * pegasus) { pegasus->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); if (!pegasus->ctrl_urb) { @@ -846,22 +841,22 @@ static int pegasus_open(struct net_device *net) if (pegasus->rx_skb == NULL) pegasus->rx_skb = pull_skb(pegasus); /* - ** Note: no point to free the pool. it is empty :-) - */ + ** Note: no point to free the pool. it is empty :-) + */ if (!pegasus->rx_skb) return -ENOMEM; down(&pegasus->sem); usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), - pegasus->rx_skb->data, PEGASUS_MTU + 8, - read_bulk_callback, pegasus); + usb_rcvbulkpipe(pegasus->usb, 1), + pegasus->rx_skb->data, PEGASUS_MTU + 8, + read_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) warn("%s: failed rx_urb %d", __FUNCTION__, res); usb_fill_int_urb(pegasus->intr_urb, pegasus->usb, - usb_rcvintpipe(pegasus->usb, 3), - pegasus->intr_buff, sizeof(pegasus->intr_buff), - intr_callback, pegasus, pegasus->intr_interval); + usb_rcvintpipe(pegasus->usb, 3), + pegasus->intr_buff, sizeof (pegasus->intr_buff), + intr_callback, pegasus, pegasus->intr_interval); if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) warn("%s: failed intr_urb %d", __FUNCTION__, res); netif_start_queue(net); @@ -896,7 +891,82 @@ static int pegasus_close(struct net_device *net) return 0; } +#ifdef CONFIG_MII +static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + pegasus_t *pegasus = dev->priv; + + if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) + return -EFAULT; + + switch (ethcmd) { + /* get driver-specific version/etc. info */ + case ETHTOOL_GDRVINFO:{ + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strncpy(info.driver, driver_name, + sizeof (info.driver) - 1); + strncpy(info.version, DRIVER_VERSION, + sizeof (info.version) - 1); + if (copy_to_user(useraddr, &info, sizeof (info))) + return -EFAULT; + return 0; + } + + /* get settings */ + case ETHTOOL_GSET:{ + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + mii_ethtool_gset(&pegasus->mii, &ecmd); + if (copy_to_user(useraddr, &ecmd, sizeof (ecmd))) + return -EFAULT; + return 0; + } + /* set settings */ + case ETHTOOL_SSET:{ + int r; + struct ethtool_cmd ecmd; + if (copy_from_user(&ecmd, useraddr, sizeof (ecmd))) + return -EFAULT; + r = mii_ethtool_sset(&pegasus->mii, &ecmd); + return r; + } + /* restart autonegotiation */ + case ETHTOOL_NWAY_RST:{ + return mii_nway_restart(&pegasus->mii); + } + + /* get link status */ + case ETHTOOL_GLINK:{ + struct ethtool_value edata = { ETHTOOL_GLINK }; + edata.data = mii_link_ok(&pegasus->mii); + if (copy_to_user(useraddr, &edata, sizeof (edata))) + return -EFAULT; + return 0; + } + /* get message-level */ + case ETHTOOL_GMSGLVL:{ + struct ethtool_value edata = { ETHTOOL_GMSGLVL }; + /* edata.data = pegasus->msg_enable; FIXME */ + if (copy_to_user(useraddr, &edata, sizeof (edata))) + return -EFAULT; + return 0; + } + /* set message-level */ + case ETHTOOL_SMSGLVL:{ + struct ethtool_value edata; + if (copy_from_user(&edata, useraddr, sizeof (edata))) + return -EFAULT; + /* sp->msg_enable = edata.data; FIXME */ + return 0; + } + + } + + return -EOPNOTSUPP; + +} +#else static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) { pegasus_t *pegasus; @@ -912,8 +982,8 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN); usb_make_path(pegasus->usb, info.bus_info, - sizeof info.bus_info); - if (copy_to_user(uaddr, &info, sizeof(info))) + sizeof info.bus_info); + if (copy_to_user(uaddr, &info, sizeof (info))) return -EFAULT; return 0; } @@ -950,7 +1020,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) ecmd.duplex = bmcr & BMCR_FULLDPLX ? DUPLEX_FULL : DUPLEX_HALF; } - if (copy_to_user(uaddr, &ecmd, sizeof(ecmd))) + if (copy_to_user(uaddr, &ecmd, sizeof (ecmd))) return -EFAULT; return 0; @@ -961,7 +1031,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) case ETHTOOL_GLINK:{ struct ethtool_value edata = { ETHTOOL_GLINK }; edata.data = netif_carrier_ok(net); - if (copy_to_user(uaddr, &edata, sizeof(edata))) + if (copy_to_user(uaddr, &edata, sizeof (edata))) return -EFAULT; return 0; } @@ -969,7 +1039,7 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr) return -EOPNOTSUPP; } } - +#endif static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd) { __u16 *data = (__u16 *) & rq->ifr_data; @@ -1045,8 +1115,26 @@ static __u8 mii_phy_probe(pegasus_t * pegasus) static inline void setup_pegasus_II(pegasus_t * pegasus) { + u16 data = 0xa5; + set_register(pegasus, Reg1d, 0); + set_register(pegasus, Reg7b, 1); + mdelay(100); set_register(pegasus, Reg7b, 2); + + set_register(pegasus, 0x83, data); + get_registers(pegasus, 0x83, 1, &data); + + if (data == 0xa5) { + pegasus->chip = 0x8513; + } else { + pegasus->chip = 0; + } + + set_register(pegasus, 0x80, 0xc0); + set_register(pegasus, 0x83, 0xff); + set_register(pegasus, 0x84, 0x01); + if (pegasus->features & HAS_HOME_PNA && mii_mode) set_register(pegasus, Reg81, 6); else @@ -1065,13 +1153,13 @@ static int pegasus_probe(struct usb_interface *intf, err("usb_set_configuration() failed"); return -ENODEV; } - if (!(pegasus = kmalloc(sizeof(struct pegasus), GFP_KERNEL))) { + if (!(pegasus = kmalloc(sizeof (struct pegasus), GFP_KERNEL))) { err("out of memory allocating device structure"); return -ENOMEM; } usb_get_dev(dev); - memset(pegasus, 0, sizeof(struct pegasus)); + memset(pegasus, 0, sizeof (struct pegasus)); pegasus->dev_index = dev_index; init_waitqueue_head(&pegasus->ctrl_wait); @@ -1088,8 +1176,8 @@ static int pegasus_probe(struct usb_interface *intf, } init_MUTEX(&pegasus->sem); - tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long)pegasus); - + tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); + down(&pegasus->sem); pegasus->usb = dev; pegasus->net = net; @@ -1104,6 +1192,11 @@ static int pegasus_probe(struct usb_interface *intf, net->set_multicast_list = pegasus_set_multicast; net->get_stats = pegasus_netdev_stats; net->mtu = PEGASUS_MTU; + pegasus->mii.dev = net; + pegasus->mii.mdio_read = mdio_read; + pegasus->mii.mdio_write = mdio_write; + pegasus->mii.phy_id_mask = 0x1f; + pegasus->mii.reg_num_mask = 0x1f; spin_lock_init(&pegasus->rx_pool_lock); pegasus->features = usb_dev_id[dev_index].private; @@ -1132,7 +1225,7 @@ static int pegasus_probe(struct usb_interface *intf, exit: up(&pegasus->sem); if (pegasus) { - dev_set_drvdata (&intf->dev, pegasus); + dev_set_drvdata(&intf->dev, pegasus); return 0; } return -EIO; @@ -1140,9 +1233,9 @@ exit: static void pegasus_disconnect(struct usb_interface *intf) { - struct pegasus *pegasus = dev_get_drvdata (&intf->dev); + struct pegasus *pegasus = dev_get_drvdata(&intf->dev); - dev_set_drvdata (&intf->dev, NULL); + dev_set_drvdata(&intf->dev, NULL); if (!pegasus) { warn("unregistering non-existant device"); return; @@ -1162,10 +1255,10 @@ static void pegasus_disconnect(struct usb_interface *intf) } static struct usb_driver pegasus_driver = { - .name = driver_name, - .probe = pegasus_probe, - .disconnect = pegasus_disconnect, - .id_table = pegasus_ids, + .name = driver_name, + .probe = pegasus_probe, + .disconnect = pegasus_disconnect, + .id_table = pegasus_ids, }; int __init pegasus_init(void) diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h index d7ec89f5d610..476cbeb92b97 100644 --- a/drivers/usb/net/pegasus.h +++ b/drivers/usb/net/pegasus.h @@ -85,6 +85,7 @@ typedef struct pegasus { struct usb_device *usb; struct net_device *net; struct net_device_stats stats; + struct mii_if_info mii; unsigned flags; unsigned features; int dev_index; @@ -97,6 +98,7 @@ typedef struct pegasus { wait_queue_head_t ctrl_wait; struct semaphore sem; spinlock_t rx_pool_lock; + int chip; unsigned char intr_buff[8]; __u8 tx_buff[PEGASUS_MTU]; __u8 eth_regs[4]; @@ -131,11 +133,11 @@ struct usb_eth_dev { #define VENDOR_LANEED 0x056e #define VENDOR_LINKSYS 0x066b #define VENDOR_MELCO 0x0411 +#define VENDOR_NETGEAR 0x0846 #define VENDOR_SMARTBRIDGES 0x08d1 #define VENDOR_SMC 0x0707 #define VENDOR_SOHOWARE 0x15e8 #define VENDOR_SIEMENS 0x067c -#define VENDOR_JTEC 0x11ad #else /* PEGASUS_DEV */ @@ -169,7 +171,10 @@ PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet", VENDOR_ADMTEK, 0x8511, DEFAULT_GPIO_RESET | PEGASUS_II ) -PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)", +PEGASUS_DEV( "ADMtek ADM8513 \"Pegasus II\" USB Ethernet", + VENDOR_ADMTEK, 0x8513, + DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (evaluation board)", VENDOR_ADMTEK, 0x0986, DEFAULT_GPIO_RESET | HAS_HOME_PNA ) PEGASUS_DEV( "AN986A USB MAC", VENDOR_ADMTEK, 1986, @@ -192,7 +197,7 @@ PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004, DEFAULT_GPIO_RESET ) -PEGASUS_DEV( "Corega FEter", VENDOR_COREGA, 0x000d, +PEGASUS_DEV( "Corega FEter USB-TXS", VENDOR_COREGA, 0x000d, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001, LINKSYS_GPIO_RESET ) @@ -246,6 +251,8 @@ PEGASUS_DEV( "MELCO/BUFFALO LUA-TX", VENDOR_MELCO, 0x0005, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009, DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "NETGEAR FA101", VENDOR_NETGEAR, 0x1020, + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200, @@ -258,8 +265,6 @@ PEGASUS_DEV( "SOHOware NUB110 Ethernet", VENDOR_SOHOWARE, 0x9110, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_SIEMENS, 0x1001, DEFAULT_GPIO_RESET | PEGASUS_II ) -PEGASUS_DEV( "FA8101 USB To ETHERNET", VENDOR_JTEC, 0x8101, - DEFAULT_GPIO_RESET | PEGASUS_II ) #endif /* PEGASUS_DEV */ diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 75510b41e8ab..1ee4eace260b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -14,6 +14,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (11/19/2002) gkh + * removed a few #ifdefs for the generic code and cleaned up the failure + * logic in initialization. + * * (10/02/2002) gkh * moved the console code to console.c and out of this file. * @@ -341,7 +345,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.6" +#define DRIVER_VERSION "v1.7" #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" #define DRIVER_DESC "USB Serial Driver core" @@ -382,7 +386,29 @@ static struct usb_device_id generic_serial_ids[] = { {.driver_info = 42}, {} }; -#endif + +static int generic_register (void) +{ + generic_device_ids[0].idVendor = vendor; + generic_device_ids[0].idProduct = product; + generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; + + /* register our generic driver with ourselves */ + return usb_serial_register (&generic_device); +} + +static void generic_deregister (void) +{ + /* remove our generic driver */ + usb_serial_deregister (&generic_device); +} + +#else + +static inline int generic_register (void) { return 0; } +static inline void generic_deregister (void) { } + +#endif /* CONFIG_USB_SERIAL_GENERIC */ /* Driver structure we register with the USB core */ static struct usb_driver usb_serial_driver = { @@ -409,7 +435,6 @@ static struct termios * serial_termios_locked[SERIAL_TTY_MINORS]; static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ static LIST_HEAD(usb_serial_driver_list); - struct usb_serial *usb_serial_get_by_minor (unsigned int minor) { return serial_table[minor]; @@ -839,7 +864,7 @@ static int serial_read_proc (char *page, char **start, off_t off, int count, int length += sprintf (page+length, "%d:", i); if (serial->type->owner) - length += sprintf (page+length, " module:%s", serial->type->owner->name); + length += sprintf (page+length, " module:%s", module_name(serial->type->owner)); length += sprintf (page+length, " name:\"%s\"", serial->type->name); length += sprintf (page+length, " vendor:%04x product:%04x", serial->vendor, serial->product); length += sprintf (page+length, " num_ports:%d", serial->num_ports); @@ -1574,40 +1599,49 @@ static struct tty_driver serial_tty_driver = { static int __init usb_serial_init(void) { int i; - int result; + int result = 0; /* Initalize our global data */ for (i = 0; i < SERIAL_TTY_MINORS; ++i) { serial_table[i] = NULL; } + /* register the generic driver, if we should */ + result = generic_register(); + if (result < 0) { + err("%s - registering generic driver failed", __FUNCTION__); + goto exit; + } + /* register the tty driver */ serial_tty_driver.init_termios = tty_std_termios; serial_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - if (tty_register_driver (&serial_tty_driver)) { - err("%s - failed to register tty driver", __FUNCTION__); - return -1; + result = tty_register_driver (&serial_tty_driver); + if (result) { + err("%s - tty_register_driver failed", __FUNCTION__); + goto exit_generic; } /* register the USB driver */ result = usb_register(&usb_serial_driver); if (result < 0) { - tty_unregister_driver(&serial_tty_driver); - err("usb_register failed for the usb-serial driver. Error number %d", result); - return -1; + err("%s - usb_register failed", __FUNCTION__); + goto exit_tty; } -#ifdef CONFIG_USB_SERIAL_GENERIC - generic_device_ids[0].idVendor = vendor; - generic_device_ids[0].idProduct = product; - generic_device_ids[0].match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT; - /* register our generic driver with ourselves */ - usb_serial_register (&generic_device); -#endif - info(DRIVER_DESC " " DRIVER_VERSION); - return 0; + return result; + +exit_tty: + tty_unregister_driver(&serial_tty_driver); + +exit_generic: + generic_deregister(); + +exit: + err ("%s - returning with error %d", __FUNCTION__, result); + return result; } @@ -1615,11 +1649,8 @@ static void __exit usb_serial_exit(void) { usb_serial_console_exit(); -#ifdef CONFIG_USB_SERIAL_GENERIC - /* remove our generic driver */ - usb_serial_deregister (&generic_device); -#endif - + generic_deregister(); + usb_deregister(&usb_serial_driver); tty_unregister_driver(&serial_tty_driver); } diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 32e9b512adc1..c58935a2e6b0 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -115,7 +115,7 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, freecom_udata_t extra = (freecom_udata_t) us->extra; struct freecom_xfer_wrap *fxfr = (struct freecom_xfer_wrap *) extra->buffer; - int result, partial; + int result; fxfr->Type = FCM_PACKET_INPUT | 0x00; fxfr->Timeout = 0; /* Short timeout for debugging. */ @@ -125,14 +125,12 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, US_DEBUGP("Read data Freecom! (c=%d)\n", count); /* Issue the transfer command. */ - result = usb_stor_bulk_msg (us, fxfr, opipe, - FCM_PACKET_LENGTH, &partial); + result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, + FCM_PACKET_LENGTH, NULL); if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("Freecom readdata xport failure: r=%d, p=%d\n", - result, partial); + US_DEBUGP ("Freecom readdata transport error\n"); return USB_STOR_TRANSPORT_ERROR; } - US_DEBUGP("Done issuing read request: %d %d\n", result, partial); /* Now transfer all of our blocks. */ US_DEBUGP("Start of read\n"); @@ -151,7 +149,7 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, freecom_udata_t extra = (freecom_udata_t) us->extra; struct freecom_xfer_wrap *fxfr = (struct freecom_xfer_wrap *) extra->buffer; - int result, partial; + int result; fxfr->Type = FCM_PACKET_OUTPUT | 0x00; fxfr->Timeout = 0; /* Short timeout for debugging. */ @@ -161,15 +159,12 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, US_DEBUGP("Write data Freecom! (c=%d)\n", count); /* Issue the transfer command. */ - result = usb_stor_bulk_msg (us, fxfr, opipe, - FCM_PACKET_LENGTH, &partial); + result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, + FCM_PACKET_LENGTH, NULL); if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("Freecom writedata xport failure: r=%d, p=%d\n", - result, partial); + US_DEBUGP ("Freecom writedata transport error\n"); return USB_STOR_TRANSPORT_ERROR; } - US_DEBUGP("Done issuing write request: %d %d\n", - result, partial); /* Now transfer all of our blocks. */ US_DEBUGP("Start of write\n"); @@ -191,7 +186,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) struct freecom_status *fst; unsigned int ipipe, opipe; /* We need both pipes. */ int result; - int partial; + unsigned int partial; int length; freecom_udata_t extra; @@ -215,23 +210,22 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) US_DEBUG(pdump (srb->cmnd, 12)); /* Send it out. */ - result = usb_stor_bulk_msg (us, fcb, opipe, - FCM_PACKET_LENGTH, &partial); + result = usb_stor_bulk_transfer_buf (us, opipe, fcb, + FCM_PACKET_LENGTH, NULL); /* The Freecom device will only fail if there is something wrong in * USB land. It returns the status in its own registers, which * come back in the bulk pipe. */ if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("freecom xport failure: r=%d, p=%d\n", - result, partial); + US_DEBUGP ("freecom transport error\n"); return USB_STOR_TRANSPORT_ERROR; } /* There are times we can optimize out this status read, but it * doesn't hurt us to always do it now. */ - result = usb_stor_bulk_msg (us, fst, ipipe, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); - US_DEBUGP("foo Status result %d %d\n", result, partial); + US_DEBUGP("foo Status result %d %u\n", result, partial); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -256,24 +250,23 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) memset (fcb->Filler, 0, sizeof (fcb->Filler)); /* Send it out. */ - result = usb_stor_bulk_msg (us, fcb, opipe, - FCM_PACKET_LENGTH, &partial); + result = usb_stor_bulk_transfer_buf (us, opipe, fcb, + FCM_PACKET_LENGTH, NULL); /* The Freecom device will only fail if there is something * wrong in USB land. It returns the status in its own * registers, which come back in the bulk pipe. */ if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("freecom xport failure: r=%d, p=%d\n", - result, partial); + US_DEBUGP ("freecom transport error\n"); return USB_STOR_TRANSPORT_ERROR; } /* get the data */ - result = usb_stor_bulk_msg (us, fst, ipipe, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); - US_DEBUGP("bar Status result %d %d\n", result, partial); + US_DEBUGP("bar Status result %d %u\n", result, partial); if (result > USB_STOR_XFER_SHORT) return USB_STOR_TRANSPORT_ERROR; @@ -328,7 +321,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) return result; US_DEBUGP("FCM: Waiting for status\n"); - result = usb_stor_bulk_msg (us, fst, ipipe, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); US_DEBUG(pdump ((void *) fst, partial)); @@ -354,7 +347,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) return result; US_DEBUGP("FCM: Waiting for status\n"); - result = usb_stor_bulk_msg (us, fst, ipipe, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); if (partial != 4 || result > USB_STOR_XFER_SHORT) @@ -385,13 +378,6 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) } return USB_STOR_TRANSPORT_GOOD; - - US_DEBUGP("Freecom: transfer_length = %d\n", - usb_stor_transfer_length (srb)); - - US_DEBUGP("Freecom: direction = %d\n", srb->sc_data_direction); - - return USB_STOR_TRANSPORT_ERROR; } int diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 32c5474b6585..a2ea1d931558 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -668,7 +668,7 @@ int isd200_write_config( struct us_data *us ) #endif /* let's send the command via the control pipe */ - result = usb_stor_control_msg( + result = usb_stor_ctrl_transfer( us, us->send_ctrl_pipe, 0x01, @@ -709,7 +709,7 @@ int isd200_read_config( struct us_data *us ) /* read the configuration information from ISD200. Use this to */ /* determine what the special ATA CDB bytes are. */ - result = usb_stor_control_msg( + result = usb_stor_ctrl_transfer( us, us->recv_ctrl_pipe, 0x02, diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index aefbefa07085..378cf03db154 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -479,7 +479,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, usb_stor_blocking_completion, NULL); status = usb_stor_msg_common(us); - /* return the actual length of the data transferred if no error*/ + /* return the actual length of the data transferred if no error */ if (status >= 0) status = us->current_urb->actual_length; return status; @@ -543,48 +543,92 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) return 0; } + /* - * Transfer one control message + * Interpret the results of a URB transfer * - * This function does basically the same thing as usb_stor_control_msg() - * above, except that return codes are USB_STOR_XFER_xxx rather than the - * urb status or transfer length. + * This function prints appropriate debugging messages, clears halts on + * bulk endpoints, and translates the status to the corresponding + * USB_STOR_XFER_xxx return code. */ -int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, - u8 request, u8 requesttype, u16 value, u16 index, - void *data, u16 size) { - int result; +static int interpret_urb_result(struct us_data *us, unsigned int pipe, + unsigned int length, int result, unsigned int partial) { - US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x " - "value=%04x index=%02x len=%d\n", - request, requesttype, value, index, size); - result = usb_stor_control_msg(us, pipe, request, requesttype, - value, index, data, size); - US_DEBUGP("usb_stor_control_msg returned %d\n", result); + US_DEBUGP("Status code %d; transferred %u/%u\n", + result, partial, length); - /* a stall indicates a protocol error */ + /* stalled */ if (result == -EPIPE) { - US_DEBUGP("-- stall on control pipe\n"); + + /* for non-bulk (i.e., control) endpoints, a stall indicates + * a protocol error */ + if (!usb_pipebulk(pipe)) { + US_DEBUGP("-- stall on control pipe\n"); + return USB_STOR_XFER_ERROR; + } + + /* for a bulk endpoint, clear the stall */ + US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); + if (usb_stor_clear_halt(us, pipe) < 0) + return USB_STOR_XFER_ERROR; + return USB_STOR_XFER_STALLED; + } + + /* NAK - that means we've retried this a few times already */ + if (result == -ETIMEDOUT) { + US_DEBUGP("-- device NAKed\n"); + return USB_STOR_XFER_ERROR; + } + + /* the transfer was cancelled, presumably by an abort */ + if (result == -ENODEV) { + US_DEBUGP("-- transfer cancelled\n"); return USB_STOR_XFER_ERROR; } - /* some other serious problem here */ + /* the catch-all error case */ if (result < 0) { US_DEBUGP("-- unknown error\n"); return USB_STOR_XFER_ERROR; } - /* was the entire command transferred? */ - if (result < size) { - US_DEBUGP("-- transferred only %d bytes\n", result); + /* no error code; did we send all the data? */ + if (partial != length) { + US_DEBUGP("-- transferred only %u bytes\n", partial); return USB_STOR_XFER_SHORT; } - US_DEBUGP("-- transfer completed successfully\n"); + US_DEBUGP("-- transfer complete\n"); return USB_STOR_XFER_GOOD; } /* + * Transfer one control message + * + * This function does basically the same thing as usb_stor_control_msg() + * above, except that return codes are USB_STOR_XFER_xxx rather than the + * urb status or transfer length. + */ +int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, + u8 request, u8 requesttype, u16 value, u16 index, + void *data, u16 size) { + int result; + unsigned int partial = 0; + + US_DEBUGP("usb_stor_ctrl_transfer(): rq=%02x rqtype=%02x " + "value=%04x index=%02x len=%u\n", + request, requesttype, value, index, size); + result = usb_stor_control_msg(us, pipe, request, requesttype, + value, index, data, size); + + if (result > 0) { /* Separate out the amount transferred */ + partial = result; + result = 0; + } + return interpret_urb_result(us, pipe, size, result, partial); +} + +/* * Transfer one buffer via bulk transfer * * This function does basically the same thing as usb_stor_bulk_msg() @@ -596,50 +640,17 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, * urb status or transfer length. */ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, - char *buf, unsigned int length, unsigned int *act_len) + void *buf, unsigned int length, unsigned int *act_len) { int result; - int partial; + unsigned int partial; /* transfer the data */ - US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %d bytes\n", length); + US_DEBUGP("usb_stor_bulk_transfer_buf(): xfer %u bytes\n", length); result = usb_stor_bulk_msg(us, buf, pipe, length, &partial); - US_DEBUGP("usb_stor_bulk_msg() returned %d xferred %d/%d\n", - result, partial, length); if (act_len) *act_len = partial; - - /* if we stall, we need to clear it before we go on */ - if (result == -EPIPE) { - US_DEBUGP("clearing endpoint halt for pipe 0x%x," - " stalled at %d bytes\n", pipe, partial); - if (usb_stor_clear_halt(us, pipe) < 0) - return USB_STOR_XFER_ERROR; - return USB_STOR_XFER_STALLED; - } - - /* NAK - that means we've retried a few times already */ - if (result == -ETIMEDOUT) { - US_DEBUGP("-- device NAKed\n"); - return USB_STOR_XFER_ERROR; - } - - /* the catch-all error case */ - if (result) { - US_DEBUGP("-- unknown error\n"); - return USB_STOR_XFER_ERROR; - } - - /* did we send all the data? */ - if (partial == length) { - US_DEBUGP("-- transfer complete\n"); - return USB_STOR_XFER_GOOD; - } - - /* no error code, so we must have transferred some data, - * just not all of it */ - US_DEBUGP("-- transferred only %d bytes\n", partial); - return USB_STOR_XFER_SHORT; + return interpret_urb_result(us, pipe, length, result, partial); } /* @@ -653,10 +664,10 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, unsigned int *act_len) { int result; - int partial; + unsigned int partial; /* initialize the scatter-gather request block */ - US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %d bytes, " + US_DEBUGP("usb_stor_bulk_transfer_sglist(): xfer %u bytes, " "%d entries\n", length, num_sg); result = usb_sg_init(us->current_sg, us->pusb_dev, pipe, 0, sg, num_sg, length, SLAB_NOIO); @@ -685,55 +696,22 @@ int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, result = us->current_sg->status; partial = us->current_sg->bytes; - US_DEBUGP("usb_sg_wait() returned %d xferred %d/%d\n", - result, partial, length); if (act_len) *act_len = partial; - - /* if we stall, we need to clear it before we go on */ - if (result == -EPIPE) { - US_DEBUGP("clearing endpoint halt for pipe 0x%x, " - "stalled at %d bytes\n", pipe, partial); - if (usb_stor_clear_halt(us, pipe) < 0) - return USB_STOR_XFER_ERROR; - return USB_STOR_XFER_STALLED; - } - - /* NAK - that means we've retried this a few times already */ - if (result == -ETIMEDOUT) { - US_DEBUGP("-- device NAKed\n"); - return USB_STOR_XFER_ERROR; - } - - /* the catch-all error case */ - if (result) { - US_DEBUGP("-- unknown error\n"); - return USB_STOR_XFER_ERROR; - } - - /* did we send all the data? */ - if (partial == length) { - US_DEBUGP("-- transfer complete\n"); - return USB_STOR_XFER_GOOD; - } - - /* no error code, so we must have transferred some data, - * just not all of it */ - US_DEBUGP("-- transferred only %d bytes\n", partial); - return USB_STOR_XFER_SHORT; + return interpret_urb_result(us, pipe, length, result, partial); } /* * Transfer an entire SCSI command's worth of data payload over the bulk * pipe. * - * Nore that this uses usb_stor_bulk_transfer_buf() and + * Note that this uses usb_stor_bulk_transfer_buf() and * usb_stor_bulk_transfer_sglist() to achieve its goals -- * this function simply determines whether we're going to use * scatter-gather or not, and acts appropriately. */ int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe, - char *buf, unsigned int length_left, int use_sg, int *residual) + void *buf, unsigned int length_left, int use_sg, int *residual) { int result; unsigned int partial; @@ -1278,7 +1256,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) (bcb.Lun >> 4), (bcb.Lun & 0x0F), le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length); result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, - (char *) &bcb, US_BULK_CB_WRAP_LEN, NULL); + &bcb, US_BULK_CB_WRAP_LEN, NULL); US_DEBUGP("Bulk command transfer result=%d\n", result); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -1302,7 +1280,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) /* get CSW for device status */ US_DEBUGP("Attempting to get CSW...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, - (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL); + &bcs, US_BULK_CS_WRAP_LEN, NULL); /* did the attempt to read the CSW fail? */ if (result == USB_STOR_XFER_STALLED) { @@ -1310,7 +1288,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) /* get the status again */ US_DEBUGP("Attempting to get CSW (2nd try)...\n"); result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, - (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL); + &bcs, US_BULK_CS_WRAP_LEN, NULL); } /* if we still have a failure at this point, we're in trouble */ diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index df787201daa2..a8ac7f3fbf8f 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -117,6 +117,7 @@ struct bulk_cs_wrap { /* * usb_stor_bulk_transfer_xxx() return codes, in order of severity */ + #define USB_STOR_XFER_GOOD 0 /* good transfer */ #define USB_STOR_XFER_SHORT 1 /* transfered less than expected */ #define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ @@ -129,7 +130,14 @@ struct bulk_cs_wrap { #define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */ #define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */ #define USB_STOR_TRANSPORT_ERROR 2 /* Transport bad (i.e. device dead) */ -#define USB_STOR_TRANSPORT_ABORTED 3 /* Transport aborted */ + +/* + * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED + * return codes. But now the transport and low-level transfer routines + * treat an abort as just another error (-ENOENT for a cancelled URB). + * It is up to the invoke_transport() function to test for aborts and + * distinguish them from genuine communication errors. + */ /* * CBI accept device specific command @@ -162,12 +170,12 @@ extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size); extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, - char *buf, unsigned int length, unsigned int *act_len); + void *buf, unsigned int length, unsigned int *act_len); extern int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, struct scatterlist *sg, int num_sg, unsigned int length, unsigned int *act_len); extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe, - char *buf, unsigned int length, int use_sg, int *residual); + void *buf, unsigned int length, int use_sg, int *residual); static __inline__ int usb_stor_bulk_transfer_srb(struct us_data *us, unsigned int pipe, Scsi_Cmnd *srb, unsigned int length) { diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 4f378704b4a8..a7952879bd8f 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -29,7 +29,7 @@ /* dir inode-ops */ static int coda_create(struct inode *dir, struct dentry *new, int mode); -static int coda_mknod(struct inode *dir, struct dentry *new, int mode, int rdev); +static int coda_mknod(struct inode *dir, struct dentry *new, int mode, dev_t rdev); static struct dentry *coda_lookup(struct inode *dir, struct dentry *target); static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, struct dentry *entry); @@ -230,7 +230,7 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode) return 0; } -static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev) +static int coda_mknod(struct inode *dir, struct dentry *de, int mode, dev_t rdev) { int error=0; const char *name=de->d_name.name; @@ -740,4 +740,3 @@ return_bad: unlock_kernel(); return -EIO; } - diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index 60de2eaee8af..221bfb88ed4a 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -310,8 +310,8 @@ int venus_rename(struct super_block *sb, struct ViceFid *old_fid, } int venus_create(struct super_block *sb, struct ViceFid *dirfid, - const char *name, int length, int excl, int mode, int rdev, - struct ViceFid *newfid, struct coda_vattr *attrs) + const char *name, int length, int excl, int mode, dev_t rdev, + struct ViceFid *newfid, struct coda_vattr *attrs) { union inputArgs *inp; union outputArgs *outp; diff --git a/fs/devfs/base.c b/fs/devfs/base.c index d54683b572ee..88c5aa160599 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -3103,7 +3103,7 @@ static int devfs_rmdir (struct inode *dir, struct dentry *dentry) } /* End Function devfs_rmdir */ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode, - int rdev) + dev_t rdev) { int err; struct fs_info *fs_info = dir->i_sb->s_fs_info; diff --git a/fs/devices.c b/fs/devices.c index 1b8f3e2546e3..adf05053eeb7 100644 --- a/fs/devices.c +++ b/fs/devices.c @@ -202,7 +202,7 @@ static struct file_operations bad_sock_fops = { .open = sock_no_open }; -void init_special_inode(struct inode *inode, umode_t mode, int rdev) +void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) { inode->i_mode = mode; if (S_ISCHR(mode)) { @@ -217,5 +217,6 @@ void init_special_inode(struct inode *inode, umode_t mode, int rdev) else if (S_ISSOCK(mode)) inode->i_fop = &bad_sock_fops; else - printk(KERN_DEBUG "init_special_inode: bogus imode (%o)\n", mode); + printk(KERN_DEBUG "init_special_inode: bogus imode (%o)\n", + mode); } diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 8e9e4069ad3b..9f0788e3f6ef 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -134,7 +134,7 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode) return err; } -static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) +static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { struct inode * inode = ext2_new_inode (dir, mode); int err = PTR_ERR(inode); diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 98ac54526a5d..e1abbb5552c0 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1616,7 +1616,7 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode) } static int ext3_mknod (struct inode * dir, struct dentry *dentry, - int mode, int rdev) + int mode, dev_t rdev) { handle_t *handle; struct inode *inode; diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 824d5785c7d8..34a2c5039cc3 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -282,7 +282,7 @@ void hpfs_decide_conv(struct inode *, unsigned char *, unsigned); int hpfs_mkdir(struct inode *, struct dentry *, int); int hpfs_create(struct inode *, struct dentry *, int); -int hpfs_mknod(struct inode *, struct dentry *, int, int); +int hpfs_mknod(struct inode *, struct dentry *, int, dev_t); int hpfs_symlink(struct inode *, struct dentry *, const char *); int hpfs_unlink(struct inode *, struct dentry *); int hpfs_rmdir(struct inode *, struct dentry *); diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index cc2857b95c46..1736980fd020 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -181,7 +181,7 @@ bail: return -ENOSPC; } -int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) +int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) { const char *name = dentry->d_name.name; unsigned len = dentry->d_name.len; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 16da9d0c9e75..2c9b1d26b8fd 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -359,7 +359,8 @@ out: return error; } -struct inode *hugetlbfs_get_inode(struct super_block *sb, int mode, int dev) +static struct inode * +hugetlbfs_get_inode(struct super_block *sb, int mode, dev_t dev) { struct inode * inode = new_inode(sb); @@ -399,7 +400,8 @@ struct inode *hugetlbfs_get_inode(struct super_block *sb, int mode, int dev) * File creation. Allocate an inode, and we're done.. */ /* SMP-safe */ -static int hugetlbfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) +static int +hugetlbfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { struct inode * inode = hugetlbfs_get_inode(dir->i_sb, mode, dev); int error = -ENOSPC; diff --git a/fs/intermezzo/dir.c b/fs/intermezzo/dir.c index b1205bf9c7bf..573c318e3138 100644 --- a/fs/intermezzo/dir.c +++ b/fs/intermezzo/dir.c @@ -720,7 +720,7 @@ static int presto_rmdir(struct inode *dir, struct dentry *dentry) return error; } -static int presto_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev) +static int presto_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev) { int error; struct presto_cache *cache; diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index 1349e6027ca0..1b0b9fa5070f 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c @@ -1072,7 +1072,7 @@ jffs_remove_end: static int -jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) +jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) { struct jffs_raw_inode raw_inode; struct jffs_file *dir_f; diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 68c34e81137b..9c60f565699a 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -32,7 +32,7 @@ static int jffs2_unlink (struct inode *,struct dentry *); static int jffs2_symlink (struct inode *,struct dentry *,const char *); static int jffs2_mkdir (struct inode *,struct dentry *,int); static int jffs2_rmdir (struct inode *,struct dentry *); -static int jffs2_mknod (struct inode *,struct dentry *,int,int); +static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t); static int jffs2_rename (struct inode *, struct dentry *, struct inode *, struct dentry *); @@ -573,7 +573,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) return ret; } -static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, int rdev) +static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, dev_t rdev) { struct jffs2_inode_info *f, *dir_f; struct jffs2_sb_info *c; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 9426deae5094..603c8f7d1322 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1316,7 +1316,7 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, * * FUNCTION: Create a special file (device) */ -int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) +int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) { struct btstack btstack; struct component_name dname; diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 01b2e3a2831a..d2b9ae264ce1 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -75,7 +75,7 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry) return NULL; } -static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev) +static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { int error; struct inode * inode = minix_new_inode(dir, &error); diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 959d512a82cc..58d2fbd70556 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -42,7 +42,7 @@ static int ncp_rmdir(struct inode *, struct dentry *); static int ncp_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); static int ncp_mknod(struct inode * dir, struct dentry *dentry, - int mode, int rdev); + int mode, dev_t rdev); #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) extern int ncp_symlink(struct inode *, struct dentry *, const char *); #else @@ -883,7 +883,7 @@ out_close: } int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode, - int rdev, int attributes) + dev_t rdev, int attributes) { struct ncp_server *server = NCP_SERVER(dir); struct ncp_entry_info finfo; @@ -1169,7 +1169,7 @@ out: } static int ncp_mknod(struct inode * dir, struct dentry *dentry, - int mode, int rdev) + int mode, dev_t rdev) { if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) { DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%o\n", mode); diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index b25803e23272..29c2ec683c77 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h @@ -117,7 +117,7 @@ int ncp_dirhandle_alloc(struct ncp_server *, __u8 vol, __u32 dirent, __u8 *dirha int ncp_dirhandle_free(struct ncp_server *, __u8 dirhandle); int ncp_create_new(struct inode *dir, struct dentry *dentry, - int mode, int rdev, int attributes); + int mode, dev_t rdev, int attributes); static inline int ncp_is_nfs_extras(struct ncp_server* server, unsigned int volnum) { #ifdef CONFIG_NCPFS_NFS_NS diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 8f7f90ba5f10..b7f9bf5eb32a 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -45,7 +45,7 @@ static int nfs_rmdir(struct inode *, struct dentry *); static int nfs_unlink(struct inode *, struct dentry *); static int nfs_symlink(struct inode *, struct dentry *, const char *); static int nfs_link(struct dentry *, struct inode *, struct dentry *); -static int nfs_mknod(struct inode *, struct dentry *, int, int); +static int nfs_mknod(struct inode *, struct dentry *, int, dev_t); static int nfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); @@ -801,7 +801,8 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode) /* * See comments for nfs_proc_create regarding failed operations. */ -static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) +static int +nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) { struct iattr attr; struct nfs_fattr fattr; diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index dea3cdd2bd1f..64b5c100cb91 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -47,7 +47,7 @@ static struct backing_dev_info ramfs_backing_dev_info = { .memory_backed = 1, /* Does not contribute to dirty memory */ }; -struct inode *ramfs_get_inode(struct super_block *sb, int mode, int dev) +static struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) { struct inode * inode = new_inode(sb); @@ -87,14 +87,15 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, int dev) * File creation. Allocate an inode, and we're done.. */ /* SMP-safe */ -static int ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) +static int +ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev); int error = -ENOSPC; if (inode) { d_instantiate(dentry, inode); - dget(dentry); /* Extra count - pin the dentry in core */ + dget(dentry); /* Extra count - pin the dentry in core */ error = 0; } return error; diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 7a5e99ce610a..c82566d48d2f 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -605,7 +605,7 @@ out_failed: } -static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) +static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { int retval; struct inode * inode; diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index c4793aa522de..b943f0052798 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -31,7 +31,7 @@ static int smb_rmdir(struct inode *, struct dentry *); static int smb_unlink(struct inode *, struct dentry *); static int smb_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -static int smb_make_node(struct inode *,struct dentry *,int,int); +static int smb_make_node(struct inode *,struct dentry *,int,dev_t); static int smb_link(struct dentry *, struct inode *, struct dentry *); struct file_operations smb_dir_operations = @@ -641,7 +641,7 @@ out: * matches the connection credentials (and we don't know which those are ...) */ static int -smb_make_node(struct inode *dir, struct dentry *dentry, int mode, int dev) +smb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { int error; struct iattr attr; diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 8d0c15af72d2..8612c9a3a4c1 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c @@ -89,7 +89,7 @@ static struct inode *sysfs_get_inode(struct super_block *sb, int mode, int dev) return inode; } -static int sysfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) +static int sysfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { struct inode *inode; int error = 0; diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 5a6c2246d251..f2988f107696 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -83,7 +83,7 @@ static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry) return NULL; } -static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev) +static int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev) { struct inode * inode = sysv_new_inode(dir, mode); int err = PTR_ERR(inode); diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 138b1c8e3deb..b5be4880deac 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -669,7 +669,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode) return 0; } -static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev) +static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t rdev) { struct inode * inode; struct udf_fileident_bh fibh; diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index b98fb35af72d..24c6c5d2938d 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -108,7 +108,7 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode) return err; } -static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) +static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) { struct inode * inode = ufs_new_inode(dir, mode); int err = PTR_ERR(inode); diff --git a/fs/umsdos/namei.c b/fs/umsdos/namei.c index 1ee0e1a35278..3d89ba970a06 100644 --- a/fs/umsdos/namei.c +++ b/fs/umsdos/namei.c @@ -237,7 +237,7 @@ static int umsdos_nevercreat (struct inode *dir, struct dentry *dentry, * The same is true for directory creation. */ static int umsdos_create_any (struct inode *dir, struct dentry *dentry, - int mode, int rdev, char flags) + int mode, dev_t rdev, char flags) { struct dentry *fake; struct inode *inode; @@ -861,7 +861,7 @@ out_remove: * in particular and other parts of the kernel I guess. */ int UMSDOS_mknod (struct inode *dir, struct dentry *dentry, - int mode, int rdev) + int mode, dev_t rdev) { return umsdos_create_any (dir, dentry, mode, rdev, 0); } diff --git a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c index b9bb91a68660..97f58864933d 100644 --- a/fs/xfs/linux/xfs_iops.c +++ b/fs/xfs/linux/xfs_iops.c @@ -69,7 +69,7 @@ linvfs_mknod( struct inode *dir, struct dentry *dentry, int mode, - int rdev) + dev_t rdev) { struct inode *ip; vattr_t va; diff --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h index e541fd274241..e9c091d591bf 100644 --- a/include/asm-ppc/atomic.h +++ b/include/asm-ppc/atomic.h @@ -17,8 +17,10 @@ typedef struct { volatile int counter; } atomic_t; extern void atomic_clear_mask(unsigned long mask, unsigned long *addr); #ifdef CONFIG_SMP +#define SMP_SYNC "sync" #define SMP_ISYNC "\n\tisync" #else +#define SMP_SYNC "" #define SMP_ISYNC #endif @@ -192,10 +194,11 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v) return t; } -#define smp_mb__before_atomic_dec() smp_mb() -#define smp_mb__after_atomic_dec() smp_mb() -#define smp_mb__before_atomic_inc() smp_mb() -#define smp_mb__after_atomic_inc() smp_mb() +#define __MB __asm__ __volatile__ (SMP_SYNC : : : "memory") +#define smp_mb__before_atomic_dec() __MB +#define smp_mb__after_atomic_dec() __MB +#define smp_mb__before_atomic_inc() __MB +#define smp_mb__after_atomic_inc() __MB #endif /* __KERNEL__ */ #endif /* _ASM_PPC_ATOMIC_H_ */ diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h index 3138ad56ec18..c96e72a0235e 100644 --- a/include/asm-ppc/hardirq.h +++ b/include/asm-ppc/hardirq.h @@ -3,7 +3,7 @@ #define __ASM_HARDIRQ_H #include <linux/config.h> -#include <asm/smp.h> +#include <linux/cache.h> /* The __last_jiffy_stamp field is needed to ensure that no decrementer * interrupt is lost on SMP machines. Since on most CPUs it is in the same diff --git a/include/asm-ppc/module.h b/include/asm-ppc/module.h index 43ddf7c6aaab..7d75a3e3e2ee 100644 --- a/include/asm-ppc/module.h +++ b/include/asm-ppc/module.h @@ -1,12 +1,33 @@ #ifndef _ASM_PPC_MODULE_H #define _ASM_PPC_MODULE_H -/* - * This file contains the PPC architecture specific module code. - */ - -#define module_map(x) vmalloc(x) -#define module_unmap(x) vfree(x) -#define module_arch_init(x) (0) -#define arch_init_modules(x) do { } while (0) +/* Module stuff for PPC. (C) 2001 Rusty Russell */ + +/* Thanks to Paul M for explaining this. + + PPC can only do rel jumps += 32MB, and often the kernel and other + modules are furthur away than this. So, we jump to a table of + trampolines attached to the module (the Procedure Linkage Table) + whenever that happens. +*/ + +struct ppc_plt_entry +{ + /* 16 byte jump instruction sequence (4 instructions) */ + unsigned int jump[4]; +}; + +struct mod_arch_specific +{ + /* How much of the core is actually taken up with core (then + we know the rest is for the PLT */ + unsigned int core_plt_offset; + + /* Same for init */ + unsigned int init_plt_offset; +}; + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr #endif /* _ASM_PPC_MODULE_H */ diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h index 07fcedee5912..4834d006adb6 100644 --- a/include/asm-ppc/page.h +++ b/include/asm-ppc/page.h @@ -14,19 +14,8 @@ #define KERNELBASE PAGE_OFFSET #ifndef __ASSEMBLY__ -#include <asm/system.h> /* for xmon definition */ +#include <asm/processor.h> /* for BUG definition */ -#ifdef CONFIG_XMON -#define BUG() do { \ - printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ - xmon(0); \ -} while (0) -#else -#define BUG() do { \ - printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ - __asm__ __volatile__(".long 0x0"); \ -} while (0) -#endif #define PAGE_BUG(page) do { BUG(); } while (0) #define STRICT_MM_TYPECHECKS diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index cd08cd136e32..cd7e330c1eb1 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -519,47 +519,6 @@ #define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */ #define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */ -/* Processor Version Numbers */ - -#define PVR_403GA 0x00200000 -#define PVR_403GB 0x00200100 -#define PVR_403GC 0x00200200 -#define PVR_403GCX 0x00201400 -#define PVR_405GP 0x40110000 -#define PVR_STB03XXX 0x40310000 -#define PVR_NP405H 0x41410000 -#define PVR_NP405L 0x41610000 -#define PVR_601 0x00010000 -#define PVR_602 0x00050000 -#define PVR_603 0x00030000 -#define PVR_603e 0x00060000 -#define PVR_603ev 0x00070000 -#define PVR_603r 0x00071000 -#define PVR_604 0x00040000 -#define PVR_604e 0x00090000 -#define PVR_604r 0x000A0000 -#define PVR_620 0x00140000 -#define PVR_740 0x00080000 -#define PVR_750 PVR_740 -#define PVR_740P 0x10080000 -#define PVR_750P PVR_740P -#define PVR_7400 0x000C0000 -#define PVR_7410 0x800C0000 -#define PVR_7450 0x80000000 -/* - * For the 8xx processors, all of them report the same PVR family for - * the PowerPC core. The various versions of these processors must be - * differentiated by the version number in the Communication Processor - * Module (CPM). - */ -#define PVR_821 0x00500000 -#define PVR_823 PVR_821 -#define PVR_850 PVR_821 -#define PVR_860 PVR_821 -#define PVR_8240 0x00810100 -#define PVR_8245 0x80811014 -#define PVR_8260 PVR_8240 - /* We only need to define a new _MACH_xxx for machines which are part of * a configuration which supports more than one type of different machine. * This is currently limited to CONFIG_ALL_PPC and CHRP/PReP/PMac. -- Tom @@ -690,11 +649,7 @@ extern struct task_struct *last_task_used_altivec; * as soon as I get around to remapping the io areas with the BATs * to match the mac we can raise this. -- Cort */ -#ifdef CONFIG_TASK_SIZE_BOOL -#define TASK_SIZE CONFIG_TASK_SIZE -#else -#define TASK_SIZE (0x80000000UL) -#endif +#define TASK_SIZE (CONFIG_TASK_SIZE) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. @@ -788,6 +743,19 @@ extern inline void prefetchw(const void *x) #define spin_lock_prefetch(x) prefetchw(x) +#ifdef CONFIG_XMON +extern void xmon(struct pt_regs *); +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + xmon(0); \ +} while (0) +#else +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + __asm__ __volatile__(".long 0x0"); \ +} while (0) +#endif + #endif /* !__ASSEMBLY__ */ #endif /* __ASM_PPC_PROCESSOR_H */ diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h index defce1be68ce..0e3f73f7a73e 100644 --- a/include/linux/coda_psdev.h +++ b/include/linux/coda_psdev.h @@ -47,13 +47,13 @@ int venus_close(struct super_block *sb, struct ViceFid *fid, int flags, int venus_open(struct super_block *sb, struct ViceFid *fid, int flags, struct file **f); int venus_mkdir(struct super_block *sb, struct ViceFid *dirfid, - const char *name, int length, - struct ViceFid *newfid, struct coda_vattr *attrs); + const char *name, int length, + struct ViceFid *newfid, struct coda_vattr *attrs); int venus_create(struct super_block *sb, struct ViceFid *dirfid, - const char *name, int length, int excl, int mode, int rdev, - struct ViceFid *newfid, struct coda_vattr *attrs) ; + const char *name, int length, int excl, int mode, dev_t rdev, + struct ViceFid *newfid, struct coda_vattr *attrs) ; int venus_rmdir(struct super_block *sb, struct ViceFid *dirfid, - const char *name, int length); + const char *name, int length); int venus_remove(struct super_block *sb, struct ViceFid *dirfid, const char *name, int length); int venus_readlink(struct super_block *sb, struct ViceFid *fid, diff --git a/include/linux/fs.h b/include/linux/fs.h index 7aa6498d7d5d..bbb4e2cacecc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -773,7 +773,7 @@ struct inode_operations { int (*symlink) (struct inode *,struct dentry *,const char *); int (*mkdir) (struct inode *,struct dentry *,int); int (*rmdir) (struct inode *,struct dentry *); - int (*mknod) (struct inode *,struct dentry *,int,int); + int (*mknod) (struct inode *,struct dentry *,int,dev_t); int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *); int (*readlink) (struct dentry *, char *,int); @@ -1109,7 +1109,7 @@ extern inline const char *bdevname(struct block_device *bdev) } extern const char * cdevname(kdev_t); extern const char * kdevname(kdev_t); -extern void init_special_inode(struct inode *, umode_t, int); +extern void init_special_inode(struct inode *, umode_t, dev_t); /* Invalid inode operations -- fs/bad_inode.c */ extern void make_bad_inode(struct inode *); diff --git a/include/linux/module.h b/include/linux/module.h index 47ff2bc63e33..927341a26c0e 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -28,8 +28,6 @@ #define MODULE_AUTHOR(name) #define MODULE_DESCRIPTION(desc) #define MODULE_SUPPORTED_DEVICE(name) -#define MODULE_GENERIC_TABLE(gtype,name) -#define MODULE_DEVICE_TABLE(type,name) #define MODULE_PARM_DESC(var,desc) #define print_modules() @@ -41,14 +39,28 @@ struct kernel_symbol }; #ifdef MODULE + +#define MODULE_GENERIC_TABLE(gtype,name) \ +static const unsigned long __module_##gtype##_size \ + __attribute__ ((unused)) = sizeof(struct gtype##_id); \ +static const struct gtype##_id * __module_##gtype##_table \ + __attribute__ ((unused)) = name + /* This is magically filled in by the linker, but THIS_MODULE must be a constant so it works in initializers. */ extern struct module __this_module; #define THIS_MODULE (&__this_module) -#else + +#else /* !MODULE */ + +#define MODULE_GENERIC_TABLE(gtype,name) #define THIS_MODULE ((struct module *)0) + #endif +#define MODULE_DEVICE_TABLE(type,name) \ + MODULE_GENERIC_TABLE(type##_device,name) + struct kernel_symbol_group { /* Links us into the global symbol list */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 7206acd7870b..3fa04d5f93f8 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -517,21 +517,6 @@ void pcibios_update_resource(struct pci_dev *, struct resource *, void pcibios_update_irq(struct pci_dev *, int irq); void pcibios_fixup_pbus_ranges(struct pci_bus *, struct pbus_set_ranges_data *); -/* Backward compatibility, don't use in new code! */ - -int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char *val); -int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short *val); -int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int *val); -int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char val); -int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short val); -int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int val); - /* Generic PCI functions used internally */ int pci_bus_exists(const struct list_head *list, int nr); @@ -668,8 +653,6 @@ extern struct pci_dev *isa_bridge; static inline int pci_present(void) { return 0; } #define _PCI_NOP(o,s,t) \ - static inline int pcibios_##o##_config_##s (u8 bus, u8 dfn, u8 where, t val) \ - { return PCIBIOS_FUNC_NOT_SUPPORTED; } \ static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \ { return PCIBIOS_FUNC_NOT_SUPPORTED; } #define _PCI_NOP_ALL(o,x) _PCI_NOP(o,byte,u8 x) \ diff --git a/include/linux/umsdos_fs.p b/include/linux/umsdos_fs.p index 99e6eefa8229..7034b7eb6b16 100644 --- a/include/linux/umsdos_fs.p +++ b/include/linux/umsdos_fs.p @@ -82,7 +82,7 @@ int UMSDOS_mkdir (struct inode *dir, int UMSDOS_mknod (struct inode *dir, struct dentry *dentry, int mode, - int rdev); + dev_t rdev); int UMSDOS_rmdir (struct inode *dir,struct dentry *dentry); int UMSDOS_unlink (struct inode *dir, struct dentry *dentry); int UMSDOS_rename (struct inode *old_dir, diff --git a/include/linux/umsdos_fs_i.h b/include/linux/umsdos_fs_i.h index 0edfb1d541a4..f4c992b44cd2 100644 --- a/include/linux/umsdos_fs_i.h +++ b/include/linux/umsdos_fs_i.h @@ -50,9 +50,9 @@ struct dir_locking_info { struct umsdos_inode_info { struct msdos_inode_info msdos_info; struct dir_locking_info dir_info; - int i_patched; /* Inode has been patched */ - int i_is_hlink; /* Resolved hardlink inode? */ - off_t pos; /* Entry offset in the emd_owner file */ + int i_patched; /* Inode has been patched */ + int i_is_hlink; /* Resolved hardlink inode? */ + off_t pos; /* Entry offset in the emd_owner file */ }; #endif diff --git a/kernel/module.c b/kernel/module.c index 1d8410b0569f..f9ee37c95dbe 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -592,14 +592,17 @@ static void *copy_section(const char *name, { void *dest; unsigned long *use; + unsigned long max; /* Only copy to init section if there is one */ if (strstr(name, ".init") && mod->module_init) { dest = mod->module_init; use = &used->init_size; + max = mod->init_size; } else { dest = mod->module_core; use = &used->core_size; + max = mod->core_size; } /* Align up */ @@ -607,6 +610,9 @@ static void *copy_section(const char *name, dest += *use; *use += sechdr->sh_size; + if (*use > max) + return ERR_PTR(-ENOEXEC); + /* May not actually be in the file (eg. bss). */ if (sechdr->sh_type != SHT_NOBITS) memcpy(dest, base + sechdr->sh_offset, sechdr->sh_size); @@ -773,9 +779,10 @@ static void simplify_symbols(Elf_Shdr *sechdrs, /* Get the total allocation size of the init and non-init sections */ static struct sizes get_sizes(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, - const char *secstrings) + const char *secstrings, + unsigned long common_length) { - struct sizes ret = { 0, 0 }; + struct sizes ret = { 0, common_length }; unsigned i; /* Everything marked ALLOC (this includes the exported @@ -933,10 +940,9 @@ static struct module *load_module(void *umod, mod->live = 0; module_unload_init(mod); - /* How much space will we need? (Common area in core) */ - sizes = get_sizes(hdr, sechdrs, secstrings); + /* How much space will we need? (Common area in first) */ common_length = read_commons(hdr, &sechdrs[symindex]); - sizes.core_size += common_length; + sizes = get_sizes(hdr, sechdrs, secstrings, common_length); /* Set these up, and allow archs to manipulate them. */ mod->core_size = sizes.core_size; @@ -963,7 +969,7 @@ static struct module *load_module(void *umod, mod->module_core = ptr; ptr = module_alloc(mod->init_size); - if (!ptr) { + if (!ptr && mod->init_size) { err = -ENOMEM; goto free_core; } diff --git a/mm/shmem.c b/mm/shmem.c index d8dc724620d4..2325743e2561 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1015,7 +1015,8 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev) +static struct inode * +shmem_get_inode(struct super_block *sb, int mode, dev_t dev) { struct inode *inode; struct shmem_inode_info *info; @@ -1426,7 +1427,8 @@ static int shmem_statfs(struct super_block *sb, struct statfs *buf) /* * File creation. Allocate an inode, and we're done.. */ -static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) +static int +shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev); int error = -ENOSPC; |
