From c0381af1dcffd2211ab66127f9b36da4e89467bd Mon Sep 17 00:00:00 2001 From: Mark Huang Date: Mon, 12 Jul 2004 21:57:37 +0000 Subject: [PATCH] kernel-2.6.6-1.422 --- Documentation/SubmittingPatches | 41 + Documentation/fb/vesafb.txt | 4 + Documentation/filesystems/ntfs.txt | 3 + Makefile | 1 + arch/arm/kernel/irq.c | 2 +- arch/arm/mach-integrator/core.c | 2 +- arch/arm/mach-pxa/pxa25x.c | 15 +- arch/arm/mach-pxa/pxa27x.c | 102 +- arch/arm/mm/init.c | 36 +- arch/cris/Kconfig | 76 +- arch/cris/Makefile | 10 +- arch/cris/arch-v10/boot/compressed/misc.c | 4 +- arch/cris/arch-v10/defconfig | 1 + arch/cris/arch-v10/drivers/Kconfig | 216 ++- arch/cris/arch-v10/drivers/Makefile | 2 + arch/cris/arch-v10/drivers/axisflashmap.c | 61 +- arch/cris/arch-v10/drivers/ds1302.c | 94 +- arch/cris/arch-v10/drivers/eeprom.c | 7 +- arch/cris/arch-v10/drivers/ethernet.c | 303 +++- arch/cris/arch-v10/drivers/gpio.c | 84 +- arch/cris/arch-v10/drivers/i2c.c | 78 +- arch/cris/arch-v10/drivers/i2c.h | 4 +- arch/cris/arch-v10/drivers/pcf8563.c | 72 +- arch/cris/arch-v10/drivers/serial.c | 1436 ++++++++++++++--- arch/cris/arch-v10/drivers/serial.h | 20 +- arch/cris/arch-v10/kernel/debugport.c | 152 +- arch/cris/arch-v10/kernel/entry.S | 21 +- arch/cris/arch-v10/kernel/fasttimer.c | 17 +- arch/cris/arch-v10/kernel/head.S | 31 +- arch/cris/arch-v10/kernel/process.c | 19 +- arch/cris/arch-v10/kernel/ptrace.c | 59 +- arch/cris/arch-v10/kernel/setup.c | 9 +- arch/cris/arch-v10/kernel/signal.c | 4 +- arch/cris/arch-v10/kernel/time.c | 8 +- arch/cris/arch-v10/lib/dram_init.S | 10 +- arch/cris/arch-v10/lib/old_checksum.c | 4 +- arch/cris/arch-v10/mm/fault.c | 36 +- arch/cris/arch-v10/mm/tlb.c | 2 +- arch/cris/defconfig | 583 ++++--- arch/cris/kernel/Makefile | 6 +- arch/cris/kernel/irq.c | 21 +- arch/cris/kernel/module.c | 25 +- arch/cris/kernel/process.c | 26 +- arch/cris/kernel/setup.c | 21 +- arch/cris/kernel/sys_cris.c | 2 +- arch/cris/kernel/time.c | 74 +- arch/cris/kernel/traps.c | 3 +- arch/cris/mm/fault.c | 26 +- arch/cris/mm/init.c | 25 +- arch/cris/mm/ioremap.c | 25 - arch/i386/kernel/acpi/wakeup.S | 1 + arch/i386/kernel/asm-offsets.c | 26 +- arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | 1 - arch/i386/kernel/cpu/cpufreq/longhaul.c | 93 +- arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 3 +- arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 21 +- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 16 +- arch/i386/kernel/cpu/proc.c | 2 +- arch/i386/kernel/entry_trampoline.c | 4 +- arch/i386/kernel/head.S | 26 + arch/i386/kernel/module.c | 2 +- arch/i386/kernel/scx200.c | 5 +- arch/i386/lib/getuser.S | 1 + arch/i386/mm/fault.c | 15 + arch/i386/mm/highmem.c | 37 +- arch/i386/mm/init.c | 85 +- arch/ppc64/configs/iSeries_defconfig | 138 +- arch/ppc64/kernel/asm-offsets.c | 1 - arch/ppc64/kernel/eeh.c | 51 +- arch/ppc64/kernel/head.S | 4 +- arch/ppc64/kernel/iSeries_setup.c | 14 +- arch/ppc64/kernel/pacaData.c | 4 +- arch/ppc64/kernel/prom.c | 48 +- arch/ppc64/kernel/stab.c | 44 +- arch/ppc64/xmon/xmon.c | 2 +- arch/sparc64/kernel/binfmt_aout32.c | 5 +- arch/sparc64/kernel/entry.S | 4 +- arch/sparc64/kernel/process.c | 22 +- arch/sparc64/kernel/signal32.c | 2 +- arch/sparc64/kernel/sunos_ioctl32.c | 15 +- arch/sparc64/kernel/sys32.S | 200 ++- arch/sparc64/kernel/sys_sparc.c | 107 +- arch/sparc64/kernel/sys_sparc32.c | 652 ++++---- arch/sparc64/kernel/sys_sunos32.c | 125 +- arch/sparc64/kernel/systbls.S | 94 +- arch/x86_64/ia32/fpu32.c | 16 +- arch/x86_64/ia32/ia32_ioctl.c | 10 +- arch/x86_64/ia32/ia32_signal.c | 36 +- arch/x86_64/ia32/ia32entry.S | 61 +- arch/x86_64/ia32/ptrace32.c | 30 +- arch/x86_64/ia32/sys_ia32.c | 111 +- arch/x86_64/ia32/syscall32.c | 6 +- arch/x86_64/ia32/tls32.c | 13 +- arch/x86_64/kernel/acpi/sleep.c | 2 +- arch/x86_64/kernel/head.S | 19 +- arch/x86_64/kernel/head64.c | 9 - arch/x86_64/kernel/i387.c | 10 +- arch/x86_64/kernel/irq.c | 6 +- arch/x86_64/kernel/ldt.c | 8 +- arch/x86_64/kernel/mce.c | 42 +- arch/x86_64/kernel/module.c | 2 +- arch/x86_64/kernel/mpparse.c | 6 +- arch/x86_64/kernel/msr.c | 18 +- arch/x86_64/kernel/process.c | 9 +- arch/x86_64/kernel/ptrace.c | 41 +- arch/x86_64/kernel/setup.c | 4 +- arch/x86_64/kernel/setup64.c | 5 +- arch/x86_64/kernel/signal.c | 37 +- arch/x86_64/kernel/smpboot.c | 10 +- arch/x86_64/kernel/sys_x86_64.c | 8 +- arch/x86_64/kernel/vmlinux.lds.S | 5 +- arch/x86_64/kernel/x8664_ksyms.c | 3 + arch/x86_64/lib/Makefile | 4 +- arch/x86_64/lib/csum-wrappers.c | 12 +- arch/x86_64/lib/io.c | 10 +- arch/x86_64/lib/usercopy.c | 16 +- arch/x86_64/mm/init.c | 4 +- arch/x86_64/mm/pageattr.c | 39 +- configs/kernel-2.6.6-i586-smp.config | 10 +- configs/kernel-2.6.6-i586.config | 10 +- configs/kernel-2.6.6-i686-smp.config | 10 +- configs/kernel-2.6.6-i686.config | 10 +- drivers/atm/fore200e.h | 14 +- drivers/block/cpqarray.c | 3 +- drivers/char/agp/amd-k7-agp.c | 51 +- drivers/char/agp/amd64-agp.c | 145 +- drivers/char/agp/ati-agp.c | 1 + drivers/char/agp/backend.c | 13 +- drivers/char/agp/intel-agp.c | 50 +- drivers/char/agp/intel-mch-agp.c | 15 +- drivers/char/agp/nvidia-agp.c | 10 +- drivers/char/agp/sis-agp.c | 60 +- drivers/char/agp/sworks-agp.c | 27 +- drivers/char/agp/via-agp.c | 58 +- drivers/char/watchdog/scx200_wdt.c | 10 +- drivers/char/watchdog/w83627hf_wdt.c | 66 +- drivers/fc4/fc.c | 43 +- drivers/i2c/busses/scx200_acb.c | 7 +- drivers/ide/Kconfig | 4 +- drivers/ide/ide-disk.c | 15 + drivers/ide/ide-probe.c | 10 +- drivers/ide/pci/aec62xx.c | 2 - drivers/ide/pci/aec62xx.h | 10 - drivers/ide/pci/alim15x3.h | 2 - drivers/ide/pci/amd74xx.c | 64 +- drivers/ide/pci/atiixp.c | 8 +- drivers/ide/pci/cmd64x.c | 5 +- drivers/ide/pci/cmd64x.h | 8 - drivers/ide/pci/cs5520.h | 8 +- drivers/ide/pci/cs5530.c | 5 +- drivers/ide/pci/cs5530.h | 3 +- drivers/ide/pci/cy82c693.h | 2 - drivers/ide/pci/generic.c | 12 +- drivers/ide/pci/generic.h | 28 - drivers/ide/pci/hpt34x.h | 2 - drivers/ide/pci/hpt366.c | 2 - drivers/ide/pci/hpt366.h | 10 - drivers/ide/pci/it8172.c | 3 +- drivers/ide/pci/it8172.h | 2 - drivers/ide/pci/ns87415.c | 5 +- drivers/ide/pci/ns87415.h | 2 - drivers/ide/pci/opti621.c | 5 +- drivers/ide/pci/opti621.h | 4 - drivers/ide/pci/pdc202xx_new.c | 2 - drivers/ide/pci/pdc202xx_new.h | 14 - drivers/ide/pci/pdc202xx_old.c | 2 - drivers/ide/pci/pdc202xx_old.h | 12 +- drivers/ide/pci/piix.c | 2 - drivers/ide/pci/piix.h | 46 +- drivers/ide/pci/rz1000.c | 5 +- drivers/ide/pci/rz1000.h | 6 +- drivers/ide/pci/sc1200.c | 5 +- drivers/ide/pci/sc1200.h | 2 - drivers/ide/pci/serverworks.c | 6 +- drivers/ide/pci/serverworks.h | 8 - drivers/ide/pci/sgiioc4.c | 13 +- drivers/ide/pci/siimage.c | 85 +- drivers/ide/pci/siimage.h | 9 - drivers/ide/pci/sis5513.c | 5 +- drivers/ide/pci/sis5513.h | 2 - drivers/ide/pci/sl82c105.c | 5 +- drivers/ide/pci/sl82c105.h | 2 - drivers/ide/pci/slc90e66.c | 5 +- drivers/ide/pci/slc90e66.h | 2 - drivers/ide/pci/triflex.c | 8 +- drivers/ide/pci/triflex.h | 2 - drivers/ide/pci/trm290.c | 5 +- drivers/ide/pci/trm290.h | 2 - drivers/ide/pci/via82cxxx.c | 7 +- drivers/ide/pci/via82cxxx.h | 12 - drivers/ide/setup-pci.c | 21 +- drivers/md/md.c | 2 +- drivers/net/Kconfig | 48 +- drivers/net/iseries_veth.c | 72 +- drivers/net/plip.c | 3 + drivers/net/ppp_async.c | 4 +- drivers/net/ppp_synctty.c | 4 +- drivers/net/wan/Makefile | 7 +- drivers/net/wan/c101.c | 2 - drivers/net/wan/hdlc_cisco.c | 22 +- drivers/net/wan/hdlc_fr.c | 20 +- drivers/net/wan/hdlc_generic.c | 108 +- drivers/net/wireless/prism54/isl_38xx.c | 2 +- drivers/net/wireless/prism54/isl_38xx.h | 2 +- drivers/net/wireless/prism54/isl_ioctl.c | 392 +++-- drivers/net/wireless/prism54/isl_ioctl.h | 2 +- drivers/net/wireless/prism54/isl_oid.h | 29 +- drivers/net/wireless/prism54/islpci_dev.c | 10 +- drivers/net/wireless/prism54/islpci_dev.h | 11 +- drivers/net/wireless/prism54/islpci_eth.c | 143 +- drivers/net/wireless/prism54/islpci_eth.h | 44 +- drivers/net/wireless/prism54/islpci_hotplug.c | 2 +- drivers/net/wireless/prism54/islpci_mgt.c | 2 +- drivers/net/wireless/prism54/islpci_mgt.h | 2 +- drivers/net/wireless/prism54/oid_mgt.c | 634 +++++--- drivers/net/wireless/prism54/oid_mgt.h | 11 +- drivers/pcmcia/pxa2xx_base.c | 12 +- drivers/pnp/pnpbios/Kconfig | 2 +- drivers/scsi/esp.c | 132 +- drivers/scsi/esp.h | 17 +- drivers/scsi/libata-scsi.c | 1 + drivers/scsi/qlogicpti.c | 48 +- drivers/scsi/qlogicpti.h | 13 +- drivers/scsi/sata_promise.c | 4 +- drivers/scsi/sata_sx4.c | 4 +- drivers/video/aty/radeon_accel.c | 5 +- drivers/video/aty/radeon_pm.c | 2 +- drivers/video/pxafb.c | 2 +- drivers/video/vesafb.c | 2 +- fs/aio.c | 10 +- fs/binfmt_elf.c | 6 +- fs/compat.c | 6 +- fs/dcache.c | 16 + fs/direct-io.c | 5 +- fs/fs-writeback.c | 3 + fs/hugetlbfs/inode.c | 2 +- fs/inode.c | 25 +- fs/nfsd/vfs.c | 14 +- fs/ntfs/ChangeLog | 16 + fs/ntfs/Makefile | 2 +- fs/ntfs/aops.c | 9 + fs/ntfs/compress.c | 20 +- fs/ntfs/dir.c | 2 +- fs/ntfs/inode.c | 134 +- fs/ntfs/inode.h | 9 + fs/ntfs/ntfs.h | 1 + fs/ntfs/super.c | 4 +- include/asm-alpha/ide.h | 2 + include/asm-alpha/resource.h | 2 +- include/asm-arm/arch-pxa/hardware.h | 5 +- include/asm-arm/ide.h | 9 - include/asm-arm/resource.h | 2 +- include/asm-arm26/ide.h | 9 - include/asm-arm26/resource.h | 2 +- include/asm-cris/arch-v10/cache.h | 1 + include/asm-cris/arch-v10/irq.h | 5 + include/asm-cris/arch-v10/offset.h | 2 +- include/asm-cris/bitops.h | 46 + include/asm-cris/dma-mapping.h | 126 +- include/asm-cris/fasttimer.h | 4 +- include/asm-cris/io.h | 2 + include/asm-cris/ioctl.h | 13 +- include/asm-cris/page.h | 11 +- include/asm-cris/pci.h | 4 + include/asm-cris/pgtable.h | 10 +- include/asm-cris/ptrace.h | 2 + include/asm-cris/resource.h | 2 +- include/asm-cris/rtc.h | 4 +- include/asm-cris/semaphore-helper.h | 4 +- include/asm-cris/semaphore.h | 12 +- include/asm-cris/termbits.h | 2 +- include/asm-cris/types.h | 1 + include/asm-cris/unistd.h | 16 +- include/asm-h8300/ide.h | 5 - include/asm-h8300/resource.h | 2 +- include/asm-i386/atomic_kmap.h | 1 + include/asm-i386/bitops.h | 4 +- include/asm-i386/cpufeature.h | 2 + include/asm-i386/highmem.h | 1 + include/asm-i386/ide.h | 2 + include/asm-i386/kmap_types.h | 5 +- include/asm-i386/msr.h | 9 + include/asm-i386/page.h | 4 +- include/asm-i386/pgtable-3level.h | 12 +- include/asm-i386/pgtable.h | 65 +- include/asm-i386/processor.h | 2 + include/asm-i386/resource.h | 2 +- include/asm-i386/uaccess.h | 12 +- include/asm-ia64/ide.h | 2 + include/asm-ia64/resource.h | 2 +- include/asm-m68k/ide.h | 26 - include/asm-m68k/resource.h | 2 +- include/asm-mips/mach-generic/ide.h | 2 + include/asm-parisc/ide.h | 5 - include/asm-parisc/resource.h | 2 +- include/asm-ppc/ide.h | 2 + include/asm-ppc/resource.h | 2 +- include/asm-ppc64/eeh.h | 16 +- include/asm-ppc64/ide.h | 5 - include/asm-ppc64/mmu_context.h | 10 +- include/asm-ppc64/naca.h | 2 +- include/asm-ppc64/processor.h | 6 + include/asm-ppc64/resource.h | 2 +- include/asm-ppc64/uaccess.h | 8 +- include/asm-s390/resource.h | 2 +- include/asm-s390/types.h | 3 +- include/asm-sh/ide.h | 2 + include/asm-sh/resource.h | 2 +- include/asm-sparc/ide.h | 12 - include/asm-sparc/resource.h | 2 +- include/asm-sparc/sbus.h | 9 +- include/asm-sparc/uaccess.h | 8 +- include/asm-sparc64/ide.h | 12 - include/asm-sparc64/resource.h | 2 +- include/asm-sparc64/sbus.h | 9 +- include/asm-sparc64/uaccess.h | 8 +- include/asm-sparc64/unistd.h | 1 - include/asm-v850/resource.h | 2 +- include/asm-x86_64/bitops.h | 7 +- include/asm-x86_64/checksum.h | 4 +- include/asm-x86_64/compat.h | 8 +- include/asm-x86_64/floppy.h | 2 +- include/asm-x86_64/fpu32.h | 4 +- include/asm-x86_64/i387.h | 10 +- include/asm-x86_64/ia32.h | 4 +- include/asm-x86_64/ia32_unistd.h | 3 +- include/asm-x86_64/io.h | 9 +- include/asm-x86_64/page.h | 13 +- include/asm-x86_64/pgtable.h | 28 +- include/asm-x86_64/processor.h | 2 +- include/asm-x86_64/ptrace.h | 2 +- include/asm-x86_64/resource.h | 2 +- include/asm-x86_64/semaphore.h | 14 +- include/asm-x86_64/sigcontext.h | 3 +- include/asm-x86_64/uaccess.h | 56 +- include/linux/aio.h | 4 +- include/linux/compiler.h | 2 + include/linux/elf.h | 2 - include/linux/futex.h | 5 +- include/linux/hdlc.h | 5 +- include/linux/highmem.h | 7 +- include/linux/ide.h | 33 +- include/linux/mca.h | 2 +- include/linux/mm.h | 14 +- include/linux/pci_ids.h | 7 + include/linux/timer.h | 1 + include/linux/vmalloc.h | 1 + include/net/ip.h | 2 +- include/net/ip6_fib.h | 2 + include/net/ipv6.h | 2 +- include/net/route.h | 2 + include/net/snmp.h | 87 +- init/Kconfig | 2 +- ipc/shm.c | 15 +- ipc/util.c | 7 +- kernel/compat.c | 11 +- kernel/exit.c | 8 + kernel/futex.c | 49 +- kernel/kthread.c | 6 +- kernel/sched.c | 19 +- kernel/signal.c | 5 +- kernel/sys.c | 1 + mm/memory.c | 58 + mm/mlock.c | 8 +- mm/mmap.c | 36 +- mm/mprotect.c | 4 +- mm/mremap.c | 6 +- mm/pdflush.c | 4 + mm/shmem.c | 21 +- mm/slab.c | 6 +- mm/usercopy.c | 34 +- mm/vmalloc.c | 22 + mm/vmscan.c | 6 + net/ipv4/af_inet.c | 4 +- net/ipv4/ip_forward.c | 2 +- net/ipv4/ip_fragment.c | 14 +- net/ipv4/ip_input.c | 18 +- net/ipv4/ip_output.c | 26 +- net/ipv4/ipcomp.c | 1 + net/ipv4/ipmr.c | 4 +- net/ipv4/proc.c | 50 +- net/ipv4/raw.c | 2 +- net/ipv4/route.c | 12 + net/ipv4/tcp_ipv4.c | 4 +- net/ipv6/af_inet6.c | 8 +- net/ipv6/exthdrs.c | 28 +- net/ipv6/icmp.c | 2 +- net/ipv6/ip6_input.c | 24 +- net/ipv6/ip6_output.c | 50 +- net/ipv6/ipv6_sockglue.c | 2 +- net/ipv6/mcast.c | 16 +- net/ipv6/ndisc.c | 8 +- net/ipv6/proc.c | 73 +- net/ipv6/raw.c | 4 +- net/ipv6/reassembly.c | 28 +- net/ipv6/route.c | 36 +- net/sctp/output.c | 2 +- net/xfrm/xfrm_state.c | 1 - security/selinux/Kconfig | 2 +- security/selinux/hooks.c | 2 +- 400 files changed, 7178 insertions(+), 4116 deletions(-) diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 6bf80fc2b..9838d32b2 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -259,6 +259,47 @@ e-mail discussions. +11) Sign your work + +To improve tracking of who did what, especially with patches that can +percolate to their final resting place in the kernel through several +layers of maintainers, we've introduced a "sign-off" procedure on +patches that are being emailed around. + +The sign-off is a simple line at the end of the explanation for the +patch, which certifies that you wrote it or otherwise have the right to +pass it on as a open-source patch. The rules are pretty simple: if you +can certify the below: + + Developer's Certificate of Origin 1.0 + + By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +then you just add a line saying + + Signed-off-by: Random J Developer + +Some people also put extra tags at the end. They'll just be ignored for +now, but you can do this to mark internal company procedures or just +point out some special detail about the sign-off. + + ----------------------------------- SECTION 2 - HINTS, TIPS, AND TRICKS ----------------------------------- diff --git a/Documentation/fb/vesafb.txt b/Documentation/fb/vesafb.txt index 93514f528..36beb54f1 100644 --- a/Documentation/fb/vesafb.txt +++ b/Documentation/fb/vesafb.txt @@ -146,6 +146,10 @@ pmipal Use the protected mode interface for palette changes. mtrr setup memory type range registers for the vesafb framebuffer. +vram:n remap 'n' MiB of video RAM. If 0 or not specified, remap memory + according to video mode. (2.5.66 patch/idea by Antonino Daplas + reversed to give override possibility (allocate more fb memory + than the kernel would) to 2.4 by tmb@iki.fi) Have fun! diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt index 352e61606..1cdc5d274 100644 --- a/Documentation/filesystems/ntfs.txt +++ b/Documentation/filesystems/ntfs.txt @@ -273,6 +273,9 @@ ChangeLog Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. +2.1.12: + - Fix the second fix to the decompression engine from the 2.1.9 release + and some further internals cleanups. 2.1.11: - Driver internal cleanups. 2.1.10: diff --git a/Makefile b/Makefile index a4cf56f43..da97882b5 100644 --- a/Makefile +++ b/Makefile @@ -904,6 +904,7 @@ help: @echo ' rpm - Build a kernel as an RPM package' @echo ' tags/TAGS - Generate tags file for editors' @echo ' cscope - Generate cscope index' + @echo ' checkstack - Generate a list of stack hogs' @echo '' @echo 'Documentation targets:' @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 90875c2ec..5777a8c2f 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -447,7 +447,7 @@ static void do_pending_irqs(struct pt_regs *regs) * come via this function. Instead, they should provide their * own 'handler' */ -asmlinkage void asm_do_IRQ(int irq, struct pt_regs *regs) +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { struct irqdesc *desc = irq_desc + irq; diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 8f30c1151..01ce14d70 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -108,7 +108,7 @@ arch_initcall(integrator_init); #define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET -static spinlock_t cm_lock; +static spinlock_t cm_lock = SPIN_LOCK_UNLOCKED; /** * cm_control - update the CM_CTRL register. diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index f57c96222..41150917f 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -83,12 +83,21 @@ unsigned int get_clk_frequency_khz(int info) EXPORT_SYMBOL(get_clk_frequency_khz); /* - * Return the current lclk requency in units of 10kHz + * Return the current memory clock frequency in units of 10kHz */ -unsigned int get_lclk_frequency_10khz(void) +unsigned int get_memclk_frequency_10khz(void) { return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000; } -EXPORT_SYMBOL(get_lclk_frequency_10khz); +EXPORT_SYMBOL(get_memclk_frequency_10khz); +/* + * Return the current LCD clock frequency in units of 10kHz + */ +unsigned int get_lcdclk_frequency_10khz(void) +{ + return get_memclk_frequency_10khz(); +} + +EXPORT_SYMBOL(get_lcdclk_frequency_10khz); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 1addceb0f..b1573c837 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -21,100 +21,98 @@ #include "generic.h" -/* Crystal clock : 13-MHZ*/ +/* Crystal clock: 13MHz */ #define BASE_CLK 13000000 /* * Get the clock frequency as reflected by CCSR and the turbo flag. * We assume these values have been applied via a fcs. * If info is not 0 we also display the current settings. - * - * For more details, refer to Bulverde Manual, section 3.8.2.1 */ unsigned int get_clk_frequency_khz( int info) { - unsigned long ccsr, turbo, b, ht; - unsigned int l, L, m, M, n2, N, S, cccra; + unsigned long ccsr, clkcfg; + unsigned int l, L, m, M, n2, N, S; + int cccr_a, t, ht, b; ccsr = CCSR; - cccra = CCCR & (0x1 << 25); + cccr_a = CCCR & (1 << 25); /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ - asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) ); - b = (turbo & (0x1 << 3)); - ht = (turbo & (0x1 << 2)); + asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); + t = clkcfg & (1 << 1); + ht = clkcfg & (1 << 2); + b = clkcfg & (1 << 3); l = ccsr & 0x1f; n2 = (ccsr>>7) & 0xf; - if (l == 31) { - /* The calculation from the Yellow Book is incorrect: - it says M=4 for L=21-30 (which is easy to calculate - by subtracting 1 and then dividing by 10, but not - with 31, so we'll do it manually */ - m = 1 << 2; - } else { - m = 1 << ((l-1)/10); - } + m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; - L = l * BASE_CLK; - N = (n2 * L) / 2; - S = (b) ? L : (L/2); - if (cccra == 0) - M = L/m; - else - M = (b) ? L : (L/2); + L = l * BASE_CLK; + N = (L * n2) / 2; + M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); + S = (b) ? L : (L/2); if (info) { printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n", L / 1000000, (L % 1000000) / 10000, l ); - printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n", - M / 1000000, (M % 1000000) / 10000, m ); printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n", N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5, - (turbo & 1) ? "" : "in" ); + (t) ? "" : "in" ); + printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n", + M / 1000000, (M % 1000000) / 10000, m ); printk( KERN_INFO "System bus clock: %d.%02dMHz \n", S / 1000000, (S % 1000000) / 10000 ); } - return (turbo & 1) ? (N/1000) : (L/1000); + return (t) ? (N/1000) : (L/1000); } /* * Return the current mem clock frequency in units of 10kHz as * reflected by CCCR[A], B, and L */ -unsigned int get_lclk_frequency_10khz(void) +unsigned int get_memclk_frequency_10khz(void) { - unsigned long ccsr, clkcfg, b; - unsigned int l, L, m, M, cccra; + unsigned long ccsr, clkcfg; + unsigned int l, L, m, M; + int cccr_a, b; - cccra = CCCR & (0x1 << 25); + ccsr = CCSR; + cccr_a = CCCR & (1 << 25); - /* Read clkcfg register to obtain b */ + /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); - b = (clkcfg & (0x1 << 3)); + b = clkcfg & (1 << 3); - ccsr = CCSR; - l = ccsr & 0x1f; - if (l == 31) { - /* The calculation from the Yellow Book is incorrect: - it says M=4 for L=21-30 (which is easy to calculate - by subtracting 1 and then dividing by 10, but not - with 31, so we'll do it manually */ - m = 1 << 2; - } else { - m = 1 << ((l-1)/10); - } + l = ccsr & 0x1f; + m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4; L = l * BASE_CLK; - if (cccra == 0) - M = L/m; - else - M = (b) ? L : L/2; + M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2)); return (M / 10000); } -EXPORT_SYMBOL(get_clk_frequency_khz); -EXPORT_SYMBOL(get_lclk_frequency_10khz); +/* + * Return the current LCD clock frequency in units of 10kHz as + */ +unsigned int get_lcdclk_frequency_10khz(void) +{ + unsigned long ccsr; + unsigned int l, L, k, K; + + ccsr = CCSR; + l = ccsr & 0x1f; + k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4; + + L = l * BASE_CLK; + K = L / k; + + return (K / 10000); +} + +EXPORT_SYMBOL(get_clk_frequency_khz); +EXPORT_SYMBOL(get_memclk_frequency_10khz); +EXPORT_SYMBOL(get_lcdclk_frequency_10khz); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index c114be6c8..07ddce798 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -281,6 +281,7 @@ static int __init check_initrd(struct meminfo *mi) static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int bootmap_pages) { pg_data_t *pgdat = NODE_DATA(0); + unsigned long res_size = 0; /* * Register the kernel text and data with bootmem. @@ -304,31 +305,32 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot bootmap_pages << PAGE_SHIFT); /* - * Hmm... This should go elsewhere, but we really really - * need to stop things allocating the low memory; we need - * a better implementation of GFP_DMA which does not assume - * that DMA-able memory starts at zero. + * Hmm... This should go elsewhere, but we really really need to + * stop things allocating the low memory; ideally we need a better + * implementation of GFP_DMA which does not assume that DMA-able + * memory starts at zero. */ - if (machine_is_integrator()) - reserve_bootmem_node(pgdat, 0, __pa(swapper_pg_dir)); + if (machine_is_integrator() || machine_is_cintegrator()) + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + /* - * These should likewise go elsewhere. They pre-reserve - * the screen memory region at the start of main system - * memory. + * These should likewise go elsewhere. They pre-reserve the + * screen memory region at the start of main system memory. */ - if (machine_is_archimedes() || machine_is_a5k()) - reserve_bootmem_node(pgdat, 0x02000000, 0x00080000); if (machine_is_edb7211()) - reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000); + res_size = 0x00020000; if (machine_is_p720t()) - reserve_bootmem_node(pgdat, PHYS_OFFSET, 0x00014000); + res_size = 0x00014000; + #ifdef CONFIG_SA1111 /* - * Because of the SA1111 DMA bug, we want to preserve - * our precious DMA-able memory... + * Because of the SA1111 DMA bug, we want to preserve our + * precious DMA-able memory... */ - reserve_bootmem_node(pgdat, PHYS_OFFSET, __pa(swapper_pg_dir)-PHYS_OFFSET); + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; #endif + if (res_size) + reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); } /* @@ -601,7 +603,7 @@ void __init mem_init(void) void free_initmem(void) { - if (!machine_is_integrator()) { + if (!machine_is_integrator() && !machine_is_cintegrator()) { free_area((unsigned long)(&__init_begin), (unsigned long)(&__init_end), "init"); diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 86a05dbff..481edcadc 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -27,19 +27,11 @@ menu "General setup" source "fs/Kconfig.binfmt" -config ETRAX_KGDB - bool "Use kernel gdb debugger" - ---help--- - The CRIS version of gdb can be used to remotely debug a running - Linux kernel via the serial debug port. Provided you have gdb-cris - installed, run gdb-cris vmlinux, then type - - (gdb) set remotebaud 115200 <- kgdb uses 115200 as default - (gdb) target remote /dev/ttyS0 <- maybe you use another port - - This should connect you to your booted kernel (or boot it now if you - didn't before). The kernel halts when it boots, waiting for gdb if - this option is turned on! +config ETRAX_CMDLINE + string "Kernel command line" + default "root=/dev/mtdblock3" + help + Pass additional commands to the kernel. config ETRAX_WATCHDOG bool "Enable ETRAX watchdog" @@ -99,11 +91,6 @@ config SVINTO_SIM help Support the xsim ETRAX Simulator. -config ETRAX200LX - bool "ETRAX-200LX-V32" - help - Support CRIS V32. - endchoice config ETRAX_ARCH_V10 @@ -111,11 +98,6 @@ config ETRAX_ARCH_V10 default y if ETRAX100LX || ETRAX100LX_V2 default n if !(ETRAX100LX || ETRAX100LX_V2) -config ETRAX_ARCH_V32 - bool - default y if ETRAX200LX - default n if !(ETRAX200LX) - config ETRAX_DRAM_SIZE int "DRAM size (dec, in MB)" default "8" @@ -128,35 +110,18 @@ config ETRAX_FLASH_BUSWIDTH help Width in bytes of the Flash bus (1, 2 or 4). Is usually 2. -config ETRAX_ROOT_DEVICE - string "Root device name" - default "/dev/mtdblock3" - help - Specifies the device that should be mounted as root file system - when booting from flash. The axisflashmap driver adds an additional - mtd partition for the appended root file system image, so this option - should normally be the mtdblock device for the partition after the - last partition in the partition table. - -# duplicate choice configs are not yet supported, so the followinguse -# doesn't work: - source arch/cris/arch-v10/Kconfig endmenu # bring in ETRAX built-in drivers menu "Drivers for built-in interfaces" - source arch/cris/arch-v10/drivers/Kconfig endmenu source "drivers/base/Kconfig" -# bring in Etrax built-in drivers -source "arch/cris/drivers/Kconfig" - # standard linux drivers source "drivers/mtd/Kconfig" @@ -212,6 +177,37 @@ config PROFILE_SHIFT depends on PROFILE default "2" +config ETRAX_KGDB + bool "Use kernel GDB debugger" + ---help--- + The CRIS version of gdb can be used to remotely debug a running + Linux kernel via the serial debug port. Provided you have gdb-cris + installed, run gdb-cris vmlinux, then type + + (gdb) set remotebaud 115200 <- kgdb uses 115200 as default + (gdb) target remote /dev/ttyS0 <- maybe you use another port + + This should connect you to your booted kernel (or boot it now if you + didn't before). The kernel halts when it boots, waiting for gdb if + this option is turned on! + + +config DEBUG_INFO + bool "Compile the kernel with debug info" + help + If you say Y here the resulting kernel image will include + debugging info resulting in a larger kernel image. + Say Y here only if you plan to use gdb to debug the kernel. + If you don't debug the kernel, you can say N. + +config FRAME_POINTER + bool "Compile the kernel with frame pointers" + help + If you say Y here the resulting kernel image will be slightly larger + and slower, but it will give very useful debugging information. + If you don't debug the kernel, you can say N, but we may not be able + to solve problems without frame pointers. + endmenu source "security/Kconfig" diff --git a/arch/cris/Makefile b/arch/cris/Makefile index 44d3caa08..30585a70c 100644 --- a/arch/cris/Makefile +++ b/arch/cris/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.15 2003/07/04 12:47:53 tobiasa Exp $ +# $Id: Makefile,v 1.20 2004/05/14 14:35:58 orjanf Exp $ # cris/Makefile # # This file is included by the global makefile so that you can add your own @@ -34,7 +34,7 @@ AFLAGS += -mlinux CFLAGS := $(CFLAGS) -mlinux -march=$(arch-y) -pipe -ifdef CONFIG_ETRAX_KGDB +ifdef CONFIG_FRAME_POINTER CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g CFLAGS += -fno-omit-frame-pointer endif @@ -90,10 +90,14 @@ prepare: arch/$(ARCH)/.links include/asm-$(ARCH)/.arch \ # Create some links to make all tools happy arch/$(ARCH)/.links: + @rm -rf arch/$(ARCH)/drivers @ln -sfn $(SARCH)/drivers arch/$(ARCH)/drivers + @rm -rf arch/$(ARCH)/boot @ln -sfn $(SARCH)/boot arch/$(ARCH)/boot + @rm -rf arch/$(ARCH)/lib @ln -sfn $(SARCH)/lib arch/$(ARCH)/lib - @ln -sfn $(SARCH)/vmlinux.lds.S arch/$(ARCH)/kernel/vmlinux.lds.S + @ln -sfn $(SARCH) arch/$(ARCH)/arch + @ln -sfn ../$(SARCH)/vmlinux.lds.S arch/$(ARCH)/kernel/vmlinux.lds.S @touch $@ # Create link to sub arch includes diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c index 6506ac4a8..1b5e83f1f 100644 --- a/arch/cris/arch-v10/boot/compressed/misc.c +++ b/arch/cris/arch-v10/boot/compressed/misc.c @@ -1,7 +1,7 @@ /* * misc.c * - * $Id: misc.c,v 1.4 2003/04/09 05:20:45 starvik Exp $ + * $Id: misc.c,v 1.6 2003/10/27 08:04:31 starvik Exp $ * * This is a collection of several routines from gzip-1.0.3 * adapted for Linux. @@ -263,7 +263,7 @@ decompress_kernel() __asm__ volatile ("move vr,%0" : "=rm" (revision)); if (revision < 10) { - puts("You need an ETRAX 100LX to run linux 2.4\n"); + puts("You need an ETRAX 100LX to run linux 2.6\n"); while(1); } diff --git a/arch/cris/arch-v10/defconfig b/arch/cris/arch-v10/defconfig index 5780e4e21..9d40dd316 100644 --- a/arch/cris/arch-v10/defconfig +++ b/arch/cris/arch-v10/defconfig @@ -267,6 +267,7 @@ CONFIG_INET=y # CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index 7b0684d07..482ac6659 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -11,29 +11,6 @@ config NET_ETHERNET bool depends on ETRAX_ETHERNET default y - ---help--- - Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common - type of Local Area Network (LAN) in universities and companies. - - Common varieties of Ethernet are: 10BASE-2 or Thinnet (10 Mbps over - coaxial cable, linking computers in a chain), 10BASE-T or twisted - pair (10 Mbps over twisted pair cable, linking computers to central - hubs), 10BASE-F (10 Mbps over optical fiber links, using hubs), - 100BASE-TX (100 Mbps over two twisted pair cables, using hubs), - 100BASE-T4 (100 Mbps over 4 standard voice-grade twisted pair - cables, using hubs), 100BASE-FX (100 Mbps over optical fiber links) - [the 100BASE varieties are also known as Fast Ethernet], and Gigabit - Ethernet (1 Gbps over optical fiber or short copper links). - - If your Linux machine will be connected to an Ethernet and you have - an Ethernet network interface card (NIC) installed in your computer, - say Y here and read the Ethernet-HOWTO, available from - . You will then also have - to say Y to the driver for your particular NIC. - - Note that the answer to this question won't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about Ethernet network cards. If unsure, say N. choice prompt "Network LED behavior" @@ -109,6 +86,32 @@ config ETRAX_SERIAL_PORT0 Normally you want this on, unless you use external DMA 1 that uses the same DMA channels. +choice + prompt "Ser0 DMA out assignment" + depends on ETRAX_SERIAL_PORT0 + default ETRAX_SERIAL_PORT0_DMA6_OUT + +config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT + bool "No DMA out" + +config CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT + bool "DMA 6" + +endchoice + +choice + prompt "Ser0 DMA in assignment" + depends on ETRAX_SERIAL_PORT0 + default ETRAX_SERIAL_PORT0_DMA7_IN + +config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN + bool "No DMA in" + +config CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN + bool "DMA 7" + +endchoice + choice prompt "Ser0 DTR, RI, DSR and CD assignment" depends on ETRAX_SERIAL_PORT0 @@ -197,6 +200,32 @@ config ETRAX_SERIAL_PORT1 help Enables the ETRAX 100 serial driver for ser1 (ttyS1). +choice + prompt "Ser1 DMA out assignment" + depends on ETRAX_SERIAL_PORT1 + default ETRAX_SERIAL_PORT1_DMA8_OUT + +config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_OUT + bool "No DMA out" + +config CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT + bool "DMA 8" + +endchoice + +choice + prompt "Ser1 DMA in assignment" + depends on ETRAX_SERIAL_PORT1 + default ETRAX_SERIAL_PORT1_DMA9_IN + +config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_IN + bool "No DMA in" + +config CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN + bool "DMA 9" + +endchoice + choice prompt "Ser1 DTR, RI, DSR and CD assignment" depends on ETRAX_SERIAL_PORT1 @@ -288,6 +317,32 @@ config ETRAX_SERIAL_PORT2 help Enables the ETRAX 100 serial driver for ser2 (ttyS2). +choice + prompt "Ser2 DMA out assignment" + depends on ETRAX_SERIAL_PORT2 + default ETRAX_SERIAL_PORT2_DMA2_OUT + +config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT + bool "No DMA out" + +config CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT + bool "DMA 2" + +endchoice + +choice + prompt "Ser2 DMA in assignment" + depends on ETRAX_SERIAL_PORT2 + default ETRAX_SERIAL_PORT2_DMA3_IN + +config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN + bool "No DMA in" + +config CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + bool "DMA 3" + +endchoice + choice prompt "Ser2 DTR, RI, DSR and CD assignment" depends on ETRAX_SERIAL_PORT2 @@ -376,6 +431,32 @@ config ETRAX_SERIAL_PORT3 help Enables the ETRAX 100 serial driver for ser3 (ttyS3). +choice + prompt "Ser3 DMA out assignment" + depends on ETRAX_SERIAL_PORT3 + default ETRAX_SERIAL_PORT3_DMA4_OUT + +config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT + bool "No DMA out" + +config CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT + bool "DMA 4" + +endchoice + +choice + prompt "Ser3 DMA in assignment" + depends on ETRAX_SERIAL_PORT3 + default ETRAX_SERIAL_PORT3_DMA5_IN + +config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN + bool "No DMA in" + +config CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN + bool "DMA 5" + +endchoice + choice prompt "Ser3 DTR, RI, DSR and CD assignment" depends on ETRAX_SERIAL_PORT3 @@ -466,6 +547,95 @@ config ETRAX_RS485_DISABLE_RECEIVER loopback. Not all products are able to do this in software only. Axis 2400/2401 must disable receiver. +config ETRAX_IDE + bool "ATA/IDE support" + help + Enable this to get support for ATA/IDE. + You can't use parallell ports or SCSI ports + at the same time. + +# here we should add the CONFIG_'s necessary to enable the basic +# general ide drivers so the common case does not need to go +# into that config submenu. enable disk and CD support. others +# need to go fiddle in the submenu.. +config IDE + tristate + depends on ETRAX_IDE + default y + +config BLK_DEV_IDE + tristate + depends on ETRAX_IDE + default y + +config BLK_DEV_IDEDISK + tristate + depends on ETRAX_IDE + default y + +config BLK_DEV_IDECD + tristate + depends on ETRAX_IDE + default y + +config BLK_DEV_IDEDMA + bool + depends on ETRAX_IDE + default y + +config DMA_NONPCI + bool + depends on ETRAX_IDE + default y + +config ETRAX_IDE_DELAY + int "Delay for drives to regain consciousness" + depends on ETRAX_IDE + default 15 + help + Number of seconds to wait for IDE drives to spin up after an IDE + reset. +choice + prompt "IDE reset pin" + depends on ETRAX_IDE + default ETRAX_IDE_PB7_RESET + +config ETRAX_IDE_PB7_RESET + bool "Port_PB_Bit_7" + help + IDE reset on pin 7 on port B + +config ETRAX_IDE_G27_RESET + bool "Port_G_Bit_27" + help + IDE reset on pin 27 on port G + +endchoice + + +config ETRAX_USB_HOST + bool "USB host" + help + This option enables the host functionality of the ETRAX 100LX + built-in USB controller. In host mode the controller is designed + for CTRL and BULK traffic only, INTR traffic may work as well + however (depending on the requirements of timeliness). + +config USB + tristate + depends on ETRAX_USB_HOST + default y + +config ETRAX_USB_HOST_PORT1 + bool " USB port 1 enabled" + depends on ETRAX_USB_HOST + default n + +config ETRAX_USB_HOST_PORT2 + bool " USB port 2 enabled" + depends on ETRAX_USB_HOST + default n + config ETRAX_AXISFLASHMAP bool "Axis flash-map support" depends on ETRAX_ARCH_V10 diff --git a/arch/cris/arch-v10/drivers/Makefile b/arch/cris/arch-v10/drivers/Makefile index 7160cdd7b..7036fc050 100644 --- a/arch/cris/arch-v10/drivers/Makefile +++ b/arch/cris/arch-v10/drivers/Makefile @@ -10,5 +10,7 @@ obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o obj-$(CONFIG_ETRAX_GPIO) += gpio.o obj-$(CONFIG_ETRAX_DS1302) += ds1302.o obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o +obj-$(CONFIG_ETRAX_IDE) += ide.o +obj-$(CONFIG_ETRAX_USB_HOST) += usb-host.o diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c index c6f90bdcf..3277019e3 100644 --- a/arch/cris/arch-v10/drivers/axisflashmap.c +++ b/arch/cris/arch-v10/drivers/axisflashmap.c @@ -11,6 +11,9 @@ * partition split defined below. * * $Log: axisflashmap.c,v $ + * Revision 1.8 2004/05/14 07:58:03 starvik + * Merge of changes from 2.4 + * * Revision 1.6 2003/07/04 08:27:37 starvik * Merge of Linux 2.5.74 * @@ -153,6 +156,9 @@ /* From head.S */ extern unsigned long romfs_start, romfs_length, romfs_in_flash; +/* The master mtd for the entire flash. */ +struct mtd_info* axisflash_mtd = NULL; + /* Map driver functions. */ static __u8 flash_read8(struct map_info *map, unsigned long ofs) @@ -314,7 +320,8 @@ static struct mtd_info *probe_cs(struct map_info *map_cs) { struct mtd_info *mtd_cs = NULL; - printk("%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", + printk(KERN_INFO + "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n", map_cs->name, map_cs->size, map_cs->map_priv_1); #ifdef CONFIG_MTD_AMDSTD @@ -398,7 +405,7 @@ static int __init init_axis_flash(void) struct mtd_info *mymtd; int err = 0; int pidx = 0; - struct partitiontable_head *ptable_head; + struct partitiontable_head *ptable_head = NULL; struct partitiontable_entry *ptable; int use_default_ptable = 1; /* Until proven otherwise. */ const char *pmsg = " /dev/flash%d at 0x%08x, size 0x%08x\n"; @@ -407,19 +414,22 @@ static int __init init_axis_flash(void) /* There's no reason to use this module if no flash chip can * be identified. Make sure that's understood. */ - panic("axisflashmap found no flash chip!\n"); + printk(KERN_INFO "axisflashmap: Found no flash chip.\n"); + } else { + printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n", + mymtd->name, mymtd->size); + axisflash_mtd = mymtd; } - printk("%s: 0x%08x bytes of flash memory.\n", - mymtd->name, mymtd->size); - - mymtd->owner = THIS_MODULE; - - ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + - CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET); + if (mymtd) { + mymtd->owner = THIS_MODULE; + ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR + + CONFIG_ETRAX_PTABLE_SECTOR + + PARTITION_TABLE_OFFSET); + } pidx++; /* First partition is always set to the default. */ - if ((ptable_head->magic == PARTITION_TABLE_MAGIC) + if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC) && (ptable_head->size < (MAX_PARTITIONS * sizeof(struct partitiontable_entry) + PARTITIONTABLE_END_MARKER_SIZE)) @@ -454,7 +464,7 @@ static int __init init_axis_flash(void) ptable_ok = (csum == ptable_head->checksum); /* Read the entries and use/show the info. */ - printk(" Found a%s partition table at 0x%p-0x%p.\n", + printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n", (ptable_ok ? " valid" : "n invalid"), ptable_head, max_addr); @@ -486,22 +496,25 @@ static int __init init_axis_flash(void) axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR; axis_partitions[pidx].mask_flags |= MTD_WRITEABLE; - printk(" Adding readonly flash partition for romfs image:\n"); + printk(KERN_INFO + " Adding readonly flash partition for romfs image:\n"); printk(pmsg, pidx, axis_partitions[pidx].offset, axis_partitions[pidx].size); pidx++; } - if (use_default_ptable) { - printk(" Using default partition table.\n"); - err = add_mtd_partitions(mymtd, axis_default_partitions, - NUM_DEFAULT_PARTITIONS); - } else { - err = add_mtd_partitions(mymtd, axis_partitions, pidx); - } + if (mymtd) { + if (use_default_ptable) { + printk(KERN_INFO " Using default partition table.\n"); + err = add_mtd_partitions(mymtd, axis_default_partitions, + NUM_DEFAULT_PARTITIONS); + } else { + err = add_mtd_partitions(mymtd, axis_partitions, pidx); + } - if (err) { - panic("axisflashmap could not add MTD partitions!\n"); + if (err) { + panic("axisflashmap could not add MTD partitions!\n"); + } } if (!romfs_in_flash) { @@ -522,7 +535,7 @@ static int __init init_axis_flash(void) "mtd_info!\n"); } - printk(" Adding RAM partition for romfs image:\n"); + printk(KERN_INFO " Adding RAM partition for romfs image:\n"); printk(pmsg, pidx, romfs_start, romfs_length); err = mtdram_init_device(mtd_ram, (void*)romfs_start, @@ -539,3 +552,5 @@ static int __init init_axis_flash(void) /* This adds the above to the kernels init-call chain. */ module_init(init_axis_flash); + +EXPORT_SYMBOL(axisflash_mtd); diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c index b244f40cd..78a200afa 100644 --- a/arch/cris/arch-v10/drivers/ds1302.c +++ b/arch/cris/arch-v10/drivers/ds1302.c @@ -4,9 +4,18 @@ *! *! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O *! -*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status +*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init *! *! $Log: ds1302.c,v $ +*! Revision 1.13 2004/05/28 09:26:59 starvik +*! Modified I2C initialization to work in 2.6. +*! +*! Revision 1.12 2004/05/14 07:58:03 starvik +*! Merge of changes from 2.4 +*! +*! Revision 1.10 2004/02/04 09:25:12 starvik +*! Merge of Linux 2.6.2 +*! *! Revision 1.9 2003/07/04 08:27:37 starvik *! Merge of Linux 2.5.74 *! @@ -114,7 +123,7 @@ *! *! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN *! -*! $Id: ds1302.c,v 1.9 2003/07/04 08:27:37 starvik Exp $ +*! $Id: ds1302.c,v 1.13 2004/05/28 09:26:59 starvik Exp $ *! *!***************************************************************************/ @@ -283,12 +292,23 @@ ds1302_readreg(int reg) void ds1302_writereg(int reg, unsigned char val) { - ds1302_wenable(); - start(); - out_byte(0x80 | (reg << 1)); /* write register */ - out_byte(val); - stop(); - ds1302_wdisable(); +#ifndef CONFIG_ETRAX_RTC_READONLY + int do_writereg = 1; +#else + int do_writereg = 0; + + if (reg == RTC_TRICKLECHARGER) + do_writereg = 1; +#endif + + if (do_writereg) { + ds1302_wenable(); + start(); + out_byte(0x80 | (reg << 1)); /* write register */ + out_byte(val); + stop(); + ds1302_wdisable(); + } } void @@ -426,20 +446,33 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F); ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); return 0; - } + } + case RTC_VLOW_RD: + { + /* TODO: + * Implement voltage low detection support + */ + printk(KERN_WARNING "DS1302: RTC Voltage Low detection" + " is not supported\n"); + return 0; + } + case RTC_VLOW_SET: + { + /* TODO: + * Nothing to do since Voltage Low detection is not supported + */ + return 0; + } default: return -ENOIOCTLCMD; } } -int -get_rtc_status(char *buf) +static void +print_rtc_status(void) { - char *p; struct rtc_time tm; - p = buf; - get_rtc_time(&tm); /* @@ -447,16 +480,12 @@ get_rtc_status(char *buf) * time or for Universal Standard Time (GMT). Probably local though. */ - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - - return p - buf; + printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n", + tm.tm_hour, tm.tm_min, tm.tm_sec); + printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); } - /* The various file operations we support. */ static struct file_operations rtc_fops = { @@ -487,11 +516,10 @@ ds1302_probe(void) out_byte(0xc1); /* read RAM byte 0 */ if((res = in_byte()) == MAGIC_PATTERN) { - char buf[100]; stop(); ds1302_wdisable(); - printk("%s: RTC found.\n", ds1302_name); - printk("%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n", + printk(KERN_INFO "%s: RTC found.\n", ds1302_name); + printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n", ds1302_name, CONFIG_ETRAX_DS1302_SDABIT, CONFIG_ETRAX_DS1302_SCLBIT, @@ -501,12 +529,10 @@ ds1302_probe(void) "PB", #endif CONFIG_ETRAX_DS1302_RSTBIT); - get_rtc_status(buf); - printk(buf); + print_rtc_status(); retval = 1; } else { stop(); - printk("%s: RTC not found.\n", ds1302_name); retval = 0; } @@ -518,7 +544,9 @@ ds1302_probe(void) int __init ds1302_init(void) -{ +{ + i2c_init(); + if (!ds1302_probe()) { #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT #if CONFIG_ETRAX_DS1302_RSTBIT == 27 @@ -539,16 +567,20 @@ ds1302_init(void) (IO_STATE(R_GEN_CONFIG, g0dir, out))); *R_GEN_CONFIG = genconfig_shadow; #endif - if (!ds1302_probe()) + if (!ds1302_probe()) { + printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); return -1; + } #else + printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name); return -1; #endif } - /* Initialise trickle charger */ ds1302_writereg(RTC_TRICKLECHARGER, RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F)); + /* Start clock by resetting CLOCK_HALT */ + ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F)); return 0; } diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index f0ea47014..960f4cbdc 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c @@ -20,6 +20,9 @@ *! in the spin-lock. *! *! $Log: eeprom.c,v $ +*! Revision 1.10 2003/09/11 07:29:48 starvik +*! Merge of Linux 2.6.0-test5 +*! *! Revision 1.9 2003/07/04 08:27:37 starvik *! Merge of Linux 2.5.74 *! @@ -441,9 +444,9 @@ int __init eeprom_init(void) static int eeprom_open(struct inode * inode, struct file * file) { - if(iminor(inode) != EEPROM_MINOR_NR) + if(MINOR(inode->i_rdev) != EEPROM_MINOR_NR) return -ENXIO; - if(imajor(inode) != EEPROM_MAJOR_NR) + if(MAJOR(inode->i_rdev) != EEPROM_MAJOR_NR) return -ENXIO; if( eeprom.size > 0 ) diff --git a/arch/cris/arch-v10/drivers/ethernet.c b/arch/cris/arch-v10/drivers/ethernet.c index 943db0b99..e13b754a2 100644 --- a/arch/cris/arch-v10/drivers/ethernet.c +++ b/arch/cris/arch-v10/drivers/ethernet.c @@ -1,4 +1,4 @@ -/* $Id: ethernet.c,v 1.17 2003/07/04 08:27:37 starvik Exp $ +/* $Id: ethernet.c,v 1.22 2004/05/14 07:58:03 starvik Exp $ * * e100net.c: A network driver for the ETRAX 100LX network controller. * @@ -7,6 +7,15 @@ * The outline of this driver comes from skeleton.c. * * $Log: ethernet.c,v $ + * Revision 1.22 2004/05/14 07:58:03 starvik + * Merge of changes from 2.4 + * + * Revision 1.20 2004/03/11 11:38:40 starvik + * Merge of Linux 2.6.4 + * + * Revision 1.18 2003/12/03 13:45:46 starvik + * Use hardware pad for short packets to prevent information leakage. + * * Revision 1.17 2003/07/04 08:27:37 starvik * Merge of Linux 2.5.74 * @@ -258,6 +267,16 @@ typedef struct etrax_eth_descr struct sk_buff* skb; } etrax_eth_descr; +/* Some transceivers requires special handling */ +struct transceiver_ops +{ + unsigned int oui; + void (*check_speed)(void); + void (*check_duplex)(void); +}; + +struct transceiver_ops* transceiver; + /* Duplex settings */ enum duplex { @@ -278,10 +297,17 @@ enum duplex */ #define MDIO_BASE_STATUS_REG 0x1 #define MDIO_BASE_CONTROL_REG 0x0 +#define MDIO_PHY_ID_HIGH_REG 0x2 +#define MDIO_PHY_ID_LOW_REG 0x3 #define MDIO_BC_NEGOTIATE 0x0200 #define MDIO_BC_FULL_DUPLEX_MASK 0x0100 #define MDIO_BC_AUTO_NEG_MASK 0x1000 #define MDIO_BC_SPEED_SELECT_MASK 0x2000 +#define MDIO_STATUS_100_FD 0x4000 +#define MDIO_STATUS_100_HD 0x2000 +#define MDIO_STATUS_10_FD 0x1000 +#define MDIO_STATUS_10_HD 0x0800 +#define MDIO_STATUS_SPEED_DUPLEX_MASK 0x7800 #define MDIO_ADVERTISMENT_REG 0x4 #define MDIO_ADVERT_100_FD 0x100 #define MDIO_ADVERT_100_HD 0x080 @@ -295,9 +321,13 @@ enum duplex /* Broadcom specific */ #define MDIO_AUX_CTRL_STATUS_REG 0x18 -#define MDIO_FULL_DUPLEX_IND 0x1 -#define MDIO_SPEED 0x2 -#define MDIO_PHYS_ADDR 0x0 +#define MDIO_BC_FULL_DUPLEX_IND 0x1 +#define MDIO_BC_SPEED 0x2 + +/* TDK specific */ +#define MDIO_TDK_DIAGNOSTIC_REG 18 +#define MDIO_TDK_DIAGNOSTIC_RATE 0x400 +#define MDIO_TDK_DIAGNOSTIC_DPLX 0x800 /* Network flash constants */ #define NET_FLASH_TIME (HZ/50) /* 20 ms */ @@ -341,6 +371,9 @@ static etrax_eth_descr* myNextTxDesc; /* Next descriptor to use */ static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32))); static unsigned int network_rec_config_shadow = 0; +static unsigned int mdio_phy_addr; /* Transciever address */ + +static unsigned int network_tr_ctrl_shadow = 0; /* Network speed indication. */ static struct timer_list speed_timer = TIMER_INITIALIZER(NULL, 0, 0); @@ -376,6 +409,7 @@ static void set_multicast_list(struct net_device *dev); static void e100_hardware_send_packet(char *buf, int length); static void update_rx_stats(struct net_device_stats *); static void update_tx_stats(struct net_device_stats *); +static int e100_probe_transceiver(void); static void e100_check_speed(unsigned long dummy); static void e100_set_speed(unsigned long speed); @@ -393,6 +427,21 @@ static void e100_reset_transceiver(void); static void e100_clear_network_leds(unsigned long dummy); static void e100_set_network_leds(int active); +static void broadcom_check_speed(void); +static void broadcom_check_duplex(void); +static void tdk_check_speed(void); +static void tdk_check_duplex(void); +static void generic_check_speed(void); +static void generic_check_duplex(void); + +struct transceiver_ops transceivers[] = +{ + {0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */ + {0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK 2120 */ + {0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */ + {0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */ +}; + #define tx_done(dev) (*R_DMA_CH0_CMD == 0) /* @@ -409,7 +458,8 @@ etrax_ethernet_init(void) struct net_device *dev; int i, err; - printk("ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2003 Axis Communications AB\n"); + printk(KERN_INFO + "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2003 Axis Communications AB\n"); dev = alloc_etherdev(sizeof(struct net_local)); if (!dev) @@ -496,7 +546,6 @@ etrax_ethernet_init(void) current_speed_selection = 0; /* Auto */ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; speed_timer.function = e100_check_speed; - add_timer(&speed_timer); clear_led_timer.function = e100_clear_network_leds; @@ -504,7 +553,6 @@ etrax_ethernet_init(void) current_duplex = autoneg; duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL; duplex_timer.function = e100_check_duplex; - add_timer(&duplex_timer); /* Initialize group address registers to make sure that no */ /* unwanted addresses are matched */ @@ -543,7 +591,7 @@ e100_set_mac_address(struct net_device *dev, void *p) /* show it in the log as well */ - printk("%s: changed MAC to ", dev->name); + printk(KERN_INFO "%s: changed MAC to ", dev->name); for (i = 0; i < 5; i++) printk("%02X:", dev->dev_addr[i]); @@ -569,12 +617,6 @@ e100_open(struct net_device *dev) { unsigned long flags; - /* disable the ethernet interface while we configure it */ - - *R_NETWORK_GEN_CONFIG = - IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | - IO_STATE(R_NETWORK_GEN_CONFIG, enable, off); - /* enable the MDIO output pin */ *R_NETWORK_MGM_CTRL = IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable); @@ -645,14 +687,14 @@ e100_open(struct net_device *dev) IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | IO_STATE(R_NETWORK_GEN_CONFIG, enable, on); - *R_NETWORK_TR_CTRL = - IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr) | - IO_STATE(R_NETWORK_TR_CTRL, delay, none) | - IO_STATE(R_NETWORK_TR_CTRL, cancel, dont) | - IO_STATE(R_NETWORK_TR_CTRL, cd, enable) | - IO_STATE(R_NETWORK_TR_CTRL, retry, enable) | - IO_STATE(R_NETWORK_TR_CTRL, pad, enable) | - IO_STATE(R_NETWORK_TR_CTRL, crc, enable); + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, delay, none); + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, cancel, dont); + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, cd, enable); + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, retry, enable); + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, pad, enable); + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, crc, enable); + *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; save_flags(flags); cli(); @@ -660,7 +702,8 @@ e100_open(struct net_device *dev) /* enable the irq's for ethernet DMA */ *R_IRQ_MASK2_SET = - IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); + IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) | + IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); *R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, overrun, set) | @@ -689,6 +732,14 @@ e100_open(struct net_device *dev) restore_flags(flags); + /* Probe for transceiver */ + if (e100_probe_transceiver()) + goto grace_exit3; + + /* Start duplex/speed timers */ + add_timer(&speed_timer); + add_timer(&duplex_timer); + /* We are now ready to accept transmit requeusts from * the queueing layer of the networking. */ @@ -696,6 +747,8 @@ e100_open(struct net_device *dev) return 0; +grace_exit3: + free_irq(NETWORK_STATUS_IRQ_NBR, (void *)dev); grace_exit2: free_irq(NETWORK_DMA_TX_IRQ_NBR, (void *)dev); grace_exit1: @@ -705,9 +758,38 @@ grace_exit0: } +static void +generic_check_speed(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG); + if ((data & MDIO_ADVERT_100_FD) || + (data & MDIO_ADVERT_100_HD)) + current_speed = 100; + else + current_speed = 10; +} + +static void +tdk_check_speed(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_TDK_DIAGNOSTIC_REG); + current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10); +} + +static void +broadcom_check_speed(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG); + current_speed = (data & MDIO_BC_SPEED ? 100 : 10); +} + static void e100_check_speed(unsigned long dummy) { + static int led_initiated = 0; unsigned long data; int old_speed = current_speed; @@ -715,12 +797,13 @@ e100_check_speed(unsigned long dummy) if (!(data & MDIO_LINK_UP_MASK)) { current_speed = 0; } else { - data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG); - current_speed = (data & MDIO_SPEED ? 100 : 10); + transceiver->check_speed(); } - if (old_speed != current_speed) + if ((old_speed != current_speed) || !led_initiated) { + led_initiated = 1; e100_set_network_leds(NO_NETWORK_ACTIVITY); + } /* Reinitialize the timer. */ speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; @@ -781,29 +864,21 @@ e100_negotiate(void) static void e100_set_speed(unsigned long speed) { - current_speed_selection = speed; - e100_negotiate(); + if (speed != current_speed_selection) { + current_speed_selection = speed; + e100_negotiate(); + } } static void e100_check_duplex(unsigned long dummy) { - unsigned long data; - - data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG); - - if (data & MDIO_FULL_DUPLEX_IND) { - if (!full_duplex) { /* Duplex changed to full? */ - full_duplex = 1; - SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); - *R_NETWORK_REC_CONFIG = network_rec_config_shadow; - } - } else { /* half */ - if (full_duplex) { /* Duplex changed to half? */ - full_duplex = 0; - SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); - *R_NETWORK_REC_CONFIG = network_rec_config_shadow; - } + int old_duplex = full_duplex; + transceiver->check_duplex(); + if (old_duplex != full_duplex) { + /* Duplex changed */ + SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex); + *R_NETWORK_REC_CONFIG = network_rec_config_shadow; } /* Reinitialize the timer. */ @@ -811,13 +886,72 @@ e100_check_duplex(unsigned long dummy) add_timer(&duplex_timer); } +static void +generic_check_duplex(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG); + if ((data & MDIO_ADVERT_100_FD) || + (data & MDIO_ADVERT_10_FD)) + full_duplex = 1; + else + full_duplex = 0; +} + +static void +tdk_check_duplex(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_TDK_DIAGNOSTIC_REG); + full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0; +} + +static void +broadcom_check_duplex(void) +{ + unsigned long data; + data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG); + full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0; +} + static void e100_set_duplex(enum duplex new_duplex) { - current_duplex = new_duplex; - e100_negotiate(); + if (new_duplex != current_duplex) { + current_duplex = new_duplex; + e100_negotiate(); + } } +static int +e100_probe_transceiver(void) +{ + unsigned int phyid_high; + unsigned int phyid_low; + unsigned int oui; + struct transceiver_ops* ops = NULL; + + /* Probe MDIO physical address */ + for (mdio_phy_addr = 0; mdio_phy_addr <= 31; mdio_phy_addr++) { + if (e100_get_mdio_reg(MDIO_BASE_STATUS_REG) != 0xffff) + break; + } + if (mdio_phy_addr == 32) + return -ENODEV; + + /* Get manufacturer */ + phyid_high = e100_get_mdio_reg(MDIO_PHY_ID_HIGH_REG); + phyid_low = e100_get_mdio_reg(MDIO_PHY_ID_LOW_REG); + oui = (phyid_high << 6) | (phyid_low >> 10); + + for (ops = &transceivers[0]; ops->oui; ops++) { + if (ops->oui == oui) + break; + } + transceiver = ops; + + return 0; +} static unsigned short e100_get_mdio_reg(unsigned char reg_num) @@ -827,7 +961,7 @@ e100_get_mdio_reg(unsigned char reg_num) int bitCounter; /* Start of frame, OP Code, Physical Address, Register Address */ - cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (MDIO_PHYS_ADDR << 7) | + cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (mdio_phy_addr << 7) | (reg_num << 2); e100_send_mdio_cmd(cmd, 0); @@ -848,7 +982,7 @@ e100_set_mdio_reg(unsigned char reg, unsigned short data) int bitCounter; unsigned short cmd; - cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) | + cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (reg << 2); e100_send_mdio_cmd(cmd, 1); @@ -916,7 +1050,7 @@ e100_reset_transceiver(void) data = e100_get_mdio_reg(MDIO_BASE_CONTROL_REG); - cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) | (MDIO_BASE_CONTROL_REG << 2); + cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (MDIO_BASE_CONTROL_REG << 2); e100_send_mdio_cmd(cmd, 1); @@ -984,7 +1118,6 @@ static int e100_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *np = (struct net_local *)dev->priv; - int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; unsigned long flags; @@ -997,15 +1130,12 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; - e100_hardware_send_packet(buf, length); + e100_hardware_send_packet(buf, skb->len); myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next); /* Stop queue if full */ if (myNextTxDesc == myFirstTxDesc) { - /* Enable transmit interrupt to wake up queue */ - *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); - *R_IRQ_MASK2_SET = IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set); netif_stop_queue(dev); } @@ -1026,6 +1156,11 @@ e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs * regs) struct net_local *np = (struct net_local *)dev->priv; unsigned long irqbits = *R_IRQ_MASK2_RD; + /* Disable RX/TX IRQs to avoid reentrancy */ + *R_IRQ_MASK2_CLR = + IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) | + IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr); + /* Handle received packets */ if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) { /* acknowledge the eop interrupt */ @@ -1069,9 +1204,14 @@ e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs * regs) if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) { /* acknowledge the eop interrupt and wake up queue */ *R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do); - *R_IRQ_MASK2_CLR = IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr); netif_wake_queue(dev); } + + /* Enable RX/TX IRQs again */ + *R_IRQ_MASK2_SET = + IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) | + IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); + return IRQ_HANDLED; } @@ -1084,7 +1224,9 @@ e100nw_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* check for underrun irq */ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, underrun, active)) { - *R_NETWORK_TR_CTRL = IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr); + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); + *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); np->stats.tx_errors++; D(printk("ethernet receiver underrun!\n")); } @@ -1096,6 +1238,9 @@ e100nw_interrupt(int irq, void *dev_id, struct pt_regs * regs) } /* check for excessive collision irq */ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, excessive_col, active)) { + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr); + *R_NETWORK_TR_CTRL = network_tr_ctrl_shadow; + SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop); *R_NETWORK_TR_CTRL = IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr); np->stats.tx_errors++; D(printk("ethernet excessive collisions!\n")); @@ -1210,14 +1355,10 @@ e100_close(struct net_device *dev) { struct net_local *np = (struct net_local *)dev->priv; - printk("Closing %s.\n", dev->name); + printk(KERN_INFO "Closing %s.\n", dev->name); netif_stop_queue(dev); - *R_NETWORK_GEN_CONFIG = - IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk) | - IO_STATE(R_NETWORK_GEN_CONFIG, enable, off); - *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) | IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) | @@ -1245,6 +1386,10 @@ e100_close(struct net_device *dev) update_rx_stats(&np->stats); update_tx_stats(&np->stats); + /* Stop speed/duplex timers */ + del_timer(&speed_timer); + del_timer(&duplex_timer); + return 0; } @@ -1259,7 +1404,7 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCETHTOOL: return e100_ethtool_ioctl(dev,ifr); case SIOCGMIIPHY: /* Get PHY address */ - data->phy_id = MDIO_PHYS_ADDR; + data->phy_id = mdio_phy_addr; break; case SIOCGMIIREG: /* Read MII register */ data->val_out = e100_get_mdio_reg(data->reg_num); @@ -1278,7 +1423,7 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SET_ETH_SPEED_AUTO: /* Auto negotiate speed */ e100_set_speed(0); break; - case SET_ETH_DUPLEX_HALF: /* Hhalf duplex. */ + case SET_ETH_DUPLEX_HALF: /* Half duplex. */ e100_set_duplex(half); break; case SET_ETH_DUPLEX_FULL: /* Full duplex. */ @@ -1312,12 +1457,12 @@ e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; ecmd.port = PORT_TP; ecmd.transceiver = XCVR_EXTERNAL; - ecmd.phy_address = MDIO_PHYS_ADDR; + ecmd.phy_address = mdio_phy_addr; ecmd.speed = current_speed; ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; ecmd.advertising = ADVERTISED_TP; if (current_duplex == autoneg && current_speed_selection == 0) - ecmd.advertising = ADVERTISED_Autoneg; + ecmd.advertising |= ADVERTISED_Autoneg; else { ecmd.advertising |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | @@ -1355,7 +1500,7 @@ e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) struct ethtool_drvinfo info; memset((void *) &info, 0, sizeof (info)); strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1); - strncpy(info.version, "$Revision: 1.17 $", sizeof(info.version) - 1); + strncpy(info.version, "$Revision: 1.22 $", sizeof(info.version) - 1); strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1); strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1); info.regdump_len = 0; @@ -1595,7 +1740,11 @@ e100_set_network_leds(int active) if (!current_speed) { /* Make LED red, link is down */ +#if defined(CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION) + LED_NETWORK_SET(LED_RED); +#else LED_NETWORK_SET(LED_OFF); +#endif } else if (light_leds) { if (current_speed == 10) { @@ -1615,4 +1764,26 @@ etrax_init_module(void) return etrax_ethernet_init(); } +static int __init +e100_boot_setup(char* str) +{ + struct sockaddr sa = {0}; + int i; + + /* Parse the colon separated Ethernet station address */ + for (i = 0; i < ETH_ALEN; i++) { + unsigned int tmp; + if (sscanf(str + 3*i, "%2x", &tmp) != 1) { + printk(KERN_WARNING "Malformed station address"); + return 0; + } + sa.sa_data[i] = (char)tmp; + } + + default_mac = sa; + return 1; +} + +__setup("etrax100_eth=", e100_boot_setup); + module_init(etrax_init_module); diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index f3a57162b..167291073 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c @@ -1,4 +1,4 @@ -/* $Id: gpio.c,v 1.8 2003/07/04 08:27:37 starvik Exp $ +/* $Id: gpio.c,v 1.11 2004/05/14 07:58:03 starvik Exp $ * * Etrax general port I/O device * @@ -9,6 +9,12 @@ * Johan Adolfsson (read/set directions, write, port G) * * $Log: gpio.c,v $ + * Revision 1.11 2004/05/14 07:58:03 starvik + * Merge of changes from 2.4 + * + * Revision 1.9 2003/09/11 07:29:48 starvik + * Merge of Linux 2.6.0-test5 + * * Revision 1.8 2003/07/04 08:27:37 starvik * Merge of Linux 2.5.74 * @@ -183,6 +189,7 @@ struct gpio_private { static struct gpio_private *alarmlist = 0; static int gpio_some_alarms = 0; /* Set if someone uses alarm */ +static unsigned long gpio_pa_irq_enabled_mask = 0; /* Port A and B use 8 bit access, but Port G is 32 bit */ #define NUM_PORTS (GPIO_MINOR_B+1) @@ -252,13 +259,19 @@ gpio_poll(struct file *file, unsigned long data; poll_wait(file, &priv->alarm_wq, wait); if (priv->minor == GPIO_MINOR_A) { + unsigned long flags; unsigned long tmp; data = *R_PORT_PA_DATA; /* PA has support for high level interrupt - * lets activate for those low and with highalarm set */ tmp = ~data & priv->highalarm & 0xFF; - *R_IRQ_MASK1_SET = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); + tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR); + save_flags(flags); cli(); + gpio_pa_irq_enabled_mask |= tmp; + *R_IRQ_MASK1_SET = tmp; + restore_flags(flags); + } else if (priv->minor == GPIO_MINOR_B) data = *R_PORT_PB_DATA; else if (priv->minor == GPIO_MINOR_G) @@ -312,12 +325,15 @@ gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long tmp; /* Find what PA interrupts are active */ - tmp = (*R_IRQ_READ1 >> R_IRQ_READ1__pa0__BITNR) & 0xFF; + tmp = (*R_IRQ_READ1); + + /* Find those that we have enabled */ + tmp &= gpio_pa_irq_enabled_mask; + /* Clear them.. */ - /* NOTE: Maybe we need to be more careful here if some other - * driver uses PA interrupt as well? - */ - *R_IRQ_MASK1_CLR = (tmp << R_IRQ_MASK1_CLR__pa0__BITNR); + *R_IRQ_MASK1_CLR = tmp; + gpio_pa_irq_enabled_mask &= ~tmp; + if (gpio_some_alarms) { return IRQ_RETVAL(etrax_gpio_wake_up_check()); } @@ -386,7 +402,7 @@ static int gpio_open(struct inode *inode, struct file *filp) { struct gpio_private *priv; - int p = iminor(inode); + int p = MINOR(inode->i_rdev); if (p > GPIO_MINOR_LAST) return -EINVAL; @@ -479,6 +495,7 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */ } else if (priv->minor == GPIO_MINOR_G) { /* We must fiddle with R_GEN_CONFIG to change dir */ + save_flags(flags); cli(); if (((arg & dir_g_in_bits) != arg) && (arg & changeable_dir_g)) { arg &= changeable_dir_g; @@ -503,16 +520,17 @@ unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg) dir_g_in_bits |= (1<<24); dir_g_out_bits &= ~(1<<24); } - printk("gpio: SETINPUT on port G set " - "genconfig to 0x%08lX " - "in_bits: 0x%08lX " - "out_bits: 0x%08lX\n", - (unsigned long)genconfig_shadow, - dir_g_in_bits, dir_g_out_bits); + D(printk(KERN_INFO "gpio: SETINPUT on port G set " + "genconfig to 0x%08lX " + "in_bits: 0x%08lX " + "out_bits: 0x%08lX\n", + (unsigned long)genconfig_shadow, + dir_g_in_bits, dir_g_out_bits)); *R_GEN_CONFIG = genconfig_shadow; /* Must be a >120 ns delay before writing this again */ } + restore_flags(flags); return dir_g_in_bits; } return 0; @@ -529,6 +547,7 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) return *priv->dir_shadow; } else if (priv->minor == GPIO_MINOR_G) { /* We must fiddle with R_GEN_CONFIG to change dir */ + save_flags(flags); cli(); if (((arg & dir_g_out_bits) != arg) && (arg & changeable_dir_g)) { /* Set bits in genconfig to set to output */ @@ -552,15 +571,16 @@ unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg) dir_g_out_bits |= (1<<24); dir_g_in_bits &= ~(1<<24); } - printk("gpio: SETOUTPUT on port G set " - "genconfig to 0x%08lX " - "in_bits: 0x%08lX " - "out_bits: 0x%08lX\n", - (unsigned long)genconfig_shadow, - dir_g_in_bits, dir_g_out_bits); + D(printk(KERN_INFO "gpio: SETOUTPUT on port G set " + "genconfig to 0x%08lX " + "in_bits: 0x%08lX " + "out_bits: 0x%08lX\n", + (unsigned long)genconfig_shadow, + dir_g_in_bits, dir_g_out_bits)); *R_GEN_CONFIG = genconfig_shadow; /* Must be a >120 ns delay before writing this again */ } + restore_flags(flags); return dir_g_out_bits & 0x7FFFFFFF; } return 0; @@ -625,6 +645,20 @@ gpio_ioctl(struct inode *inode, struct file *file, // clear alarm for bits with 1 in arg priv->highalarm &= ~arg; priv->lowalarm &= ~arg; + { + /* Must update gpio_some_alarms */ + struct gpio_private *p = alarmlist; + int some_alarms; + some_alarms = 0; + while (p) { + if (p->highalarm | p->lowalarm) { + some_alarms = 1; + break; + } + p = p->next; + } + gpio_some_alarms = some_alarms; + } break; case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */ /* Read direction 0=input 1=output */ @@ -844,9 +878,9 @@ static void __init gpio_init_port_g(void) dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g); - printk("GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", + printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n", dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA); - printk("GPIO port G: dir: %08lX changeable: %08lX\n", + printk(KERN_INFO "GPIO port G: dir: %08lX changeable: %08lX\n", dir_g_shadow, changeable_dir_g); } @@ -883,7 +917,7 @@ gpio_init(void) #endif gpio_init_port_g(); - printk("ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n"); + printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n"); /* We call etrax_gpio_wake_up_check() from timer interrupt and * from cpu_idle() in kernel/process.c * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms @@ -891,11 +925,11 @@ gpio_init(void) */ if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt, SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) { - printk("err: timer0 irq for gpio\n"); + printk(KERN_CRIT "err: timer0 irq for gpio\n"); } if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt, SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) { - printk("err: PA irq for gpio\n"); + printk(KERN_CRIT "err: PA irq for gpio\n"); } diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c index 7731f7d22..52a299d89 100644 --- a/arch/cris/arch-v10/drivers/i2c.c +++ b/arch/cris/arch-v10/drivers/i2c.c @@ -12,6 +12,12 @@ *! don't use PB_I2C if DS1302 uses same bits, *! use PB. *! $Log: i2c.c,v $ +*! Revision 1.7 2004/05/28 09:26:59 starvik +*! Modified I2C initialization to work in 2.6. +*! +*! Revision 1.6 2004/05/14 07:58:03 starvik +*! Merge of changes from 2.4 +*! *! Revision 1.4 2002/12/11 13:13:57 starvik *! Added arch/ to v10 specific includes *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer) @@ -63,7 +69,7 @@ *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN *! *!***************************************************************************/ -/* $Id: i2c.c,v 1.4 2002/12/11 13:13:57 starvik Exp $ */ +/* $Id: i2c.c,v 1.7 2004/05/28 09:26:59 starvik Exp $ */ /****************** INCLUDE FILES SECTION ***********************************/ @@ -310,6 +316,12 @@ i2c_inbyte(void) } i2c_clk(I2C_CLOCK_HIGH); i2c_delay(CLOCK_HIGH_TIME); + + /* + * we leave the clock low, getbyte is usually followed + * by sendack/nack, they assume the clock to be low + */ + i2c_clk(I2C_CLOCK_LOW); return aBitByte; } @@ -371,6 +383,13 @@ i2c_getack(void) i2c_delay(CLOCK_HIGH_TIME/2); } + /* + * our clock is high now, make sure data is low + * before we enable our output. If we keep data high + * and enable output, we would generate a stop condition. + */ + i2c_data(I2C_DATA_LOW); + /* * end clock pulse */ @@ -426,6 +445,37 @@ i2c_sendack(void) i2c_dir_in(); } +/*#--------------------------------------------------------------------------- +*# +*# FUNCTION NAME: i2c_sendnack +*# +*# DESCRIPTION : Sends NACK on received data +*# +*#--------------------------------------------------------------------------*/ +void +i2c_sendnack(void) +{ + /* + * enable output + */ + i2c_delay(CLOCK_LOW_TIME); + i2c_dir_out(); + /* + * set data high + */ + i2c_data(I2C_DATA_HIGH); + /* + * generate clock pulse + */ + i2c_delay(CLOCK_HIGH_TIME/6); + i2c_clk(I2C_CLOCK_HIGH); + i2c_delay(CLOCK_HIGH_TIME); + i2c_clk(I2C_CLOCK_LOW); + i2c_delay(CLOCK_LOW_TIME); + + i2c_dir_in(); +} + /*#--------------------------------------------------------------------------- *# *# FUNCTION NAME: i2c_writereg @@ -489,7 +539,7 @@ i2c_writereg(unsigned char theSlave, unsigned char theReg, } while(error && cntr--); i2c_delay(CLOCK_LOW_TIME); - + return -error; } @@ -557,7 +607,8 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg) */ b = i2c_inbyte(); /* - * send Ack + * last received byte needs to be nacked + * instead of acked */ i2c_sendack(); /* @@ -634,11 +685,9 @@ static struct file_operations i2c_fops = { .release = i2c_release, }; -static int __init +int __init i2c_init(void) { - int res; - /* Setup and enable the Port B I2C interface */ #ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C @@ -656,21 +705,28 @@ i2c_init(void) IO_STATE(R_PORT_PB_DIR, dir0, input) | IO_STATE(R_PORT_PB_DIR, dir1, output)); - /* register char device */ + return 0; +} + +static int __init +i2c_register(void) +{ + int res; - res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); + i2c_init(); + res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops); if(res < 0) { printk(KERN_ERR "i2c: couldn't get a major number.\n"); return res; } - printk("I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); + printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n"); return 0; } -/* this makes sure that i2c_init is called during boot */ +/* this makes sure that i2c_register is called during boot */ -module_init(i2c_init); +module_init(i2c_register); /****************** END OF FILE i2c.c ********************************/ diff --git a/arch/cris/arch-v10/drivers/i2c.h b/arch/cris/arch-v10/drivers/i2c.h index d0caa9ff8..4ee91426b 100644 --- a/arch/cris/arch-v10/drivers/i2c.h +++ b/arch/cris/arch-v10/drivers/i2c.h @@ -1,4 +1,6 @@ -/* $Id: i2c.h,v 1.2 2002/11/18 13:16:06 starvik Exp $ */ +/* $Id: i2c.h,v 1.3 2004/05/28 09:26:59 starvik Exp $ */ + +int i2c_init(void); /* High level I2C actions */ int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue); diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c index 95cfaddc8..8cf5f620e 100644 --- a/arch/cris/arch-v10/drivers/pcf8563.c +++ b/arch/cris/arch-v10/drivers/pcf8563.c @@ -15,7 +15,7 @@ * * Author: Tobias Anderberg . * - * $Id: pcf8563.c,v 1.1 2002/12/12 08:27:26 starvik Exp $ + * $Id: pcf8563.c,v 1.4 2004/05/28 09:26:59 starvik Exp $ */ #include @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -39,7 +40,7 @@ #define PCF8563_MAJOR 121 /* Local major number. */ #define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */ #define PCF8563_NAME "PCF8563" -#define DRIVER_VERSION "$Revision: 1.1 $" +#define DRIVER_VERSION "$Revision: 1.4 $" /* I2C bus slave registers. */ #define RTC_I2C_READ 0xa3 @@ -85,7 +86,12 @@ pcf8563_readreg(int reg) void pcf8563_writereg(int reg, unsigned char val) { - i2c_writereg(RTC_I2C_WRITE,reg,val); +#ifdef CONFIG_ETRAX_RTC_READONLY + if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR)) + return; +#endif + + rtc_write(reg, val); } void @@ -120,6 +126,9 @@ int __init pcf8563_init(void) { unsigned char ret; + + i2c_init(); + /* * First of all we need to reset the chip. This is done by * clearing control1, control2 and clk freq, clear the @@ -152,14 +161,6 @@ pcf8563_init(void) if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0) goto err; - - if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { - printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", - PCF8563_NAME, PCF8563_MAJOR); - return -1; - } - - printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); /* Check for low voltage, and warn about it.. */ if (rtc_read(RTC_SECONDS) & 0x80) @@ -210,9 +211,11 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned break; case RTC_SET_TIME: { +#ifdef CONFIG_ETRAX_RTC_READONLY + return -EPERM; +#else int leap; int century; - unsigned long flags; struct rtc_time tm; memset(&tm, 0, sizeof (struct rtc_time)); @@ -256,8 +259,35 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned rtc_write(RTC_SECONDS, tm.tm_sec); return 0; +#endif /* !CONFIG_ETRAX_RTC_READONLY */ } - break; + + case RTC_VLOW_RD: + { + int vl_bit = 0; + + if (rtc_read(RTC_SECONDS) & 0x80) { + vl_bit = 1; + printk(KERN_WARNING "%s: RTC Voltage Low - reliable " + "date/time information is no longer guaranteed!\n", + PCF8563_NAME); + } + if (copy_to_user((int *) arg, &vl_bit, sizeof(int))) + return -EFAULT; + + return 0; + } + + case RTC_VLOW_SET: + { + /* Clear the VL bit in the seconds register */ + int ret = rtc_read(RTC_SECONDS); + + rtc_write(RTC_SECONDS, (ret & 0x7F)); + + return 0; + } + default: return -ENOTTY; } @@ -265,5 +295,19 @@ pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned return 0; } -module_init(pcf8563_init); +static int __init +pcf8563_register(void) +{ + pcf8563_init(); + if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) { + printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", + PCF8563_NAME, PCF8563_MAJOR); + return -1; + } + + printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION); + return 0; +} + +module_init(pcf8563_register); module_exit(pcf8563_exit); diff --git a/arch/cris/arch-v10/drivers/serial.c b/arch/cris/arch-v10/drivers/serial.c index 2822ffb81..272795de9 100644 --- a/arch/cris/arch-v10/drivers/serial.c +++ b/arch/cris/arch-v10/drivers/serial.c @@ -1,4 +1,4 @@ -/* $Id: serial.c,v 1.17 2003/07/04 08:27:37 starvik Exp $ +/* $Id: serial.c,v 1.20 2004/05/24 12:00:20 starvik Exp $ * * Serial port driver for the ETRAX 100LX chip * @@ -7,6 +7,16 @@ * Many, many authors. Based once upon a time on serial.c for 16x50. * * $Log: serial.c,v $ + * Revision 1.20 2004/05/24 12:00:20 starvik + * Big merge of stuff from Linux 2.4 (e.g. manual mode for the serial port). + * + * Revision 1.19 2004/05/17 13:12:15 starvik + * Kernel console hook + * Big merge from Linux 2.4 still pending. + * + * Revision 1.18 2003/10/28 07:18:30 starvik + * Compiles with debug info + * * Revision 1.17 2003/07/04 08:27:37 starvik * Merge of Linux 2.5.74 * @@ -399,7 +409,7 @@ * */ -static char *serial_version = "$Revision: 1.17 $"; +static char *serial_version = "$Revision: 1.20 $"; #include #include @@ -447,6 +457,10 @@ static char *serial_version = "$Revision: 1.17 $"; #error "RX_TIMEOUT_TICKS == 0 not allowed, use 1" #endif +#if defined(CONFIG_ETRAX_RS485_ON_PA) && defined(CONFIG_ETRAX_RS485_ON_PORT_G) +#error "Disable either CONFIG_ETRAX_RS485_ON_PA or CONFIG_ETRAX_RS485_ON_PORT_G" +#endif + /* * All of the compatibilty code so we can compile serial.c against * older kernels is hidden in serial_compat.h @@ -473,7 +487,7 @@ struct tty_driver *serial_driver; //#define SERIAL_DEBUG_DATA //#define SERIAL_DEBUG_THROTTLE //#define SERIAL_DEBUG_IO /* Debug for Extra control and status pins */ -#define SERIAL_DEBUG_LINE 0 /* What serport we want to debug */ +//#define SERIAL_DEBUG_LINE 0 /* What serport we want to debug */ /* Enable this to use serial interrupts to handle when you expect the first received event on the serial port to @@ -481,14 +495,74 @@ struct tty_driver *serial_driver; from eLinux */ #define SERIAL_HANDLE_EARLY_ERRORS -#define TTY_THROTTLE_LIMIT (TTY_FLIPBUF_SIZE/10) +/* Defined and used in n_tty.c, but we need it here as well */ +#define TTY_THRESHOLD_THROTTLE 128 +/* Due to buffersizes and threshold values, our SERIAL_DESCR_BUF_SIZE + * must not be to high or flow control won't work if we leave it to the tty + * layer so we have our own throttling in flush_to_flip + * TTY_FLIPBUF_SIZE=512, + * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128 + * BUF_SIZE can't be > 128 + */ +/* Currently 16 descriptors x 128 bytes = 2048 bytes */ #define SERIAL_DESCR_BUF_SIZE 256 +#define SERIAL_PRESCALE_BASE 3125000 /* 3.125MHz */ +#define DEF_BAUD_BASE SERIAL_PRESCALE_BASE + +/* We don't want to load the system with massive fast timer interrupt + * on high baudrates so limit it to 250 us (4kHz) */ +#define MIN_FLUSH_TIME_USEC 250 + /* Add an x here to log a lot of timer stuff */ #define TIMERD(x) - +/* Debug details of interrupt handling */ +#define DINTR1(x) /* irq on/off, errors */ +#define DINTR2(x) /* tx and rx */ +/* Debug flip buffer stuff */ +#define DFLIP(x) +/* Debug flow control and overview of data flow */ +#define DFLOW(x) +#define DBAUD(x) +#define DLOG_INT_TRIG(x) + +//#define DEBUG_LOG_INCLUDED +#ifndef DEBUG_LOG_INCLUDED #define DEBUG_LOG(line, string, value) +#else +struct debug_log_info +{ + unsigned long time; + unsigned long timer_data; +// int line; + const char *string; + int value; +}; +#define DEBUG_LOG_SIZE 4096 + +struct debug_log_info debug_log[DEBUG_LOG_SIZE]; +int debug_log_pos = 0; + +#define DEBUG_LOG(_line, _string, _value) do { \ + if ((_line) == SERIAL_DEBUG_LINE) {\ + debug_log_func(_line, _string, _value); \ + }\ +}while(0) + +void debug_log_func(int line, const char *string, int value) +{ + if (debug_log_pos < DEBUG_LOG_SIZE) { + debug_log[debug_log_pos].time = jiffies; + debug_log[debug_log_pos].timer_data = *R_TIMER_DATA; +// debug_log[debug_log_pos].line = line; + debug_log[debug_log_pos].string = string; + debug_log[debug_log_pos].value = value; + debug_log_pos++; + } + /*printk(string, value);*/ +} +#endif #ifndef CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS /* Default number of timer ticks before flushing rx fifo @@ -498,11 +572,14 @@ struct tty_driver *serial_driver; #define CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS 5 #endif +unsigned long timer_data_to_ns(unsigned long timer_data); + static void change_speed(struct e100_serial *info); +static void rs_throttle(struct tty_struct * tty); static void rs_wait_until_sent(struct tty_struct *tty, int timeout); static int rs_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count); -static inline int raw_write(struct tty_struct * tty, int from_user, +extern _INLINE_ int rs_raw_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count); #ifdef CONFIG_ETRAX_RS485 static int e100_write_rs485(struct tty_struct * tty, int from_user, @@ -511,7 +588,7 @@ static int e100_write_rs485(struct tty_struct * tty, int from_user, static int get_lsr_info(struct e100_serial * info, unsigned int *value); -#define DEF_BAUD 0x99 /* 115.2 kbit/s */ +#define DEF_BAUD 115200 /* 115.2 kbit/s */ #define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) #define DEF_RX 0x20 /* or SERIAL_CTRL_W >> 8 */ /* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */ @@ -520,6 +597,7 @@ static int get_lsr_info(struct e100_serial * info, unsigned int *value); /* offsets from R_SERIALx_CTRL */ #define REG_DATA 0 +#define REG_DATA_STATUS32 0 /* this is the 32 bit register R_SERIALx_READ */ #define REG_TR_DATA 0 #define REG_STATUS 1 #define REG_TR_CTRL 1 @@ -555,60 +633,162 @@ static int get_lsr_info(struct e100_serial * info, unsigned int *value); */ +/* Mask for the irqs possibly enabled in R_IRQ_MASK1_RD etc. */ +static const unsigned long e100_ser_int_mask = 0 +#ifdef CONFIG_ETRAX_SERIAL_PORT0 +| IO_MASK(R_IRQ_MASK1_RD, ser0_data) | IO_MASK(R_IRQ_MASK1_RD, ser0_ready) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT1 +| IO_MASK(R_IRQ_MASK1_RD, ser1_data) | IO_MASK(R_IRQ_MASK1_RD, ser1_ready) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2 +| IO_MASK(R_IRQ_MASK1_RD, ser2_data) | IO_MASK(R_IRQ_MASK1_RD, ser2_ready) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT3 +| IO_MASK(R_IRQ_MASK1_RD, ser3_data) | IO_MASK(R_IRQ_MASK1_RD, ser3_ready) +#endif +; +unsigned long r_alt_ser_baudrate_shadow = 0; + /* this is the data for the four serial ports in the etrax100 */ /* DMA2(ser2), DMA4(ser3), DMA6(ser0) or DMA8(ser1) */ /* R_DMA_CHx_CLR_INTR, R_DMA_CHx_FIRST, R_DMA_CHx_CMD */ static struct e100_serial rs_table[] = { - { DEF_BAUD, (unsigned char *)R_SERIAL0_CTRL, 1U << 12, /* uses DMA 6 and 7 */ - R_DMA_CH6_CLR_INTR, R_DMA_CH6_FIRST, R_DMA_CH6_CMD, - R_DMA_CH6_STATUS, R_DMA_CH6_HWSW, R_DMA_CH6_DESCR, - R_DMA_CH7_CLR_INTR, R_DMA_CH7_FIRST, R_DMA_CH7_CMD, - R_DMA_CH7_STATUS, R_DMA_CH7_HWSW, R_DMA_CH7_DESCR, - STD_FLAGS, DEF_RX, DEF_TX, 2, + { .baud = DEF_BAUD, + .port = (unsigned char *)R_SERIAL0_CTRL, + .irq = 1U << 12, /* uses DMA 6 and 7 */ + .oclrintradr = R_DMA_CH6_CLR_INTR, + .ofirstadr = R_DMA_CH6_FIRST, + .ocmdadr = R_DMA_CH6_CMD, + .ostatusadr = R_DMA_CH6_STATUS, + .iclrintradr = R_DMA_CH7_CLR_INTR, + .ifirstadr = R_DMA_CH7_FIRST, + .icmdadr = R_DMA_CH7_CMD, + .idescradr = R_DMA_CH7_DESCR, + .flags = STD_FLAGS, + .rx_ctrl = DEF_RX, + .tx_ctrl = DEF_TX, + .iseteop = 2, #ifdef CONFIG_ETRAX_SERIAL_PORT0 - 1 + .enabled = 1, +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT + .dma_out_enabled = 1, +#else + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN + .dma_in_enabled = 1, #else - 0 + .dma_in_enabled = 0 #endif +#else + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 +#endif + }, /* ttyS0 */ #ifndef CONFIG_SVINTO_SIM - { DEF_BAUD, (unsigned char *)R_SERIAL1_CTRL, 1U << 16, /* uses DMA 8 and 9 */ - R_DMA_CH8_CLR_INTR, R_DMA_CH8_FIRST, R_DMA_CH8_CMD, - R_DMA_CH8_STATUS, R_DMA_CH8_HWSW, R_DMA_CH8_DESCR, - R_DMA_CH9_CLR_INTR, R_DMA_CH9_FIRST, R_DMA_CH9_CMD, - R_DMA_CH9_STATUS, R_DMA_CH9_HWSW, R_DMA_CH9_DESCR, - STD_FLAGS, DEF_RX, DEF_TX, 3 , + { .baud = DEF_BAUD, + .port = (unsigned char *)R_SERIAL1_CTRL, + .irq = 1U << 16, /* uses DMA 8 and 9 */ + .oclrintradr = R_DMA_CH8_CLR_INTR, + .ofirstadr = R_DMA_CH8_FIRST, + .ocmdadr = R_DMA_CH8_CMD, + .ostatusadr = R_DMA_CH8_STATUS, + .iclrintradr = R_DMA_CH9_CLR_INTR, + .ifirstadr = R_DMA_CH9_FIRST, + .icmdadr = R_DMA_CH9_CMD, + .idescradr = R_DMA_CH9_DESCR, + .flags = STD_FLAGS, + .rx_ctrl = DEF_RX, + .tx_ctrl = DEF_TX, + .iseteop = 3, #ifdef CONFIG_ETRAX_SERIAL_PORT1 - 1 + .enabled = 1, +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT + .dma_out_enabled = 1, +#else + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN + .dma_in_enabled = 1, +#else + .dma_in_enabled = 0 +#endif #else - 0 + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 #endif }, /* ttyS1 */ - { DEF_BAUD, (unsigned char *)R_SERIAL2_CTRL, 1U << 4, /* uses DMA 2 and 3 */ - R_DMA_CH2_CLR_INTR, R_DMA_CH2_FIRST, R_DMA_CH2_CMD, - R_DMA_CH2_STATUS, R_DMA_CH2_HWSW, R_DMA_CH2_DESCR, - R_DMA_CH3_CLR_INTR, R_DMA_CH3_FIRST, R_DMA_CH3_CMD, - R_DMA_CH3_STATUS, R_DMA_CH3_HWSW, R_DMA_CH3_DESCR, - STD_FLAGS, DEF_RX, DEF_TX, 0, + { .baud = DEF_BAUD, + .port = (unsigned char *)R_SERIAL2_CTRL, + .irq = 1U << 4, /* uses DMA 2 and 3 */ + .oclrintradr = R_DMA_CH2_CLR_INTR, + .ofirstadr = R_DMA_CH2_FIRST, + .ocmdadr = R_DMA_CH2_CMD, + .ostatusadr = R_DMA_CH2_STATUS, + .iclrintradr = R_DMA_CH3_CLR_INTR, + .ifirstadr = R_DMA_CH3_FIRST, + .icmdadr = R_DMA_CH3_CMD, + .idescradr = R_DMA_CH3_DESCR, + .flags = STD_FLAGS, + .rx_ctrl = DEF_RX, + .tx_ctrl = DEF_TX, + .iseteop = 0, #ifdef CONFIG_ETRAX_SERIAL_PORT2 - 1 + .enabled = 1, +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT + .dma_out_enabled = 1, +#else + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + .dma_in_enabled = 1, +#else + .dma_in_enabled = 0 +#endif #else - 0 + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 #endif }, /* ttyS2 */ - { DEF_BAUD, (unsigned char *)R_SERIAL3_CTRL, 1U << 8, /* uses DMA 4 and 5 */ - R_DMA_CH4_CLR_INTR, R_DMA_CH4_FIRST, R_DMA_CH4_CMD, - R_DMA_CH4_STATUS, R_DMA_CH4_HWSW, R_DMA_CH4_DESCR, - R_DMA_CH5_CLR_INTR, R_DMA_CH5_FIRST, R_DMA_CH5_CMD, - R_DMA_CH5_STATUS, R_DMA_CH5_HWSW, R_DMA_CH5_DESCR, - STD_FLAGS, DEF_RX, DEF_TX, 1, + { .baud = DEF_BAUD, + .port = (unsigned char *)R_SERIAL3_CTRL, + .irq = 1U << 8, /* uses DMA 4 and 5 */ + .oclrintradr = R_DMA_CH4_CLR_INTR, + .ofirstadr = R_DMA_CH4_FIRST, + .ocmdadr = R_DMA_CH4_CMD, + .ostatusadr = R_DMA_CH4_STATUS, + .iclrintradr = R_DMA_CH5_CLR_INTR, + .ifirstadr = R_DMA_CH5_FIRST, + .icmdadr = R_DMA_CH5_CMD, + .idescradr = R_DMA_CH5_DESCR, + .flags = STD_FLAGS, + .rx_ctrl = DEF_RX, + .tx_ctrl = DEF_TX, + .iseteop = 1, #ifdef CONFIG_ETRAX_SERIAL_PORT3 - 1 + .enabled = 1, +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT + .dma_out_enabled = 1, #else - 0 + .dma_out_enabled = 0, +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN + .dma_in_enabled = 1, +#else + .dma_in_enabled = 0 +#endif +#else + .enabled = 0, + .dma_out_enabled = 0, + .dma_in_enabled = 0 #endif } /* ttyS3 */ #endif @@ -616,6 +796,9 @@ static struct e100_serial rs_table[] = { #define NR_PORTS (sizeof(rs_table)/sizeof(struct e100_serial)) + +static struct termios *serial_termios[NR_PORTS]; +static struct termios *serial_termios_locked[NR_PORTS]; #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER static struct fast_timer fast_timers[NR_PORTS]; #endif @@ -652,6 +835,9 @@ static struct fast_timer fast_timers_rs485[NR_PORTS]; #if defined(CONFIG_ETRAX_RS485_ON_PA) static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT; #endif +#if defined(CONFIG_ETRAX_RS485_ON_PORT_G) +static int rs485_port_g_bit = CONFIG_ETRAX_RS485_ON_PORT_G_BIT; +#endif #endif /* Info and macros needed for each ports extra control/status signals. */ @@ -761,7 +947,7 @@ static unsigned char dummy_ser[NR_PORTS] = {0xFF, 0xFF, 0xFF,0xFF}; # endif #endif -#define SER0_PB_BITSUM (CONFIG_ETRAX_SER1_DTR_ON_PB_BIT+CONFIG_ETRAX_SER1_RI_ON_PB_BIT+CONFIG_ETRAX_SER1_DSR_ON_PB_BIT+CONFIG_ETRAX_SER1_CD_ON_PB_BIT) +#define SER1_PB_BITSUM (CONFIG_ETRAX_SER1_DTR_ON_PB_BIT+CONFIG_ETRAX_SER1_RI_ON_PB_BIT+CONFIG_ETRAX_SER1_DSR_ON_PB_BIT+CONFIG_ETRAX_SER1_CD_ON_PB_BIT) #if SER1_PB_BITSUM != -4 # if CONFIG_ETRAX_SER1_DTR_ON_PB_BIT == -1 @@ -1081,15 +1267,9 @@ static const struct control_pins e100_modem_pins[NR_PORTS] = }; #endif /* !CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED */ -#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_RS485_ON_PA) -unsigned char rs485_pa_port = CONFIG_ETRAX_RS485_ON_PA_BIT; -#endif - - #define E100_RTS_MASK 0x20 #define E100_CTS_MASK 0x40 - /* All serial port signals are active low: * active = 0 -> 3.3V to RS-232 driver -> -12V on RS-232 level * inactive = 1 -> 0V to RS-232 driver -> +12V on RS-232 level @@ -1151,6 +1331,10 @@ static void update_char_time(struct e100_serial * info) /* calc timeout */ info->char_time_usec = ((bits * 1000000) / info->baud) + 1; + info->flush_time_usec = 4*info->char_time_usec; + if (info->flush_time_usec < MIN_FLUSH_TIME_USEC) + info->flush_time_usec = MIN_FLUSH_TIME_USEC; + } /* @@ -1250,9 +1434,13 @@ static inline void e100_rts(struct e100_serial *info, int set) { #ifndef CONFIG_SVINTO_SIM + unsigned long flags; + save_flags(flags); + cli(); info->rx_ctrl &= ~E100_RTS_MASK; info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */ info->port[REG_REC_CTRL] = info->rx_ctrl; + restore_flags(flags); #ifdef SERIAL_DEBUG_IO printk("ser%i rts %i\n", info->line, set); #endif @@ -1326,6 +1514,7 @@ e100_disable_rxdma_irq(struct e100_serial *info) #ifdef SERIAL_DEBUG_INTR printk("rxdma_irq(%d): 0\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ disable_rxdma_irq %i\n", info->line)); *R_IRQ_MASK2_CLR = (info->irq << 2) | (info->irq << 3); } @@ -1335,30 +1524,33 @@ e100_enable_rxdma_irq(struct e100_serial *info) #ifdef SERIAL_DEBUG_INTR printk("rxdma_irq(%d): 1\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ enable_rxdma_irq %i\n", info->line)); *R_IRQ_MASK2_SET = (info->irq << 2) | (info->irq << 3); } /* the tx DMA uses only dma_descr interrupt */ -static inline void +static _INLINE_ void e100_disable_txdma_irq(struct e100_serial *info) { #ifdef SERIAL_DEBUG_INTR printk("txdma_irq(%d): 0\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ disable_txdma_irq %i\n", info->line)); *R_IRQ_MASK2_CLR = info->irq; } -static inline void +static _INLINE_ void e100_enable_txdma_irq(struct e100_serial *info) { #ifdef SERIAL_DEBUG_INTR printk("txdma_irq(%d): 1\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ enable_txdma_irq %i\n", info->line)); *R_IRQ_MASK2_SET = info->irq; } -static inline void +static _INLINE_ void e100_disable_txdma_channel(struct e100_serial *info) { unsigned long flags; @@ -1367,32 +1559,46 @@ e100_disable_txdma_channel(struct e100_serial *info) * ( set to something other then serialX) */ save_flags(flags); - cli(); + cli(); + DFLOW(DEBUG_LOG(info->line, "disable_txdma_channel %i\n", info->line)); if (info->line == 0) { - genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); - genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma6)) == + IO_STATE(R_GEN_CONFIG, dma6, serial0)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); + } } else if (info->line == 1) { - genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); - genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma8)) == + IO_STATE(R_GEN_CONFIG, dma8, serial1)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); + } } else if (info->line == 2) { - genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); - genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma2)) == + IO_STATE(R_GEN_CONFIG, dma2, serial2)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); + } } else if (info->line == 3) { - genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4); - genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1); + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma4)) == + IO_STATE(R_GEN_CONFIG, dma4, serial3)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1); + } } *R_GEN_CONFIG = genconfig_shadow; restore_flags(flags); } -static inline void +static _INLINE_ void e100_enable_txdma_channel(struct e100_serial *info) { unsigned long flags; save_flags(flags); - cli(); + cli(); + DFLOW(DEBUG_LOG(info->line, "enable_txdma_channel %i\n", info->line)); /* Enable output DMA channel for the serial port in question */ if (info->line == 0) { genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); @@ -1411,6 +1617,70 @@ e100_enable_txdma_channel(struct e100_serial *info) restore_flags(flags); } +static _INLINE_ void +e100_disable_rxdma_channel(struct e100_serial *info) +{ + unsigned long flags; + + /* Disable input DMA channel for the serial port in question + * ( set to something other then serialX) + */ + save_flags(flags); + cli(); + if (info->line == 0) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma7)) == + IO_STATE(R_GEN_CONFIG, dma7, serial0)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, unused); + } + } else if (info->line == 1) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma9)) == + IO_STATE(R_GEN_CONFIG, dma9, serial1)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma9); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, usb); + } + } else if (info->line == 2) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma3)) == + IO_STATE(R_GEN_CONFIG, dma3, serial2)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0); + } + } else if (info->line == 3) { + if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma5)) == + IO_STATE(R_GEN_CONFIG, dma5, serial3)) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1); + } + } + *R_GEN_CONFIG = genconfig_shadow; + restore_flags(flags); +} + + +static _INLINE_ void +e100_enable_rxdma_channel(struct e100_serial *info) +{ + unsigned long flags; + + save_flags(flags); + cli(); + /* Enable input DMA channel for the serial port in question */ + if (info->line == 0) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma7); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, serial0); + } else if (info->line == 1) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma9); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, serial1); + } else if (info->line == 2) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, serial2); + } else if (info->line == 3) { + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, serial3); + } + *R_GEN_CONFIG = genconfig_shadow; + restore_flags(flags); +} #ifdef SERIAL_HANDLE_EARLY_ERRORS /* in order to detect and fix errors on the first byte @@ -1422,6 +1692,7 @@ e100_disable_serial_data_irq(struct e100_serial *info) #ifdef SERIAL_DEBUG_INTR printk("ser_irq(%d): 0\n",info->line); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ disable data_irq %i\n", info->line)); *R_IRQ_MASK1_CLR = (1U << (8+2*info->line)); } @@ -1434,10 +1705,49 @@ e100_enable_serial_data_irq(struct e100_serial *info) (8+2*info->line), (1U << (8+2*info->line))); #endif + DINTR1(DEBUG_LOG(info->line,"IRQ enable data_irq %i\n", info->line)); *R_IRQ_MASK1_SET = (1U << (8+2*info->line)); } #endif +static inline void +e100_disable_serial_tx_ready_irq(struct e100_serial *info) +{ +#ifdef SERIAL_DEBUG_INTR + printk("ser_tx_irq(%d): 0\n",info->line); +#endif + DINTR1(DEBUG_LOG(info->line,"IRQ disable ready_irq %i\n", info->line)); + *R_IRQ_MASK1_CLR = (1U << (8+1+2*info->line)); +} + +static inline void +e100_enable_serial_tx_ready_irq(struct e100_serial *info) +{ +#ifdef SERIAL_DEBUG_INTR + printk("ser_tx_irq(%d): 1\n",info->line); + printk("**** %d = %d\n", + (8+1+2*info->line), + (1U << (8+1+2*info->line))); +#endif + DINTR2(DEBUG_LOG(info->line,"IRQ enable ready_irq %i\n", info->line)); + *R_IRQ_MASK1_SET = (1U << (8+1+2*info->line)); +} + +static inline void e100_enable_rx_irq(struct e100_serial *info) +{ + if (info->uses_dma_in) + e100_enable_rxdma_irq(info); + else + e100_enable_serial_data_irq(info); +} +static inline void e100_disable_rx_irq(struct e100_serial *info) +{ + if (info->uses_dma_in) + e100_disable_rxdma_irq(info); + else + e100_disable_serial_data_irq(info); +} + #if defined(CONFIG_ETRAX_RS485) /* Enable RS-485 mode on selected port. This is UGLY. */ static int @@ -1448,10 +1758,23 @@ e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r) #if defined(CONFIG_ETRAX_RS485_ON_PA) *R_PORT_PA_DATA = port_pa_data_shadow |= (1 << rs485_pa_bit); #endif +#if defined(CONFIG_ETRAX_RS485_ON_PORT_G) + REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, + rs485_port_g_bit, 1); +#endif +#if defined(CONFIG_ETRAX_RS485_LTC1387) + REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, + CONFIG_ETRAX_RS485_LTC1387_DXEN_PORT_G_BIT, 1); + REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, + CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 1); +#endif info->rs485.rts_on_send = 0x01 & r->rts_on_send; info->rs485.rts_after_sent = 0x01 & r->rts_after_sent; - info->rs485.delay_rts_before_send = r->delay_rts_before_send; + if (r->delay_rts_before_send >= 1000) + info->rs485.delay_rts_before_send = 1000; + else + info->rs485.delay_rts_before_send = r->delay_rts_before_send; info->rs485.enabled = r->enabled; /* printk("rts: on send = %i, after = %i, enabled = %i", info->rs485.rts_on_send, @@ -1491,7 +1814,7 @@ static void rs485_toggle_rts_timer_function(unsigned long data) e100_rts(info, info->rs485.rts_after_sent); #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) e100_enable_rx(info); - e100_enable_rxdma_irq(info); + e100_enable_rx_irq(info); #endif } #endif @@ -1513,8 +1836,12 @@ rs_stop(struct tty_struct *tty) if (info) { unsigned long flags; unsigned long xoff; - + save_flags(flags); cli(); + DFLOW(DEBUG_LOG(info->line, "XOFF rs_stop xmit %i\n", + CIRC_CNT(info->xmit.head, + info->xmit.tail,SERIAL_XMIT_SIZE))); + xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty)); xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); if (tty->termios->c_iflag & IXON ) { @@ -1535,6 +1862,9 @@ rs_start(struct tty_struct *tty) unsigned long xoff; save_flags(flags); cli(); + DFLOW(DEBUG_LOG(info->line, "XOFF rs_start xmit %i\n", + CIRC_CNT(info->xmit.head, + info->xmit.tail,SERIAL_XMIT_SIZE))); xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); if (tty->termios->c_iflag & IXON ) { @@ -1542,6 +1872,9 @@ rs_start(struct tty_struct *tty) } *((unsigned long *)&info->port[REG_XOFF]) = xoff; + if (!info->uses_dma_out && + info->xmit.head != info->xmit.tail && info->xmit.buf) + e100_enable_serial_tx_ready_irq(info); restore_flags(flags); } @@ -1576,6 +1909,8 @@ static _INLINE_ void rs_sched_event(struct e100_serial *info, int event) { + if (info->event & (1 << event)) + return; info->event |= 1 << event; schedule_work(&info->work); } @@ -1592,7 +1927,7 @@ rs_sched_event(struct e100_serial *info, */ static void -transmit_chars(struct e100_serial *info) +transmit_chars_dma(struct e100_serial *info) { unsigned int c, sentl; struct etrax_dma_descr *descr; @@ -1600,11 +1935,11 @@ transmit_chars(struct e100_serial *info) #ifdef CONFIG_SVINTO_SIM /* This will output too little if tail is not 0 always since * we don't reloop to send the other part. Anyway this SHOULD be a - * no-op - transmit_chars would never really be called during sim + * no-op - transmit_chars_dma would never really be called during sim * since rs_write does not write into the xmit buffer then. */ if (info->xmit.tail) - printk("Error in serial.c:transmit_chars(), tail!=0\n"); + printk("Error in serial.c:transmit_chars-dma(), tail!=0\n"); if (info->xmit.head != info->xmit.tail) { SIMCOUT(info->xmit.buf + info->xmit.tail, CIRC_CNT(info->xmit.head, @@ -1626,7 +1961,7 @@ transmit_chars(struct e100_serial *info) #endif if (!info->tr_running) { /* weirdo... we shouldn't get here! */ - printk(KERN_WARNING "Achtung: transmit_chars with !tr_running\n"); + printk(KERN_WARNING "Achtung: transmit_chars_dma with !tr_running\n"); return; } @@ -1642,6 +1977,8 @@ transmit_chars(struct e100_serial *info) /* otherwise we find the amount of data sent here */ sentl = descr->hw_len; + DFLOW(DEBUG_LOG(info->line, "TX %i done\n", sentl)); + /* update stats */ info->icount.tx += sentl; @@ -1659,6 +1996,13 @@ transmit_chars(struct e100_serial *info) c = CIRC_CNT_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + /* Don't send all in one DMA transfer - divide it so we wake up + * application before all is sent + */ + + if (c >= 4*WAKEUP_CHARS) + c = c/2; + if (c <= 0) { /* our job here is done, don't schedule any new DMA transfer */ info->tr_running = 0; @@ -1678,17 +2022,17 @@ transmit_chars(struct e100_serial *info) /* ok we can schedule a dma send of c chars starting at info->xmit.tail */ /* set up the descriptor correctly for output */ - + DFLOW(DEBUG_LOG(info->line, "TX %i\n", c)); descr->ctrl = d_int | d_eol | d_wait; /* Wait needed for tty_wait_until_sent() */ descr->sw_len = c; descr->buf = virt_to_phys(info->xmit.buf + info->xmit.tail); descr->status = 0; *info->ofirstadr = virt_to_phys(descr); /* write to R_DMAx_FIRST */ - *info->ocmdadr = 1; /* dma command start -> R_DMAx_CMD */ + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start); /* DMA is now running (hopefully) */ -} /* transmit_chars */ +} /* transmit_chars_dma */ static void start_transmit(struct e100_serial *info) @@ -1702,15 +2046,17 @@ start_transmit(struct e100_serial *info) info->tr_descr.hw_len = 0; info->tr_descr.status = 0; info->tr_running = 1; - - transmit_chars(info); + if (info->uses_dma_out) + transmit_chars_dma(info); + else + e100_enable_serial_tx_ready_irq(info); } /* start_transmit */ #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER static int serial_fast_timer_started = 0; static int serial_fast_timer_expired = 0; static void flush_timeout_function(unsigned long data); -#define START_FLUSH_FAST_TIMER(info, string) {\ +#define START_FLUSH_FAST_TIMER_TIME(info, string, usec) {\ unsigned long timer_flags; \ save_flags(timer_flags); \ cli(); \ @@ -1721,7 +2067,7 @@ static void flush_timeout_function(unsigned long data); start_one_shot_timer(&fast_timers[info->line], \ flush_timeout_function, \ (unsigned long)info, \ - info->char_time_usec*4, \ + (usec), \ string); \ } \ else { \ @@ -1729,8 +2075,10 @@ static void flush_timeout_function(unsigned long data); } \ restore_flags(timer_flags); \ } +#define START_FLUSH_FAST_TIMER(info, string) START_FLUSH_FAST_TIMER_TIME(info, string, info->flush_time_usec) #else +#define START_FLUSH_FAST_TIMER_TIME(info, string, usec) #define START_FLUSH_FAST_TIMER(info, string) #endif @@ -1775,17 +2123,26 @@ static int add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char flag) { struct etrax_recv_buffer *buffer; + if (info->uses_dma_in) { + if (!(buffer = alloc_recv_buffer(4))) + return 0; - if (!(buffer = alloc_recv_buffer(4))) - return 0; - - buffer->length = 1; - buffer->error = flag; - buffer->buffer[0] = data; + buffer->length = 1; + buffer->error = flag; + buffer->buffer[0] = data; - append_recv_buffer(info, buffer); + append_recv_buffer(info, buffer); - info->icount.rx++; + info->icount.rx++; + } else { + struct tty_struct *tty = info->tty; + *tty->flip.char_buf_ptr = data; + *tty->flip.flag_buf_ptr = flag; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + info->icount.rx++; + } return 1; } @@ -1847,7 +2204,14 @@ handle_all_descr_data(struct e100_serial *info) /* Reset the status information */ descr->status = 0; - DEBUG_LOG(info->line, "recvl %lu\n", recvl); + DFLOW( DEBUG_LOG(info->line, "RX %lu\n", recvl); + if (info->tty->stopped) { + unsigned char *buf = phys_to_virt(descr->buf); + DEBUG_LOG(info->line, "rx 0x%02X\n", buf[0]); + DEBUG_LOG(info->line, "rx 0x%02X\n", buf[1]); + DEBUG_LOG(info->line, "rx 0x%02X\n", buf[2]); + } + ); /* update stats */ info->icount.rx += recvl; @@ -1859,7 +2223,7 @@ handle_all_descr_data(struct e100_serial *info) } static _INLINE_ void -receive_chars(struct e100_serial *info) +receive_chars_dma(struct e100_serial *info) { struct tty_struct *tty; unsigned char rstat; @@ -1881,7 +2245,8 @@ receive_chars(struct e100_serial *info) return; #ifdef SERIAL_HANDLE_EARLY_ERRORS - e100_enable_serial_data_irq(info); + if (info->uses_dma_in) + e100_enable_serial_data_irq(info); #endif if (info->errorcode == ERRCODE_INSERT_BREAK) @@ -1891,6 +2256,9 @@ receive_chars(struct e100_serial *info) /* Read the status register to detect errors */ rstat = info->port[REG_STATUS]; + if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { + DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat)); + } if (rstat & SER_ERROR_MASK) { /* If we got an error, we must reset it by reading the @@ -1959,16 +2327,16 @@ start_receive(struct e100_serial *info) */ return; #endif - - /* reset the input dma channel to be sure it works */ - - *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == - IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); - info->tty->flip.count = 0; + if (info->uses_dma_in) { + /* reset the input dma channel to be sure it works */ + + *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == + IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); - start_recv_dma(info); + start_recv_dma(info); + } } @@ -2014,27 +2382,27 @@ tr_interrupt(int irq, void *dev_id, struct pt_regs * regs) for (i = 0; i < NR_PORTS; i++) { info = rs_table + i; - if (!info->enabled || !info->uses_dma) + if (!info->enabled || !info->uses_dma_out) continue; /* check for dma_descr (don't need to check for dma_eop in output dma for serial */ if (ireg & info->irq) { handled = 1; /* we can send a new dma bunch. make it so. */ - DEBUG_LOG(info->line, "tr_interrupt %i\n", i); + DINTR2(DEBUG_LOG(info->line, "tr_interrupt %i\n", i)); /* Read jiffies_usec first, * we want this time to be as late as possible */ PROCSTAT(ser_stat[info->line].tx_dma_ints++); info->last_tx_active_usec = GET_JIFFIES_USEC(); info->last_tx_active = jiffies; - transmit_chars(info); + transmit_chars_dma(info); } /* FIXME: here we should really check for a change in the status lines and if so call status_handle(info) */ } return IRQ_RETVAL(handled); -} +} /* tr_interrupt */ /* dma input channel interrupt handler */ @@ -2054,7 +2422,7 @@ rec_interrupt(int irq, void *dev_id, struct pt_regs * regs) const char *s = "What? rec_interrupt in simulator??\n"; SIMCOUT(s,strlen(s)); } - return; + return IRQ_HANDLED; #endif /* find out the line that caused this irq and get it from rs_table */ @@ -2063,20 +2431,20 @@ rec_interrupt(int irq, void *dev_id, struct pt_regs * regs) for (i = 0; i < NR_PORTS; i++) { info = rs_table + i; - if (!info->enabled || !info->uses_dma) + if (!info->enabled || !info->uses_dma_in) continue; /* check for both dma_eop and dma_descr for the input dma channel */ if (ireg & ((info->irq << 2) | (info->irq << 3))) { handled = 1; /* we have received something */ - receive_chars(info); + receive_chars_dma(info); } /* FIXME: here we should really check for a change in the status lines and if so call status_handle(info) */ } return IRQ_RETVAL(handled); -} +} /* rec_interrupt */ static _INLINE_ int force_eop_if_needed(struct e100_serial *info) @@ -2116,20 +2484,21 @@ force_eop_if_needed(struct e100_serial *info) if (!info->forced_eop) { info->forced_eop = 1; PROCSTAT(ser_stat[info->line].timeout_flush_cnt++); - DEBUG_LOG(info->line, "timeout EOP %i\n", info->line); + TIMERD(DEBUG_LOG(info->line, "timeout EOP %i\n", info->line)); FORCE_EOP(info); } return 1; } -static _INLINE_ void +extern _INLINE_ void flush_to_flip_buffer(struct e100_serial *info) { struct tty_struct *tty; struct etrax_recv_buffer *buffer; unsigned int length; unsigned long flags; + int max_flip_size; if (!info->first_recv_buffer) return; @@ -2143,12 +2512,46 @@ flush_to_flip_buffer(struct e100_serial *info) } length = tty->flip.count; + /* Don't flip more than the ldisc has room for. + * The return value from ldisc.receive_room(tty) - might not be up to + * date, the previous flip of up to TTY_FLIPBUF_SIZE might be on the + * processed and not accounted for yet. + * Since we use DMA, 1 SERIAL_DESCR_BUF_SIZE could be on the way. + * Lets buffer data here and let flow control take care of it. + * Since we normally flip large chunks, the ldisc don't react + * with throttle until too late if we flip to much. + */ + max_flip_size = tty->ldisc.receive_room(tty); + if (max_flip_size < 0) + max_flip_size = 0; + if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */ + length + info->recv_cnt + /* We have this queued */ + 2*SERIAL_DESCR_BUF_SIZE + /* This could be on the way */ + TTY_THRESHOLD_THROTTLE)) { /* Some slack */ + /* check TTY_THROTTLED first so it indicates our state */ + if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { + DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles room %lu\n", max_flip_size)); + rs_throttle(tty); + } +#if 0 + else if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */ + length + info->recv_cnt + /* We have this queued */ + SERIAL_DESCR_BUF_SIZE + /* This could be on the way */ + TTY_THRESHOLD_THROTTLE)) { /* Some slack */ + DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles again! %lu\n", max_flip_size)); + rs_throttle(tty); + } +#endif + } - while ((buffer = info->first_recv_buffer) && length < TTY_FLIPBUF_SIZE) { + if (max_flip_size > TTY_FLIPBUF_SIZE) + max_flip_size = TTY_FLIPBUF_SIZE; + + while ((buffer = info->first_recv_buffer) && length < max_flip_size) { unsigned int count = buffer->length; - if (length + count > TTY_FLIPBUF_SIZE) - count = TTY_FLIPBUF_SIZE - length; + if (length + count > max_flip_size) + count = max_flip_size - length; memcpy(tty->flip.char_buf_ptr + length, buffer->buffer, count); memset(tty->flip.flag_buf_ptr + length, TTY_NORMAL, count); @@ -2156,6 +2559,7 @@ flush_to_flip_buffer(struct e100_serial *info) length += count; info->recv_cnt -= count; + DFLIP(DEBUG_LOG(info->line,"flip: %i\n", length)); if (count == buffer->length) { info->first_recv_buffer = buffer->next; @@ -2171,9 +2575,30 @@ flush_to_flip_buffer(struct e100_serial *info) info->last_recv_buffer = NULL; tty->flip.count = length; - + DFLIP(if (tty->ldisc.chars_in_buffer(tty) > 3500) { + DEBUG_LOG(info->line, "ldisc %lu\n", + tty->ldisc.chars_in_buffer(tty)); + DEBUG_LOG(info->line, "flip.count %lu\n", + tty->flip.count); + } + ); restore_flags(flags); + DFLIP( + if (1) { + + if (test_bit(TTY_DONT_FLIP, &tty->flags)) { + DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count); + DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt); + } else { + } + DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); + DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); + DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); + } + + ); + /* this includes a check for low-latency */ tty_flip_buffer_push(tty); } @@ -2181,12 +2606,19 @@ flush_to_flip_buffer(struct e100_serial *info) static _INLINE_ void check_flush_timeout(struct e100_serial *info) { - force_eop_if_needed(info); - + /* Flip what we've got (if we can) */ flush_to_flip_buffer(info); + /* We might need to flip later, but not to fast + * since the system is busy processing input... */ if (info->first_recv_buffer) - START_FLUSH_FAST_TIMER(info, "flip"); + START_FLUSH_FAST_TIMER_TIME(info, "flip", 2000); + + /* Force eop last, since data might have come while we're processing + * and if we started the slow timer above, we won't start a fast + * below. + */ + force_eop_if_needed(info); } #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER @@ -2222,7 +2654,7 @@ timed_flush_handler(unsigned long ptr) for (i = 0; i < NR_PORTS; i++) { info = rs_table + i; - if (info->uses_dma) + if (info->uses_dma_in) check_flush_timeout(info); } @@ -2301,14 +2733,158 @@ TODO: The break will be delayed until an F or V character is received. */ -extern irqreturn_t _INLINE_ handle_ser_interrupt(struct e100_serial *info) +extern _INLINE_ +struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) { - unsigned char rstat = info->port[REG_STATUS]; + unsigned long data_read; + struct tty_struct *tty = info->tty; + + if (!tty) { + printk("!NO TTY!\n"); + return info; + } + if (tty->flip.count >= TTY_FLIPBUF_SIZE - TTY_THRESHOLD_THROTTLE) { + /* check TTY_THROTTLED first so it indicates our state */ + if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { + DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count)); + rs_throttle(tty); + } + } + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count); + tty->flip.work.func((void *) tty); + if (tty->flip.count >= TTY_FLIPBUF_SIZE) { + DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count); + return info; /* if TTY_DONT_FLIP is set */ + } + } + /* Read data and status at the same time */ + data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]); +more_data: + if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) { + DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); + } + DINTR2(DEBUG_LOG(info->line, "ser_rx %c\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read))); + + if (data_read & ( IO_MASK(R_SERIAL0_READ, framing_err) | + IO_MASK(R_SERIAL0_READ, par_err) | + IO_MASK(R_SERIAL0_READ, overrun) )) { + /* An error */ + info->last_rx_active_usec = GET_JIFFIES_USEC(); + info->last_rx_active = jiffies; + DINTR1(DEBUG_LOG(info->line, "ser_rx err stat_data %04X\n", data_read)); + DLOG_INT_TRIG( + if (!log_int_trig1_pos) { + log_int_trig1_pos = log_int_pos; + log_int(rdpc(), 0, 0); + } + ); + + + if ( ((data_read & IO_MASK(R_SERIAL0_READ, data_in)) == 0) && + (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) ) { + /* Most likely a break, but we get interrupts over and + * over again. + */ + + if (!info->break_detected_cnt) { + DEBUG_LOG(info->line, "#BRK start\n", 0); + } + if (data_read & IO_MASK(R_SERIAL0_READ, rxd)) { + /* The RX pin is high now, so the break + * must be over, but.... + * we can't really know if we will get another + * last byte ending the break or not. + * And we don't know if the byte (if any) will + * have an error or look valid. + */ + DEBUG_LOG(info->line, "# BL BRK\n", 0); + info->errorcode = ERRCODE_INSERT_BREAK; + } + info->break_detected_cnt++; + } else { + /* The error does not look like a break, but could be + * the end of one + */ + if (info->break_detected_cnt) { + DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt); + info->errorcode = ERRCODE_INSERT_BREAK; + } else { + if (info->errorcode == ERRCODE_INSERT_BREAK) { + info->icount.brk++; + *tty->flip.char_buf_ptr = 0; + *tty->flip.flag_buf_ptr = TTY_BREAK; + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + info->icount.rx++; + } + *tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read); + + if (data_read & IO_MASK(R_SERIAL0_READ, par_err)) { + info->icount.parity++; + *tty->flip.flag_buf_ptr = TTY_PARITY; + } else if (data_read & IO_MASK(R_SERIAL0_READ, overrun)) { + info->icount.overrun++; + *tty->flip.flag_buf_ptr = TTY_OVERRUN; + } else if (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) { + info->icount.frame++; + *tty->flip.flag_buf_ptr = TTY_FRAME; + } + info->errorcode = 0; + } + info->break_detected_cnt = 0; + } + } else if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { + /* No error */ + DLOG_INT_TRIG( + if (!log_int_trig1_pos) { + if (log_int_pos >= log_int_size) { + log_int_pos = 0; + } + log_int_trig0_pos = log_int_pos; + log_int(rdpc(), 0, 0); + } + ); + *tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read); + *tty->flip.flag_buf_ptr = 0; + } else { + DEBUG_LOG(info->line, "ser_rx int but no data_avail %08lX\n", data_read); + } + + + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + info->icount.rx++; + data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]); + if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { + DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read)); + goto more_data; + } + + tty_flip_buffer_push(info->tty); + return info; +} + +extern _INLINE_ +struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) +{ + unsigned char rstat; #ifdef SERIAL_DEBUG_INTR printk("Interrupt from serport %d\n", i); #endif /* DEBUG_LOG(info->line, "ser_interrupt stat %03X\n", rstat | (i << 8)); */ + if (!info->uses_dma_in) { + return handle_ser_rx_interrupt_no_dma(info); + } + /* DMA is used */ + rstat = info->port[REG_STATUS]; + if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { + DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); + } + if (rstat & SER_ERROR_MASK) { unsigned char data; @@ -2318,7 +2894,8 @@ extern irqreturn_t _INLINE_ handle_ser_interrupt(struct e100_serial *info) * data_in field */ data = info->port[REG_DATA]; - + DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data)); + DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat)); if (!data && (rstat & SER_FRAMING_ERR_MASK)) { /* Most likely a break, but we get interrupts over and * over again. @@ -2347,15 +2924,22 @@ extern irqreturn_t _INLINE_ handle_ser_interrupt(struct e100_serial *info) DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt); info->errorcode = ERRCODE_INSERT_BREAK; } else { - if (info->errorcode == ERRCODE_INSERT_BREAK) + if (info->errorcode == ERRCODE_INSERT_BREAK) { + info->icount.brk++; add_char_and_flag(info, '\0', TTY_BREAK); + } - if (rstat & SER_PAR_ERR_MASK) + if (rstat & SER_PAR_ERR_MASK) { + info->icount.parity++; add_char_and_flag(info, data, TTY_PARITY); - else if (rstat & SER_OVERRUN_MASK) + } else if (rstat & SER_OVERRUN_MASK) { + info->icount.overrun++; add_char_and_flag(info, data, TTY_OVERRUN); - else if (rstat & SER_FRAMING_ERR_MASK) + } else if (rstat & SER_FRAMING_ERR_MASK) { + info->icount.frame++; add_char_and_flag(info, data, TTY_FRAME); + } + info->errorcode = 0; } info->break_detected_cnt = 0; @@ -2379,7 +2963,7 @@ extern irqreturn_t _INLINE_ handle_ser_interrupt(struct e100_serial *info) if (elapsed_usec < 2*info->char_time_usec) { DEBUG_LOG(info->line, "FBRK %i\n", info->line); /* Report as BREAK (error) and let - * receive_chars() handle it + * receive_chars_dma() handle it */ info->errorcode = ERRCODE_SET_BREAK; } else { @@ -2392,38 +2976,196 @@ extern irqreturn_t _INLINE_ handle_ser_interrupt(struct e100_serial *info) printk("** OK, disabling ser_interrupts\n"); #endif e100_disable_serial_data_irq(info); - + DINTR2(DEBUG_LOG(info->line, "ser_rx OK %d\n", info->line)); info->break_detected_cnt = 0; PROCSTAT(ser_stat[info->line].ser_ints_ok_cnt++); - DEBUG_LOG(info->line, "ser_int OK %d\n", info->line); } - /* Restarting the DMA never hurts */ *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart); START_FLUSH_FAST_TIMER(info, "ser_int"); - return IRQ_HANDLED; -} /* handle_ser_interrupt */ + return info; +} /* handle_ser_rx_interrupt */ + +extern _INLINE_ void handle_ser_tx_interrupt(struct e100_serial *info) +{ + unsigned long flags; + + if (info->x_char) { + unsigned char rstat; + DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char)); + save_flags(flags); cli(); + rstat = info->port[REG_STATUS]; + DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); + + info->port[REG_TR_DATA] = info->x_char; + info->icount.tx++; + info->x_char = 0; + /* We must enable since it is disabled in ser_interrupt */ + e100_enable_serial_tx_ready_irq(info); + restore_flags(flags); + return; + } + if (info->uses_dma_out) { + unsigned char rstat; + int i; + /* We only use normal tx interrupt when sending x_char */ + DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0)); + save_flags(flags); cli(); + rstat = info->port[REG_STATUS]; + DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); + e100_disable_serial_tx_ready_irq(info); + if (info->tty->stopped) + rs_stop(info->tty); + /* Enable the DMA channel and tell it to continue */ + e100_enable_txdma_channel(info); + /* Wait 12 cycles before doing the DMA command */ + for(i = 6; i > 0; i--) + nop(); + + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, continue); + restore_flags(flags); + return; + } + /* Normal char-by-char interrupt */ + if (info->xmit.head == info->xmit.tail + || info->tty->stopped + || info->tty->hw_stopped) { + DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", info->tty->stopped)); + e100_disable_serial_tx_ready_irq(info); + info->tr_running = 0; + return; + } + DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail])); + /* Send a byte, rs485 timing is critical so turn of ints */ + save_flags(flags); cli(); + info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail]; + info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); + info->icount.tx++; + if (info->xmit.head == info->xmit.tail) { +#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER) + if (info->rs485.enabled) { + /* Set a short timer to toggle RTS */ + start_one_shot_timer(&fast_timers_rs485[info->line], + rs485_toggle_rts_timer_function, + (unsigned long)info, + info->char_time_usec*2, + "RS-485"); + } +#endif /* RS485 */ + info->last_tx_active_usec = GET_JIFFIES_USEC(); + info->last_tx_active = jiffies; + e100_disable_serial_tx_ready_irq(info); + info->tr_running = 0; + DFLOW(DEBUG_LOG(info->line, "tx_int: stop2\n", 0)); + } else { + /* We must enable since it is disabled in ser_interrupt */ + e100_enable_serial_tx_ready_irq(info); + } + restore_flags(flags); + + if (CIRC_CNT(info->xmit.head, + info->xmit.tail, + SERIAL_XMIT_SIZE) < WAKEUP_CHARS) + rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); +} /* handle_ser_tx_interrupt */ + +/* result of time measurements: + * RX duration 54-60 us when doing something, otherwise 6-9 us + * ser_int duration: just sending: 8-15 us normally, up to 73 us + */ static irqreturn_t ser_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + static volatile int tx_started = 0; struct e100_serial *info; int i; + unsigned long flags; + unsigned long irq_mask1_rd; + unsigned long data_mask = (1 << (8+2*0)); /* ser0 data_avail */ int handled = 0; + static volatile unsigned long reentered_ready_mask = 0; + save_flags(flags); cli(); + irq_mask1_rd = *R_IRQ_MASK1_RD; + /* First handle all rx interrupts with ints disabled */ + info = rs_table; + irq_mask1_rd &= e100_ser_int_mask; for (i = 0; i < NR_PORTS; i++) { - info = rs_table + i; - - if (!info->enabled || !info->uses_dma) - continue; - - /* Which line caused the irq? */ - if (*R_IRQ_MASK1_RD & (1U << (8+2*info->line))) { + /* Which line caused the data irq? */ + if (irq_mask1_rd & data_mask) { handled = 1; - handle_ser_interrupt(info); + handle_ser_rx_interrupt(info); + } + info += 1; + data_mask <<= 2; + } + /* Handle tx interrupts with interrupts enabled so we + * can take care of new data interrupts while transmitting + * We protect the tx part with the tx_started flag. + * We disable the tr_ready interrupts we are about to handle and + * unblock the serial interrupt so new serial interrupts may come. + * + * If we get a new interrupt: + * - it migth be due to synchronous serial ports. + * - serial irq will be blocked by general irq handler. + * - async data will be handled above (sync will be ignored). + * - tx_started flag will prevent us from trying to send again and + * we will exit fast - no need to unblock serial irq. + * - Next (sync) serial interrupt handler will be runned with + * disabled interrupt due to restore_flags() at end of function, + * so sync handler will not be preempted or reentered. + */ + if (!tx_started) { + unsigned long ready_mask; + unsigned long + tx_started = 1; + /* Only the tr_ready interrupts left */ + irq_mask1_rd &= (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser1_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser2_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser3_ready)); + while (irq_mask1_rd) { + /* Disable those we are about to handle */ + *R_IRQ_MASK1_CLR = irq_mask1_rd; + /* Unblock the serial interrupt */ + *R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set); + + sti(); + ready_mask = (1 << (8+1+2*0)); /* ser0 tr_ready */ + info = rs_table; + for (i = 0; i < NR_PORTS; i++) { + /* Which line caused the ready irq? */ + if (irq_mask1_rd & ready_mask) { + handled = 1; + handle_ser_tx_interrupt(info); + } + info += 1; + ready_mask <<= 2; + } + /* handle_ser_tx_interrupt enables tr_ready interrupts */ + cli(); + /* Handle reentered TX interrupt */ + irq_mask1_rd = reentered_ready_mask; + } + cli(); + tx_started = 0; + } else { + unsigned long ready_mask; + ready_mask = irq_mask1_rd & (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser1_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser2_ready) | + IO_MASK(R_IRQ_MASK1_RD, ser3_ready)); + if (ready_mask) { + reentered_ready_mask |= ready_mask; + /* Disable those we are about to handle */ + *R_IRQ_MASK1_CLR = ready_mask; + DFLOW(DEBUG_LOG(SERIAL_DEBUG_LINE, "ser_int reentered with TX %X\n", ready_mask)); } } + + restore_flags(flags); return IRQ_RETVAL(handled); } /* ser_interrupt */ #endif @@ -2489,7 +3231,7 @@ startup(struct e100_serial * info) info->xmit.buf = (unsigned char *) xmit_page; #ifdef SERIAL_DEBUG_OPEN - printk("starting up ttyS%d (xmit_buf 0x%p, recv_buf 0x%p)...\n", info->line, info->xmit.buf, info->recv.buf); + printk("starting up ttyS%d (xmit_buf 0x%p)...\n", info->line, info->xmit.buf); #endif #ifdef CONFIG_SVINTO_SIM @@ -2520,24 +3262,39 @@ startup(struct e100_serial * info) * Reset the DMA channels and make sure their interrupts are cleared */ - info->uses_dma = 1; - *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + if (info->dma_in_enabled) { + info->uses_dma_in = 1; + e100_enable_rxdma_channel(info); - /* Wait until reset cycle is complete */ - while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == - IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); + *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) == - IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); + /* Wait until reset cycle is complete */ + while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) == + IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); - /* Make sure the irqs are cleared */ - *info->iclrintradr = - IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | - IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); - *info->oclrintradr = - IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | - IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); + /* Make sure the irqs are cleared */ + *info->iclrintradr = + IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | + IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); + } else { + e100_disable_rxdma_channel(info); + } + + if (info->dma_out_enabled) { + info->uses_dma_out = 1; + e100_enable_txdma_channel(info); + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + + while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) == + IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset)); + + /* Make sure the irqs are cleared */ + *info->oclrintradr = + IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) | + IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do); + } else { + e100_disable_txdma_channel(info); + } if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); @@ -2563,9 +3320,10 @@ startup(struct e100_serial * info) (void)info->port[REG_DATA]; /* enable the interrupts */ + if (info->uses_dma_out) + e100_enable_txdma_irq(info); - e100_enable_txdma_irq(info); - e100_enable_rxdma_irq(info); + e100_enable_rx_irq(info); info->tr_running = 0; /* to be sure we don't lock up the transmitter */ @@ -2606,20 +3364,28 @@ shutdown(struct e100_serial * info) #ifndef CONFIG_SVINTO_SIM /* shut down the transmitter and receiver */ - + DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line)); e100_disable_rx(info); info->port[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40); - e100_disable_rxdma_irq(info); - e100_disable_txdma_irq(info); - - info->tr_running = 0; - - /* reset both dma channels */ + /* disable interrupts, reset dma channels */ + if (info->uses_dma_in) { + e100_disable_rxdma_irq(info); + *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + info->uses_dma_in = 0; + } else { + e100_disable_serial_data_irq(info); + } - *info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); - info->uses_dma = 0; + if (info->uses_dma_out) { + e100_disable_txdma_irq(info); + info->tr_running = 0; + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset); + info->uses_dma_out = 0; + } else { + e100_disable_serial_tx_ready_irq(info); + info->tr_running = 0; + } #endif /* CONFIG_SVINTO_SIM */ @@ -2667,7 +3433,7 @@ change_speed(struct e100_serial *info) { unsigned int cflag; unsigned long xoff; - + unsigned long flags; /* first some safety checks */ if (!info->tty || !info->tty->termios) @@ -2676,17 +3442,80 @@ change_speed(struct e100_serial *info) return; cflag = info->tty->termios->c_cflag; - + /* possibly, the tx/rx should be disabled first to do this safely */ /* change baud-rate and write it to the hardware */ - - info->baud = cflag_to_baud(cflag); + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { + /* Special baudrate */ + u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ + unsigned long alt_source = + IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) | + IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal); + /* R_ALT_SER_BAUDRATE selects the source */ + DBAUD(printk("Custom baudrate: baud_base/divisor %lu/%i\n", + (unsigned long)info->baud_base, info->custom_divisor)); + if (info->baud_base == SERIAL_PRESCALE_BASE) { + /* 0, 2-65535 (0=65536) */ + u16 divisor = info->custom_divisor; + /* R_SERIAL_PRESCALE (upper 16 bits of R_CLOCK_PRESCALE) */ + /* baudrate is 3.125MHz/custom_divisor */ + alt_source = + IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, prescale) | + IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, prescale); + alt_source = 0x11; + DBAUD(printk("Writing SERIAL_PRESCALE: divisor %i\n", divisor)); + *R_SERIAL_PRESCALE = divisor; + info->baud = SERIAL_PRESCALE_BASE/divisor; + } +#ifdef CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED + else if ((info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8 && + info->custom_divisor == 1) || + (info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ && + info->custom_divisor == 8)) { + /* ext_clk selected */ + alt_source = + IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, extern) | + IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, extern); + DBAUD(printk("using external baudrate: %lu\n", CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8)); + info->baud = CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8; + } + } +#endif + else + { + /* Bad baudbase, we don't support using timer0 + * for baudrate. + */ + printk(KERN_WARNING "Bad baud_base/custom_divisor: %lu/%i\n", + (unsigned long)info->baud_base, info->custom_divisor); + } + r_alt_ser_baudrate_shadow &= ~mask; + r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8)); + *R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow; + } else { + /* Normal baudrate */ + /* Make sure we use normal baudrate */ + u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */ + unsigned long alt_source = + IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) | + IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal); + r_alt_ser_baudrate_shadow &= ~mask; + r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8)); +#ifndef CONFIG_SVINTO_SIM + *R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow; +#endif /* CONFIG_SVINTO_SIM */ + + info->baud = cflag_to_baud(cflag); +#ifndef CONFIG_SVINTO_SIM + info->port[REG_BAUD] = cflag_to_etrax_baud(cflag); +#endif /* CONFIG_SVINTO_SIM */ + } #ifndef CONFIG_SVINTO_SIM - info->port[REG_BAUD] = cflag_to_etrax_baud(cflag); /* start with default settings and then fill in changes */ - + save_flags(flags); + cli(); /* 8 bit, no/even parity */ info->rx_ctrl &= ~(IO_MASK(R_SERIAL0_REC_CTRL, rec_bitnr) | IO_MASK(R_SERIAL0_REC_CTRL, rec_par_en) | @@ -2717,24 +3546,19 @@ change_speed(struct e100_serial *info) } if (cflag & CMSPAR) { - /* enable stick parity */ + /* enable stick parity, PARODD mean Mark which matches ETRAX */ info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, stick); info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, stick); - if (!(cflag & PARODD)) { - /* set mark parity */ - info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); - info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); - } - } else { - if (cflag & PARODD) { - /* set odd parity */ - info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); - info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); - } + } + if (cflag & PARODD) { + /* set odd parity (or Mark if CMSPAR) */ + info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd); + info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd); } if (cflag & CRTSCTS) { /* enable automatic CTS handling */ + DFLOW(DEBUG_LOG(info->line, "FLOW auto_cts enabled\n", 0)); info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, active); } @@ -2750,13 +3574,16 @@ change_speed(struct e100_serial *info) xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty)); xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); if (info->tty->termios->c_iflag & IXON ) { + DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", STOP_CHAR(info->tty))); xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); } *((unsigned long *)&info->port[REG_XOFF]) = xoff; + restore_flags(flags); #endif /* !CONFIG_SVINTO_SIM */ update_char_time(info); + } /* change_speed */ /* start transmitting chars NOW */ @@ -2786,8 +3613,8 @@ rs_flush_chars(struct tty_struct *tty) restore_flags(flags); } -extern inline int -raw_write(struct tty_struct * tty, int from_user, +extern _INLINE_ int +rs_raw_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { int c, ret = 0; @@ -2801,7 +3628,7 @@ raw_write(struct tty_struct * tty, int from_user, #ifdef SERIAL_DEBUG_DATA if (info->line == SERIAL_DEBUG_LINE) - printk("raw_write (%d), status %d\n", + printk("rs_raw_write (%d), status %d\n", count, info->port[REG_STATUS]); #endif @@ -2811,6 +3638,9 @@ raw_write(struct tty_struct * tty, int from_user, return count; #endif save_flags(flags); + DFLOW(DEBUG_LOG(info->line, "write count %i ", count)); + DFLOW(DEBUG_LOG(info->line, "ldisc %i\n", tty->ldisc.chars_in_buffer(tty))); + /* the cli/restore_flags pairs below are needed because the * DMA interrupt handler moves the info->xmit values. the memcpy @@ -2878,6 +3708,7 @@ raw_write(struct tty_struct * tty, int from_user, * this does not need IRQ protection since if tr_running == 0 * the IRQ's are not running anyway for this port. */ + DFLOW(DEBUG_LOG(info->line, "write ret %i\n", ret)); if (info->xmit.head != info->xmit.tail && !tty->stopped && @@ -2887,7 +3718,7 @@ raw_write(struct tty_struct * tty, int from_user, } return ret; -} /* raw_write() */ +} /* raw_raw_write() */ static int rs_write(struct tty_struct * tty, int from_user, @@ -2909,7 +3740,7 @@ rs_write(struct tty_struct * tty, int from_user, e100_rts(info, info->rs485.rts_on_send); #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER) e100_disable_rx(info); - e100_disable_rxdma_irq(info); + e100_enable_rx_irq(info); #endif if (info->rs485.delay_rts_before_send > 0) { @@ -2919,7 +3750,7 @@ rs_write(struct tty_struct * tty, int from_user, } #endif /* CONFIG_ETRAX_RS485 */ - count = raw_write(tty, from_user, buf, count); + count = rs_raw_write(tty, from_user, buf, count); #if defined(CONFIG_ETRAX_RS485) if (info->rs485.enabled) @@ -3003,23 +3834,33 @@ rs_flush_buffer(struct tty_struct *tty) * This function is used to send a high-priority XON/XOFF character to * the device * - * Since we use DMA we don't check for info->x_char in transmit_chars, - * just disable DMA channel and write the character when possible. + * Since we use DMA we don't check for info->x_char in transmit_chars_dma(), + * but we do it in handle_ser_tx_interrupt(). + * We disable DMA channel and enable tx ready interrupt and write the + * character when possible. */ static void rs_send_xchar(struct tty_struct *tty, char ch) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; + unsigned long flags; + save_flags(flags); cli(); + if (info->uses_dma_out) { + /* Put the DMA on hold and disable the channel */ + *info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, hold); + while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) != + IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, hold)); + e100_disable_txdma_channel(info); + } - e100_disable_txdma_channel(info); - - /* Wait for tr_ready */ - while (!(info->port[REG_STATUS] & IO_MASK(R_SERIAL0_STATUS, tr_ready))) - /* wait */; - - /* Write the XON/XOFF char */ - info->port[REG_TR_DATA] = ch; + /* Must make sure transmitter is not stopped before we can transmit */ + if (tty->stopped) + rs_start(tty); - e100_enable_txdma_channel(info); + /* Enable manual transmit interrupt and send from there */ + DFLOW(DEBUG_LOG(info->line, "rs_send_xchar 0x%02X\n", ch)); + info->x_char = ch; + e100_enable_serial_tx_ready_irq(info); + restore_flags(flags); } /* @@ -3034,21 +3875,18 @@ static void rs_throttle(struct tty_struct * tty) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; - unsigned long flags; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; - printk("throttle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); + printk("throttle %s: %lu....\n", tty_name(tty, buf), + (unsigned long)tty->ldisc.chars_in_buffer(tty)); #endif + DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); /* Do RTS before XOFF since XOFF might take some time */ if (tty->termios->c_cflag & CRTSCTS) { - /* Turn off RTS line (do this atomic) */ - save_flags(flags); - cli(); + /* Turn off RTS line */ e100_rts(info, 0); - restore_flags(flags); } if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); @@ -3059,21 +3897,18 @@ static void rs_unthrottle(struct tty_struct * tty) { struct e100_serial *info = (struct e100_serial *)tty->driver_data; - unsigned long flags; #ifdef SERIAL_DEBUG_THROTTLE char buf[64]; - printk("unthrottle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); + printk("unthrottle %s: %lu....\n", tty_name(tty, buf), + (unsigned long)tty->ldisc.chars_in_buffer(tty)); #endif - + DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); + DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); /* Do RTS before XOFF since XOFF might take some time */ if (tty->termios->c_cflag & CRTSCTS) { - /* Assert RTS line (do this atomic) */ - save_flags(flags); - cli(); + /* Assert RTS line */ e100_rts(info, 1); - restore_flags(flags); } if (I_IXOFF(tty)) { @@ -3110,8 +3945,10 @@ get_serial_info(struct e100_serial * info, tmp.port = (int)info->port; tmp.irq = info->irq; tmp.flags = info->flags; + tmp.baud_base = info->baud_base; tmp.close_delay = info->close_delay; tmp.closing_wait = info->closing_wait; + tmp.custom_divisor = info->custom_divisor; if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) return -EFAULT; return 0; @@ -3149,8 +3986,10 @@ set_serial_info(struct e100_serial *info, * At this point, we start making changes..... */ + info->baud_base = new_serial.baud_base; info->flags = ((info->flags & ~ASYNC_FLAGS) | (new_serial.flags & ASYNC_FLAGS)); + info->custom_divisor = new_serial.custom_divisor; info->type = new_serial.type; info->close_delay = new_serial.close_delay; info->closing_wait = new_serial.closing_wait; @@ -3418,6 +4257,7 @@ rs_set_termios(struct tty_struct *tty, struct termios *old_termios) change_speed(info); + /* Handle turning off CRTSCTS */ if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { tty->hw_stopped = 0; @@ -3426,6 +4266,42 @@ rs_set_termios(struct tty_struct *tty, struct termios *old_termios) } +/* In debugport.c - register a console write function that uses the normal + * serial driver + */ +typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len); + +extern debugport_write_function debug_write_function; + +static int rs_debug_write_function(int i, const char *buf, unsigned int len) +{ + int cnt; + struct tty_struct *tty; + static int recurse_cnt = 0; + + tty = rs_table[i].tty; + if (tty) { + unsigned long flags; + if (recurse_cnt > 5) /* We skip this debug output */ + return 1; + + local_irq_save(flags); + recurse_cnt++; + do { + cnt = rs_write(tty, 0, buf, len); + if (cnt >= 0) { + buf += cnt; + len -= cnt; + } else + len = cnt; + } while(len > 0); + recurse_cnt--; + local_irq_restore(flags); + return 1; + } + return 0; +} + /* * ------------------------------------------------------------ * rs_close() @@ -3482,6 +4358,12 @@ rs_close(struct tty_struct *tty, struct file * filp) return; } info->flags |= ASYNC_CLOSING; + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ASYNC_NORMAL_ACTIVE) + info->normal_termios = *tty->termios; /* * Now we wait for the transmit buffer to clear; and we notify * the line discipline to only process XON/XOFF characters. @@ -3499,7 +4381,7 @@ rs_close(struct tty_struct *tty, struct file * filp) #ifndef CONFIG_SVINTO_SIM e100_disable_rx(info); - e100_disable_rxdma_irq(info); + e100_disable_rx_irq(info); if (info->flags & ASYNC_INITIALIZED) { /* @@ -3537,6 +4419,16 @@ rs_close(struct tty_struct *tty, struct file * filp) info->rs485.enabled = 0; #if defined(CONFIG_ETRAX_RS485_ON_PA) *R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit); +#endif +#if defined(CONFIG_ETRAX_RS485_ON_PORT_G) + REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, + rs485_port_g_bit, 0); +#endif +#if defined(CONFIG_ETRAX_RS485_LTC1387) + REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, + CONFIG_ETRAX_RS485_LTC1387_DXEN_PORT_G_BIT, 0); + REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, + CONFIG_ETRAX_RS485_LTC1387_RXEN_PORT_G_BIT, 0); #endif } #endif @@ -3637,8 +4529,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp, return 0; } - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; + if (tty->termios->c_cflag & CLOCAL) { + do_clocal = 1; + } /* * Block waiting for the carrier detect and the line to become @@ -3664,7 +4557,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, while (1) { save_flags(flags); cli(); - /* assert RTS and DTR */ + /* assert RTS and DTR */ e100_rts(info, 1); e100_dtr(info, 1); restore_flags(flags); @@ -3681,7 +4574,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, #endif break; } - if (!(info->flags & ASYNC_CLOSING) && do_clocal) + if (!(info->flags & ASYNC_CLOSING) && do_clocal) /* && (do_clocal || DCD_IS_ASSERTED) */ break; if (signal_pending(current)) { @@ -3787,10 +4680,21 @@ rs_open(struct tty_struct *tty, struct file * filp) #endif return retval; } - + + if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { + *tty->termios = info->normal_termios; + change_speed(info); + } + #ifdef SERIAL_DEBUG_OPEN printk("rs_open ttyS%d successful...\n", info->line); #endif + DLOG_INT_TRIG( log_int_pos = 0); + + DFLIP( if (info->line == SERIAL_DEBUG_LINE) { + info->icount.rx = 0; + } ); + return 0; } @@ -3798,10 +4702,11 @@ rs_open(struct tty_struct *tty, struct file * filp) * /proc fs routines.... */ -extern inline int line_info(char *buf, struct e100_serial *info) +extern _INLINE_ int line_info(char *buf, struct e100_serial *info) { char stat_buf[30]; int ret; + unsigned long tmp; ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d", info->line, (unsigned long)info->port, info->irq); @@ -3831,11 +4736,39 @@ extern inline int line_info(char *buf, struct e100_serial *info) ret += sprintf(buf+ret, " tx:%lu rx:%lu", (unsigned long)info->icount.tx, (unsigned long)info->icount.rx); + tmp = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + if (tmp) { + ret += sprintf(buf+ret, " tx_pend:%lu/%lu", + (unsigned long)tmp, + (unsigned long)SERIAL_XMIT_SIZE); + } ret += sprintf(buf+ret, " rx_pend:%lu/%lu", (unsigned long)info->recv_cnt, (unsigned long)info->max_recv_cnt); +#if 1 + if (info->tty) { + + if (info->tty->stopped) + ret += sprintf(buf+ret, " stopped:%i", + (int)info->tty->stopped); + if (info->tty->hw_stopped) + ret += sprintf(buf+ret, " hw_stopped:%i", + (int)info->tty->hw_stopped); + } + + { + unsigned char rstat = info->port[REG_STATUS]; + if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) + ret += sprintf(buf+ret, " xoff_detect:1"); + } + +#endif + + + + if (info->icount.frame) ret += sprintf(buf+ret, " fe:%lu", (unsigned long)info->icount.frame); @@ -3879,6 +4812,22 @@ int rs_read_proc(char *page, char **start, off_t off, int count, len = 0; } } +#ifdef DEBUG_LOG_INCLUDED + for (i = 0; i < debug_log_pos; i++) { + len += sprintf(page + len, "%-4i %lu.%lu ", i, debug_log[i].time, timer_data_to_ns(debug_log[i].timer_data)); + len += sprintf(page + len, debug_log[i].string, debug_log[i].value); + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + len += sprintf(page + len, "debug_log %i/%i %li bytes\n", + i, DEBUG_LOG_SIZE, begin+len); + debug_log_pos = 0; +#endif + *eof = 1; done: if (off >= len+begin) @@ -3893,7 +4842,7 @@ static void show_serial_version(void) { printk(KERN_INFO - "ETRAX 100LX serial-driver %s, (c) 2000-2003 Axis Communications AB\r\n", + "ETRAX 100LX serial-driver %s, (c) 2000-2004 Axis Communications AB\r\n", &serial_version[11]); /* "$Revision: x.yy" */ } @@ -3952,20 +4901,25 @@ rs_init(void) driver->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; + driver->termios = serial_termios; + driver->termios_locked = serial_termios_locked; + tty_set_operations(driver, &rs_ops); + serial_driver = driver; if (tty_register_driver(driver)) panic("Couldn't register serial driver\n"); - serial_driver = driver; - /* do some initializing for the separate ports */ for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) { - info->uses_dma = 0; + info->uses_dma_in = 0; + info->uses_dma_out = 0; info->line = i; info->tty = 0; info->type = PORT_ETRAX; info->tr_running = 0; info->forced_eop = 0; + info->baud_base = DEF_BAUD_BASE; + info->custom_divisor = 0; info->flags = 0; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; @@ -3973,6 +4927,7 @@ rs_init(void) info->event = 0; info->count = 0; info->blocked_open = 0; + info->normal_termios = driver->init_termios; init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); info->xmit.buf = NULL; @@ -4009,39 +4964,62 @@ rs_init(void) #ifndef CONFIG_SVINTO_SIM /* Not needed in simulator. May only complicate stuff. */ /* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */ + + if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL)) + panic("irq8"); + #ifdef CONFIG_ETRAX_SERIAL_PORT0 +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT if (request_irq(SER0_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL)) panic("irq22"); +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN if (request_irq(SER0_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL)) panic("irq23"); #endif -#ifdef SERIAL_HANDLE_EARLY_ERRORS - if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL)) - panic("irq8"); #endif + #ifdef CONFIG_ETRAX_SERIAL_PORT1 +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT if (request_irq(SER1_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL)) panic("irq24"); +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN if (request_irq(SER1_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL)) panic("irq25"); #endif +#endif #ifdef CONFIG_ETRAX_SERIAL_PORT2 /* DMA Shared with par0 (and SCSI0 and ATA) */ - if (request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL)) +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT + if (request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 2 dma tr", NULL)) panic("irq18"); - if (request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL)) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN + if (request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 2 dma rec", NULL)) panic("irq19"); #endif +#endif #ifdef CONFIG_ETRAX_SERIAL_PORT3 /* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */ - if (request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL)) +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT + if (request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 3 dma tr", NULL)) panic("irq20"); - if (request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL)) +#endif +#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN + if (request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 3 dma rec", NULL)) panic("irq21"); #endif +#endif +#ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST + if (request_irq(TIMER1_IRQ_NBR, timeout_interrupt, SA_SHIRQ | SA_INTERRUPT, + "fast serial dma timeout", NULL)) { + printk(KERN_CRIT "err: timer1 irq\n"); + } +#endif #endif /* CONFIG_SVINTO_SIM */ - + debug_write_function = rs_debug_write_function; return 0; } diff --git a/arch/cris/arch-v10/drivers/serial.h b/arch/cris/arch-v10/drivers/serial.h index 45813c657..b7bc8ddf5 100644 --- a/arch/cris/arch-v10/drivers/serial.h +++ b/arch/cris/arch-v10/drivers/serial.h @@ -44,15 +44,11 @@ struct e100_serial { volatile u32 *ofirstadr; /* adr to R_DMA_CHx_FIRST */ volatile u8 *ocmdadr; /* adr to R_DMA_CHx_CMD */ const volatile u8 *ostatusadr; /* adr to R_DMA_CHx_STATUS */ - volatile u32 *ohwswadr; /* adr to R_DMA_CHx_HWSW */ - volatile u32 *odescradr; /* adr to R_DMA_CHx_DESCR */ /* Input registers */ volatile u8 *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR */ volatile u32 *ifirstadr; /* adr to R_DMA_CHx_FIRST */ volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */ - const volatile u8 *istatusadr; /* adr to R_DMA_CHx_STATUS */ - volatile u32 *ihwswadr; /* adr to R_DMA_CHx_HWSW */ volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */ int flags; /* defined in tty.h */ @@ -60,14 +56,17 @@ struct e100_serial { u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ u8 iseteop; /* bit number for R_SET_EOP for the input dma */ - int enabled; /* Set to 1 if the port is enabled in HW config */ - - /* end of fields defined in rs_table[] in .c-file */ - int uses_dma; /* Set to 1 if DMA should be used */ - unsigned char forced_eop; /* a fifo eop has been forced */ + u8 dma_out_enabled:1; /* Set to 1 if DMA should be used */ + u8 dma_in_enabled:1; /* Set to 1 if DMA should be used */ + /* end of fields defined in rs_table[] in .c-file */ + u8 uses_dma_in; /* Set to 1 if DMA is used */ + u8 uses_dma_out; /* Set to 1 if DMA is used */ + u8 forced_eop; /* a fifo eop has been forced */ + int baud_base; /* For special baudrates */ + int custom_divisor; /* For special baudrates */ struct etrax_dma_descr tr_descr; struct etrax_dma_descr rec_descr[SERIAL_RECV_DESCRIPTORS]; int cur_rec_descr; @@ -95,6 +94,8 @@ struct e100_serial { struct work_struct work; struct async_icount icount; /* error-statistics etc.*/ + struct termios normal_termios; + struct termios callout_termios; #ifdef DECLARE_WAITQUEUE wait_queue_head_t open_wait; wait_queue_head_t close_wait; @@ -104,6 +105,7 @@ struct e100_serial { #endif unsigned long char_time_usec; /* The time for 1 char, in usecs */ + unsigned long flush_time_usec; /* How often we should flush */ unsigned long last_tx_active_usec; /* Last tx usec in the jiffies */ unsigned long last_tx_active; /* Last tx time in jiffies */ unsigned long last_rx_active_usec; /* Last rx usec in the jiffies */ diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c index 012c3028e..d80269f6f 100644 --- a/arch/cris/arch-v10/kernel/debugport.c +++ b/arch/cris/arch-v10/kernel/debugport.c @@ -12,6 +12,15 @@ * init_etrax_debug() * * $Log: debugport.c,v $ + * Revision 1.14 2004/05/17 13:11:29 starvik + * Disable DMA until real serial driver is up + * + * Revision 1.13 2004/05/14 07:58:01 starvik + * Merge of changes from 2.4 + * + * Revision 1.12 2003/09/11 07:29:49 starvik + * Merge of Linux 2.6.0-test5 + * * Revision 1.11 2003/07/07 09:53:36 starvik * Revert all the 2.5.74 merge changes to make the console work again * @@ -59,7 +68,7 @@ #include #include #include - +#include #include #include #include /* Get SIMCOUT. */ @@ -124,22 +133,28 @@ #define MIN_SIZE 32 /* Size that triggers the FIFO to flush characters to interface */ -/* Write a string of count length to the console (debug port) using DMA, polled - * for completion. Interrupts are disabled during the whole process. Some - * caution needs to be taken to not interfere with ttyS business on this port. - */ +static struct tty_driver *serial_driver; + +typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len); + +debugport_write_function debug_write_function = NULL; + +static void +console_write_direct(struct console *co, const char *buf, unsigned int len) +{ + int i; + /* Send data */ + for (i = 0; i < len; i++) { + /* Wait until transmitter is ready and send.*/ + while(!(*DEBUG_READ & IO_MASK(R_SERIAL0_READ, tr_ready))); + *DEBUG_WRITE = buf[i]; + } +} static void console_write(struct console *co, const char *buf, unsigned int len) { - - static struct etrax_dma_descr descr; - static struct etrax_dma_descr descr2; - static char tmp_buf[MIN_SIZE]; - static int tmp_size = 0; - - unsigned long flags; - + unsigned long flags; #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL /* no debug printout at all */ return; @@ -150,86 +165,18 @@ console_write(struct console *co, const char *buf, unsigned int len) SIMCOUT(buf,len); return; #endif - - local_save_flags(flags); - local_irq_disable(); #ifdef CONFIG_ETRAX_KGDB /* kgdb needs to output debug info using the gdb protocol */ putDebugString(buf, len); - local_irq_restore(flags); return; #endif - /* To make this work together with the real serial port driver - * we have to make sure that everything is flushed when we leave - * here. The following steps are made to assure this: - * 1. Wait until DMA stops, FIFO is empty and serial port pipeline empty. - * 2. Write at least half the FIFO to trigger flush to serial port. - * 3. Wait until DMA stops, FIFO is empty and serial port pipeline empty. - */ - - /* Do we have enough characters to make the DMA/FIFO happy? */ - if (tmp_size + len < MIN_SIZE) - { - int size = min((int)(MIN_SIZE - tmp_size),(int)len); - memcpy(&tmp_buf[tmp_size], buf, size); - tmp_size += size; - len -= size; - - /* Pad with space if complete line */ - if (tmp_buf[tmp_size-1] == '\n') - { - memset(&tmp_buf[tmp_size-1], ' ', MIN_SIZE - tmp_size); - tmp_buf[MIN_SIZE - 1] = '\n'; - tmp_size = MIN_SIZE; - len = 0; - } - else - { - /* Wait for more characters */ - local_irq_restore(flags); + local_irq_save(flags); + if (debug_write_function) + if (debug_write_function(co->index, buf, len)) return; - } - } - - /* make sure the transmitter is enabled. - * NOTE: this overrides any setting done in ttySx, to 8N1, no auto-CTS. - * in the future, move the tr/rec_ctrl shadows from etrax100ser.c to - * shadows.c and use it here as well... - */ - - *DEBUG_TR_CTRL = 0x40; - while(*DEBUG_OCMD & 7); /* Until DMA is not running */ - while(*DEBUG_STATUS & 0x7f); /* wait until output FIFO is empty as well */ - udelay(200); /* Wait for last two characters to leave the serial transmitter */ - - if (tmp_size) - { - descr.ctrl = len ? 0 : d_eop | d_wait | d_eol; - descr.sw_len = tmp_size; - descr.buf = virt_to_phys(tmp_buf); - descr.next = virt_to_phys(&descr2); - descr2.ctrl = d_eop | d_wait | d_eol; - descr2.sw_len = len; - descr2.buf = virt_to_phys((char*)buf); - } - else - { - descr.ctrl = d_eop | d_wait | d_eol; - descr.sw_len = len; - descr.buf = virt_to_phys((char*)buf); - } - - *DEBUG_FIRST = virt_to_phys(&descr); /* write to R_DMAx_FIRST */ - *DEBUG_OCMD = 1; /* dma command start -> R_DMAx_CMD */ - - /* wait until the output dma channel is ready again */ - while(*DEBUG_OCMD & 7); - while(*DEBUG_STATUS & 0x7f); - udelay(200); - - tmp_size = 0; + console_write_direct(co, buf, len); local_irq_restore(flags); } @@ -279,10 +226,11 @@ enableDebugIRQ(void) *DEBUG_REC_CTRL = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable); } -static kdev_t -console_device(struct console *c) +static struct tty_driver* +console_device(struct console *c, int *index) { - return mk_kdev(TTY_MAJOR, 64 + c->index); + *index = c->index; + return serial_driver; } static int __init @@ -311,5 +259,33 @@ static struct console sercons = { void __init init_etrax_debug(void) { +#if CONFIG_ETRAX_DEBUG_PORT_NULL + return; +#endif + +#if DEBUG_PORT_IDX == 0 + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused); +#elif DEBUG_PORT_IDX == 1 + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb); +#elif DEBUG_PORT_IDX == 2 + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0); +#elif DEBUG_PORT_IDX == 3 + genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4); + genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1); +#endif + *R_GEN_CONFIG = genconfig_shadow; + register_console(&sercons); } + +int __init +init_console(void) +{ + serial_driver = alloc_tty_driver(1); + if (!serial_driver) + return -ENOMEM; + return 0; +} diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index 5e5f5be7e..ddd947d1c 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.16 2003/07/04 08:27:41 starvik Exp $ +/* $Id: entry.S,v 1.18 2004/05/11 12:28:25 starvik Exp $ * * linux/arch/cris/entry.S * @@ -7,6 +7,12 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: entry.S,v $ + * Revision 1.18 2004/05/11 12:28:25 starvik + * Merge of Linux 2.6.6 + * + * Revision 1.17 2003/09/11 07:29:49 starvik + * Merge of Linux 2.6.0-test5 + * * Revision 1.16 2003/07/04 08:27:41 starvik * Merge of Linux 2.5.74 * @@ -1060,6 +1066,19 @@ sys_call_table: .long sys_clock_nanosleep .long sys_statfs64 .long sys_fstatfs64 + .long sys_tgkill /* 270 */ + .long sys_utimes + .long sys_fadvise64_64 + .long sys_ni_syscall /* sys_vserver */ + .long sys_ni_syscall /* sys_mbind */ + .long sys_ni_syscall /* 275 sys_get_mempolicy */ + .long sys_ni_syscall /* sys_set_mempolicy */ + .long sys_mq_open + .long sys_mq_unlink + .long sys_mq_timedsend + .long sys_mq_timedreceive /* 280 */ + .long sys_mq_notify + .long sys_mq_getsetattr /* * NOTE!! This doesn't have to be exact - we just have diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c index 2c2cb60c4..53b94eb3e 100644 --- a/arch/cris/arch-v10/kernel/fasttimer.c +++ b/arch/cris/arch-v10/kernel/fasttimer.c @@ -1,10 +1,16 @@ -/* $Id: fasttimer.c,v 1.4 2003/07/04 08:27:41 starvik Exp $ +/* $Id: fasttimer.c,v 1.6 2004/05/14 10:18:39 starvik Exp $ * linux/arch/cris/kernel/fasttimer.c * * Fast timers for ETRAX100/ETRAX100LX * This may be useful in other OS than Linux so use 2 space indentation... * * $Log: fasttimer.c,v $ + * Revision 1.6 2004/05/14 10:18:39 starvik + * Export fast_timer_list + * + * Revision 1.5 2004/05/14 07:58:01 starvik + * Merge of changes from 2.4 + * * Revision 1.4 2003/07/04 08:27:41 starvik * Merge of Linux 2.5.74 * @@ -130,7 +136,7 @@ static int fast_timers_deleted = 0; static int fast_timer_is_init = 0; static int fast_timer_ints = 0; -static struct fast_timer *fast_timer_list = NULL; +struct fast_timer *fast_timer_list = NULL; #ifdef DEBUG_LOG_INCLUDED #define DEBUG_LOG_MAX 128 @@ -325,7 +331,8 @@ void start_one_shot_timer(struct fast_timer *t, { if (tmp == t) { - printk("timer name: %s data: 0x%08lX already in list!\n", name, data); + printk(KERN_WARNING + "timer name: %s data: 0x%08lX already in list!\n", name, data); sanity_failed++; return; } @@ -784,7 +791,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len cli(); if (t->next != nextt) { - printk("timer removed!\n"); + printk(KERN_WARNING "timer removed!\n"); } t = nextt; } @@ -965,7 +972,7 @@ void fast_timer_init(void) int i; #endif - printk("fast_timer_init()\n"); + printk(KERN_INFO "fast_timer_init()\n"); #if 0 && defined(FAST_TIMER_TEST) for (i = 0; i <= TIMER0_DIV; i++) diff --git a/arch/cris/arch-v10/kernel/head.S b/arch/cris/arch-v10/kernel/head.S index 8192cd758..2c1dd1184 100644 --- a/arch/cris/arch-v10/kernel/head.S +++ b/arch/cris/arch-v10/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.6 2003/04/28 05:31:46 starvik Exp $ +/* $Id: head.S,v 1.7 2004/05/14 07:58:01 starvik Exp $ * * Head of the kernel - alter with care * @@ -7,6 +7,9 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: head.S,v $ + * Revision 1.7 2004/05/14 07:58:01 starvik + * Merge of changes from 2.4 + * * Revision 1.6 2003/04/28 05:31:46 starvik * Added section attributes * @@ -331,7 +334,16 @@ _inflash: move.d START_ETHERNET_CLOCK, $r0 move.d $r0, [R_NETWORK_GEN_CONFIG] #endif - + + ;; Set up waitstates etc according to kernel configuration. +#ifndef CONFIG_SVINTO_SIM + move.d CONFIG_ETRAX_DEF_R_WAITSTATES, $r0 + move.d $r0, [R_WAITSTATES] + + move.d CONFIG_ETRAX_DEF_R_BUS_CONFIG, $r0 + move.d $r0, [R_BUS_CONFIG] +#endif + ;; We need to initialze DRAM registers before we start using the DRAM cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized? @@ -626,8 +638,19 @@ _start_it: | IO_STATE (R_GEN_CONFIG, dma4, extdma0),$r0 #endif -#if defined(CONFIG_BLUETOOTH) && (defined(CONFIG_BLUETOOTH_RESET_G10) || defined(CONFIG_BLUETOOTH_RESET_G11)) - or.d IO_STATE (R_GEN_CONFIG, g8_15dir, out),$r0 +#if defined(CONFIG_ETRAX_DEF_R_PORT_G0_DIR_OUT) + or.d IO_STATE (R_GEN_CONFIG, g0dir, out),$r0 +#endif + +#if defined(CONFIG_ETRAX_DEF_R_PORT_G8_15_DIR_OUT) + or.d IO_STATE (R_GEN_CONFIG, g8_15dir, out),$r0 +#endif +#if defined(CONFIG_ETRAX_DEF_R_PORT_G16_23_DIR_OUT) + or.d IO_STATE (R_GEN_CONFIG, g16_23dir, out),$r0 +#endif + +#if defined(CONFIG_ETRAX_DEF_R_PORT_G24_DIR_OUT) + or.d IO_STATE (R_GEN_CONFIG, g24dir, out),$r0 #endif move.d $r0,[genconfig_shadow] ; init a shadow register of R_GEN_CONFIG diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index 7ad794280..8aba42472 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.3 2003/07/04 08:27:41 starvik Exp $ +/* $Id: process.c,v 1.6 2004/05/11 12:28:25 starvik Exp $ * * linux/arch/cris/kernel/process.c * @@ -16,6 +16,7 @@ #include #include #include +#include #include #ifdef CONFIG_ETRAX_GPIO @@ -249,3 +250,19 @@ unsigned long get_wchan(struct task_struct *p) } #undef last_sched #undef first_sched + +void show_regs(struct pt_regs * regs) +{ + unsigned long usp = rdusp(); + printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", + regs->irp, regs->srp, regs->dccr, usp, regs->mof ); + printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", + regs->r0, regs->r1, regs->r2, regs->r3); + printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", + regs->r4, regs->r5, regs->r6, regs->r7); + printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", + regs->r8, regs->r9, regs->r10, regs->r11); + printk("r12: %08lx r13: %08lx oR10: %08lx\n", + regs->r12, regs->r13, regs->orig_r10); +} + diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index c83eba5d6..39dcc3c72 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c @@ -118,19 +118,13 @@ sys_ptrace(long request, long pid, long addr, long data) /* Read the word at location address in the USER area. */ case PTRACE_PEEKUSR: { unsigned long tmp; - + ret = -EIO; - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) break; - - tmp = 0; /* Default return condition */ - ret = -EIO; - - if (addr < sizeof(struct pt_regs)) { - tmp = get_reg(child, addr >> 2); - ret = put_user(tmp, (unsigned long *)data); - } - + + tmp = get_reg(child, addr >> 2); + ret = put_user(tmp, (unsigned long *)data); break; } @@ -148,28 +142,21 @@ sys_ptrace(long request, long pid, long addr, long data) /* Write the word at location address in the USER area. */ case PTRACE_POKEUSR: ret = -EIO; - - if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) + if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) break; - if (addr < sizeof(struct pt_regs)) { - addr >>= 2; + addr >>= 2; - if (addr == PT_DCCR) { - /* - * Don't allow the tracing process to - * change stuff like interrupt enable, - * kernel/user bit, etc. - */ - data &= DCCR_MASK; - data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; - } - - if (put_reg(child, addr, data)) - break; - - ret = 0; + if (addr == PT_DCCR) { + /* don't allow the tracing process to change stuff like + * interrupt enable, kernel/user bit, dma enables etc. + */ + data &= DCCR_MASK; + data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; } + if (put_reg(child, addr, data)) + break; + ret = 0; break; case PTRACE_SYSCALL: @@ -237,7 +224,7 @@ sys_ptrace(long request, long pid, long addr, long data) if (put_user(tmp, (unsigned long *) data)) { ret = -EFAULT; - break; + goto out_tsk; } data += sizeof(long); @@ -255,7 +242,7 @@ sys_ptrace(long request, long pid, long addr, long data) for (i = 0; i <= PT_MAX; i++) { if (get_user(tmp, (unsigned long *) data)) { ret = -EFAULT; - break; + goto out_tsk; } if (i == PT_DCCR) { @@ -290,12 +277,10 @@ void do_syscall_trace(void) if (!(current->ptrace & PT_PTRACED)) return; - current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0); - - current->state = TASK_STOPPED; - notify_parent(current, SIGCHLD); - schedule(); + /* the 0x80 provides a way for the tracing parent to distinguish + between a syscall stop and SIGTRAP delivery */ + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) + ? 0x80 : 0)); /* * This isn't the same as continuing with a signal, but it will do for diff --git a/arch/cris/arch-v10/kernel/setup.c b/arch/cris/arch-v10/kernel/setup.c index d95930270..b668d7fb6 100644 --- a/arch/cris/arch-v10/kernel/setup.c +++ b/arch/cris/arch-v10/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.1 2002/12/11 15:42:02 starvik Exp $ +/* * * linux/arch/cris/arch-v10/kernel/setup.c * @@ -94,3 +94,10 @@ int show_cpuinfo(struct seq_file *m, void *v) } #endif /* CONFIG_PROC_FS */ + +void +show_etrax_copyright(void) +{ + printk(KERN_INFO + "Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB\n"); +} diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index 6698054a5..8db985e29 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c @@ -180,6 +180,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) unsigned int err = 0; unsigned long old_usp; + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + /* restore the regs from &sc->regs (same as sc, since regs is first) * (sc is already checked for VERIFY_READ since the sigframe was * checked in sys_sigreturn previously) @@ -492,7 +495,6 @@ handle_signal(int canrestart, unsigned long sig, /* If so, check system call restarting.. */ switch (regs->r10) { case -ERESTART_RESTARTBLOCK: - current_thread_info()->restart_block.fn = do_no_restart_syscall; case -ERESTARTNOHAND: /* ERESTARTNOHAND means that the syscall should only be restarted if there was no handler for the signal, and since diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 31e83a84e..c4d78d52f 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.2 2003/07/04 08:27:41 starvik Exp $ +/* $Id: time.c,v 1.3 2004/06/01 05:38:42 starvik Exp $ * * linux/arch/cris/arch-v10/kernel/time.c * @@ -277,6 +277,12 @@ time_init(void) update_xtime_from_cmos(); } + /* + * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the + * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC). + */ + set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); + /* Setup the etrax timers * Base frequency is 25000 hz, divider 250 -> 100 HZ * In normal mode, we use timer0, so timer1 is free. In cascade diff --git a/arch/cris/arch-v10/lib/dram_init.S b/arch/cris/arch-v10/lib/dram_init.S index 4852709dc..2ef4ad570 100644 --- a/arch/cris/arch-v10/lib/dram_init.S +++ b/arch/cris/arch-v10/lib/dram_init.S @@ -1,4 +1,4 @@ -/* $Id: dram_init.S,v 1.3 2003/03/31 09:38:37 starvik Exp $ +/* $Id: dram_init.S,v 1.4 2003/09/22 09:21:59 starvik Exp $ * * DRAM/SDRAM initialization - alter with care * This file is intended to be included from other assembler files @@ -11,6 +11,10 @@ * Authors: Mikael Starvik (starvik@axis.com) * * $Log: dram_init.S,v $ + * Revision 1.4 2003/09/22 09:21:59 starvik + * Decompresser is linked to 0x407xxxxx and sdram commands are at 0x000xxxxx + * so we need to mask off 12 bits. + * * Revision 1.3 2003/03/31 09:38:37 starvik * Corrected calculation of end of sdram init commands * @@ -152,9 +156,9 @@ _set_timing: ; Issue initialization command sequence move.d _sdram_commands_start, $r2 - and.d 0x00ffffff, $r2 ; Make sure commands are read from flash + and.d 0x000fffff, $r2 ; Make sure commands are read from flash move.d _sdram_commands_end, $r3 - and.d 0x00ffffff, $r3 + and.d 0x000fffff, $r3 1: clear.d $r4 move.b [$r2+], $r4 lslq 9, $r4 ; Command starts at bit 9 diff --git a/arch/cris/arch-v10/lib/old_checksum.c b/arch/cris/arch-v10/lib/old_checksum.c index 901a68d0b..22a6f0aa9 100644 --- a/arch/cris/arch-v10/lib/old_checksum.c +++ b/arch/cris/arch-v10/lib/old_checksum.c @@ -1,4 +1,4 @@ -/* $Id: old_checksum.c,v 1.2 2002/11/05 06:45:12 starvik Exp $ +/* $Id: old_checksum.c,v 1.3 2003/10/27 08:04:32 starvik Exp $ * * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket @@ -76,7 +76,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) sum += *((unsigned short *)buff)++; } if(endMarker - buff > 0) { - sum += *buff; /* add extra byte separately */ + sum += *buff; /* add extra byte seperately */ } BITOFF; return(sum); diff --git a/arch/cris/arch-v10/mm/fault.c b/arch/cris/arch-v10/mm/fault.c index 7a012adc1..0c6bac018 100644 --- a/arch/cris/arch-v10/mm/fault.c +++ b/arch/cris/arch-v10/mm/fault.c @@ -30,7 +30,7 @@ extern const struct exception_table_entry *search_exception_tables(unsigned long addr); asmlinkage void do_page_fault(unsigned long address, struct pt_regs *regs, - int error_code); + int protection, int writeaccess); /* fast TLB-fill fault handler * this is called from entry.S with interrupts disabled @@ -39,8 +39,9 @@ asmlinkage void do_page_fault(unsigned long address, struct pt_regs *regs, void handle_mmu_bus_fault(struct pt_regs *regs) { - int cause, select; + int cause; #ifdef DEBUG + int select; int index; int page_id; int acc, inv; @@ -48,15 +49,14 @@ handle_mmu_bus_fault(struct pt_regs *regs) int miss, we, writeac; pmd_t *pmd; pte_t pte; - int errcode; unsigned long address; cause = *R_MMU_CAUSE; - select = *R_TLB_SELECT; address = cause & PAGE_MASK; /* get faulting address */ #ifdef DEBUG + select = *R_TLB_SELECT; page_id = IO_EXTRACT(R_MMU_CAUSE, page_id, cause); acc = IO_EXTRACT(R_MMU_CAUSE, acc_excp, cause); inv = IO_EXTRACT(R_MMU_CAUSE, inv_excp, cause); @@ -82,12 +82,6 @@ handle_mmu_bus_fault(struct pt_regs *regs) if(writeac) regs->csrinstr &= ~(1 << 5); - /* Set errcode's R/W flag according to the mode which caused the - * fault - */ - - errcode = writeac << 1; - D(printk("bus_fault from IRP 0x%lx: addr 0x%lx, miss %d, inv %d, we %d, acc %d, dx %d pid %d\n", regs->irp, address, miss, inv, we, acc, index, page_id)); @@ -99,16 +93,20 @@ handle_mmu_bus_fault(struct pt_regs *regs) */ pmd = (pmd_t *)(current_pgd + pgd_index(address)); - if (pmd_none(*pmd)) - goto dofault; + if (pmd_none(*pmd)) { + do_page_fault(address, regs, 0, writeac); + return; + } if (pmd_bad(*pmd)) { printk("bad pgdir entry 0x%lx at 0x%p\n", *(unsigned long*)pmd, pmd); pmd_clear(pmd); return; } pte = *pte_offset_kernel(pmd, address); - if (!pte_present(pte)) - goto dofault; + if (!pte_present(pte)) { + do_page_fault(address, regs, 0, writeac); + return; + } #ifdef DEBUG printk(" found pte %lx pg %p ", pte_val(pte), pte_page(pte)); @@ -143,14 +141,10 @@ handle_mmu_bus_fault(struct pt_regs *regs) *R_TLB_LO = pte_val(pte); return; - } - - errcode = 1 | (we << 1); + } - dofault: - /* leave it to the MM system fault handler below */ - D(printk("do_page_fault %lx errcode %d\n", address, errcode)); - do_page_fault(address, regs, errcode); + /* leave it to the MM system fault handler */ + do_page_fault(address, regs, 1, we); } /* Called from arch/cris/mm/fault.c to find fixup code. */ diff --git a/arch/cris/arch-v10/mm/tlb.c b/arch/cris/arch-v10/mm/tlb.c index 2ddb0a61c..62fd0143c 100644 --- a/arch/cris/arch-v10/mm/tlb.c +++ b/arch/cris/arch-v10/mm/tlb.c @@ -212,7 +212,7 @@ dump_tlb_all(void) void switch_mm(struct mm_struct *prev, struct mm_struct *next, - struct task_struct *tsk, int cpu) + struct task_struct *tsk) { /* make sure we have a context */ diff --git a/arch/cris/defconfig b/arch/cris/defconfig index 3932dfa8e..0cef3f998 100644 --- a/arch/cris/defconfig +++ b/arch/cris/defconfig @@ -1,25 +1,55 @@ # # Automatically generated make config: don't edit # +CONFIG_MMU=y CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y # # General setup # -CONFIG_NET=y -CONFIG_SYSVIPC=y +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# General setup +# CONFIG_BINFMT_ELF=y -# CONFIG_ETRAX_KGDB is not set -# CONFIG_ETRAX_WATCHDOG is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock3 init=/linuxrc" +CONFIG_ETRAX_WATCHDOG=y +CONFIG_ETRAX_WATCHDOG_NICE_DOGGY=y +CONFIG_ETRAX_FAST_TIMER=y +# CONFIG_PREEMPT is not set # # Hardware setup @@ -27,74 +57,170 @@ CONFIG_BINFMT_ELF=y CONFIG_ETRAX100LX=y # CONFIG_ETRAX100LX_V2 is not set # CONFIG_SVINTO_SIM is not set -CONFIG_ETRAX_DRAM_SIZE=8 +CONFIG_ETRAX_ARCH_V10=y +CONFIG_ETRAX_DRAM_SIZE=16 CONFIG_ETRAX_FLASH_BUSWIDTH=2 -CONFIG_ETRAX_ROOT_DEVICE="/dev/mtdblock3" +CONFIG_CRIS_LOW_MAP=y +CONFIG_ETRAX_DRAM_VIRTUAL_BASE=60000000 +CONFIG_ETRAX_PA_LEDS=y +# CONFIG_ETRAX_PB_LEDS is not set +# CONFIG_ETRAX_CSP0_LEDS is not set +# CONFIG_ETRAX_NO_LEDS is not set +CONFIG_ETRAX_LED1G=2 +CONFIG_ETRAX_LED1R=2 +CONFIG_ETRAX_LED2G=3 +CONFIG_ETRAX_LED2R=3 +CONFIG_ETRAX_LED3G=2 +CONFIG_ETRAX_LED3R=2 +CONFIG_ETRAX_DEBUG_PORT0=y +# CONFIG_ETRAX_DEBUG_PORT1 is not set +# CONFIG_ETRAX_DEBUG_PORT2 is not set +# CONFIG_ETRAX_DEBUG_PORT3 is not set +# CONFIG_ETRAX_DEBUG_PORT_NULL is not set +CONFIG_ETRAX_RESCUE_SER0=y +# CONFIG_ETRAX_RESCUE_SER1 is not set +# CONFIG_ETRAX_RESCUE_SER2 is not set +# CONFIG_ETRAX_RESCUE_SER3 is not set +CONFIG_ETRAX_DEF_R_WAITSTATES=0x95f8 +CONFIG_ETRAX_DEF_R_BUS_CONFIG=0x104 +CONFIG_ETRAX_SDRAM=y +CONFIG_ETRAX_DEF_R_SDRAM_CONFIG=0x00e03636 +CONFIG_ETRAX_DEF_R_SDRAM_TIMING=0x80008002 +CONFIG_ETRAX_DEF_R_PORT_PA_DIR=0x1d +CONFIG_ETRAX_DEF_R_PORT_PA_DATA=0xf0 +CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=0x00 +CONFIG_ETRAX_DEF_R_PORT_PB_DIR=0x1e +CONFIG_ETRAX_DEF_R_PORT_PB_DATA=0xf3 +# CONFIG_ETRAX_SOFT_SHUTDOWN is not set + +# +# Drivers for built-in interfaces +# +CONFIG_ETRAX_ETHERNET=y +CONFIG_NET_ETHERNET=y +# CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set +CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y +CONFIG_ETRAX_SERIAL=y +CONFIG_ETRAX_SERIAL_FAST_TIMER=y +CONFIG_ETRAX_SERIAL_PORT0=y +# CONFIG_CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT is not set +CONFIG_CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT=y +# CONFIG_CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN is not set +CONFIG_CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN=y +CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE=y +# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA is not set +# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set +# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED is not set +CONFIG_ETRAX_SER0_DTR_ON_PA_BIT=-1 +CONFIG_ETRAX_SER0_RI_ON_PA_BIT=-1 +CONFIG_ETRAX_SER0_DSR_ON_PA_BIT=-1 +CONFIG_ETRAX_SER0_CD_ON_PA_BIT=-1 +CONFIG_ETRAX_SER0_DTR_ON_PB_BIT=-1 +CONFIG_ETRAX_SER0_RI_ON_PB_BIT=-1 +CONFIG_ETRAX_SER0_DSR_ON_PB_BIT=-1 +CONFIG_ETRAX_SER0_CD_ON_PB_BIT=-1 +# CONFIG_ETRAX_SERIAL_PORT1 is not set +CONFIG_ETRAX_SERIAL_PORT2=y +# CONFIG_CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT is not set +CONFIG_CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT=y +# CONFIG_CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN is not set +CONFIG_CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN=y +CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE=y +# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA is not set +# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PB is not set +# CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED is not set +CONFIG_ETRAX_SER2_DTR_ON_PA_BIT=-1 +CONFIG_ETRAX_SER2_RI_ON_PA_BIT=-1 +CONFIG_ETRAX_SER2_DSR_ON_PA_BIT=-1 +CONFIG_ETRAX_SER2_CD_ON_PA_BIT=-1 +CONFIG_ETRAX_SER2_DTR_ON_PB_BIT=-1 +CONFIG_ETRAX_SER2_RI_ON_PB_BIT=-1 +CONFIG_ETRAX_SER2_DSR_ON_PB_BIT=-1 +CONFIG_ETRAX_SER2_CD_ON_PB_BIT=-1 +# CONFIG_ETRAX_SERIAL_PORT3 is not set +# CONFIG_ETRAX_RS485 is not set +# CONFIG_ETRAX_IDE is not set +# CONFIG_IDE is not set +# CONFIG_ETRAX_USB_HOST is not set +CONFIG_ETRAX_AXISFLASHMAP=y +CONFIG_ETRAX_PTABLE_SECTOR=65536 +CONFIG_MTD=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_OBSOLETE_CHIPS=y +CONFIG_MTD_AMDSTD=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_CONCAT=y +# CONFIG_ETRAX_I2C is not set +CONFIG_ETRAX_GPIO=y +CONFIG_ETRAX_PA_BUTTON_BITMASK=0x02 +CONFIG_ETRAX_PA_CHANGEABLE_DIR=0x00 +CONFIG_ETRAX_PA_CHANGEABLE_BITS=0xFF +CONFIG_ETRAX_PB_CHANGEABLE_DIR=0x00 +CONFIG_ETRAX_PB_CHANGEABLE_BITS=0xFF +# CONFIG_ETRAX_RTC is not set # -# Drivers for ETRAX 100LX built-in interfaces +# Generic Driver Options # # # Memory Technology Devices (MTD) # -CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # -# Disk-On-Chip Device Drivers +# User Modules And Translation Layers # -# CONFIG_MTD_DOC1000 is not set -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set # -# RAM/ROM Device Drivers +# RAM/ROM/Flash chip drivers # -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_RAM is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_RAM=y # CONFIG_MTD_ROM is not set -# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set # -# Linearly Mapped Flash Device Drivers +# Mapping drivers for chip access # -CONFIG_MTD_CFI=y -# CONFIG_MTD_CFI_GEOMETRY is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_AMDSTD=y -# CONFIG_MTD_SHARP is not set +CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_NORA is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_RPXLITE is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_SBC_MEDIAGX is not set -# CONFIG_MTD_ELAN_104NC is not set -# CONFIG_MTD_SA1100 is not set -# CONFIG_MTD_DC21285 is not set -# CONFIG_MTD_CSTM_CFI_JEDEC is not set -# CONFIG_MTD_JEDEC is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set # -# NAND Flash Device Drivers +# Self-contained MTD device drivers # -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_NAND_SPIA is not set +# CONFIG_MTD_SLRAM is not set +CONFIG_MTD_MTDRAM=y +CONFIG_MTDRAM_TOTAL_SIZE=0 +CONFIG_MTDRAM_ERASE_SIZE=64 +CONFIG_MTDRAM_ABS_POS=0x0 +# CONFIG_MTD_BLKMTD is not set # -# User Modules And Translation Layers +# Disk-On-Chip Device Drivers # -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set # # Parallel port support @@ -102,51 +228,98 @@ CONFIG_MTD_BLOCK=y # CONFIG_PARPORT is not set # -# Plug and Play configuration +# Plug and Play support # -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_INITRD is not set +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# ATA/ATAPI/MFM/RLL support +# + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + # # Networking options # -# CONFIG_PACKET is not set -# CONFIG_NETLINK is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y +# CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_INET_ECN is not set +# CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set # CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -159,167 +332,114 @@ CONFIG_INET=y # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# IDE, ATA and ATAPI Block devices -# -# CONFIG_BLK_DEV_IDE is not set -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -# CONFIG_BLK_DEV_IDEDISK is not set -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_IDEDMA_AUTO is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_NET_SB1000 is not set # # Ethernet (10 or 100Mbit) # -CONFIG_NET_ETHERNET=y -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set +# CONFIG_MII is not set # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set # -# Wireless LAN (non-hamradio) +# Ethernet (10000 Mbit) # -# CONFIG_NET_RADIO is not set # # Token Ring devices # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set # # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # -# Amateur Radio support +# ISDN subsystem # -# CONFIG_HAMRADIO is not set +# CONFIG_ISDN is not set # -# IrDA (infrared) support +# Telephony Support # -# CONFIG_IRDA is not set +# CONFIG_PHONE is not set # -# ISDN subsystem +# Input device support # -# CONFIG_ISDN is not set +# CONFIG_INPUT is not set # -# CD-ROM drivers (not for SCSI or IDE/ATAPI drives) +# Userland interfaces # -# CONFIG_CD_NO_IDESCSI is not set # -# Input core support +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers # -# CONFIG_INPUT is not set # # Character devices # # CONFIG_VT is not set -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_UNIX98_PTYS is not set # -# I2C support +# Serial drivers # -# CONFIG_I2C is not set +# CONFIG_SERIAL_8250 is not set # -# Mice +# Non-8250 serial port support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set # -# Joysticks +# IPMI # -# CONFIG_JOYSTICK is not set -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -330,83 +450,106 @@ CONFIG_NET_ETHERNET=y # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + # # File systems # +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set +CONFIG_JFFS_FS=y +CONFIG_JFFS_FS_VERBOSE=0 +# CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set -# CONFIG_SYSV_FS_WRITE is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFS_V3 is not set -# CONFIG_ROOT_NFS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# # CONFIG_NLS is not set # @@ -417,9 +560,33 @@ CONFIG_MSDOS_PARTITION=y # # USB support # -# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set # # Kernel hacking # # CONFIG_PROFILE is not set +# CONFIG_ETRAX_KGDB is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_FRAME_POINTER is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile index 49bb782bd..7c071a765 100644 --- a/arch/cris/kernel/Makefile +++ b/arch/cris/kernel/Makefile @@ -1,14 +1,14 @@ -# $Id: Makefile,v 1.8 2003/04/09 05:20:47 starvik Exp $ +# $Id: Makefile,v 1.10 2004/05/14 10:18:12 starvik Exp $ # # Makefile for the linux kernel. # -extra-y := vmlinux.lds.s +extra-y := vmlinux.lds.s obj-y := process.o traps.o irq.o ptrace.o setup.o \ time.o sys_cris.o semaphore.o -obj-$(CONFIG_MODULES) += ksyms.o +obj-$(CONFIG_MODULES) += crisksyms.o obj-$(CONFIG_MODULES) += module.o clean: diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index 5eba7c184..a963dda74 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.8 2003/07/04 08:27:52 starvik Exp $ +/* * * linux/arch/cris/kernel/irq.c * @@ -99,7 +99,7 @@ int show_interrupts(struct seq_file *p, void *v) if (!action) goto skip; seq_printf(p, "%2d: %10u %c %s", - i, kstat_cpu(0).irqs[i], + i, kstat_this_cpu.irqs[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action = action->next; action; action = action->next) { @@ -129,13 +129,12 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) cpu = smp_processor_id(); irq_enter(); - kstat_cpu(cpu).irqs[irq]++; + kstat_cpu(cpu).irqs[irq - FIRST_IRQ]++; + action = irq_action[irq - FIRST_IRQ]; - action = irq_action[irq]; if (action) { if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); - action = irq_action[irq]; do_random = 0; do { do_random |= action->flags; @@ -175,7 +174,7 @@ int setup_irq(int irq, struct irqaction * new) struct irqaction *old, **p; unsigned long flags; - p = irq_action + irq; + p = irq_action + irq - FIRST_IRQ; if ((old = *p) != NULL) { /* Can't share interrupts unless both agree to */ if (!(old->flags & new->flags & SA_SHIRQ)) @@ -230,12 +229,6 @@ int request_irq(unsigned int irq, int retval; struct irqaction * action; - /* interrupts 0 and 1 are hardware breakpoint and NMI and we can't support - these yet. interrupt 15 is the multiple irq, it's special. */ - - if(irq < 2 || irq == 15 || irq >= NR_IRQS) - return -EINVAL; - if(!handler) return -EINVAL; @@ -270,7 +263,7 @@ void free_irq(unsigned int irq, void *dev_id) printk("Trying to free IRQ%d\n",irq); return; } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { + for (p = irq - FIRST_IRQ + irq_action; (action = *p) != NULL; p = &action->next) { if (action->dev_id != dev_id) continue; @@ -278,7 +271,7 @@ void free_irq(unsigned int irq, void *dev_id) local_save_flags(flags); local_irq_disable(); *p = action->next; - if (!irq_action[irq]) { + if (!irq_action[irq - FIRST_IRQ]) { mask_irq(irq); arch_free_irq(irq); } diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c index 052c0031f..f1d3e784f 100644 --- a/arch/cris/kernel/module.c +++ b/arch/cris/kernel/module.c @@ -75,8 +75,6 @@ int apply_relocate(Elf32_Shdr *sechdrs, sym = (Elf32_Sym *)sechdrs[symindex].sh_addr + ELF32_R_SYM(rel[i].r_info); - /* TODO: This is probably not correct */ - printk("Beware: untested code in module.c!\n"); /* We add the value into the location given */ *location += sym->st_value; } @@ -89,9 +87,26 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, unsigned int relsec, struct module *me) { - printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", - me->name); - return -ENOEXEC; + unsigned int i; + Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; + + DEBUGP ("Applying 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 */ + uint32_t *loc + = ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + + rela[i].r_offset); + /* This is the symbol it is referring to. Note that all + undefined symbols have been resolved. */ + Elf32_Sym *sym + = ((Elf32_Sym *)sechdrs[symindex].sh_addr + + ELF32_R_SYM (rela[i].r_info)); + *loc = sym->st_value + rela[i].r_addend; + } + + return 0; } int module_finalize(const Elf_Ehdr *hdr, diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index cbb0bad22..c4992bf89 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.14 2003/06/10 10:21:12 johana Exp $ +/* $Id: process.c,v 1.17 2004/04/05 13:53:48 starvik Exp $ * * linux/arch/cris/kernel/process.c * @@ -8,9 +8,18 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: process.c,v $ + * Revision 1.17 2004/04/05 13:53:48 starvik + * Merge of Linux 2.6.5 + * + * Revision 1.16 2003/10/27 08:04:33 starvik + * Merge of Linux 2.6.0-test9 + * + * Revision 1.15 2003/09/11 07:29:52 starvik + * Merge of Linux 2.6.0-test5 + * * Revision 1.14 2003/06/10 10:21:12 johana * Moved thread_saved_pc() from arch/cris/kernel/process.c to - * subarch specific process.c. + * subarch specific process.c. arch-v32 has an erp, no irp. * * Revision 1.13 2003/04/09 05:20:47 starvik * Merge of Linux 2.5.67 @@ -94,6 +103,7 @@ #include #include #include +#include #include #include #include @@ -182,13 +192,17 @@ void cpu_idle (void) { /* endless idle loop with no priority at all */ while (1) { - void (*idle)(void) = pm_idle; - if (!idle) - idle = default_idle; - while (!need_resched()) + while (!need_resched()) { + void (*idle)(void) = pm_idle; + + if (!idle) + idle = default_idle; + idle(); + } schedule(); } + } void hard_reset_now (void); diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index fc989d2c7..95a9f4408 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.7 2003/07/04 08:27:52 starvik Exp $ +/* * * linux/arch/cris/kernel/setup.c * @@ -10,6 +10,7 @@ * This file handles the architecture-dependent parts of initialization */ +#include #include #include #include @@ -38,6 +39,8 @@ extern unsigned long dram_start, dram_end; extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */ +extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */ + /* This mainly sets up the memory area, and can be really confusing. * * The physical DRAM is virtually mapped into dram_start to dram_end @@ -153,18 +156,16 @@ setup_arch(char **cmdline_p) *cmdline_p = command_line; #ifdef CONFIG_ETRAX_CMDLINE - strlcpy(command_line, CONFIG_ETRAX_CMDLINE, sizeof(command_line)); -#elif defined(CONFIG_ETRAX_ROOT_DEVICE) - strlcpy(command_line, "root=", sizeof(command_line)); - strlcat(command_line, CONFIG_ETRAX_ROOT_DEVICE, - sizeof(command_line)); -#endif + strlcpy(command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE); command_line[COMMAND_LINE_SIZE - 1] = '\0'; - /* give credit for the CRIS port */ - - printk("Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB\n"); + /* Save command line for future references. */ + memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); + saved_command_line[COMMAND_LINE_SIZE - 1] = '\0'; +#endif + /* give credit for the CRIS port */ + show_etrax_copyright(); } static void *c_start(struct seq_file *m, loff_t *pos) diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c index cd50e5ba2..0aa0e0ebb 100644 --- a/arch/cris/kernel/sys_cris.c +++ b/arch/cris/kernel/sys_cris.c @@ -1,4 +1,4 @@ -/* $Id: sys_cris.c,v 1.5 2003/07/04 08:27:52 starvik Exp $ +/* $Id: sys_cris.c,v 1.6 2004/03/11 11:38:40 starvik Exp $ * * linux/arch/cris/kernel/sys_cris.c * diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c index 9ca0f2025..6c28b0e7f 100644 --- a/arch/cris/kernel/time.c +++ b/arch/cris/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.9 2003/07/04 08:27:52 starvik Exp $ +/* $Id: time.c,v 1.14 2004/06/01 05:38:11 starvik Exp $ * * linux/arch/cris/kernel/time.c * @@ -29,6 +29,7 @@ #include #include #include +#include u64 jiffies_64 = INITIAL_JIFFIES; @@ -39,6 +40,8 @@ int have_rtc; /* used to remember if we have an RTC or not */; #define TICK_SIZE tick extern unsigned long wall_jiffies; +extern unsigned long loops_per_jiffy; /* init/main.c */ +unsigned long loops_per_usec; extern unsigned long do_slow_gettimeoffset(void); static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; @@ -62,6 +65,15 @@ void do_gettimeofday(struct timeval *tv) if (lost) usec += lost * (1000000 / HZ); } + + /* + * If time_adjust is negative then NTP is slowing the clock + * so make sure not to go into next possible interval. + * Better to lose some accuracy than have time go backwards.. + */ + if (unlikely(time_adjust < 0) && usec > tickadj) + usec = tickadj; + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; local_irq_restore(flags); @@ -79,35 +91,33 @@ EXPORT_SYMBOL(do_gettimeofday); int do_settimeofday(struct timespec *tv) { - unsigned long flags; + time_t wtm_sec, sec = tv->tv_sec; + long wtm_nsec, nsec = tv->tv_nsec; - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; - local_irq_save(flags); - local_irq_disable(); - - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + write_seqlock_irq(&xtime_lock); + /* + * This is revolting. We need to set "xtime" correctly. However, the + * value in this location is the value at the most recent update of + * wall time. Discover what correction gettimeofday() would have + * made, and then undo it! */ - tv->tv_nsec -= do_gettimeoffset() * 1000; - tv->tv_nsec -= (jiffies - wall_jiffies) * TICK_NSEC; + nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; + + wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); + wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); + + set_normalized_timespec(&xtime, sec, nsec); + set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - while (tv->tv_nsec < 0) { - tv->tv_nsec += NSEC_PER_SEC; - tv->tv_sec--; - } - xtime.tv_sec = tv->tv_sec; - xtime.tv_nsec = tv->tv_nsec; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; - time_state = TIME_ERROR; /* p. 24, (a) */ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - local_irq_restore(flags); + write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; } @@ -125,7 +135,7 @@ int set_rtc_mmss(unsigned long nowtime) int retval = 0; int real_seconds, real_minutes, cmos_minutes; - printk("set_rtc_mmss(%lu)\n", nowtime); + printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime); if(!have_rtc) return 0; @@ -174,7 +184,8 @@ get_cmos_time(void) mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); - printk("rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", + printk(KERN_DEBUG + "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", sec, min, hour, day, mon, year); BCD_TO_BIN(sec); @@ -202,3 +213,20 @@ update_xtime_from_cmos(void) xtime.tv_nsec = 0; } } + +/* + * Scheduler clock - returns current time in nanosec units. + */ +unsigned long long sched_clock(void) +{ + return (unsigned long long)jiffies * (1000000000 / HZ); +} + +static int +__init init_udelay(void) +{ + loops_per_usec = (loops_per_jiffy * HZ) / 1000000; + return 0; +} + +__initcall(init_udelay); diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c index d9e656565..d4dfa050e 100644 --- a/arch/cris/kernel/traps.c +++ b/arch/cris/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.7 2003/07/04 08:27:52 starvik Exp $ +/* $Id: traps.c,v 1.9 2004/05/11 12:28:26 starvik Exp $ * * linux/arch/cris/traps.c * @@ -14,6 +14,7 @@ */ #include +#include #include #include diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index 7e8f2a3ee..03254b9ed 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c @@ -6,9 +6,18 @@ * Authors: Bjorn Wesen * * $Log: fault.c,v $ + * Revision 1.11 2004/05/14 07:58:05 starvik + * Merge of changes from 2.4 + * + * Revision 1.10 2003/10/27 14:51:24 starvik + * Removed debugcode + * + * Revision 1.9 2003/10/27 14:50:42 starvik + * Changed do_page_fault signature + * * Revision 1.8 2003/07/04 13:02:48 tobiasa * Moved code snippet from arch/cris/mm/fault.c that searches for fixup code - * to separate function in arch-specific files. + * to seperate function in arch-specific files. * * Revision 1.7 2003/01/22 06:48:38 starvik * Fixed warnings issued by GCC 3.2.1 @@ -95,10 +104,6 @@ extern int find_fixup_code(struct pt_regs *); extern void die_if_kernel(const char *, struct pt_regs *, long); -asmlinkage void do_invalid_op (struct pt_regs *, unsigned long); -asmlinkage void do_page_fault(unsigned long address, struct pt_regs *regs, - int error_code); - /* debug of low-level TLB reload */ #undef DEBUG @@ -134,14 +139,16 @@ volatile pgd_t *current_pgd; asmlinkage void do_page_fault(unsigned long address, struct pt_regs *regs, - int error_code) + int protection, int writeaccess) { struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct * vma; - int writeaccess; siginfo_t info; + D(printk("Page fault for %X at %X, prot %d write %d\n", + address, regs->erp, protection, writeaccess)); + tsk = current; /* @@ -164,7 +171,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, */ if (address >= VMALLOC_START && - !(error_code & 1) && + !protection && !user_mode(regs)) goto vmalloc_fault; @@ -172,7 +179,6 @@ do_page_fault(unsigned long address, struct pt_regs *regs, sti(); mm = tsk->mm; - writeaccess = error_code & 2; info.si_code = SEGV_MAPERR; /* @@ -291,7 +297,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, printk(KERN_ALERT "Unable to handle kernel access"); printk(" at virtual address %08lx\n",address); - die_if_kernel("Oops", regs, error_code); + die_if_kernel("Oops", regs, (writeaccess << 1) | protection); do_exit(SIGKILL); diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index 3ff9bfcb8..d0bd0c957 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c @@ -7,6 +7,13 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: init.c,v $ + * Revision 1.11 2004/05/28 09:28:56 starvik + * Calculation of loops_per_usec moved because initalization order has changed + * in Linux 2.6. + * + * Revision 1.10 2004/05/14 07:58:05 starvik + * Merge of changes from 2.4 + * * Revision 1.9 2003/07/04 08:27:54 starvik * Merge of Linux 2.5.74 * @@ -120,9 +127,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); unsigned long empty_zero_page; -extern unsigned long loops_per_jiffy; /* init/main.c */ -unsigned long loops_per_usec; - extern char _stext, _edata, _etext; /* From linkerscript */ extern char __init_begin, __init_end; @@ -190,7 +194,8 @@ mem_init(void) datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, " + printk(KERN_INFO + "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, " "%dk init)\n" , (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), @@ -199,16 +204,6 @@ mem_init(void) datasize >> 10, initsize >> 10 ); - - /* HACK alert - calculate a loops_per_usec for asm/delay.h here - * since this is called just after calibrate_delay in init/main.c - * but before places which use udelay. cannot be in time.c since - * that is called _before_ calibrate_delay - */ - - loops_per_usec = (loops_per_jiffy * HZ) / 1000000; - - return; } /* free the pages occupied by initialization code */ @@ -225,6 +220,6 @@ free_initmem(void) free_page(addr); totalram_pages++; } - printk ("Freeing unused kernel memory: %luk freed\n", + printk (KERN_INFO "Freeing unused kernel memory: %luk freed\n", (unsigned long)((&__init_end - &__init_begin) >> 10)); } diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c index 52151df2f..6b9130bfb 100644 --- a/arch/cris/mm/ioremap.c +++ b/arch/cris/mm/ioremap.c @@ -118,31 +118,6 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag if (!size || last_addr < phys_addr) return NULL; -#if 0 - /* TODO: Here we can put checks for driver-writer abuse... */ - - /* - * Don't remap the low PCI/ISA area, it's always mapped.. - */ - if (phys_addr >= 0xA0000 && last_addr < 0x100000) - return phys_to_virt(phys_addr); - - /* - * Don't allow anybody to remap normal RAM that we're using.. - */ - if (phys_addr < virt_to_phys(high_memory)) { - char *t_addr, *t_end; - struct page *page; - - t_addr = __va(phys_addr); - t_end = t_addr + (size - 1); - - for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) - if(!PageReserved(page)) - return NULL; - } -#endif - /* * Mappings have to be page-aligned */ diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S index 3c9ca261c..c43349a31 100644 --- a/arch/i386/kernel/acpi/wakeup.S +++ b/arch/i386/kernel/acpi/wakeup.S @@ -285,6 +285,7 @@ ENTRY(do_suspend_lowlevel) call save_registers pushl $3 call acpi_enter_sleep_state + addl $4,%esp ret .p2align 4,,7 ret_point: diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index 3508c5b26..43943f871 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -53,16 +53,6 @@ void foo(void) OFFSET(TI_addr_limit, thread_info, addr_limit); OFFSET(TI_restart_block, thread_info, restart_block); OFFSET(TI_sysenter_return, thread_info, sysenter_return); - DEFINE(TI_real_stack, offsetof (struct thread_info, real_stack)); - DEFINE(TI_virtual_stack, offsetof (struct thread_info, virtual_stack)); - DEFINE(TI_user_pgd, offsetof (struct thread_info, user_pgd)); - - DEFINE(FIX_ENTRY_TRAMPOLINE_0_addr, - __fix_to_virt(FIX_ENTRY_TRAMPOLINE_0)); - DEFINE(FIX_VSYSCALL_addr, __fix_to_virt(FIX_VSYSCALL)); - - DEFINE(task_thread_db7, - offsetof (struct task_struct, thread.debugreg[7])); BLANK(); OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); @@ -72,5 +62,21 @@ void foo(void) DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) - sizeof(struct tss_struct)); + DEFINE(TI_task, offsetof (struct thread_info, task)); + DEFINE(TI_exec_domain, offsetof (struct thread_info, exec_domain)); + DEFINE(TI_flags, offsetof (struct thread_info, flags)); + DEFINE(TI_preempt_count, offsetof (struct thread_info, preempt_count)); + DEFINE(TI_addr_limit, offsetof (struct thread_info, addr_limit)); + DEFINE(TI_sysenter_return, + offsetof (struct thread_info, sysenter_return)); + DEFINE(TI_real_stack, offsetof (struct thread_info, real_stack)); + DEFINE(TI_virtual_stack, offsetof (struct thread_info, virtual_stack)); + DEFINE(TI_user_pgd, offsetof (struct thread_info, user_pgd)); + + DEFINE(FIX_ENTRY_TRAMPOLINE_0_addr, + __fix_to_virt(FIX_ENTRY_TRAMPOLINE_0)); + DEFINE(FIX_VSYSCALL_addr, __fix_to_virt(FIX_VSYSCALL)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); + DEFINE(task_thread_db7, + offsetof (struct task_struct, thread.debugreg[7])); } diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index b7c16fe49..000aac11e 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c @@ -75,7 +75,6 @@ #include #include -#include #include #include #include diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index 5510cd6a2..53145bbfe 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -18,7 +18,8 @@ */ #include -#include +#include +#include #include #include #include @@ -30,25 +31,25 @@ #include "longhaul.h" -#define DEBUG - -#ifdef DEBUG -#define dprintk(msg...) printk(msg) -#else -#define dprintk(msg...) do { } while(0) -#endif - #define PFX "longhaul: " static unsigned int numscales=16, numvscales; +static unsigned int fsb; static int minvid, maxvid; static int can_scale_voltage; static int vrmrev; - /* Module parameters */ static int dont_scale_voltage; -static unsigned int fsb; +static int debug; +static int debug; + +static void dprintk(const char *msg, ...) +{ + if (debug == 1) + printk(msg); +} + #define __hlt() __asm__ __volatile__("hlt": : :"memory") @@ -118,8 +119,7 @@ static void longhaul_setstate (unsigned int clock_ratio_index) cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - dprintk (KERN_INFO PFX "FSB:%d Mult:%d.%dx\n", fsb, - mult/10, mult%10); + dprintk (KERN_INFO PFX "FSB:%d Mult:%d.%dx\n", fsb, mult/10, mult%10); switch (longhaul_version) { case 1: @@ -167,16 +167,16 @@ static void longhaul_setstate (unsigned int clock_ratio_index) longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf; longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; longhaul.bits.EnableSoftBusRatio = 1; - + longhaul.bits.RevisionKey = 0x0; - + wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); __hlt(); - + rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); longhaul.bits.EnableSoftBusRatio = 0; longhaul.bits.RevisionKey = 0xf; - wrmsrl (MSR_VIA_LONGHAUL, longhaul.val); + wrmsrl (MSR_VIA_LONGHAUL, longhaul.val); break; } @@ -276,26 +276,26 @@ static int __init longhaul_get_ranges (void) break; } break; - + case 4: rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); - + //TODO: Nehemiah may have borken MaxMHzBR. // need to extrapolate from FSB. - + invalue2 = longhaul.bits.MinMHzBR; invalue = longhaul.bits.MaxMHzBR; - if (longhaul.bits.MaxMHzBR4) + if (longhaul.bits.MaxMHzBR4) invalue += 16; maxmult=multipliers[invalue]; - + maxmult=longhaul_get_cpu_mult(); - + printk(KERN_INFO PFX " invalue: %ld maxmult: %d \n", invalue, maxmult); printk(KERN_INFO PFX " invalue2: %ld \n", invalue2); - + minmult=50; - + switch (longhaul.bits.MaxMHzFSB) { case 0x0: fsb=133; break; @@ -306,8 +306,8 @@ static int __init longhaul_get_ranges (void) case 0x3: fsb=66; break; } - - break; + + break; } dprintk (KERN_INFO PFX "MinMult=%d.%dx MaxMult=%d.%dx\n", @@ -418,13 +418,13 @@ static int longhaul_target (struct cpufreq_policy *policy, unsigned int relation) { unsigned int table_index = 0; - unsigned int new_clock_ratio = 0; + unsigned int new_clock_ratio = 0; if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index)) return -EINVAL; new_clock_ratio = longhaul_table[table_index].index & 0xFF; - + longhaul_setstate(new_clock_ratio); return 0; @@ -500,7 +500,6 @@ static int __init longhaul_cpu_init (struct cpufreq_policy *policy) break; } break; - default: cpuname = "Unknown"; @@ -514,11 +513,11 @@ static int __init longhaul_cpu_init (struct cpufreq_policy *policy) if (ret != 0) return ret; - if ((longhaul_version==2) && (dont_scale_voltage==0)) + if ((longhaul_version==2) && (dont_scale_voltage==0)) longhaul_setup_voltagescaling(); policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = calc_speed (longhaul_get_cpu_mult(), fsb); ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); @@ -530,7 +529,7 @@ static int __init longhaul_cpu_init (struct cpufreq_policy *policy) return 0; } -static int __exit longhaul_cpu_exit(struct cpufreq_policy *policy) +static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy) { cpufreq_frequency_table_put_attr(policy->cpu); return 0; @@ -542,14 +541,14 @@ static struct freq_attr* longhaul_attr[] = { }; static struct cpufreq_driver longhaul_driver = { - .verify = longhaul_verify, - .target = longhaul_target, - .get = longhaul_get, - .init = longhaul_cpu_init, - .exit = longhaul_cpu_exit, - .name = "longhaul", - .owner = THIS_MODULE, - .attr = longhaul_attr, + .verify = longhaul_verify, + .target = longhaul_target, + .get = longhaul_get, + .init = longhaul_cpu_init, + .exit = __devexit_p(longhaul_cpu_exit), + .name = "longhaul", + .owner = THIS_MODULE, + .attr = longhaul_attr, }; static int __init longhaul_init (void) @@ -560,12 +559,8 @@ static int __init longhaul_init (void) return -ENODEV; switch (c->x86_model) { - case 6 ... 8: + case 6 ... 9: return cpufreq_register_driver(&longhaul_driver); - case 9: - printk (KERN_INFO PFX "Nehemiah unsupported: Waiting on working silicon " - "from VIA before this is usable.\n"); - break; default: printk (KERN_INFO PFX "Unknown VIA CPU. Contact davej@codemonkey.org.uk\n"); } @@ -579,7 +574,11 @@ static void __exit longhaul_exit (void) kfree(longhaul_table); } -MODULE_PARM (dont_scale_voltage, "i"); +module_param (dont_scale_voltage, int, 0644); +MODULE_PARM_DESC(dont_scale_voltage, "Don't scale voltage of processor"); + +module_param (debug, int, 0644); +MODULE_PARM_DESC(debug, "Dump debugging information."); MODULE_AUTHOR ("Dave Jones "); MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index b521aa70a..b5daeccfa 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -35,7 +34,7 @@ #include "speedstep-lib.h" -#define PFX "cpufreq: " +#define PFX "p4-clockmod: " /* * Duty Cycle (3bits), note DC_DISABLE is not specified in diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index d67f776d3..cf008b4af 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include @@ -86,7 +86,7 @@ static int mobile_vid_table[32] = { /* divide by 10 to get FID. */ static int fid_codes[32] = { 110, 115, 120, 125, 50, 55, 60, 65, - 70, 75, 80, 85, 90, 95, 100, 105, + 70, 75, 80, 85, 90, 95, 100, 105, 30, 190, 40, 200, 130, 135, 140, 210, 150, 225, 160, 165, 170, 180, -1, -1, }; @@ -95,7 +95,7 @@ static int fid_codes[32] = { * configuration purpose. */ -static int powernow_acpi_force; +static int acpi_force; static struct cpufreq_frequency_table *powernow_table; @@ -144,6 +144,11 @@ static int check_powernow(void) } cpuid(0x80000007, &eax, &ebx, &ecx, &edx); + + /* Check we can actually do something before we say anything.*/ + if (!(edx & (1 << 1 | 1 << 2))) + return 0; + printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: "); if (edx & 1 << 1) { @@ -159,11 +164,6 @@ static int check_powernow(void) can_scale_vid=1; } - if (!(edx & (1 << 1 | 1 << 2))) { - printk ("nothing.\n"); - return 0; - } - printk (".\n"); return 1; } @@ -572,7 +572,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) } dprintk(KERN_INFO PFX "FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000); - if ((dmi_broken & BROKEN_CPUFREQ) || powernow_acpi_force) { + if ((dmi_broken & BROKEN_CPUFREQ) || acpi_force) { printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); result = powernow_acpi_init(); } else { @@ -653,8 +653,7 @@ static void __exit powernow_exit (void) kfree(powernow_table); } -module_param(powernow_acpi_force, int, 0444); - +module_param(acpi_force, int, 0444); MODULE_PARM_DESC(acpi_force, "Force ACPI to be used"); MODULE_AUTHOR ("Dave Jones "); diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 51c59ef50..63737e8cb 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -553,7 +553,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, printk(KERN_ERR PFX "no p states to transition\n"); return -ENODEV; } - + if (check_pst_table(data, pst, maxvid)) return -EINVAL; @@ -736,9 +736,9 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) /* verify only 1 entry from the lo frequency table */ if ((fid < HI_FID_TABLE_BOTTOM) && (cntlofreq++)) { printk(KERN_ERR PFX "Too many lo freq table entries\n"); - goto err_out; + goto err_out_mem; } - + if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n", powernow_table[i].frequency, @@ -757,12 +757,16 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) print_basics(data); powernow_k8_acpi_pst_values(data, 0); return 0; + +err_out_mem: + kfree(powernow_table); + err_out: acpi_processor_unregister_performance(&data->acpi_data, data->cpu); /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ data->acpi_data.state_count = 0; - + return -ENODEV; } @@ -945,7 +949,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n"); kfree(data); - return 0; + return -ENODEV; } rc = find_psb_table(data); if (rc) { @@ -1047,7 +1051,7 @@ static unsigned int powernowk8_get (unsigned int cpu) if (query_current_values_with_pending_wait(data)) goto out; - khz = find_khz_freq_from_fid(data->currfid); + khz = find_khz_freq_from_fid(data->currfid); out: preempt_enable_no_resched(); diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index 99b8d1116..423429491 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c @@ -27,7 +27,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* AMD-defined */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, - NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL, + NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL, NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow", /* Transmeta-defined */ diff --git a/arch/i386/kernel/entry_trampoline.c b/arch/i386/kernel/entry_trampoline.c index 4cce52fa6..db6f6eaa8 100644 --- a/arch/i386/kernel/entry_trampoline.c +++ b/arch/i386/kernel/entry_trampoline.c @@ -30,8 +30,8 @@ void __init init_entry_mappings(void) */ trap_init_virtual_IDT(); - __set_fixmap(FIX_ENTRY_TRAMPOLINE_0, __pa((unsigned long)&__entry_tramp_start), PAGE_KERNEL); - __set_fixmap(FIX_ENTRY_TRAMPOLINE_1, __pa((unsigned long)&__entry_tramp_start) + PAGE_SIZE, PAGE_KERNEL); + __set_fixmap(FIX_ENTRY_TRAMPOLINE_0, __pa((unsigned long)&__entry_tramp_start), PAGE_KERNEL_EXEC); + __set_fixmap(FIX_ENTRY_TRAMPOLINE_1, __pa((unsigned long)&__entry_tramp_start) + PAGE_SIZE, PAGE_KERNEL_EXEC); tramp = (void *)fix_to_virt(FIX_ENTRY_TRAMPOLINE_0); printk("mapped 4G/4G trampoline to %p.\n", tramp); diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 3f868ea50..69bad9bd0 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -153,6 +153,32 @@ ENTRY(startup_32_smp) orl %edx,%eax movl %eax,%cr4 + btl $5, %eax # check if PAE is enabled + jnc 6f + + /* Check if extended functions are implemented */ + movl $0x80000000, %eax + cpuid + cmpl $0x80000000, %eax + jbe 6f + mov $0x80000001, %eax + cpuid + /* Execute Disable bit supported? */ + btl $20, %edx + jnc 6f + + /* Setup EFER (Extended Feature Enable Register) */ + movl $0xc0000080, %ecx + rdmsr + + btsl $11, %eax + /* Make changes effective */ + wrmsr + +6: + /* cpuid clobbered ebx, set it up again: */ + xorl %ebx,%ebx + incl %ebx 3: #endif /* CONFIG_SMP */ diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c index e8258ad35..5149c8a62 100644 --- a/arch/i386/kernel/module.c +++ b/arch/i386/kernel/module.c @@ -32,7 +32,7 @@ void *module_alloc(unsigned long size) { if (size == 0) return NULL; - return vmalloc(size); + return vmalloc_exec(size); } diff --git a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c index 340e7f39a..22a2fe2f8 100644 --- a/arch/i386/kernel/scx200.c +++ b/arch/i386/kernel/scx200.c @@ -86,7 +86,10 @@ int __init scx200_init(void) if ((bridge = pci_find_device(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE, - NULL)) == NULL) + NULL)) == NULL + && (bridge = pci_find_device(PCI_VENDOR_ID_NS, + PCI_DEVICE_ID_NS_SC1100_BRIDGE, + NULL)) == NULL) return -ENODEV; base = pci_resource_start(bridge, 0); diff --git a/arch/i386/lib/getuser.S b/arch/i386/lib/getuser.S index 62d7f178a..1985ca1e0 100644 --- a/arch/i386/lib/getuser.S +++ b/arch/i386/lib/getuser.S @@ -9,6 +9,7 @@ * return value. */ #include +#include /* diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index f611eaf3b..97d4af301 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -431,6 +431,21 @@ no_context: bust_spinlocks(1); +#ifdef CONFIG_X86_PAE + { + pgd_t *pgd; + pmd_t *pmd; + + + + pgd = init_mm.pgd + pgd_index(address); + if (pgd_present(*pgd)) { + pmd = pmd_offset(pgd, address); + if (pmd_val(*pmd) & _PAGE_NX) + printk(KERN_CRIT "kernel tried to access NX-protected page - exploit attempt? (uid: %d)\n", current->uid); + } + } +#endif if (address < PAGE_SIZE) printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); else diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index 581753285..83972da8e 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c @@ -41,12 +41,47 @@ void *kmap_atomic(struct page *page, enum km_type type) if (!pte_none(*(kmap_pte-idx))) BUG(); #endif - set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + /* + * If the page is not a normal RAM page, then map it + * uncached to be on the safe side - it could be device + * memory that must not be prefetched: + */ + if (PageReserved(page)) + set_pte(kmap_pte-idx, mk_pte(page, kmap_prot_nocache)); + else + set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); __flush_tlb_one(vaddr); return (void*) vaddr; } +/* + * page frame number based kmaps - useful for PCI mappings. + * NOTE: we map the page with the dont-cache flag. + */ +void *kmap_atomic_nocache_pfn(unsigned long pfn, enum km_type type) +{ + enum fixed_addresses idx; + unsigned long vaddr; + + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ + inc_preempt_count(); + if (pfn < highstart_pfn) + return pfn_to_kaddr(pfn); + + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#ifdef CONFIG_DEBUG_HIGHMEM + if (!pte_none(*(kmap_pte-idx))) + BUG(); +#endif + set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot_nocache)); + __flush_tlb_one(vaddr); + + return (void*) vaddr; +} + + void kunmap_atomic(void *kvaddr, enum km_type type) { #ifdef CONFIG_DEBUG_HIGHMEM diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 8b4d9801d..77179eb95 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -137,7 +137,8 @@ extern void set_highmem_pages_init(int); # define set_highmem_pages_init(bad_ppro) do { } while (0) #endif -unsigned long __PAGE_KERNEL = _PAGE_KERNEL; +unsigned long long __PAGE_KERNEL = _PAGE_KERNEL; +unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC; #ifndef CONFIG_DISCONTIGMEM #define remap_numa_kva() do {} while (0) @@ -208,7 +209,7 @@ void setup_identity_mappings(pgd_t *pgd_base, unsigned long start, unsigned long if (!pmd_present(*pmd)) pte_base = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); else - pte_base = (pte_t *) pte_offset_kernel(pmd, 0); + pte_base = pte_offset_kernel(pmd, 0); pte = pte_base; for (k = 0; k < PTRS_PER_PTE; pte++, k++) { vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE; @@ -293,24 +294,6 @@ static void __init pagetable_init (void) #endif } -#if defined(CONFIG_PM_DISK) || defined(CONFIG_SOFTWARE_SUSPEND) -/* - * Swap suspend & friends need this for resume because things like the intel-agp - * driver might have split up a kernel 4MB mapping. - */ -char __nosavedata swsusp_pg_dir[PAGE_SIZE] - __attribute__ ((aligned (PAGE_SIZE))); - -static inline void save_pg_dir(void) -{ - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE); -} -#else -static inline void save_pg_dir(void) -{ -} -#endif - /* * Clear kernel pagetables in a PMD_SIZE-aligned range. */ @@ -343,9 +326,6 @@ static void clear_mappings(pgd_t *pgd_base, unsigned long start, unsigned long e void zap_low_mappings(void) { printk("zapping low mappings.\n"); - - save_pg_dir(); - /* * Zap initial low-memory mappings. */ @@ -377,6 +357,53 @@ void __init zone_sizes_init(void) extern void zone_sizes_init(void); #endif /* !CONFIG_DISCONTIGMEM */ +static int disable_nx __initdata = 0; +u64 __supported_pte_mask = ~_PAGE_NX; + +/* + * noexec = on|off + * + * Control non executable mappings. + * + * on Enable + * off Disable (disables exec-shield too) + */ +static int __init noexec_setup(char *str) +{ + if (!strncmp(str, "on",2) && cpu_has_nx) { + __supported_pte_mask |= _PAGE_NX; + disable_nx = 0; + } else if (!strncmp(str,"off",3)) { + disable_nx = 1; + __supported_pte_mask &= ~_PAGE_NX; + exec_shield = 0; + } + return 1; +} + +__setup("noexec=", noexec_setup); + +int use_nx = 0; +#ifdef CONFIG_X86_PAE + +static void __init set_nx(void) +{ + unsigned int v[4], l, h; + + if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) { + cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]); + if ((v[3] & (1 << 20)) && !disable_nx) { + rdmsr(MSR_EFER, l, h); + l |= EFER_NX; + wrmsr(MSR_EFER, l, h); + use_nx = 1; + __supported_pte_mask |= _PAGE_NX; + } + } +} + +#endif + /* * paging_init() sets up the page tables - note that the first 8MB are * already mapped by head.S. @@ -386,6 +413,17 @@ extern void zone_sizes_init(void); */ void __init paging_init(void) { +#ifdef CONFIG_X86_PAE + set_nx(); + if (use_nx) + printk("NX (Execute Disable) protection: active\n"); + else { + printk("NX (Execute Disable) protection: not present!\n"); + if (exec_shield) + printk("Using x86 segment limits to approximate NX protection\n"); + } +#endif + pagetable_init(); load_cr3(swapper_pg_dir); @@ -411,7 +449,6 @@ void __init paging_init(void) kmap_init(); zone_sizes_init(); } - /* * Test if the WP bit works in supervisor mode. It isn't supported on 386's * and also on some strange 486's (NexGen etc.). All 586+'s are OK. This diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig index b80b92389..fdb3606aa 100644 --- a/arch/ppc64/configs/iSeries_defconfig +++ b/arch/ppc64/configs/iSeries_defconfig @@ -23,19 +23,23 @@ CONFIG_STANDALONE=y # CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -CONFIG_EMBEDDED=y +# CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # @@ -48,6 +52,7 @@ CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_KMOD is not set CONFIG_STOP_MACHINE=y +CONFIG_SYSVIPC_COMPAT=y # # Platform support @@ -60,6 +65,7 @@ CONFIG_PPC64=y # CONFIG_IOMMU_VMERGE is not set CONFIG_SMP=y CONFIG_NR_CPUS=32 +# CONFIG_SCHED_SMT is not set CONFIG_MSCHUNKS=y CONFIG_LPARCFG=y @@ -72,6 +78,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG_CPU is not set # # PCMCIA/CardBus support @@ -148,7 +155,6 @@ CONFIG_CHR_DEV_SG=y # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_REPORT_LUNS=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -180,6 +186,7 @@ CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -221,6 +228,7 @@ CONFIG_DM_CRYPT=m # # I2O device support # +# CONFIG_I2O is not set # # Macintosh device drivers @@ -247,7 +255,6 @@ CONFIG_NET_IPIP=y # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set -CONFIG_INET_ECN=y CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m @@ -258,8 +265,6 @@ CONFIG_INET_IPCOMP=m # # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -319,16 +324,18 @@ CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_IP_NF_COMPAT_IPCHAINS=m CONFIG_IP_NF_COMPAT_IPFWADM=m +# CONFIG_IP_NF_RAW is not set CONFIG_XFRM=y CONFIG_XFRM_USER=m # # SCTP Configuration (EXPERIMENTAL) # -CONFIG_IPV6_SCTP__=y # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set +# CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set CONFIG_LLC=y # CONFIG_LLC2 is not set # CONFIG_IPX is not set @@ -350,16 +357,23 @@ CONFIG_LLC=y # Network testing # # CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +CONFIG_NETPOLL_RX=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_BONDING=m +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m # # ARCnet devices # # CONFIG_ARCNET is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m # # Ethernet (10 or 100Mbit) @@ -397,27 +411,29 @@ CONFIG_E100=y # CONFIG_VIA_RHINE is not set # -# Ethernet (1000 Mbit) +# Gigabit Ethernet (1000/10000 Mbit) # -CONFIG_ACENIC=y -CONFIG_ACENIC_OMIT_TIGON_I=y -# CONFIG_DL2K is not set -CONFIG_E1000=y -# CONFIG_E1000_NAPI is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set +# CONFIG_NET_GIGE is not set # -# Ethernet (10000 Mbit) +# Token Ring devices +# +CONFIG_TR=y +CONFIG_IBMOL=y +# CONFIG_IBMLS is not set +# CONFIG_3C359 is not set +# CONFIG_TMS380TR is not set + +# +# Wireless LAN (non-hamradio) # -CONFIG_IXGB=m -# CONFIG_IXGB_NAPI is not set -# CONFIG_VETH is not set +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_ISERIES_VETH=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=m @@ -429,48 +445,10 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m CONFIG_PPPOE=m # CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -CONFIG_TR=y -CONFIG_IBMOL=y -# CONFIG_IBMLS is not set -# CONFIG_3C359 is not set -# CONFIG_TMS380TR is not set # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# Bluetooth support -# -# CONFIG_BT is not set -CONFIG_NETPOLL=y -CONFIG_NETPOLL_RX=y -CONFIG_NETPOLL_TRAP=y -CONFIG_NET_POLL_CONTROLLER=y - # # ISDN subsystem # @@ -489,7 +467,10 @@ CONFIG_INPUT=y # # Userland interfaces # -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set @@ -518,7 +499,6 @@ CONFIG_SERIO_SERPORT=y # # Character devices # -# CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -532,11 +512,6 @@ CONFIG_SERIO_SERPORT=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 - -# -# Mice -# -# CONFIG_BUSMOUSE is not set # CONFIG_QIC02_TAPE is not set # @@ -618,6 +593,7 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=y # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set CONFIG_JFS_FS=y CONFIG_JFS_POSIX_ACL=y # CONFIG_JFS_DEBUG is not set @@ -655,6 +631,7 @@ CONFIG_VFAT_FS=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set CONFIG_DEVPTS_FS_XATTR=y # CONFIG_DEVPTS_FS_SECURITY is not set @@ -695,10 +672,11 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=m -CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_SMB_FS is not set CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -757,8 +735,8 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_VIOCONS=y CONFIG_VIODASD=y -CONFIG_VIOCD=y -# CONFIG_VIOTAPE is not set +CONFIG_VIOCD=m +CONFIG_VIOTAPE=m CONFIG_VIOPATH=y # @@ -778,6 +756,7 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUGGER is not set # CONFIG_PPCDBG is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_IRQSTACKS is not set # # Security options @@ -791,11 +770,11 @@ CONFIG_CRYPTO=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_SERPENT=m @@ -804,11 +783,14 @@ CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set CONFIG_CRYPTO_TEST=m # # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c index 98e8d373b..9368fb0ff 100644 --- a/arch/ppc64/kernel/asm-offsets.c +++ b/arch/ppc64/kernel/asm-offsets.c @@ -73,7 +73,6 @@ int main(void) DEFINE(ICACHEL1LINESIZE, offsetof(struct systemcfg, iCacheL1LineSize)); DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct naca_struct, iCacheL1LogLineSize)); DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct naca_struct, iCacheL1LinesPerPage)); - DEFINE(SLBSIZE, offsetof(struct naca_struct, slb_size)); DEFINE(PLATFORM, offsetof(struct systemcfg, platform)); /* paca */ diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c index 303eac178..dc83803db 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/ppc64/kernel/eeh.c @@ -612,33 +612,25 @@ void __init eeh_init(void) } /** - * eeh_add_device - perform EEH initialization for the indicated pci device - * @dev: pci device for which to set up EEH + * eeh_add_device_early - enable EEH for the indicated device_node + * @dn: device node for which to set up EEH * - * This routine can be used to perform EEH initialization for PCI + * This routine must be used to perform EEH initialization for PCI * devices that were added after system boot (e.g. hotplug, dlpar). + * This routine must be called before any i/o is performed to the + * adapter (inluding any config-space i/o). * Whether this actually enables EEH or not for this device depends - * on the type of the device, on earlier boot command-line - * arguments & etc. + * on the CEC architecture, type of the device, on earlier boot + * command-line arguments & etc. */ -void eeh_add_device(struct pci_dev *dev) +void eeh_add_device_early(struct device_node *dn) { - struct device_node *dn; struct pci_controller *phb; struct eeh_early_enable_info info; - if (!dev || !eeh_subsystem_enabled) - return; - -#ifdef DEBUG - printk(KERN_DEBUG "EEH: adding device %s %s\n", pci_name(dev), - pci_pretty_name(dev)); -#endif - dn = pci_device_to_OF_node(dev); - if (NULL == dn) + if (!dn || !eeh_subsystem_enabled) return; - - phb = PCI_GET_PHB_PTR(dev); + phb = dn->phb; if (NULL == phb || 0 == phb->buid) { printk(KERN_WARNING "EEH: Expected buid but found none\n"); return; @@ -646,11 +638,30 @@ void eeh_add_device(struct pci_dev *dev) info.buid_hi = BUID_HI(phb->buid); info.buid_lo = BUID_LO(phb->buid); - early_enable_eeh(dn, &info); +} +EXPORT_SYMBOL(eeh_add_device_early); + +/** + * eeh_add_device_late - perform EEH initialization for the indicated pci device + * @dev: pci device for which to set up EEH + * + * This routine must be used to complete EEH initialization for PCI + * devices that were added after system boot (e.g. hotplug, dlpar). + */ +void eeh_add_device_late(struct pci_dev *dev) +{ + if (!dev || !eeh_subsystem_enabled) + return; + +#ifdef DEBUG + printk(KERN_DEBUG "EEH: adding device %s %s\n", pci_name(dev), + pci_pretty_name(dev)); +#endif + pci_addr_cache_insert_device (dev); } -EXPORT_SYMBOL(eeh_add_device); +EXPORT_SYMBOL(eeh_add_device_late); /** * eeh_remove_device - undo EEH setup for the indicated pci device diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 892c957ad..6b22a87d9 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -1123,13 +1123,11 @@ _GLOBAL(do_slb_bolted) */ /* r20 = paca */ - /* use a cpu feature mask if we ever change our slb size */ -SLB_NUM_ENTRIES = 64 1: ld r22,PACASTABRR(r20) addi r21,r22,1 cmpdi r21,SLB_NUM_ENTRIES blt+ 2f - li r21,1 /* dont touch bolted slot 0 */ + li r21,2 /* dont touch slot 0 or 1 */ 2: std r21,PACASTABRR(r20) /* r20 = paca, r22 = entry */ diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index f2271fdbb..3f17d5e25 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -563,11 +563,6 @@ static void __init build_iSeries_Memory_Map(void) lmb_add(0, systemcfg->physicalMemorySize); lmb_analyze(); /* ?? */ lmb_reserve(0, __pa(klimit)); - - /* - * Hardcode to GP size. I am not sure where to get this info. DRENG - */ - naca->slb_size = 64; } /* @@ -858,3 +853,12 @@ static void iSeries_setup_dprofile(void) } } } + +int __init iSeries_src_init(void) +{ + /* clear the progress line */ + ppc_md.progress(" ", 0xffff); + return 0; +} + +late_initcall(iSeries_src_init); diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c index b12048b4d..d283f4897 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/ppc64/kernel/pacaData.c @@ -42,6 +42,7 @@ struct systemcfg *systemcfg; .xStab_data = { \ .real = (asrr), /* Real pointer to segment table */ \ .virt = (asrv), /* Virt pointer to segment table */ \ + .next_round_robin = 1, \ }, \ .lpQueuePtr = (lpq), /* &xItLpQueue, */ \ /* .xRtas = { \ @@ -54,7 +55,8 @@ struct systemcfg *systemcfg; .xFPRegsInUse = 1, \ .xDynProcStatus = 2, \ .xDecrVal = 0x00ff0000, \ - .xEndOfQuantum = 0xfffffffffffffffful \ + .xEndOfQuantum = 0xfffffffffffffffful, \ + .xSLBCount = 64, \ }, \ .xRegSav = { \ .xDesc = 0xd397d9e2, /* "LpRS" */ \ diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 76216f3fb..a5f8f2418 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -458,13 +458,6 @@ static void __init prom_initialize_naca(void) PROM_BUG(); } - /* - * Hardcode to GP size. I am not sure where to get this info - * in general, as there does not appear to be a slb-size OF - * entry. At least in Condor and earlier. DRENG - */ - _naca->slb_size = 64; - /* Add an eye catcher and the systemcfg layout version number */ strcpy(_systemcfg->eye_catcher, RELOC("SYSTEMCFG:PPC64")); _systemcfg->version.major = SYSTEMCFG_MAJOR; @@ -654,8 +647,6 @@ static void __init prom_initialize_lmb(void) #endif /* DEBUG_PROM */ } -static char hypertas_funcs[1024]; - static void __init prom_instantiate_rtas(void) { @@ -665,6 +656,7 @@ prom_instantiate_rtas(void) struct systemcfg *_systemcfg = RELOC(systemcfg); ihandle prom_rtas; u32 getprop_rval; + char hypertas_funcs[4]; #ifdef DEBUG_PROM prom_print(RELOC("prom_instantiate_rtas: start...\n")); @@ -1556,7 +1548,7 @@ static void __init *__make_room(unsigned long *mem_start, unsigned long *mem_end if (*mem_end != RELOC(initrd_start)) prom_panic(RELOC("No memory for copy_device_tree")); - prom_print("Huge device_tree: moving initrd\n"); + prom_print(RELOC("Huge device_tree: moving initrd\n")); /* Move by 4M. */ initrd_len = RELOC(initrd_end) - RELOC(initrd_start); *mem_end = RELOC(initrd_start) + 4 * 1024 * 1024; @@ -1590,6 +1582,7 @@ inspect_node(phandle node, struct device_node *dad, char *prev_name, *namep; unsigned char *valp; unsigned long offset = reloc_offset(); + phandle ibm_phandle; np = make_room(mem_start, mem_end, struct device_node); memset(np, 0, sizeof(*np)); @@ -1652,23 +1645,24 @@ inspect_node(phandle node, struct device_node *dad, prev_propp = &pp->next; } - /* Add a "linux_phandle" value */ - if (np->node) { - u32 ibm_phandle = 0; - int len; - - /* First see if "ibm,phandle" exists and use its value */ - len = (int) - call_prom(RELOC("getprop"), 4, 1, node, RELOC("ibm,phandle"), - &ibm_phandle, sizeof(ibm_phandle)); - if (len < 0) { - np->linux_phandle = np->node; - } else { - np->linux_phandle = ibm_phandle; - } - } - - *prev_propp = 0; + /* Add a "linux,phandle" property. */ + namep = make_room(mem_start, mem_end, char[16]); + strcpy(namep, RELOC("linux,phandle")); + pp = make_room(mem_start, mem_end, struct property); + pp->name = PTRUNRELOC(namep); + pp->length = sizeof(phandle); + valp = make_room(mem_start, mem_end, phandle); + pp->value = PTRUNRELOC(valp); + *(phandle *)valp = node; + *prev_propp = PTRUNRELOC(pp); + pp->next = NULL; + + /* Set np->linux_phandle to the value of the ibm,phandle property + if it exists, otherwise to the phandle for this node. */ + np->linux_phandle = node; + if ((int)call_prom(RELOC("getprop"), 4, 1, node, RELOC("ibm,phandle"), + &ibm_phandle, sizeof(ibm_phandle)) > 0) + np->linux_phandle = ibm_phandle; /* get the node's full name */ namep = (char *)*mem_start; diff --git a/arch/ppc64/kernel/stab.c b/arch/ppc64/kernel/stab.c index b3ac3ac62..061890449 100644 --- a/arch/ppc64/kernel/stab.c +++ b/arch/ppc64/kernel/stab.c @@ -24,6 +24,23 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid); static void make_slbe(unsigned long esid, unsigned long vsid, int large, int kernel_segment); +static inline void slb_add_bolted(void) +{ +#ifndef CONFIG_PPC_ISERIES + unsigned long esid = GET_ESID(VMALLOCBASE); + unsigned long vsid = get_kernel_vsid(VMALLOCBASE); + + WARN_ON(!irqs_disabled()); + + /* + * Bolt in the first vmalloc segment. Since modules end + * up there it gets hit very heavily. + */ + get_paca()->xStab_data.next_round_robin = 1; + make_slbe(esid, vsid, 0, 1); +#endif +} + /* * Build an entry for the base kernel segment and put it into * the segment table or SLB. All other segment table or SLB @@ -48,9 +65,12 @@ void stab_initialize(unsigned long stab) asm volatile("isync":::"memory"); asm volatile("slbmte %0,%0"::"r" (0) : "memory"); asm volatile("isync; slbia; isync":::"memory"); + get_paca()->xStab_data.next_round_robin = 0; make_slbe(esid, vsid, seg0_largepages, 1); asm volatile("isync":::"memory"); #endif + + slb_add_bolted(); } else { asm volatile("isync; slbia; isync":::"memory"); make_ste(stab, esid, vsid); @@ -317,6 +337,7 @@ static void make_slbe(unsigned long esid, unsigned long vsid, int large, unsigned long word0; slb_dword1 data; } vsid_data; + struct paca_struct *lpaca = get_paca(); /* * We take the next entry, round robin. Previously we tried @@ -330,18 +351,25 @@ static void make_slbe(unsigned long esid, unsigned long vsid, int large, * for the kernel stack during the first part of exception exit * which gets invalidated due to a tlbie from another cpu at a * non recoverable point (after setting srr0/1) - Anton + * + * paca Ksave is always valid (even when on the interrupt stack) + * so we use that. */ - castout_entry = get_paca()->xStab_data.next_round_robin; + castout_entry = lpaca->xStab_data.next_round_robin; do { entry = castout_entry; castout_entry++; - if (castout_entry >= naca->slb_size) - castout_entry = 1; + /* + * We bolt in the first kernel segment and the first + * vmalloc segment. + */ + if (castout_entry >= SLB_NUM_ENTRIES) + castout_entry = 2; asm volatile("slbmfee %0,%1" : "=r" (esid_data) : "r" (entry)); } while (esid_data.data.v && - esid_data.data.esid == GET_ESID(__get_SP())); + esid_data.data.esid == GET_ESID(lpaca->xKsave)); - get_paca()->xStab_data.next_round_robin = castout_entry; + lpaca->xStab_data.next_round_robin = castout_entry; /* slbie not needed as the previous mapping is still valid. */ @@ -422,6 +450,9 @@ int slb_allocate(unsigned long ea) } esid = GET_ESID(ea); +#ifndef CONFIG_PPC_ISERIES + BUG_ON((esid << SID_SHIFT) == VMALLOCBASE); +#endif __slb_allocate(esid, vsid, context); return 0; @@ -479,18 +510,19 @@ void flush_slb(struct task_struct *tsk, struct mm_struct *mm) slb_dword0 data; } esid_data; - if (offset <= NR_STAB_CACHE_ENTRIES) { int i; asm volatile("isync" : : : "memory"); for (i = 0; i < offset; i++) { esid_data.word0 = 0; esid_data.data.esid = __get_cpu_var(stab_cache[i]); + BUG_ON(esid_data.data.esid == GET_ESID(VMALLOCBASE)); asm volatile("slbie %0" : : "r" (esid_data)); } asm volatile("isync" : : : "memory"); } else { asm volatile("isync; slbia; isync" : : : "memory"); + slb_add_bolted(); } /* Workaround POWER5 < DD2.1 issue */ diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c index cbb26f6b0..97b1509ac 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/ppc64/xmon/xmon.c @@ -2512,7 +2512,7 @@ static void dump_slb(void) printf("SLB contents of cpu %x\n", smp_processor_id()); - for (i = 0; i < naca->slb_size; i++) { + for (i = 0; i < SLB_NUM_ENTRIES; i++) { asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i)); printf("%02d %016lx ", i, tmp); diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index 4ba5d4801..580a8c5d2 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -147,7 +147,6 @@ end_coredump: * memory and creates the pointer tables from them, and puts their * addresses on the "stack", returning the new stack pointer value. */ -#define A(__x) ((unsigned long)(__x)) static u32 *create_aout32_tables(char * p, struct linux_binprm * bprm) { @@ -171,7 +170,7 @@ static u32 *create_aout32_tables(char * p, struct linux_binprm * bprm) current->mm->arg_start = (unsigned long) p; while (argc-->0) { char c; - put_user(((u32)A(p)),argv++); + put_user(((u32)(unsigned long)(p)),argv++); do { get_user(c,p++); } while (c); @@ -180,7 +179,7 @@ static u32 *create_aout32_tables(char * p, struct linux_binprm * bprm) current->mm->arg_end = current->mm->env_start = (unsigned long) p; while (envc-->0) { char c; - put_user(((u32)A(p)),envp++); + put_user(((u32)(unsigned long)(p)),envp++); do { get_user(c,p++); } while (c); diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 6b6694a0e..f82adfbf7 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1697,12 +1697,12 @@ linux_sparc_syscall32: add %sp, PTREGS_OFF, %o0 srl %i0, 0, %o0 #endif - mov %i4, %o4 ! IEU1 + srl %i4, 0, %o4 ! IEU1 lduw [%l7 + %l4], %l7 ! Load srl %i1, 0, %o1 ! IEU0 Group ldx [%curptr + TI_FLAGS], %l0 ! Load - mov %i5, %o5 ! IEU1 + srl %i5, 0, %o5 ! IEU1 srl %i2, 0, %o2 ! IEU0 Group andcc %l0, _TIF_SYSCALL_TRACE, %g0 ! IEU0 Group bne,pn %icc, linux_syscall_trace32 ! CTI diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index ac67fb347..7f03853f8 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -579,26 +579,26 @@ barf: do_exit(SIGILL); } -asmlinkage int sparc_do_fork(unsigned long clone_flags, - unsigned long stack_start, - struct pt_regs *regs, - unsigned long stack_size) +asmlinkage long sparc_do_fork(unsigned long clone_flags, + unsigned long stack_start, + struct pt_regs *regs, + unsigned long stack_size) { - unsigned long parent_tid_ptr, child_tid_ptr; + int __user *parent_tid_ptr, *child_tid_ptr; clone_flags &= ~CLONE_IDLETASK; - parent_tid_ptr = regs->u_regs[UREG_I2]; - child_tid_ptr = regs->u_regs[UREG_I4]; if (test_thread_flag(TIF_32BIT)) { - parent_tid_ptr &= 0xffffffff; - child_tid_ptr &= 0xffffffff; + parent_tid_ptr = compat_ptr(regs->u_regs[UREG_I2]); + child_tid_ptr = compat_ptr(regs->u_regs[UREG_I4]); + } else { + parent_tid_ptr = (int __user *) regs->u_regs[UREG_I2]; + child_tid_ptr = (int __user *) regs->u_regs[UREG_I4]; } return do_fork(clone_flags, stack_start, regs, stack_size, - (int __user *) parent_tid_ptr, - (int __user *) child_tid_ptr); + parent_tid_ptr, child_tid_ptr); } /* Copy a Sparc thread. The fork() return value conventions diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 04e3bbfe8..2fb26c9b9 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -1349,7 +1349,7 @@ out: return ret; } -asmlinkage int do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp) +asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp) { stack_t uss, uoss; u32 u_ss_sp = 0; diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c index 1e041b002..87c1aeb02 100644 --- a/arch/sparc64/kernel/sunos_ioctl32.c +++ b/arch/sparc64/kernel/sunos_ioctl32.c @@ -26,15 +26,6 @@ #include #include -/* Use this to get at 32-bit user passed pointers. */ -#define A(__x) \ -({ unsigned long __ret; \ - __asm__ ("srl %0, 0, %0" \ - : "=r" (__ret) \ - : "0" (__x)); \ - __ret; \ -}) - #define SUNOS_NR_OPEN 256 struct rtentry32 { @@ -108,7 +99,7 @@ asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg) int ntty = N_TTY; int tmp; - p = (int __user *)A(arg); + p = (int __user *) (unsigned long) arg; ret = -EFAULT; if(get_user(tmp, p)) goto out; @@ -241,7 +232,7 @@ asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg) int oldval, newval, __user *ptr; cmd = TIOCSPGRP; - ptr = (int __user *) A(arg); + ptr = (int __user *) (unsigned long) arg; ret = -EFAULT; if(get_user(oldval, ptr)) goto out; @@ -260,7 +251,7 @@ asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg) int oldval, newval, __user *ptr; cmd = TIOCGPGRP; - ptr = (int __user *) A(arg); + ptr = (int __user *) (unsigned long) arg; ret = -EFAULT; if(get_user(oldval, ptr)) goto out; diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index 110d91aed..95e3d3ace 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -13,85 +13,135 @@ .text - .align 32 - .globl sys32_mmap -sys32_mmap: - srl %o4, 0, %o4 - sethi %hi(sys_mmap), %g1 - jmpl %g1 + %lo(sys_mmap), %g0 - srl %o5, 0, %o5 +#define SIGN1(STUB,SYSCALL,REG1) \ + .align 32; \ + .globl STUB; \ +STUB: sethi %hi(SYSCALL), %g1; \ + jmpl %g1 + %lo(SYSCALL), %g0; \ + sra REG1, 0, REG1 - .align 32 - .globl sys32_lseek - .globl sys32_chmod, sys32_mknod -sys32_lseek: - sra %o1, 0, %o1 - sethi %hi(sys_lseek), %g1 - jmpl %g1 + %lo(sys_lseek), %g0 - nop -sys32_chmod: - sethi %hi(0xffff), %g2 - sethi %hi(sys_chmod), %g1 - orcc %g2, %lo(0xffff), %g2 - jmpl %g1 + %lo(sys_chmod), %g0 - and %o1, %g2, %o1 -sys32_mknod: - sethi %hi(0xffff), %g2 - sethi %hi(sys_mknod), %g1 - orcc %g2, %lo(0xffff), %g2 - jmpl %g1 + %lo(sys_mknod), %g0 - and %o2, %g2, %o2 +#define SIGN2(STUB,SYSCALL,REG1,REG2) \ + .align 32; \ + .globl STUB; \ +STUB: sethi %hi(SYSCALL), %g1; \ + sra REG1, 0, REG1; \ + jmpl %g1 + %lo(SYSCALL), %g0; \ + sra REG2, 0, REG2 - .align 32 - .globl sys32_sendto, sys32_recvfrom -sys32_sendto: - sethi %hi(sys_sendto), %g1 - jmpl %g1 + %lo(sys_sendto), %g0 - srl %o4, 0, %o4 -sys32_recvfrom: - srl %o4, 0, %o4 - sethi %hi(sys_recvfrom), %g1 - jmpl %g1 + %lo(sys_recvfrom), %g0 - srl %o5, 0, %o5 +#define SIGN3(STUB,SYSCALL,REG1,REG2,REG3) \ + .align 32; \ + .globl STUB; \ +STUB: sra REG1, 0, REG1; \ + sethi %hi(SYSCALL), %g1; \ + sra REG2, 0, REG2; \ + jmpl %g1 + %lo(SYSCALL), %g0; \ + sra REG3, 0, REG3 - .globl sys32_bdflush -sys32_bdflush: - sethi %hi(sys_bdflush), %g1 - jmpl %g1 + %lo(sys_bdflush), %g0 - sra %o1, 0, %o1 +#define SIGN4(STUB,SYSCALL,REG1,REG2,REG3,REG4) \ + .align 32; \ + .globl STUB; \ +STUB: sra REG1, 0, REG1; \ + sethi %hi(SYSCALL), %g1; \ + sra REG2, 0, REG2; \ + sra REG3, 0, REG3; \ + jmpl %g1 + %lo(SYSCALL), %g0; \ + sra REG4, 0, REG4 + +SIGN1(sys32_exit, sparc_exit, %o0) +SIGN1(sys32_exit_group, sys_exit_group, %o0) +SIGN1(sys32_wait4, compat_sys_wait4, %o2) +SIGN1(sys32_creat, sys_creat, %o1) +SIGN1(sys32_mknod, sys_mknod, %o1) +SIGN1(sys32_perfctr, sys_perfctr, %o0) +SIGN1(sys32_umount, sys_umount, %o1) +SIGN1(sys32_signal, sys_signal, %o0) +SIGN1(sys32_access, sys_access, %o1) +SIGN1(sys32_msync, sys_msync, %o2) +SIGN2(sys32_reboot, sys_reboot, %o0, %o1) +SIGN1(sys32_setitimer, compat_sys_setitimer, %o0) +SIGN1(sys32_getitimer, compat_sys_getitimer, %o0) +SIGN1(sys32_sethostname, sys_sethostname, %o1) +SIGN1(sys32_swapon, sys_swapon, %o1) +SIGN1(sys32_sigaction, compat_sys_sigaction, %o0) +SIGN1(sys32_rt_sigaction, compat_sys_rt_sigaction, %o0) +SIGN1(sys32_sigprocmask, compat_sys_sigprocmask, %o0) +SIGN1(sys32_rt_sigprocmask, compat_sys_rt_sigprocmask, %o0) +SIGN2(sys32_rt_sigqueueinfo, compat_sys_rt_sigqueueinfo, %o0, %o1) +SIGN1(sys32_getrusage, compat_sys_getrusage, %o0) +SIGN1(sys32_setxattr, sys_setxattr, %o4) +SIGN1(sys32_lsetxattr, sys_lsetxattr, %o4) +SIGN1(sys32_fsetxattr, sys_fsetxattr, %o4) +SIGN1(sys32_fgetxattr, sys_fgetxattr, %o0) +SIGN1(sys32_flistxattr, sys_flistxattr, %o0) +SIGN1(sys32_fremovexattr, sys_fremovexattr, %o0) +SIGN2(sys32_tkill, sys_tkill, %o0, %o1) +SIGN1(sys32_epoll_create, sys_epoll_create, %o0) +SIGN3(sys32_epoll_ctl, sys_epoll_ctl, %o0, %o1, %o2) +SIGN3(sys32_epoll_wait, sys_epoll_wait, %o0, %o2, %o3) +SIGN1(sys32_readahead, compat_sys_readahead, %o0) +SIGN2(sys32_fadvise64, compat_sys_fadvise64, %o0, %o4) +SIGN2(sys32_fadvise64_64, compat_sys_fadvise64_64, %o0, %o5) +SIGN2(sys32_bdflush, sys_bdflush, %o0, %o1) +SIGN1(sys32_mlockall, sys_mlockall, %o0) +SIGN1(sys32_nfsservctl, compat_sys_nfsservctl, %o0) +SIGN1(sys32_clock_settime, compat_clock_settime, %o1) +SIGN1(sys32_clock_nanosleep, compat_clock_nanosleep, %o1) +SIGN1(sys32_timer_settime, compat_timer_settime, %o1) +SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) +SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) +SIGN1(sys32_select, compat_sys_select, %o0) +SIGN1(sys32_mkdir, sys_mkdir, %o1) +SIGN2(sys32_futex, compat_sys_futex, %o1, %o2) +SIGN1(sys32_sysfs, compat_sys_sysfs, %o0) +SIGN3(sys32_ipc, compat_sys_ipc, %o1, %o2, %o3) +SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1) +SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1) +SIGN1(sys32_prctl, sys_prctl, %o0) +SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0) +SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2) +SIGN1(sys32_getgroups, sys_getgroups, %o0) +SIGN1(sys32_getpgid, sys_getpgid, %o0) +SIGN2(sys32_getpriority, sys_getpriority, %o0, %o1) +SIGN1(sys32_getsid, sys_getsid, %o0) +SIGN2(sys32_kill, sys_kill, %o0, %o1) +SIGN1(sys32_nice, sys_nice, %o0) +SIGN1(sys32_lseek, sys_lseek, %o1) +SIGN2(sys32_open, sparc32_open, %o1, %o2) +SIGN1(sys32_readlink, sys_readlink, %o2) +SIGN1(sys32_sched_get_priority_max, sys_sched_get_priority_max, %o0) +SIGN1(sys32_sched_get_priority_min, sys_sched_get_priority_min, %o0) +SIGN1(sys32_sched_getparam, sys_sched_getparam, %o0) +SIGN1(sys32_sched_getscheduler, sys_sched_getscheduler, %o0) +SIGN1(sys32_sched_setparam, sys_sched_setparam, %o0) +SIGN2(sys32_sched_setscheduler, sys_sched_setscheduler, %o0, %o1) +SIGN1(sys32_getdomainname, sys_getdomainname, %o1) +SIGN1(sys32_setdomainname, sys_setdomainname, %o1) +SIGN1(sys32_setgroups, sys_setgroups, %o0) +SIGN2(sys32_setpgid, sys_setpgid, %o0, %o1) +SIGN3(sys32_setpriority, sys_setpriority, %o0, %o1, %o2) +SIGN1(sys32_ssetmask, sys_ssetmask, %o0) +SIGN2(sys32_syslog, sys_syslog, %o0, %o1) +SIGN1(sys32_umask, sys_umask, %o0) +SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2) +SIGN1(sys32_sendto, sys_sendto, %o0) +SIGN1(sys32_recvfrom, sys_recvfrom, %o0) +SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2) +SIGN2(sys32_connect, sys_connect, %o0, %o2) +SIGN2(sys32_bind, sys_bind, %o0, %o2) +SIGN2(sys32_listen, sys_listen, %o0, %o1) +SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) +SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) +SIGN2(sys32_shutdown, sys_shutdown, %o0, %o1) +SIGN3(sys32_socketpair, sys_socketpair, %o0, %o1, %o2) +SIGN1(sys32_getpeername, sys_getpeername, %o0) +SIGN1(sys32_getsockname, sys_getsockname, %o0) - .align 32 .globl sys32_mmap2 sys32_mmap2: - srl %o4, 0, %o4 sethi %hi(sys_mmap), %g1 - srl %o5, 0, %o5 jmpl %g1 + %lo(sys_mmap), %g0 sllx %o5, 12, %o5 - .globl sys32_mq_timedsend -sys32_mq_timedsend: - sethi %hi(compat_sys_mq_timedsend), %g1 - jmpl %g1 + %lo(compat_sys_mq_timedsend), %g0 - srl %o4, 0, %o4 - .globl sys32_mq_timedreceive -sys32_mq_timedreceive: - sethi %hi(compat_sys_mq_timedreceive), %g1 - jmpl %g1 + %lo(compat_sys_mq_timedreceive), %g0 - srl %o4, 0, %o4 - - .globl sys32_select -sys32_select: - sethi %hi(compat_sys_select), %g1 - jmpl %g1 + %lo(compat_sys_select), %g0 - srl %o4, 0, %o4 - - .globl sys32_futex -sys32_futex: - sethi %hi(compat_sys_futex), %g1 - jmpl %g1 + %lo(compat_sys_futex), %g0 - srl %o4, 0, %o4 - .align 32 .globl sys32_socketcall sys32_socketcall: /* %o0=call, %o1=args */ @@ -199,23 +249,23 @@ do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */ lduwa [%o1 + 0x4] %asi, %o1 nop nop -do_sys_sendto: /* sys32_sendto(int, u32, compat_size_t, unsigned int, u32, int) */ +do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */ ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys32_sendto), %g1 + sethi %hi(sys_sendto), %g1 lduwa [%o1 + 0x8] %asi, %o2 lduwa [%o1 + 0xc] %asi, %o3 lduwa [%o1 + 0x10] %asi, %o4 ldswa [%o1 + 0x14] %asi, %o5 - jmpl %g1 + %lo(sys32_sendto), %g0 + jmpl %g1 + %lo(sys_sendto), %g0 lduwa [%o1 + 0x4] %asi, %o1 -do_sys_recvfrom: /* sys32_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */ +do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */ ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys32_recvfrom), %g1 + sethi %hi(sys_recvfrom), %g1 lduwa [%o1 + 0x8] %asi, %o2 lduwa [%o1 + 0xc] %asi, %o3 lduwa [%o1 + 0x10] %asi, %o4 lduwa [%o1 + 0x14] %asi, %o5 - jmpl %g1 + %lo(sys32_recvfrom), %g0 + jmpl %g1 + %lo(sys_recvfrom), %g0 lduwa [%o1 + 0x4] %asi, %o1 do_sys_shutdown: /* sys_shutdown(int, int) */ ldswa [%o1 + 0x0] %asi, %o0 diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index d3ce03bd7..c38c83b4f 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -179,7 +179,7 @@ asmlinkage unsigned long sparc_brk(unsigned long brk) * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way unix traditionally does this, though. */ -asmlinkage int sparc_pipe(struct pt_regs *regs) +asmlinkage long sparc_pipe(struct pt_regs *regs) { int fd[2]; int error; @@ -199,22 +199,22 @@ out: * This is really horribly ugly. */ -asmlinkage int sys_ipc (unsigned call, int first, int second, unsigned long third, void *ptr, long fifth) +asmlinkage long sys_ipc(unsigned int call, int first, int second, unsigned long third, void __user *ptr, long fifth) { int err; /* No need for backward compatibility. We can start fresh... */ - - if (call <= SEMCTL) + if (call <= SEMCTL) { switch (call) { case SEMOP: - err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL); + err = sys_semtimedop(first, ptr, second, NULL); goto out; case SEMTIMEDOP: - err = sys_semtimedop (first, (struct sembuf __user *)ptr, second, (const struct timespec __user *) fifth); + err = sys_semtimedop(first, ptr, second, + (const struct timespec __user *) fifth); goto out; case SEMGET: - err = sys_semget (first, second, (int)third); + err = sys_semget(first, second, (int)third); goto out; case SEMCTL: { union semun fourth; @@ -222,79 +222,87 @@ asmlinkage int sys_ipc (unsigned call, int first, int second, unsigned long thir if (!ptr) goto out; err = -EFAULT; - if (get_user(fourth.__pad, (void __user * __user *)ptr)) + if (get_user(fourth.__pad, + (void __user * __user *) ptr)) goto out; - err = sys_semctl (first, second | IPC_64, (int)third, fourth); + err = sys_semctl(first, second | IPC_64, + (int)third, fourth); goto out; - } + } default: err = -ENOSYS; goto out; - } - if (call <= MSGCTL) + }; + } + if (call <= MSGCTL) { switch (call) { case MSGSND: - err = sys_msgsnd (first, (struct msgbuf __user *) ptr, - second, (int)third); + err = sys_msgsnd(first, ptr, second, (int)third); goto out; case MSGRCV: - err = sys_msgrcv (first, (struct msgbuf __user *) ptr, second, fifth, (int)third); + err = sys_msgrcv(first, ptr, second, fifth, + (int)third); goto out; case MSGGET: - err = sys_msgget ((key_t) first, second); + err = sys_msgget((key_t) first, second); goto out; case MSGCTL: - err = sys_msgctl (first, second | IPC_64, (struct msqid_ds __user *) ptr); + err = sys_msgctl(first, second | IPC_64, ptr); goto out; default: err = -ENOSYS; goto out; - } - if (call <= SHMCTL) + }; + } + if (call <= SHMCTL) { switch (call) { case SHMAT: { ulong raddr; - err = do_shmat (first, (char __user *) ptr, second, &raddr); + err = do_shmat(first, ptr, second, &raddr); if (!err) { - if (put_user(raddr, (ulong __user *) third)) + if (put_user(raddr, + (ulong __user *) third)) err = -EFAULT; } goto out; } case SHMDT: - err = sys_shmdt ((char __user *)ptr); + err = sys_shmdt(ptr); goto out; case SHMGET: - err = sys_shmget (first, second, (int)third); + err = sys_shmget(first, second, (int)third); goto out; case SHMCTL: - err = sys_shmctl (first, second | IPC_64, (struct shmid_ds __user *) ptr); + err = sys_shmctl(first, second | IPC_64, ptr); goto out; default: err = -ENOSYS; goto out; - } - else + }; + } else { err = -ENOSYS; + } out: return err; } -asmlinkage int sparc64_newuname(struct new_utsname __user *name) +asmlinkage long sparc64_newuname(struct new_utsname __user *name) { int ret = sys_newuname(name); if (current->personality == PER_LINUX32 && !ret) { - ret = copy_to_user(name->machine, "sparc\0\0", 8) ? -EFAULT : 0; + ret = (copy_to_user(name->machine, "sparc\0\0", 8) + ? -EFAULT : 0); } return ret; } -asmlinkage int sparc64_personality(unsigned long personality) +asmlinkage long sparc64_personality(unsigned long personality) { int ret; - if (current->personality == PER_LINUX32 && personality == PER_LINUX) + if (current->personality == PER_LINUX32 && + personality == PER_LINUX) personality = PER_LINUX32; ret = sys_personality(personality); if (ret == PER_LINUX32) @@ -408,8 +416,7 @@ out: } /* we come to here via sys_nis_syscall so it can setup the regs argument */ -asmlinkage unsigned long -c_sys_nis_syscall (struct pt_regs *regs) +asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs) { static int count; @@ -427,8 +434,7 @@ c_sys_nis_syscall (struct pt_regs *regs) /* #define DEBUG_SPARC_BREAKPOINT */ -asmlinkage void -sparc_breakpoint (struct pt_regs *regs) +asmlinkage void sparc_breakpoint(struct pt_regs *regs) { siginfo_t info; @@ -452,7 +458,7 @@ sparc_breakpoint (struct pt_regs *regs) extern void check_pending(int signum); -asmlinkage int sys_getdomainname(char __user *name, int len) +asmlinkage long sys_getdomainname(char __user *name, int len) { int nlen; int err = -EFAULT; @@ -473,7 +479,7 @@ done: return err; } -asmlinkage int solaris_syscall(struct pt_regs *regs) +asmlinkage long solaris_syscall(struct pt_regs *regs) { static int count; @@ -493,7 +499,7 @@ asmlinkage int solaris_syscall(struct pt_regs *regs) } #ifndef CONFIG_SUNOS_EMUL -asmlinkage int sunos_syscall(struct pt_regs *regs) +asmlinkage long sunos_syscall(struct pt_regs *regs) { static int count; @@ -511,11 +517,11 @@ asmlinkage int sunos_syscall(struct pt_regs *regs) } #endif -asmlinkage int sys_utrap_install(utrap_entry_t type, - utrap_handler_t new_p, - utrap_handler_t new_d, - utrap_handler_t __user *old_p, - utrap_handler_t __user *old_d) +asmlinkage long sys_utrap_install(utrap_entry_t type, + utrap_handler_t new_p, + utrap_handler_t new_d, + utrap_handler_t __user *old_p, + utrap_handler_t __user *old_d) { if (type < UT_INSTRUCTION_EXCEPTION || type > UT_TRAP_INSTRUCTION_31) return -EINVAL; @@ -582,12 +588,11 @@ long sparc_memory_ordering(unsigned long model, struct pt_regs *regs) return 0; } -asmlinkage long -sys_rt_sigaction(int sig, - const struct sigaction __user *act, - struct sigaction __user *oact, - void __user *restorer, - size_t sigsetsize) +asmlinkage long sys_rt_sigaction(int sig, + const struct sigaction __user *act, + struct sigaction __user *oact, + void __user *restorer, + size_t sigsetsize) { struct k_sigaction new_ka, old_ka; int ret; @@ -615,8 +620,7 @@ sys_rt_sigaction(int sig, /* Invoked by rtrap code to update performance counters in * user space. */ -asmlinkage void -update_perfctrs(void) +asmlinkage void update_perfctrs(void) { unsigned long pic, tmp; @@ -628,8 +632,7 @@ update_perfctrs(void) reset_pic(); } -asmlinkage int -sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long arg2) +asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long arg2) { int err = 0; diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index b226be3f5..c3a52ceb3 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -62,31 +62,6 @@ #include #include -/* Use this to get at 32-bit user passed pointers. */ -/* Things to consider: the low-level assembly stub does - srl x, 0, x for first four arguments, so if you have - pointer to something in the first four arguments, just - declare it as a pointer, not u32. On the other side, - arguments from 5th onwards should be declared as u32 - for pointers, and need AA() around each usage. - A() macro should be used for places where you e.g. - have some internal variable u32 and just want to get - rid of a compiler warning. AA() has to be used in - places where you want to convert a function argument - to 32bit pointer or when you e.g. access pt_regs - structure and want to consider 32bit registers only. - -jj - */ -#define A(__x) ((unsigned long)(__x)) -#define AA(__x) \ -({ unsigned long __ret; \ - __asm__ ("srl %0, 0, %0" \ - : "=r" (__ret) \ - : "0" (__x)); \ - __ret; \ -}) - - asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group) { return sys_chown(filename, low2highuid(user), low2highgid(group)); @@ -281,8 +256,7 @@ static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) struct msgbuf32 { s32 mtype; char mtext[1]; }; -struct ipc_perm32 -{ +struct ipc_perm32 { key_t key; compat_uid_t uid; compat_gid_t gid; @@ -383,21 +357,22 @@ struct shmid64_ds32 { * This is really horribly ugly. */ #define IPCOP_MASK(__x) (1UL << ((__x)&~IPC_64)) -static int do_sys32_semctl(int first, int second, int third, void *uptr) +static int do_sys32_semctl(int first, int second, int third, + compat_uptr_t __user *uptr) { union semun fourth; - u32 pad; + compat_uptr_t pad; int err = -EINVAL; if (!uptr) goto out; err = -EFAULT; - if (get_user (pad, (u32 __user *)uptr)) + if (get_user(pad, uptr)) goto out; if ((third & ~IPC_64) == SETVAL) fourth.val = (int)pad; else - fourth.__pad = (void __user *)A(pad); + fourth.__pad = compat_ptr(pad); if (IPCOP_MASK (third) & (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) | IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) | @@ -405,8 +380,7 @@ static int do_sys32_semctl(int first, int second, int third, void *uptr) err = sys_semctl (first, second, third, fourth); } else if (third & IPC_64) { struct semid64_ds s; - struct semid64_ds32 __user *usp = - (struct semid64_ds32 __user *)A(pad); + struct semid64_ds32 __user *usp = compat_ptr(pad); mm_segment_t old_fs; int need_back_translation; @@ -434,8 +408,7 @@ static int do_sys32_semctl(int first, int second, int third, void *uptr) } } else { struct semid_ds s; - struct semid_ds32 __user *usp = - (struct semid_ds32 __user *)A(pad); + struct semid_ds32 __user *usp = compat_ptr(pad); mm_segment_t old_fs; int need_back_translation; @@ -474,13 +447,15 @@ out: return err; } -static int do_sys32_msgsnd (int first, int second, int third, void *uptr) +static int do_sys32_msgsnd(int first, int second, int third, + void __user *uptr) { - struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_USER); - struct msgbuf32 __user *up = (struct msgbuf32 __user *) uptr; + struct msgbuf32 __user *up = uptr; + struct msgbuf *p; mm_segment_t old_fs; int err; + p = kmalloc(second + sizeof (struct msgbuf), GFP_USER); if (!p) return -ENOMEM; err = -EFAULT; @@ -489,15 +464,16 @@ static int do_sys32_msgsnd (int first, int second, int third, void *uptr) goto out; old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_msgsnd (first, (struct msgbuf __user *) p, second, third); + err = sys_msgsnd (first, (struct msgbuf __user *) p, + second, third); set_fs (old_fs); out: kfree (p); return err; } -static int do_sys32_msgrcv (int first, int second, int msgtyp, int third, - int version, void *uptr) +static int do_sys32_msgrcv(int first, int second, int msgtyp, int third, + int version, void __user *uptr) { struct msgbuf32 __user *up; struct msgbuf *p; @@ -505,21 +481,21 @@ static int do_sys32_msgrcv (int first, int second, int msgtyp, int third, int err; if (!version) { - struct ipc_kludge __user *uipck = - (struct ipc_kludge __user *) uptr; + struct ipc_kludge __user *uipck = uptr; struct ipc_kludge ipck; err = -EINVAL; if (!uptr) goto out; err = -EFAULT; - if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge))) + if (copy_from_user (&ipck, uipck, + sizeof (struct ipc_kludge))) goto out; - uptr = (void *)A(ipck.msgp); + uptr = compat_ptr(ipck.msgp); msgtyp = ipck.msgtyp; } err = -ENOMEM; - p = kmalloc (second + sizeof (struct msgbuf), GFP_USER); + p = kmalloc(second + sizeof (struct msgbuf), GFP_USER); if (!p) goto out; old_fs = get_fs (); @@ -529,7 +505,7 @@ static int do_sys32_msgrcv (int first, int second, int msgtyp, int third, set_fs (old_fs); if (err < 0) goto free_then_out; - up = (struct msgbuf32 __user *) uptr; + up = uptr; if (put_user (p->mtype, &up->mtype) || __copy_to_user (&up->mtext, p->mtext, err)) err = -EFAULT; @@ -539,39 +515,46 @@ out: return err; } -static int do_sys32_msgctl (int first, int second, void *uptr) +static int do_sys32_msgctl(int first, int second, void __user *uptr) { int err; if (IPCOP_MASK (second) & (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) | IPCOP_MASK (IPC_RMID))) { - err = sys_msgctl (first, second, - (struct msqid_ds __user *)uptr); + err = sys_msgctl (first, second, uptr); } else if (second & IPC_64) { struct msqid64_ds m; - struct msqid64_ds32 __user *up = - (struct msqid64_ds32 __user *) uptr; + struct msqid64_ds32 __user *up = uptr; mm_segment_t old_fs; if (second == (IPC_SET|IPC_64)) { - err = get_user (m.msg_perm.uid, &up->msg_perm.uid); - err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid); - err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode); - err |= __get_user (m.msg_qbytes, &up->msg_qbytes); + err = get_user (m.msg_perm.uid, + &up->msg_perm.uid); + err |= __get_user (m.msg_perm.gid, + &up->msg_perm.gid); + err |= __get_user (m.msg_perm.mode, + &up->msg_perm.mode); + err |= __get_user (m.msg_qbytes, + &up->msg_qbytes); if (err) goto out; } old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_msgctl (first, second, (struct msqid_ds __user *)&m); + err = sys_msgctl(first, second, + (struct msqid_ds __user *)&m); set_fs (old_fs); if (IPCOP_MASK (second) & (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) { - int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t)); - err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes); + int err2 = copy_to_user(&up->msg_perm, + &m.msg_perm, + (sizeof(struct ipc64_perm) + 3*sizeof(time_t))); + err2 |= __put_user (m.msg_cbytes, + &up->msg_cbytes); err2 |= __put_user (m.msg_qnum, &up->msg_qnum); - err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes); + err2 |= __put_user (m.msg_qbytes, + &up->msg_qbytes); err2 |= __put_user (m.msg_lspid, &up->msg_lspid); err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid); if (err2) @@ -579,39 +562,52 @@ static int do_sys32_msgctl (int first, int second, void *uptr) } } else { struct msqid_ds m; - struct msqid_ds32 __user *up = - (struct msqid_ds32 __user *)uptr; + struct msqid_ds32 __user *up = uptr; mm_segment_t old_fs; if (second == IPC_SET) { - err = get_user (m.msg_perm.uid, &up->msg_perm.uid); - err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid); - err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode); - err |= __get_user (m.msg_qbytes, &up->msg_qbytes); + err = get_user(m.msg_perm.uid, + &up->msg_perm.uid); + err |= __get_user(m.msg_perm.gid, + &up->msg_perm.gid); + err |= __get_user(m.msg_perm.mode, + &up->msg_perm.mode); + err |= __get_user(m.msg_qbytes, + &up->msg_qbytes); if (err) goto out; } old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_msgctl (first, second, (struct msqid_ds __user *) &m); + err = sys_msgctl(first, second, + (struct msqid_ds __user *) &m); set_fs (old_fs); if (IPCOP_MASK (second) & (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) { - int err2 = put_user (m.msg_perm.key, &up->msg_perm.key); - err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid); - err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid); - err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid); - err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid); - err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode); - err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq); - err2 |= __put_user (m.msg_stime, &up->msg_stime); - err2 |= __put_user (m.msg_rtime, &up->msg_rtime); - err2 |= __put_user (m.msg_ctime, &up->msg_ctime); - err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes); - err2 |= __put_user (m.msg_qnum, &up->msg_qnum); - err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes); - err2 |= __put_user (m.msg_lspid, &up->msg_lspid); - err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid); + int err2 = put_user(m.msg_perm.key, + &up->msg_perm.key); + err2 |= __put_user(high2lowuid(m.msg_perm.uid), + &up->msg_perm.uid); + err2 |= __put_user(high2lowgid(m.msg_perm.gid), + &up->msg_perm.gid); + err2 |= __put_user(high2lowuid(m.msg_perm.cuid), + &up->msg_perm.cuid); + err2 |= __put_user(high2lowgid(m.msg_perm.cgid), + &up->msg_perm.cgid); + err2 |= __put_user(m.msg_perm.mode, + &up->msg_perm.mode); + err2 |= __put_user(m.msg_perm.seq, + &up->msg_perm.seq); + err2 |= __put_user(m.msg_stime, &up->msg_stime); + err2 |= __put_user(m.msg_rtime, &up->msg_rtime); + err2 |= __put_user(m.msg_ctime, &up->msg_ctime); + err2 |= __put_user(m.msg_cbytes, + &up->msg_cbytes); + err2 |= __put_user(m.msg_qnum, &up->msg_qnum); + err2 |= __put_user(m.msg_qbytes, + &up->msg_qbytes); + err2 |= __put_user(m.msg_lspid, &up->msg_lspid); + err2 |= __put_user(m.msg_lrpid, &up->msg_lrpid); if (err2) err = -EFAULT; } @@ -624,7 +620,7 @@ out: static int do_sys32_shmat (int first, int second, int third, int version, void __user *uptr) { unsigned long raddr; - u32 __user *uaddr = (u32 __user *)A((u32)third); + u32 __user *uaddr = compat_ptr((compat_uptr_t)third); int err = -EINVAL; if (version == 1) @@ -637,66 +633,75 @@ out: return err; } -static int do_sys32_shmctl (int first, int second, void *uptr) +static int do_sys32_shmctl(int first, int second, void __user *uptr) { int err; if (IPCOP_MASK (second) & - (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) | - IPCOP_MASK (IPC_RMID))) { - if (second == (IPC_INFO|IPC_64)) - second = IPC_INFO; /* So that we don't have to translate it */ - err = sys_shmctl (first, second, - (struct shmid_ds __user *) uptr); + (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | + IPCOP_MASK (SHM_UNLOCK) | IPCOP_MASK (IPC_RMID))) { + if (second == (IPC_INFO|IPC_64)) { + /* So that we don't have to translate it */ + second = IPC_INFO; + } + err = sys_shmctl(first, second, uptr); } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) { struct shmid64_ds s; - struct shmid64_ds32 __user *up = - (struct shmid64_ds32 __user *) uptr; + struct shmid64_ds32 __user *up = uptr; mm_segment_t old_fs; if (second == (IPC_SET|IPC_64)) { - err = get_user (s.shm_perm.uid, &up->shm_perm.uid); - err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid); - err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode); + err = get_user(s.shm_perm.uid, + &up->shm_perm.uid); + err |= __get_user(s.shm_perm.gid, + &up->shm_perm.gid); + err |= __get_user(s.shm_perm.mode, + &up->shm_perm.mode); if (err) goto out; } - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_shmctl (first, second, (struct shmid_ds __user *)&s); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_shmctl(first, second, + (struct shmid_ds __user *)&s); + set_fs(old_fs); if (err < 0) goto out; /* Mask it even in this case so it becomes a CSE. */ if (IPCOP_MASK (second) & (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) { - int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t)); - err2 |= __put_user (s.shm_segsz, &up->shm_segsz); - err2 |= __put_user (s.shm_nattch, &up->shm_nattch); - err2 |= __put_user (s.shm_cpid, &up->shm_cpid); - err2 |= __put_user (s.shm_lpid, &up->shm_lpid); + int err2 = copy_to_user(&up->shm_perm, + &s.shm_perm, + sizeof(struct ipc64_perm) + 3*sizeof(time_t)); + err2 |= __put_user(s.shm_segsz, &up->shm_segsz); + err2 |= __put_user(s.shm_nattch,&up->shm_nattch); + err2 |= __put_user(s.shm_cpid, &up->shm_cpid); + err2 |= __put_user(s.shm_lpid, &up->shm_lpid); if (err2) err = -EFAULT; } } else { struct shmid_ds s; - struct shmid_ds32 __user *up = - (struct shmid_ds32 __user *) uptr; + struct shmid_ds32 __user *up = uptr; mm_segment_t old_fs; second &= ~IPC_64; if (second == IPC_SET) { - err = get_user (s.shm_perm.uid, &up->shm_perm.uid); - err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid); - err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode); + err = get_user(s.shm_perm.uid, + &up->shm_perm.uid); + err |= __get_user(s.shm_perm.gid, + &up->shm_perm.gid); + err |= __get_user(s.shm_perm.mode, + &up->shm_perm.mode); if (err) goto out; } - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_shmctl (first, second, (struct shmid_ds __user *) &s); - set_fs (old_fs); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = sys_shmctl(first, second, + (struct shmid_ds __user *) &s); + set_fs(old_fs); if (err < 0) goto out; @@ -707,33 +712,45 @@ static int do_sys32_shmctl (int first, int second, void *uptr) u32 shm_tot, shm_rss, shm_swp; u32 swap_attempts, swap_successes; }; - struct shm_info32 __user *uip = - (struct shm_info32 __user *) uptr; - struct shm_info *kp = (struct shm_info *)&s; - int err2 = put_user (kp->used_ids, &uip->used_ids); - err2 |= __put_user (kp->shm_tot, &uip->shm_tot); - err2 |= __put_user (kp->shm_rss, &uip->shm_rss); - err2 |= __put_user (kp->shm_swp, &uip->shm_swp); - err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts); - err2 |= __put_user (kp->swap_successes, &uip->swap_successes); + struct shm_info32 __user *uip = uptr; + struct shm_info *kp = (struct shm_info *) &s; + int err2 = put_user(kp->used_ids, + &uip->used_ids); + err2 |= __put_user(kp->shm_tot, &uip->shm_tot); + err2 |= __put_user(kp->shm_rss, &uip->shm_rss); + err2 |= __put_user(kp->shm_swp, &uip->shm_swp); + err2 |= __put_user(kp->swap_attempts, + &uip->swap_attempts); + err2 |= __put_user(kp->swap_successes, + &uip->swap_successes); if (err2) err = -EFAULT; } else if (IPCOP_MASK (second) & - (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) { - int err2 = put_user (s.shm_perm.key, &up->shm_perm.key); - err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid); - err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid); - err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid); - err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid); - err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode); - err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq); - err2 |= __put_user (s.shm_atime, &up->shm_atime); - err2 |= __put_user (s.shm_dtime, &up->shm_dtime); - err2 |= __put_user (s.shm_ctime, &up->shm_ctime); - err2 |= __put_user (s.shm_segsz, &up->shm_segsz); - err2 |= __put_user (s.shm_nattch, &up->shm_nattch); - err2 |= __put_user (s.shm_cpid, &up->shm_cpid); - err2 |= __put_user (s.shm_lpid, &up->shm_lpid); + (IPCOP_MASK (SHM_STAT) | + IPCOP_MASK (IPC_STAT))) { + int err2; + + err2 = put_user(s.shm_perm.key, + &up->shm_perm.key); + err2 |= __put_user(high2lowuid(s.shm_perm.uid), + &up->shm_perm.uid); + err2 |= __put_user(high2lowuid(s.shm_perm.gid), + &up->shm_perm.gid); + err2 |= __put_user(high2lowuid(s.shm_perm.cuid), + &up->shm_perm.cuid); + err2 |= __put_user(high2lowuid(s.shm_perm.cgid), + &up->shm_perm.cgid); + err2 |= __put_user(s.shm_perm.mode, + &up->shm_perm.mode); + err2 |= __put_user(s.shm_perm.seq, + &up->shm_perm.seq); + err2 |= __put_user(s.shm_atime, &up->shm_atime); + err2 |= __put_user(s.shm_dtime, &up->shm_dtime); + err2 |= __put_user(s.shm_ctime, &up->shm_ctime); + err2 |= __put_user(s.shm_segsz, &up->shm_segsz); + err2 |= __put_user(s.shm_nattch,&up->shm_nattch); + err2 |= __put_user(s.shm_cpid, &up->shm_cpid); + err2 |= __put_user(s.shm_lpid, &up->shm_lpid); if (err2) err = -EFAULT; } @@ -742,12 +759,14 @@ out: return err; } -static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems, - const struct compat_timespec __user *timeout32) +static int sys32_semtimedop(int semid, struct sembuf __user *tsems, + int nsems, + const struct compat_timespec __user *timeout32) { struct compat_timespec t32; - struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64)); + struct timespec __user *t64; + t64 = compat_alloc_user_space(sizeof(*t64)); if (copy_from_user(&t32, timeout32, sizeof(t32))) return -EFAULT; @@ -758,77 +777,81 @@ static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems, return sys_semtimedop(semid, tsems, nsems, t64); } -asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) +asmlinkage long compat_sys_ipc(u32 call, int first, int second, int third, compat_uptr_t __ptr, u32 fifth) { int version, err; + void __user *ptr = compat_ptr(__ptr); version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; - if (call <= SEMCTL) + if (call <= SEMCTL) { switch (call) { case SEMOP: - /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second, NULL); + /* struct sembuf is the same on 32 and 64 :)) */ + err = sys_semtimedop (first, ptr, second, NULL); goto out; case SEMTIMEDOP: - err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second, (const struct compat_timespec __user *) AA(fifth)); + err = sys32_semtimedop(first, ptr, second, + compat_ptr(fifth)); case SEMGET: - err = sys_semget (first, second, third); + err = sys_semget(first, second, third); goto out; case SEMCTL: - err = do_sys32_semctl (first, second, third, (void *)AA(ptr)); + err = do_sys32_semctl(first, second, third, ptr); goto out; default: err = -ENOSYS; goto out; }; - if (call <= MSGCTL) + } + if (call <= MSGCTL) { switch (call) { case MSGSND: - err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr)); + err = do_sys32_msgsnd(first, second, third, ptr); goto out; case MSGRCV: - err = do_sys32_msgrcv (first, second, fifth, third, - version, (void *)AA(ptr)); + err = do_sys32_msgrcv(first, second, fifth, + third, version, ptr); goto out; case MSGGET: - err = sys_msgget ((key_t) first, second); + err = sys_msgget((key_t) first, second); goto out; case MSGCTL: - err = do_sys32_msgctl (first, second, (void *)AA(ptr)); + err = do_sys32_msgctl(first, second, ptr); goto out; default: err = -ENOSYS; goto out; - } - if (call <= SHMCTL) + }; + } + if (call <= SHMCTL) { switch (call) { case SHMAT: - err = do_sys32_shmat (first, second, third, - version, (void __user *)AA(ptr)); + err = do_sys32_shmat(first, second, third, + version, ptr); goto out; case SHMDT: - err = sys_shmdt ((char __user *)AA(ptr)); + err = sys_shmdt(ptr); goto out; case SHMGET: - err = sys_shmget (first, second, third); + err = sys_shmget(first, second, third); goto out; case SHMCTL: - err = do_sys32_shmctl (first, second, (void *)AA(ptr)); + err = do_sys32_shmctl(first, second, ptr); goto out; default: err = -ENOSYS; goto out; - } - + }; + } err = -ENOSYS; out: return err; } -asmlinkage int sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) +asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) { if ((int)high < 0) return -EINVAL; @@ -836,7 +859,7 @@ asmlinkage int sys32_truncate64(const char __user * path, unsigned long high, un return sys_truncate(path, (high << 32) | low); } -asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low) +asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low) { if ((int)high < 0) return -EINVAL; @@ -879,7 +902,7 @@ static int fillonedir(void * __buf, const char * name, int namlen, return 0; } -asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 __user *dirent, unsigned int count) +asmlinkage long old32_readdir(unsigned int fd, struct old_linux_dirent32 __user *dirent, unsigned int count) { int error = -EBADF; struct file * file; @@ -943,7 +966,7 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, i return 0; } -asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dirent, unsigned int count) +asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dirent, unsigned int count) { struct file * file; struct linux_dirent32 __user *lastdirent; @@ -964,7 +987,7 @@ asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 __user *dir goto out_putf; lastdirent = buf.previous; error = buf.error; - if(lastdirent) { + if (lastdirent) { put_user(file->f_pos, &lastdirent->d_off); error = count - buf.count; } @@ -1006,7 +1029,7 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) return err; } -asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2) +asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2) { return sys_sysfs(option, arg1, arg2); } @@ -1028,7 +1051,7 @@ struct sysinfo32 { char _f[20-2*sizeof(int)-sizeof(int)]; }; -asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info) +asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info) { struct sysinfo s; int ret, err; @@ -1075,7 +1098,7 @@ asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info) return ret; } -asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) +asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) { struct timespec t; int ret; @@ -1089,7 +1112,10 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_times return ret; } -asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset, compat_size_t sigsetsize) +asmlinkage long compat_sys_rt_sigprocmask(int how, + compat_sigset_t __user *set, + compat_sigset_t __user *oset, + compat_size_t sigsetsize) { sigset_t s; compat_sigset_t s32; @@ -1126,7 +1152,8 @@ asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat return 0; } -asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) +asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set, + compat_size_t sigsetsize) { sigset_t s; compat_sigset_t s32; @@ -1149,10 +1176,10 @@ asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t si return ret; } -asmlinkage int -sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo, - struct compat_timespec __user *uts, - compat_size_t sigsetsize) +asmlinkage long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, + siginfo_t32 __user *uinfo, + struct compat_timespec __user *uts, + compat_size_t sigsetsize) { int ret, sig; sigset_t these; @@ -1234,8 +1261,8 @@ sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo, return ret; } -asmlinkage int -sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo) +asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig, + siginfo_t32 __user *uinfo) { siginfo_t info; int ret; @@ -1250,8 +1277,8 @@ sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo) return ret; } -asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 __user *act, - struct old_sigaction32 __user *oact) +asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act, + struct old_sigaction32 __user *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -1289,10 +1316,11 @@ asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 __user *act, return ret; } -asmlinkage int -sys32_rt_sigaction(int sig, struct sigaction32 __user *act, - struct sigaction32 __user *oact, - void __user *restorer, compat_size_t sigsetsize) +asmlinkage long compat_sys_rt_sigaction(int sig, + struct sigaction32 __user *act, + struct sigaction32 __user *oact, + void __user *restorer, + compat_size_t sigsetsize) { struct k_sigaction new_ka, old_ka; int ret; @@ -1351,27 +1379,29 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act, * sparc32_execve() executes a new program after the asm stub has set * things up for us. This should basically do what I want it to. */ -asmlinkage int sparc32_execve(struct pt_regs *regs) +asmlinkage long sparc32_execve(struct pt_regs *regs) { - int error, base = 0; - char *filename; + int error, base = 0; + char *filename; /* User register window flush is done by entry.S */ - /* Check for indirect call. */ - if((u32)regs->u_regs[UREG_G1] == 0) - base = 1; + /* Check for indirect call. */ + if ((u32)regs->u_regs[UREG_G1] == 0) + base = 1; - filename = getname((char __user *)AA(regs->u_regs[base + UREG_I0])); + filename = getname(compat_ptr(regs->u_regs[base + UREG_I0])); error = PTR_ERR(filename); - if(IS_ERR(filename)) - goto out; - error = compat_do_execve(filename, - compat_ptr((u32)regs->u_regs[base + UREG_I1]), - compat_ptr((u32)regs->u_regs[base + UREG_I2]), regs); - putname(filename); - - if(!error) { + if (IS_ERR(filename)) + goto out; + + error = compat_do_execve(filename, + compat_ptr(regs->u_regs[base + UREG_I1]), + compat_ptr(regs->u_regs[base + UREG_I2]), regs); + + putname(filename); + + if (!error) { fprs_write(0); current_thread_info()->xfsr[0] = 0; current_thread_info()->fpsaved[0] = 0; @@ -1379,33 +1409,32 @@ asmlinkage int sparc32_execve(struct pt_regs *regs) current->ptrace &= ~PT_DTRACE; } out: - return error; + return error; } #ifdef CONFIG_MODULES -asmlinkage int sys32_init_module(void __user *umod, u32 len, - const char __user *uargs) +asmlinkage long sys32_init_module(void __user *umod, u32 len, + const char __user *uargs) { return sys_init_module(umod, len, uargs); } -asmlinkage int sys32_delete_module(const char __user *name_user, - unsigned int flags) +asmlinkage long sys32_delete_module(const char __user *name_user, + unsigned int flags) { return sys_delete_module(name_user, flags); } #else /* CONFIG_MODULES */ -asmlinkage int -sys32_init_module(const char *name_user, struct module *mod_user) +asmlinkage long sys32_init_module(const char __user *name_user, + struct module __user *mod_user) { return -ENOSYS; } -asmlinkage int -sys32_delete_module(const char *name_user) +asmlinkage long sys32_delete_module(const char __user *name_user) { return -ENOSYS; } @@ -1417,8 +1446,8 @@ sys32_delete_module(const char *name_user) extern struct timezone sys_tz; -asmlinkage int sys32_gettimeofday(struct compat_timeval __user *tv, - struct timezone __user *tz) +asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz) { if (tv) { struct timeval ktv; @@ -1447,8 +1476,8 @@ static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) return 0; } -asmlinkage int sys32_settimeofday(struct compat_timeval __user *tv, - struct timezone __user *tz) +asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz) { struct timespec kts; struct timezone ktz; @@ -1465,8 +1494,8 @@ asmlinkage int sys32_settimeofday(struct compat_timeval __user *tv, return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } -asmlinkage int sys32_utimes(char __user *filename, - struct compat_timeval __user *tvs) +asmlinkage long sys32_utimes(char __user *filename, + struct compat_timeval __user *tvs) { struct timeval ktvs[2]; @@ -1480,74 +1509,61 @@ asmlinkage int sys32_utimes(char __user *filename, } /* These are here just in case some old sparc32 binary calls it. */ -asmlinkage int sys32_pause(void) +asmlinkage long sys32_pause(void) { current->state = TASK_INTERRUPTIBLE; schedule(); return -ERESTARTNOHAND; } -/* PCI config space poking. */ - -asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf) -{ - return sys_pciconfig_read((unsigned long) bus, - (unsigned long) dfn, - (unsigned long) off, - (unsigned long) len, - (unsigned char __user *)AA(ubuf)); -} - -asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf) -{ - return sys_pciconfig_write((unsigned long) bus, - (unsigned long) dfn, - (unsigned long) off, - (unsigned long) len, - (unsigned char __user *)AA(ubuf)); -} - -asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) -{ - return sys_prctl(option, - (unsigned long) arg2, - (unsigned long) arg3, - (unsigned long) arg4, - (unsigned long) arg5); -} - - -asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, char __user *ubuf, +asmlinkage compat_ssize_t sys32_pread64(unsigned int fd, + char __user *ubuf, compat_size_t count, - u32 poshi, u32 poslo) + unsigned long poshi, + unsigned long poslo) { - return sys_pread64(fd, ubuf, count, - ((loff_t)AA(poshi) << 32) | AA(poslo)); + return sys_pread64(fd, ubuf, count, (poshi << 32) | poslo); } -asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd, char __user *ubuf, - compat_size_t count, u32 poshi, u32 poslo) +asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd, + char __user *ubuf, + compat_size_t count, + unsigned long poshi, + unsigned long poslo) { - return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); + return sys_pwrite64(fd, ubuf, count, (poshi << 32) | poslo); } -asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count) +asmlinkage long compat_sys_readahead(int fd, + unsigned long offhi, + unsigned long offlo, + compat_size_t count) { - return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); + return sys_readahead(fd, (offhi << 32) | offlo, count); } -long sys32_fadvise64(int fd, u32 offhi, u32 offlo, s32 len, int advice) +long compat_sys_fadvise64(int fd, + unsigned long offhi, + unsigned long offlo, + compat_size_t len, int advice) { - return sys_fadvise64_64(fd, ((loff_t)AA(offhi)<<32)|AA(offlo), len, advice); + return sys_fadvise64_64(fd, (offhi << 32) | offlo, len, advice); } -long sys32_fadvise64_64(int fd, u32 offhi, u32 offlo, u32 lenhi, u32 lenlo, int advice) +long compat_sys_fadvise64_64(int fd, + unsigned long offhi, unsigned long offlo, + unsigned long lenhi, unsigned long lenlo, + int advice) { - return sys_fadvise64_64(fd, ((loff_t)AA(offhi)<<32)|AA(offlo), - ((loff_t)AA(lenhi)<<32)|AA(lenlo), advice); + return sys_fadvise64_64(fd, + (offhi << 32) | offlo, + (lenhi << 32) | lenlo, + advice); } -asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) +asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, + compat_off_t __user *offset, + compat_size_t count) { mm_segment_t old_fs = get_fs(); int ret; @@ -1568,7 +1584,9 @@ asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset return ret; } -asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) +asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd, + compat_loff_t __user *offset, + compat_size_t count) { mm_segment_t old_fs = get_fs(); int ret; @@ -1606,57 +1624,57 @@ struct timex32 { extern int do_adjtimex(struct timex *); -asmlinkage int sys32_adjtimex(struct timex32 __user *utp) +asmlinkage long sys32_adjtimex(struct timex32 __user *utp) { struct timex txc; int ret; memset(&txc, 0, sizeof(struct timex)); - if(get_user(txc.modes, &utp->modes) || - __get_user(txc.offset, &utp->offset) || - __get_user(txc.freq, &utp->freq) || - __get_user(txc.maxerror, &utp->maxerror) || - __get_user(txc.esterror, &utp->esterror) || - __get_user(txc.status, &utp->status) || - __get_user(txc.constant, &utp->constant) || - __get_user(txc.precision, &utp->precision) || - __get_user(txc.tolerance, &utp->tolerance) || - __get_user(txc.time.tv_sec, &utp->time.tv_sec) || - __get_user(txc.time.tv_usec, &utp->time.tv_usec) || - __get_user(txc.tick, &utp->tick) || - __get_user(txc.ppsfreq, &utp->ppsfreq) || - __get_user(txc.jitter, &utp->jitter) || - __get_user(txc.shift, &utp->shift) || - __get_user(txc.stabil, &utp->stabil) || - __get_user(txc.jitcnt, &utp->jitcnt) || - __get_user(txc.calcnt, &utp->calcnt) || - __get_user(txc.errcnt, &utp->errcnt) || - __get_user(txc.stbcnt, &utp->stbcnt)) + if (get_user(txc.modes, &utp->modes) || + __get_user(txc.offset, &utp->offset) || + __get_user(txc.freq, &utp->freq) || + __get_user(txc.maxerror, &utp->maxerror) || + __get_user(txc.esterror, &utp->esterror) || + __get_user(txc.status, &utp->status) || + __get_user(txc.constant, &utp->constant) || + __get_user(txc.precision, &utp->precision) || + __get_user(txc.tolerance, &utp->tolerance) || + __get_user(txc.time.tv_sec, &utp->time.tv_sec) || + __get_user(txc.time.tv_usec, &utp->time.tv_usec) || + __get_user(txc.tick, &utp->tick) || + __get_user(txc.ppsfreq, &utp->ppsfreq) || + __get_user(txc.jitter, &utp->jitter) || + __get_user(txc.shift, &utp->shift) || + __get_user(txc.stabil, &utp->stabil) || + __get_user(txc.jitcnt, &utp->jitcnt) || + __get_user(txc.calcnt, &utp->calcnt) || + __get_user(txc.errcnt, &utp->errcnt) || + __get_user(txc.stbcnt, &utp->stbcnt)) return -EFAULT; ret = do_adjtimex(&txc); - if(put_user(txc.modes, &utp->modes) || - __put_user(txc.offset, &utp->offset) || - __put_user(txc.freq, &utp->freq) || - __put_user(txc.maxerror, &utp->maxerror) || - __put_user(txc.esterror, &utp->esterror) || - __put_user(txc.status, &utp->status) || - __put_user(txc.constant, &utp->constant) || - __put_user(txc.precision, &utp->precision) || - __put_user(txc.tolerance, &utp->tolerance) || - __put_user(txc.time.tv_sec, &utp->time.tv_sec) || - __put_user(txc.time.tv_usec, &utp->time.tv_usec) || - __put_user(txc.tick, &utp->tick) || - __put_user(txc.ppsfreq, &utp->ppsfreq) || - __put_user(txc.jitter, &utp->jitter) || - __put_user(txc.shift, &utp->shift) || - __put_user(txc.stabil, &utp->stabil) || - __put_user(txc.jitcnt, &utp->jitcnt) || - __put_user(txc.calcnt, &utp->calcnt) || - __put_user(txc.errcnt, &utp->errcnt) || - __put_user(txc.stbcnt, &utp->stbcnt)) + if (put_user(txc.modes, &utp->modes) || + __put_user(txc.offset, &utp->offset) || + __put_user(txc.freq, &utp->freq) || + __put_user(txc.maxerror, &utp->maxerror) || + __put_user(txc.esterror, &utp->esterror) || + __put_user(txc.status, &utp->status) || + __put_user(txc.constant, &utp->constant) || + __put_user(txc.precision, &utp->precision) || + __put_user(txc.tolerance, &utp->tolerance) || + __put_user(txc.time.tv_sec, &utp->time.tv_sec) || + __put_user(txc.time.tv_usec, &utp->time.tv_usec) || + __put_user(txc.tick, &utp->tick) || + __put_user(txc.ppsfreq, &utp->ppsfreq) || + __put_user(txc.jitter, &utp->jitter) || + __put_user(txc.shift, &utp->shift) || + __put_user(txc.stabil, &utp->stabil) || + __put_user(txc.jitcnt, &utp->jitcnt) || + __put_user(txc.calcnt, &utp->calcnt) || + __put_user(txc.errcnt, &utp->errcnt) || + __put_user(txc.stbcnt, &utp->stbcnt)) ret = -EFAULT; return ret; @@ -1666,7 +1684,8 @@ asmlinkage int sys32_adjtimex(struct timex32 __user *utp) * not force O_LARGEFILE on. */ -asmlinkage long sparc32_open(const char __user *filename, int flags, int mode) +asmlinkage long sparc32_open(const char __user *filename, + int flags, int mode) { char * tmp; int fd, error; @@ -1703,7 +1722,7 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr, { struct vm_area_struct *vma; unsigned long ret = -EINVAL; - unsigned long new_addr = AA(__new_addr); + unsigned long new_addr = __new_addr; if (old_len > 0xf0000000UL || new_len > 0xf0000000UL) goto out; @@ -1744,13 +1763,6 @@ out: return ret; } -asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval) -{ - return sys_setpriority((int) which, - (int) who, - (int) niceval); -} - struct __sysctl_args32 { u32 name; int nlen; @@ -1781,21 +1793,24 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) basically copy the whole sysctl.c here, and glibc's __sysctl uses rw memory for the structure anyway. */ - if (get_user(oldlen, (u32 __user *)A(tmp.oldlenp)) || + if (get_user(oldlen, (u32 __user *)(unsigned long)tmp.oldlenp) || put_user(oldlen, (size_t __user *)addr)) return -EFAULT; oldlenp = (size_t __user *)addr; } lock_kernel(); - error = do_sysctl((int __user *)A(tmp.name), tmp.nlen, - (void __user *)A(tmp.oldval), - oldlenp, (void __user *)A(tmp.newval), tmp.newlen); + error = do_sysctl((int __user *)(unsigned long) tmp.name, + tmp.nlen, + (void __user *)(unsigned long) tmp.oldval, + oldlenp, + (void __user *)(unsigned long) tmp.newval, + tmp.newlen); unlock_kernel(); if (oldlenp) { if (!error) { if (get_user(oldlen, (size_t __user *)addr) || - put_user(oldlen, (u32 __user *)A(tmp.oldlenp))) + put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp)) error = -EFAULT; } copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); @@ -1804,10 +1819,11 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) #endif } -long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, +long sys32_lookup_dcookie(unsigned long cookie_high, + unsigned long cookie_low, char __user *buf, size_t len) { - return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low, + return sys_lookup_dcookie((cookie_high << 32) | cookie_low, buf, len); } diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 4a6df8c94..c1c064021 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -59,15 +59,6 @@ #include #include -/* Use this to get at 32-bit user passed pointers. */ -#define A(__x) \ -({ unsigned long __ret; \ - __asm__ ("srl %0, 0, %0" \ - : "=r" (__ret) \ - : "0" (__x)); \ - __ret; \ -}) - #define SUNOS_NR_OPEN 256 asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off) @@ -308,13 +299,12 @@ static int sunos_filldir(void * __buf, const char * name, int namlen, return 0; } -asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt) +asmlinkage int sunos_getdents(unsigned int fd, void __user *dirent, int cnt) { struct file * file; struct sunos_dirent __user *lastdirent; struct sunos_dirent_callback buf; int error = -EBADF; - void __user *dirent = (void __user *)A(u_dirent); if (fd >= SUNOS_NR_OPEN) goto out; @@ -389,11 +379,11 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen, return 0; } -asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent, - int cnt, u32 u_basep) +asmlinkage int sunos_getdirentries(unsigned int fd, + void __user *dirent, + int cnt, + unsigned int __user *basep) { - void __user *dirent = (void __user *) A(u_dirent); - unsigned int __user *basep = (unsigned int __user *)A(u_basep); struct file * file; struct sunos_direntry __user *lastdirent; int error = -EBADF; @@ -813,13 +803,12 @@ asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) extern long compat_sys_wait4(compat_pid_t, compat_uint_t *, int, struct compat_rusage *); -asmlinkage int sunos_wait4(compat_pid_t pid, u32 stat_addr, int options, u32 ru) +asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru) { int ret; ret = compat_sys_wait4((pid ? pid : ((compat_pid_t)-1)), - (compat_uint_t *)A(stat_addr), options, - (struct compat_rusage *)A(ru)); + stat_addr, options, ru); return ret; } @@ -893,7 +882,7 @@ asmlinkage s32 sunos_sysconf (int name) return ret; } -asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr) +asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, void __user *ptr) { union semun arg4; int ret; @@ -919,7 +908,7 @@ asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr) } /* sys_semctl(): */ /* value to modify semaphore to */ - arg4.__pad=(void __user *)A(ptr); + arg4.__pad = ptr; ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4); break; case 1: @@ -928,7 +917,7 @@ asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr) break; case 2: /* sys_semop(): */ - ret = sys_semop((int)arg1, (struct sembuf __user *)A(arg2), + ret = sys_semop((int)arg1, (struct sembuf __user *)(unsigned long)arg2, (unsigned int) arg3); break; default: @@ -1041,13 +1030,13 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) rval = sys_msgget((key_t)arg1, (int)arg2); break; case 1: - if (!sunos_msqid_get((struct msqid_ds32 __user *)A(arg3), &kds)) { + if (!sunos_msqid_get((struct msqid_ds32 __user *)(unsigned long)arg3, &kds)) { set_fs(KERNEL_DS); rval = sys_msgctl((int)arg1, (int)arg2, - (struct msqid_ds __user *)A(arg3)); + (struct msqid_ds __user *)(unsigned long)arg3); set_fs(old_fs); if (!rval) - rval = sunos_msqid_put((struct msqid_ds32 __user *)A(arg3), + rval = sunos_msqid_put((struct msqid_ds32 __user *)(unsigned long)arg3, &kds); } else rval = -EFAULT; @@ -1071,7 +1060,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) (long)arg4, (int)arg5); set_fs(old_fs); if (!rval) - rval = sunos_msgbuf_put((struct msgbuf32 __user *)A(arg2), + rval = sunos_msgbuf_put((struct msgbuf32 __user *)(unsigned long)arg2, kmbuf, arg3); kfree(kmbuf); break; @@ -1079,7 +1068,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) rval = -EFAULT; kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3, GFP_KERNEL); - if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)A(arg2), + if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2, kmbuf, arg3)) break; set_fs(KERNEL_DS); @@ -1154,26 +1143,26 @@ asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3) switch(op) { case 0: /* do_shmat(): attach a shared memory area */ - rval = do_shmat((int)arg1,(char __user *)A(arg2),(int)arg3,&raddr); + rval = do_shmat((int)arg1,(char __user *)(unsigned long)arg2,(int)arg3,&raddr); if (!rval) rval = (int) raddr; break; case 1: /* sys_shmctl(): modify shared memory area attr. */ - if (!sunos_shmid_get((struct shmid_ds32 __user *)A(arg3), &ksds)) { + if (!sunos_shmid_get((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds)) { set_fs(KERNEL_DS); rval = sys_shmctl((int) arg1,(int) arg2, (struct shmid_ds __user *) &ksds); set_fs(old_fs); if (!rval) - rval = sunos_shmid_put((struct shmid_ds32 __user *)A(arg3), + rval = sunos_shmid_put((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds); } else rval = -EFAULT; break; case 2: /* sys_shmdt(): detach a shared memory area */ - rval = sys_shmdt((char __user *)A(arg1)); + rval = sys_shmdt((char __user *)(unsigned long)arg1); break; case 3: /* sys_shmget(): get a shared memory area */ @@ -1215,66 +1204,60 @@ static inline int check_nonblock(int ret, int fd) return ret; } -asmlinkage int sunos_read(unsigned int fd, u32 buf, u32 count) +asmlinkage int sunos_read(unsigned int fd, char __user *buf, u32 count) { int ret; - ret = check_nonblock(sys_read(fd, (char __user *)A(buf), count), fd); + ret = check_nonblock(sys_read(fd, buf, count), fd); return ret; } -asmlinkage int sunos_readv(u32 fd, u32 vector, s32 count) +asmlinkage int sunos_readv(u32 fd, void __user *vector, s32 count) { int ret; - ret = check_nonblock(compat_sys_readv(fd, (void __user *) A(vector), - count), fd); + ret = check_nonblock(compat_sys_readv(fd, vector, count), fd); return ret; } -asmlinkage int sunos_write(unsigned int fd, u32 buf, u32 count) +asmlinkage int sunos_write(unsigned int fd, char __user *buf, u32 count) { int ret; - ret = check_nonblock(sys_write(fd, (char __user *)A(buf), count), fd); + ret = check_nonblock(sys_write(fd, buf, count), fd); return ret; } -asmlinkage int sunos_writev(u32 fd, u32 vector, s32 count) +asmlinkage int sunos_writev(u32 fd, void __user *vector, s32 count) { int ret; - ret = check_nonblock(compat_sys_writev(fd, (void __user *)A(vector), - count), fd); + ret = check_nonblock(compat_sys_writev(fd, vector, count), fd); return ret; } -asmlinkage int sunos_recv(int fd, u32 ubuf, int size, unsigned flags) +asmlinkage int sunos_recv(u32 __fd, void __user *ubuf, int size, unsigned flags) { - int ret; + int ret, fd = (int) __fd; - ret = check_nonblock(sys_recv(fd, (void __user *)A(ubuf), - size, flags), fd); + ret = check_nonblock(sys_recv(fd, ubuf, size, flags), fd); return ret; } -asmlinkage int sunos_send(int fd, u32 buff, int len, unsigned flags) +asmlinkage int sunos_send(u32 __fd, void __user *buff, int len, unsigned flags) { - int ret; + int ret, fd = (int) __fd; - ret = check_nonblock(sys_send(fd, (void __user *)A(buff), - len, flags), fd); + ret = check_nonblock(sys_send(fd, buff, len, flags), fd); return ret; } -asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen) +asmlinkage int sunos_accept(u32 __fd, struct sockaddr __user *sa, int __user *addrlen) { - int ret; + int ret, fd = (int) __fd; while (1) { - ret = check_nonblock(sys_accept(fd, - (struct sockaddr __user *)A(sa), - (int __user *)A(addrlen)), fd); + ret = check_nonblock(sys_accept(fd, sa, addrlen), fd); if (ret != -ENETUNREACH && ret != -EHOSTUNREACH) break; } @@ -1283,7 +1266,9 @@ asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen) #define SUNOS_SV_INTERRUPT 2 -asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact) +asmlinkage int sunos_sigaction (int sig, + struct old_sigaction32 __user *act, + struct old_sigaction32 __user *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -1292,11 +1277,11 @@ asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact) compat_old_sigset_t mask; u32 u_handler; - if (get_user(u_handler, &((struct old_sigaction32 __user *)A(act))->sa_handler) || - __get_user(new_ka.sa.sa_flags, &((struct old_sigaction32 __user *)A(act))->sa_flags)) + if (get_user(u_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags)) return -EFAULT; new_ka.sa.sa_handler = (void *) (long) u_handler; - __get_user(mask, &((struct old_sigaction32 __user *)A(act))->sa_mask); + __get_user(mask, &act->sa_mask); new_ka.sa.sa_restorer = NULL; new_ka.ka_restorer = NULL; siginitset(&new_ka.sa.sa_mask, mask); @@ -1307,18 +1292,22 @@ asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact) if (!ret && oact) { old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT; - if (put_user((long)old_ka.sa.sa_handler, &((struct old_sigaction32 __user *)A(oact))->sa_handler) || - __put_user(old_ka.sa.sa_flags, &((struct old_sigaction32 __user *)A(oact))->sa_flags)) + if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) return -EFAULT; - __put_user(old_ka.sa.sa_mask.sig[0], &((struct old_sigaction32 __user *)A(oact))->sa_mask); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; } -asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval, - int optlen) +asmlinkage int sunos_setsockopt(u32 __fd, u32 __level, u32 __optname, + char __user *optval, u32 __optlen) { + int fd = (int) __fd; + int level = (int) __level; + int optname = (int) __optname; + int optlen = (int) __optlen; int tr_opt = optname; int ret; @@ -1328,13 +1317,16 @@ asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval, tr_opt += 30; } ret = sys_setsockopt(fd, level, tr_opt, - (char __user *)A(optval), optlen); + optval, optlen); return ret; } -asmlinkage int sunos_getsockopt(int fd, int level, int optname, - u32 optval, u32 optlen) +asmlinkage int sunos_getsockopt(u32 __fd, u32 __level, u32 __optname, + char __user *optval, int __user *optlen) { + int fd = (int) __fd; + int level = (int) __level; + int optname = (int) __optname; int tr_opt = optname; int ret; @@ -1344,7 +1336,6 @@ asmlinkage int sunos_getsockopt(int fd, int level, int optname, tr_opt += 30; } ret = compat_sys_getsockopt(fd, level, tr_opt, - (void __user *)(unsigned long) optval, - (void __user *)(unsigned long) optlen); + optval, optlen); return ret; } diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index b2ce2cdad..966e2b11f 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -19,62 +19,62 @@ .globl sys_call_table32 sys_call_table32: -/*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write -/*5*/ .word sparc32_open, sys_close, compat_sys_wait4, sys_creat, sys_link +/*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write +/*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod -/*15*/ .word sys32_chmod, sys32_lchown16, sparc_brk, sys_perfctr, sys32_lseek +/*15*/ .word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek /*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16 /*25*/ .word sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause -/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice - .word sys_chown, sys_sync, sys_kill, compat_sys_newstat, sys32_sendfile +/*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice + .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile /*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid - .word sys_umount, sys32_setgid16, sys32_getgid16, sys_signal, sys32_geteuid16 + .word sys32_umount, sys32_setgid16, sys32_getgid16, sys32_signal, sys32_geteuid16 /*50*/ .word sys32_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl - .word sys_reboot, sys32_mmap2, sys_symlink, sys_readlink, sys32_execve -/*60*/ .word sys_umask, sys_chroot, compat_sys_newfstat, sys_fstat64, sys_getpagesize - .word sys_msync, sys_vfork, sys32_pread64, sys32_pwrite64, sys_geteuid -/*70*/ .word sys_getegid, sys32_mmap, sys_setreuid, sys_munmap, sys_mprotect + .word sys32_reboot, sys32_mmap2, sys_symlink, sys32_readlink, sys32_execve +/*60*/ .word sys32_umask, sys_chroot, compat_sys_newfstat, sys_fstat64, sys_getpagesize + .word sys32_msync, sys_vfork, sys32_pread64, sys32_pwrite64, sys_geteuid +/*70*/ .word sys_getegid, sys_mmap, sys_setreuid, sys_munmap, sys_mprotect .word sys_madvise, sys_vhangup, sys32_truncate64, sys_mincore, sys32_getgroups16 -/*80*/ .word sys32_setgroups16, sys_getpgrp, sys_setgroups, compat_sys_setitimer, sys32_ftruncate64 - .word sys_swapon, compat_sys_getitimer, sys_setuid, sys_sethostname, sys_setgid +/*80*/ .word sys32_setgroups16, sys_getpgrp, sys32_setgroups, sys32_setitimer, sys32_ftruncate64 + .word sys32_swapon, sys32_getitimer, sys_setuid, sys32_sethostname, sys_setgid /*90*/ .word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid - .word sys_fsync, sys_setpriority32, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall -/*100*/ .word sys_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending + .word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall +/*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending .word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall - .word sys_getgroups, sys32_gettimeofday, compat_sys_getrusage, sys_nis_syscall, sys_getcwd + .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd /*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate /*130*/ .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall - .word sys_nis_syscall, sys_mkdir, sys_rmdir, sys32_utimes, sys_stat64 + .word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, sys_stat64 /*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit - .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write + .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write /*150*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64 .word compat_sys_fcntl64, sys_ni_syscall, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount -/*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall - .word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys_setxattr -/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents - .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr -/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall - .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname -/*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl - .word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask -/*200*/ .word sys_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, old32_readdir - .word sys32_readahead, sys32_socketcall, sys_syslog, sys32_lookup_dcookie, sys32_fadvise64 -/*210*/ .word sys32_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys32_sysinfo +/*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall + .word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys32_setxattr +/*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents + .word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr +/*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall + .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sparc64_newuname +/*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl + .word sys32_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask +/*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, old32_readdir + .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 +/*210*/ .word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, sys32_sysinfo .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex -/*220*/ .word compat_sys_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid +/*220*/ .word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 /*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, compat_statfs64 - .word compat_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall -/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler - .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep -/*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, compat_sys_nfsservctl - .word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep -/*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun + .word compat_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys32_mlockall +/*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys32_sched_setscheduler, sys32_sched_getscheduler + .word sys_sched_yield, sys32_sched_get_priority_max, sys32_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep +/*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl + .word sys_ni_syscall, sys32_clock_settime, compat_clock_gettime, compat_clock_getres, sys32_clock_nanosleep +/*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_timer_gettime, sys_timer_getoverrun .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy -/*270*/ .word compat_sys_io_submit, sys_io_cancel, compat_sys_io_getevents, compat_sys_mq_open, sys_mq_unlink - .word sys32_mq_timedsend, sys32_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, sys_ni_syscall +/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink + .word sys_mq_timedsend, sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, sys_ni_syscall /*280*/ .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall /* Now the 64-bit native Linux syscall table. */ @@ -148,12 +148,12 @@ sys_call_table: .align 4 .globl sunos_sys_table sunos_sys_table: -/*0*/ .word sunos_indir, sparc_exit, sys_fork +/*0*/ .word sunos_indir, sys32_exit, sys_fork .word sunos_read, sunos_write, sunos_open .word sys_close, sunos_wait4, sys_creat .word sys_link, sys_unlink, sunos_execv .word sys_chdir, sunos_nosys, sys32_mknod - .word sys32_chmod, sys32_lchown16, sunos_brk + .word sys_chmod, sys32_lchown16, sunos_brk .word sunos_nosys, sys32_lseek, sunos_getpid .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_getuid, sunos_nosys, sys_ptrace @@ -180,26 +180,26 @@ sunos_sys_table: .word compat_sys_getitimer, sys_gethostname, sys_sethostname .word sunos_getdtablesize, sys_dup2, sunos_nop .word compat_sys_fcntl, sunos_select, sunos_nop - .word sys_fsync, sys_setpriority32, sys_socket - .word sys_connect, sunos_accept + .word sys_fsync, sys32_setpriority, sys32_socket + .word sys32_connect, sunos_accept /*100*/ .word sys_getpriority, sunos_send, sunos_recv - .word sunos_nosys, sys_bind, sunos_setsockopt - .word sys_listen, sunos_nosys, sunos_sigaction + .word sunos_nosys, sys32_bind, sunos_setsockopt + .word sys32_listen, sunos_nosys, sunos_sigaction .word sunos_sigblock, sunos_sigsetmask, sys_sigpause - .word sys32_sigstack, compat_sys_recvmsg, compat_sys_sendmsg + .word sys32_sigstack, sys32_recvmsg, sys32_sendmsg .word sunos_nosys, sys32_gettimeofday, compat_sys_getrusage .word sunos_getsockopt, sunos_nosys, sunos_readv .word sunos_writev, sys32_settimeofday, sys32_fchown16 .word sys_fchmod, sys32_recvfrom, sys32_setreuid16 .word sys32_setregid16, sys_rename, sys_truncate .word sys_ftruncate, sys_flock, sunos_nosys - .word sys32_sendto, sys_shutdown, sys_socketpair + .word sys32_sendto, sys32_shutdown, sys32_socketpair .word sys_mkdir, sys_rmdir, sys32_utimes - .word sys32_sigreturn, sunos_nosys, sys_getpeername + .word sys32_sigreturn, sunos_nosys, sys32_getpeername .word sunos_gethostid, sunos_nosys, compat_sys_getrlimit .word compat_sys_setrlimit, sunos_killpg, sunos_nosys .word sunos_nosys, sunos_nosys -/*150*/ .word sys_getsockname, sunos_nosys, sunos_nosys +/*150*/ .word sys32_getsockname, sunos_nosys, sunos_nosys .word sys_poll, sunos_nosys, sunos_nosys .word sunos_getdirentries, compat_sys_statfs, compat_sys_fstatfs .word sys_oldumount, sunos_nosys, sunos_nosys diff --git a/arch/x86_64/ia32/fpu32.c b/arch/x86_64/ia32/fpu32.c index f9a2638c8..c6d0b02a1 100644 --- a/arch/x86_64/ia32/fpu32.c +++ b/arch/x86_64/ia32/fpu32.c @@ -72,15 +72,15 @@ static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave) static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave, - struct _fpstate_ia32 __user *buf) + struct _fpstate_ia32 *buf) { struct _fpxreg *to; - struct _fpreg __user *from; + struct _fpreg *from; int i; u32 v; int err = 0; -#define G(num,val) err |= __get_user(val, num + (u32 __user *)buf) +#define G(num,val) err |= __get_user(val, num + (u32 *)buf) G(0, fxsave->cwd); G(1, fxsave->swd); G(2, fxsave->twd); @@ -104,12 +104,12 @@ static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave, } -static inline int convert_fxsr_to_user(struct _fpstate_ia32 __user *buf, +static inline int convert_fxsr_to_user(struct _fpstate_ia32 *buf, struct i387_fxsave_struct *fxsave, struct pt_regs *regs, struct task_struct *tsk) { - struct _fpreg __user *to; + struct _fpreg *to; struct _fpxreg *from; int i; u16 cs,ds; @@ -125,7 +125,7 @@ static inline int convert_fxsr_to_user(struct _fpstate_ia32 __user *buf, cs = regs->cs; } -#define P(num,val) err |= __put_user(val, num + (u32 __user *)buf) +#define P(num,val) err |= __put_user(val, num + (u32 *)buf) P(0, (u32)fxsave->cwd | 0xffff0000); P(1, (u32)fxsave->swd | 0xffff0000); P(2, twd_fxsr_to_i387(fxsave)); @@ -147,7 +147,7 @@ static inline int convert_fxsr_to_user(struct _fpstate_ia32 __user *buf, return 0; } -int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave) +int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, int fsave) { clear_fpu(tsk); if (!fsave) { @@ -162,7 +162,7 @@ int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, } int save_i387_ia32(struct task_struct *tsk, - struct _fpstate_ia32 __user *buf, + struct _fpstate_ia32 *buf, struct pt_regs *regs, int fsave) { diff --git a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c index 8c6964245..d39795746 100644 --- a/arch/x86_64/ia32/ia32_ioctl.c +++ b/arch/x86_64/ia32/ia32_ioctl.c @@ -21,7 +21,7 @@ #ifndef TIOCGDEV #define TIOCGDEV _IOR('T',0x32, unsigned int) #endif -static int tiocgdev(unsigned fd, unsigned cmd, unsigned int __user *ptr) +static int tiocgdev(unsigned fd, unsigned cmd, unsigned int *ptr) { struct file *file = fget(fd); @@ -54,7 +54,7 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg) ret = sys_ioctl(fd, RTC_IRQP_READ, (unsigned long)&val); set_fs(oldfs); if (!ret) - ret = put_user(val, (unsigned int __user *) arg); + ret = put_user(val, (unsigned int*) arg); return ret; case RTC_IRQP_SET32: @@ -66,7 +66,7 @@ static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg) ret = sys_ioctl(fd, RTC_EPOCH_READ, (unsigned long) &val); set_fs(oldfs); if (!ret) - ret = put_user(val, (unsigned int __user *) arg); + ret = put_user(val, (unsigned int*) arg); return ret; case RTC_EPOCH_SET32: @@ -113,7 +113,7 @@ static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg) struct mtrr_gentry g; struct mtrr_sentry s; int get = 0, err = 0; - struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)arg; + struct mtrr_gentry32 *g32 = (struct mtrr_gentry32 *)arg; mm_segment_t oldfs = get_fs(); switch (cmd) { @@ -139,7 +139,7 @@ static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg) arg = (unsigned long)&g; } else { - struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)arg; + struct mtrr_sentry32 *s32 = (struct mtrr_sentry32 *)arg; err = get_user(s.base, &s32->base); err |= get_user(s.size, &s32->size); err |= get_user(s.type, &s32->type); diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c index 2fe68d976..7e95c0a6e 100644 --- a/arch/x86_64/ia32/ia32_signal.c +++ b/arch/x86_64/ia32/ia32_signal.c @@ -42,7 +42,7 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); -void signal_fault(struct pt_regs *regs, void __user *frame, char *where); +void signal_fault(struct pt_regs *regs, void *frame, char *where); int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from) { @@ -136,9 +136,8 @@ sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs r } asmlinkage long -sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, - stack_ia32_t __user *uoss_ptr, - struct pt_regs regs) +sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr, + struct pt_regs regs) { stack_t uss,uoss; int ret; @@ -194,7 +193,7 @@ struct rt_sigframe }; static int -ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc, unsigned int *peax) +ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned int *peax) { unsigned int err = 0; @@ -253,9 +252,9 @@ ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc, { u32 tmp; - struct _fpstate_ia32 __user * buf; + struct _fpstate_ia32 * buf; err |= __get_user(tmp, &sc->fpstate); - buf = compat_ptr(tmp); + buf = (struct _fpstate_ia32 *) (u64)tmp; if (buf) { if (verify_area(VERIFY_READ, buf, sizeof(*buf))) goto badframe; @@ -276,7 +275,7 @@ badframe: asmlinkage long sys32_sigreturn(struct pt_regs regs) { - struct sigframe __user *frame = (struct sigframe __user *)(regs.rsp-8); + struct sigframe *frame = (struct sigframe *)(regs.rsp - 8); sigset_t set; unsigned int eax; @@ -305,8 +304,9 @@ badframe: asmlinkage long sys32_rt_sigreturn(struct pt_regs regs) { - struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(regs.rsp - 4); + struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4); sigset_t set; + stack_t st; unsigned int eax; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) @@ -338,20 +338,20 @@ badframe: */ static int -ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate, +ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate, struct pt_regs *regs, unsigned int mask) { int tmp, err = 0; tmp = 0; __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp)); - err |= __put_user(tmp, (unsigned int __user *)&sc->gs); + err |= __put_user(tmp, (unsigned int *)&sc->gs); __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp)); - err |= __put_user(tmp, (unsigned int __user *)&sc->fs); + err |= __put_user(tmp, (unsigned int *)&sc->fs); __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp)); - err |= __put_user(tmp, (unsigned int __user *)&sc->ds); + err |= __put_user(tmp, (unsigned int *)&sc->ds); __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp)); - err |= __put_user(tmp, (unsigned int __user *)&sc->es); + err |= __put_user(tmp, (unsigned int *)&sc->es); err |= __put_user((u32)regs->rdi, &sc->edi); err |= __put_user((u32)regs->rsi, &sc->esi); @@ -388,7 +388,7 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __ /* * Determine which stack to use.. */ -static void __user * +static void * get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) { unsigned long rsp; @@ -409,13 +409,13 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) rsp = (unsigned long) ka->sa.sa_restorer; } - return (void __user *)((rsp - frame_size) & -8UL); + return (void *)((rsp - frame_size) & -8UL); } void ia32_setup_frame(int sig, struct k_sigaction *ka, compat_sigset_t *set, struct pt_regs * regs) { - struct sigframe __user *frame; + struct sigframe *frame; int err = 0; frame = get_sigframe(ka, regs, sizeof(*frame)); @@ -502,7 +502,7 @@ give_sigsegv: void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, compat_sigset_t *set, struct pt_regs * regs) { - struct rt_sigframe __user *frame; + struct rt_sigframe *frame; int err = 0; frame = get_sigframe(ka, regs, sizeof(*frame)); diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 4215e32bc..1b988918e 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -322,7 +322,7 @@ ia32_sys_call_table: .quad sys_mknod .quad sys_chmod /* 15 */ .quad sys_lchown16 - .quad quiet_ni_syscall /* old break syscall holder */ + .quad ni_syscall /* old break syscall holder */ .quad sys_stat .quad sys32_lseek .quad sys_getpid /* 20 */ @@ -336,11 +336,11 @@ ia32_sys_call_table: .quad sys_fstat /* (old)fstat */ .quad sys_pause .quad compat_sys_utime /* 30 */ - .quad quiet_ni_syscall /* old stty syscall holder */ - .quad quiet_ni_syscall /* old gtty syscall holder */ + .quad ni_syscall /* old stty syscall holder */ + .quad ni_syscall /* old gtty syscall holder */ .quad sys_access .quad sys_nice - .quad quiet_ni_syscall /* 35 */ /* old ftime syscall holder */ + .quad ni_syscall /* 35 */ /* old ftime syscall holder */ .quad sys_sync .quad sys32_kill .quad sys_rename @@ -349,7 +349,7 @@ ia32_sys_call_table: .quad sys_dup .quad sys32_pipe .quad compat_sys_times - .quad quiet_ni_syscall /* old prof syscall holder */ + .quad ni_syscall /* old prof syscall holder */ .quad sys_brk /* 45 */ .quad sys_setgid16 .quad sys_getgid16 @@ -358,12 +358,12 @@ ia32_sys_call_table: .quad sys_getegid16 /* 50 */ .quad sys_acct .quad sys_umount /* new_umount */ - .quad quiet_ni_syscall /* old lock syscall holder */ + .quad ni_syscall /* old lock syscall holder */ .quad compat_sys_ioctl .quad compat_sys_fcntl64 /* 55 */ - .quad quiet_ni_syscall /* old mpx syscall holder */ + .quad ni_syscall /* old mpx syscall holder */ .quad sys_setpgid - .quad quiet_ni_syscall /* old ulimit syscall holder */ + .quad ni_syscall /* old ulimit syscall holder */ .quad sys32_olduname .quad sys_umask /* 60 */ .quad sys_chroot @@ -403,7 +403,7 @@ ia32_sys_call_table: .quad sys_fchown16 /* 95 */ .quad sys_getpriority .quad sys_setpriority - .quad quiet_ni_syscall /* old profil syscall holder */ + .quad ni_syscall /* old profil syscall holder */ .quad compat_sys_statfs .quad compat_sys_fstatfs /* 100 */ .quad sys_ioperm @@ -417,7 +417,7 @@ ia32_sys_call_table: .quad sys32_uname .quad stub32_iopl /* 110 */ .quad sys_vhangup - .quad quiet_ni_syscall /* old "idle" system call */ + .quad ni_syscall /* old "idle" system call */ .quad sys32_vm86_warning /* vm86old */ .quad compat_sys_wait4 .quad sys_swapoff /* 115 */ @@ -442,7 +442,7 @@ ia32_sys_call_table: .quad quiet_ni_syscall /* bdflush */ .quad sys_sysfs /* 135 */ .quad sys_personality - .quad quiet_ni_syscall /* for afs_syscall */ + .quad ni_syscall /* for afs_syscall */ .quad sys_setfsuid16 .quad sys_setfsgid16 .quad sys_llseek /* 140 */ @@ -493,8 +493,8 @@ ia32_sys_call_table: .quad sys_capset .quad stub32_sigaltstack .quad sys32_sendfile - .quad quiet_ni_syscall /* streams1 */ - .quad quiet_ni_syscall /* streams2 */ + .quad ni_syscall /* streams1 */ + .quad ni_syscall /* streams2 */ .quad stub32_vfork /* 190 */ .quad compat_sys_getrlimit .quad sys32_mmap2 @@ -543,52 +543,51 @@ ia32_sys_call_table: .quad sys_removexattr /* 235 */ .quad sys_lremovexattr .quad sys_fremovexattr - .quad sys_tkill + .quad sys_tkill /* 238 */ .quad sys_sendfile64 .quad compat_sys_futex /* 240 */ - .quad compat_sys_sched_setaffinity - .quad compat_sys_sched_getaffinity + .quad compat_sys_sched_setaffinity + .quad compat_sys_sched_getaffinity .quad sys32_set_thread_area .quad sys32_get_thread_area - .quad sys32_io_setup /* 245 */ + .quad sys32_io_setup .quad sys_io_destroy .quad sys32_io_getevents .quad sys32_io_submit .quad sys_io_cancel - .quad sys_fadvise64 /* 250 */ - .quad quiet_ni_syscall /* free_huge_pages */ - .quad sys_exit_group + .quad sys_fadvise64 + .quad quiet_ni_syscall /* free_huge_pages */ + .quad sys_exit_group /* exit_group */ .quad sys_lookup_dcookie .quad sys_epoll_create - .quad sys_epoll_ctl /* 255 */ + .quad sys_epoll_ctl .quad sys_epoll_wait .quad sys_remap_file_pages .quad sys_set_tid_address .quad sys32_timer_create - .quad compat_timer_settime /* 260 */ + .quad compat_timer_settime .quad compat_timer_gettime .quad sys_timer_getoverrun .quad sys_timer_delete .quad compat_clock_settime - .quad compat_clock_gettime /* 265 */ + .quad compat_clock_gettime .quad compat_clock_getres .quad compat_clock_nanosleep - .quad compat_statfs64 - .quad compat_fstatfs64 - .quad sys_tgkill /* 270 */ + .quad compat_statfs64 /* statfs64 */ + .quad compat_fstatfs64 /* fstatfs64 */ + .quad sys_tgkill .quad compat_sys_utimes .quad sys32_fadvise64_64 - .quad quiet_ni_syscall /* sys_vserver */ - .quad sys_mbind - .quad quiet_ni_syscall /* 275 */ - .quad sys_set_mempolicy + .quad sys_ni_syscall /* sys_vserver */ + .quad sys_ni_syscall /* sys_mbind */ + .quad sys_ni_syscall /* 275 sys_get_mempolicy */ + .quad sys_ni_syscall /* sys_set_mempolicy */ .quad compat_sys_mq_open .quad sys_mq_unlink .quad compat_sys_mq_timedsend .quad compat_sys_mq_timedreceive /* 280 */ .quad compat_sys_mq_notify .quad compat_sys_mq_getsetattr - .quad quiet_ni_syscall /* reserved for kexec */ /* don't forget to change IA32_NR_syscalls */ ia32_syscall_end: .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c index 01202b792..c2ef94295 100644 --- a/arch/x86_64/ia32/ptrace32.c +++ b/arch/x86_64/ia32/ptrace32.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -229,7 +228,6 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) { struct task_struct *child; struct pt_regs *childregs; - void __user *datap = compat_ptr(data); int ret; __u32 val; @@ -266,7 +264,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) if (access_process_vm(child, addr, &val, sizeof(u32), 0)!=sizeof(u32)) ret = -EIO; else - ret = put_user(val, (unsigned int __user *)datap); + ret = put_user(val, (unsigned int *)(u64)data); break; case PTRACE_POKEDATA: @@ -279,7 +277,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_PEEKUSR: ret = getreg32(child, addr, &val); if (ret == 0) - ret = put_user(val, (__u32 __user *)datap); + ret = put_user(val, (__u32 *)(unsigned long) data); break; case PTRACE_POKEUSR: @@ -288,15 +286,15 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_GETREGS: { /* Get all gp regs from the child. */ int i; - if (!access_ok(VERIFY_WRITE, datap, 16*4)) { + if (!access_ok(VERIFY_WRITE, (unsigned *)(unsigned long)data, 16*4)) { ret = -EIO; break; } ret = 0; for ( i = 0; i <= 16*4 ; i += sizeof(__u32) ) { getreg32(child, i, &val); - ret |= __put_user(val,(u32 __user *)datap); - datap += sizeof(u32); + ret |= __put_user(val,(u32 *) (unsigned long) data); + data += sizeof(u32); } break; } @@ -304,40 +302,40 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_SETREGS: { /* Set all gp regs in the child. */ unsigned long tmp; int i; - if (!access_ok(VERIFY_READ, datap, 16*4)) { + if (!access_ok(VERIFY_READ, (unsigned *)(unsigned long)data, 16*4)) { ret = -EIO; break; } ret = 0; for ( i = 0; i <= 16*4; i += sizeof(u32) ) { - ret |= __get_user(tmp, (u32 __user *)datap); + ret |= __get_user(tmp, (u32 *) (unsigned long) data); putreg32(child, i, tmp); - datap += sizeof(u32); + data += sizeof(u32); } break; } case PTRACE_GETFPREGS: ret = -EIO; - if (!access_ok(VERIFY_READ, compat_ptr(data), + if (!access_ok(VERIFY_READ, (void *)(u64)data, sizeof(struct user_i387_struct))) break; - save_i387_ia32(child, datap, childregs, 1); + save_i387_ia32(child, (void *)(u64)data, childregs, 1); ret = 0; break; case PTRACE_SETFPREGS: ret = -EIO; - if (!access_ok(VERIFY_WRITE, datap, + if (!access_ok(VERIFY_WRITE, (void *)(u64)data, sizeof(struct user_i387_struct))) break; ret = 0; /* don't check EFAULT to be bug-to-bug compatible to i386 */ - restore_i387_ia32(child, datap, 1); + restore_i387_ia32(child, (void *)(u64)data, 1); break; case PTRACE_GETFPXREGS: { - struct user32_fxsr_struct __user *u = datap; + struct user32_fxsr_struct *u = (void *)(u64)data; init_fpu(child); ret = -EIO; if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) @@ -350,7 +348,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) break; } case PTRACE_SETFPXREGS: { - struct user32_fxsr_struct __user *u = datap; + struct user32_fxsr_struct *u = (void *)(u64)data; unlazy_fpu(child); ret = -EIO; if (!access_ok(VERIFY_READ, u, sizeof(*u))) diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index af5f3218a..465476e09 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c @@ -76,9 +76,9 @@ #define A(__x) ((unsigned long)(__x)) #define AA(__x) ((unsigned long)(__x)) #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) -#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) +#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) -int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) +int cp_compat_stat(struct kstat *kbuf, struct compat_stat *ubuf) { typeof(ubuf->st_uid) uid = 0; typeof(ubuf->st_gid) gid = 0; @@ -110,7 +110,7 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) } asmlinkage long -sys32_truncate64(char __user * filename, unsigned long offset_low, unsigned long offset_high) +sys32_truncate64(char * filename, unsigned long offset_low, unsigned long offset_high) { return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low); } @@ -125,7 +125,7 @@ sys32_ftruncate64(unsigned int fd, unsigned long offset_low, unsigned long offse support for 64bit inode numbers. */ static int -cp_stat64(struct stat64 __user *ubuf, struct kstat *stat) +cp_stat64(struct stat64 *ubuf, struct kstat *stat) { typeof(ubuf->st_uid) uid = 0; typeof(ubuf->st_gid) gid = 0; @@ -154,7 +154,7 @@ cp_stat64(struct stat64 __user *ubuf, struct kstat *stat) } asmlinkage long -sys32_stat64(char __user * filename, struct stat64 __user *statbuf) +sys32_stat64(char * filename, struct stat64 *statbuf) { struct kstat stat; int ret = vfs_stat(filename, &stat); @@ -164,7 +164,7 @@ sys32_stat64(char __user * filename, struct stat64 __user *statbuf) } asmlinkage long -sys32_lstat64(char __user * filename, struct stat64 __user *statbuf) +sys32_lstat64(char * filename, struct stat64 *statbuf) { struct kstat stat; int ret = vfs_lstat(filename, &stat); @@ -174,7 +174,7 @@ sys32_lstat64(char __user * filename, struct stat64 __user *statbuf) } asmlinkage long -sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf) +sys32_fstat64(unsigned int fd, struct stat64 *statbuf) { struct kstat stat; int ret = vfs_fstat(fd, &stat); @@ -199,7 +199,7 @@ struct mmap_arg_struct { }; asmlinkage long -sys32_mmap(struct mmap_arg_struct __user *arg) +sys32_mmap(struct mmap_arg_struct *arg) { struct mmap_arg_struct a; struct file *file = NULL; @@ -241,7 +241,7 @@ sys32_mprotect(unsigned long start, size_t len, unsigned long prot) } asmlinkage long -sys32_pipe(int __user *fd) +sys32_pipe(int *fd) { int retval; int fds[2]; @@ -256,8 +256,8 @@ sys32_pipe(int __user *fd) } asmlinkage long -sys32_rt_sigaction(int sig, struct sigaction32 __user *act, - struct sigaction32 __user *oact, unsigned int sigsetsize) +sys32_rt_sigaction(int sig, struct sigaction32 *act, + struct sigaction32 *oact, unsigned int sigsetsize) { struct k_sigaction new_ka, old_ka; int ret; @@ -321,7 +321,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act, } asmlinkage long -sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact) +sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -395,7 +395,7 @@ sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, } static inline long -get_tv32(struct timeval *o, struct compat_timeval __user *i) +get_tv32(struct timeval *o, struct compat_timeval *i) { int err = -EFAULT; if (access_ok(VERIFY_READ, i, sizeof(*i))) { @@ -406,7 +406,7 @@ get_tv32(struct timeval *o, struct compat_timeval __user *i) } static inline long -put_tv32(struct compat_timeval __user *o, struct timeval *i) +put_tv32(struct compat_timeval *o, struct timeval *i) { int err = -EFAULT; if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { @@ -442,7 +442,7 @@ sys32_alarm(unsigned int seconds) extern struct timezone sys_tz; asmlinkage long -sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) { if (tv) { struct timeval ktv; @@ -458,7 +458,7 @@ sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) } asmlinkage long -sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) +sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) { struct timeval ktv; struct timespec kts; @@ -493,14 +493,14 @@ struct old_linux32_dirent { }; struct getdents32_callback { - struct linux32_dirent __user * current_dir; - struct linux32_dirent __user * previous; + struct linux32_dirent * current_dir; + struct linux32_dirent * previous; int count; int error; }; struct readdir32_callback { - struct old_linux32_dirent __user * dirent; + struct old_linux32_dirent * dirent; int count; }; @@ -508,7 +508,7 @@ static int filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, unsigned int d_type) { - struct linux32_dirent __user * dirent; + struct linux32_dirent * dirent; struct getdents32_callback * buf = (struct getdents32_callback *) __buf; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2, 4); @@ -524,18 +524,18 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, put_user(reclen, &dirent->d_reclen); copy_to_user(dirent->d_name, name, namlen); put_user(0, dirent->d_name + namlen); - put_user(d_type, (char __user *)dirent + reclen - 1); - dirent = ((void __user *)dirent) + reclen; + put_user(d_type, (char *)dirent + reclen - 1); + dirent = ((void *)dirent) + reclen; buf->current_dir = dirent; buf->count -= reclen; return 0; } asmlinkage long -sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) +sys32_getdents (unsigned int fd, void * dirent, unsigned int count) { struct file * file; - struct linux32_dirent __user * lastdirent; + struct linux32_dirent * lastdirent; struct getdents32_callback buf; int error; @@ -544,7 +544,7 @@ sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) if (!file) goto out; - buf.current_dir = (struct linux32_dirent __user *) dirent; + buf.current_dir = (struct linux32_dirent *) dirent; buf.previous = NULL; buf.count = count; buf.error = 0; @@ -569,7 +569,7 @@ static int fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned d_type) { struct readdir32_callback * buf = (struct readdir32_callback *) __buf; - struct old_linux32_dirent __user * dirent; + struct old_linux32_dirent * dirent; if (buf->count) return -EINVAL; @@ -584,7 +584,7 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t } asmlinkage long -sys32_oldreaddir (unsigned int fd, void __user * dirent, unsigned int count) +sys32_oldreaddir (unsigned int fd, void * dirent, unsigned int count) { int error; struct file * file; @@ -615,7 +615,7 @@ struct sel_arg_struct { }; asmlinkage long -sys32_old_select(struct sel_arg_struct __user *arg) +sys32_old_select(struct sel_arg_struct *arg) { struct sel_arg_struct a; @@ -630,7 +630,7 @@ sys32_old_select(struct sel_arg_struct __user *arg) * sys_gettimeofday(). x86-64 did this but i386 Linux did not * so we have to implement this system call here. */ -asmlinkage long sys32_time(int __user * tloc) +asmlinkage long sys32_time(int * tloc) { int i; struct timeval tv; @@ -693,7 +693,7 @@ struct sysinfo32 { }; asmlinkage long -sys32_sysinfo(struct sysinfo32 __user *info) +sys32_sysinfo(struct sysinfo32 *info) { struct sysinfo s; int ret; @@ -742,7 +742,7 @@ sys32_sysinfo(struct sysinfo32 __user *info) } asmlinkage long -sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) +sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec *interval) { struct timespec t; int ret; @@ -782,8 +782,8 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) asmlinkage long -sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo, - struct compat_timespec __user *uts, compat_size_t sigsetsize) +sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo, + struct compat_timespec *uts, compat_size_t sigsetsize) { sigset_t s; compat_sigset_t s32; @@ -820,7 +820,7 @@ sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo, } asmlinkage long -sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo) +sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo) { siginfo_t info; int ret; @@ -856,7 +856,7 @@ struct sysctl_ia32 { asmlinkage long -sys32_sysctl(struct sysctl_ia32 __user *args32) +sys32_sysctl(struct sysctl_ia32 *args32) { #ifndef CONFIG_SYSCTL return -ENOSYS; @@ -906,14 +906,14 @@ sys32_sysctl(struct sysctl_ia32 __user *args32) /* warning: next two assume little endian */ asmlinkage long -sys32_pread(unsigned int fd, char __user *ubuf, u32 count, u32 poslo, u32 poshi) +sys32_pread(unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi) { return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); } asmlinkage long -sys32_pwrite(unsigned int fd, char __user *ubuf, u32 count, u32 poslo, u32 poshi) +sys32_pwrite(unsigned int fd, char *ubuf, u32 count, u32 poslo, u32 poshi) { return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); @@ -934,7 +934,7 @@ sys32_personality(unsigned long personality) } asmlinkage long -sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) +sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count) { mm_segment_t old_fs = get_fs(); int ret; @@ -971,7 +971,7 @@ struct timex32 { extern int do_adjtimex(struct timex *); asmlinkage long -sys32_adjtimex(struct timex32 __user *utp) +sys32_adjtimex(struct timex32 *utp) { struct timex txc; int ret; @@ -1056,7 +1056,7 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, return error; } -asmlinkage long sys32_olduname(struct oldold_utsname __user * name) +asmlinkage long sys32_olduname(struct oldold_utsname * name) { int error; @@ -1090,7 +1090,7 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name) return error; } -long sys32_uname(struct old_utsname __user * name) +long sys32_uname(struct old_utsname * name) { int err; if (!name) @@ -1124,7 +1124,7 @@ long sys32_ustat(unsigned dev, struct ustat32 __user *u32p) return ret; } -asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv, +asmlinkage long sys32_execve(char *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp, struct pt_regs regs) { long error; @@ -1143,8 +1143,8 @@ asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv, asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs) { - void __user *parent_tid = (void __user *)regs.rdx; - void __user *child_tid = (void __user *)regs.rdi; + void *parent_tid = (void *)regs.rdx; + void *child_tid = (void *)regs.rdi; if (!newsp) newsp = regs.rsp; return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, @@ -1166,7 +1166,7 @@ long sys32_kill(int pid, int sig) } -long sys32_io_setup(unsigned nr_reqs, u32 __user *ctx32p) +long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p) { long ret; aio_context_t ctx64; @@ -1181,7 +1181,7 @@ long sys32_io_setup(unsigned nr_reqs, u32 __user *ctx32p) } asmlinkage long sys32_io_submit(aio_context_t ctx_id, int nr, - compat_uptr_t __user *iocbpp) + compat_uptr_t *iocbpp) { struct kioctx *ctx; long ret = 0; @@ -1201,8 +1201,7 @@ asmlinkage long sys32_io_submit(aio_context_t ctx_id, int nr, for (i=0; i 32bit use arch_prctl() */ -int do_set_thread_area(struct thread_struct *t, struct user_desc __user *u_info) +int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info) { struct user_desc info; struct n_desc_struct *desc; @@ -75,7 +75,7 @@ int do_set_thread_area(struct thread_struct *t, struct user_desc __user *u_info) return 0; } -asmlinkage long sys32_set_thread_area(struct user_desc __user *u_info) +asmlinkage long sys32_set_thread_area(struct user_desc *u_info) { return do_set_thread_area(¤t->thread, u_info); } @@ -102,7 +102,7 @@ asmlinkage long sys32_set_thread_area(struct user_desc __user *u_info) #define GET_USEABLE(desc) (((desc)->b >> 20) & 1) #define GET_LONGMODE(desc) (((desc)->b >> 21) & 1) -int do_get_thread_area(struct thread_struct *t, struct user_desc __user *u_info) +int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info) { struct user_desc info; struct n_desc_struct *desc; @@ -132,7 +132,7 @@ int do_get_thread_area(struct thread_struct *t, struct user_desc __user *u_info) return 0; } -asmlinkage long sys32_get_thread_area(struct user_desc __user *u_info) +asmlinkage long sys32_get_thread_area(struct user_desc *u_info) { return do_get_thread_area(¤t->thread, u_info); } @@ -141,11 +141,10 @@ asmlinkage long sys32_get_thread_area(struct user_desc __user *u_info) int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs) { struct n_desc_struct *desc; - struct user_desc info; - struct user_desc __user *cp; + struct user_desc info, *cp; int idx; - cp = (void __user *)childregs->rsi; + cp = (void *)childregs->rsi; if (copy_from_user(&info, cp, sizeof(info))) return -EFAULT; if (LDT_empty(&info)) diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c index 73ddfc1ea..20e9266df 100644 --- a/arch/x86_64/kernel/acpi/sleep.c +++ b/arch/x86_64/kernel/acpi/sleep.c @@ -114,7 +114,7 @@ void __init acpi_reserve_bootmem(void) acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); - Dprintk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); + printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address); } static int __init acpi_sleep_setup(char *str) diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 23acf2fbd..23a2b5e02 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S @@ -255,7 +255,7 @@ temp_boot_pmds: .org 0x5000 ENTRY(level2_kernel_pgt) - /* 10MB kernel mapping. The kernel code cannot be bigger than that. + /* 40MB kernel mapping. The kernel code cannot be bigger than that. When you change this change KERNEL_TEXT_SIZE in page.h too. */ /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ .quad 0x0000000000000183 @@ -263,8 +263,21 @@ ENTRY(level2_kernel_pgt) .quad 0x0000000000400183 .quad 0x0000000000600183 .quad 0x0000000000800183 - /* 10MB mapping for now to decrease the aliasing window */ - .fill 15,8,0 + .quad 0x0000000000A00183 + .quad 0x0000000000C00183 + .quad 0x0000000000E00183 + .quad 0x0000000001000183 + .quad 0x0000000001200183 + .quad 0x0000000001400183 + .quad 0x0000000001600183 + .quad 0x0000000001800183 + .quad 0x0000000001A00183 + .quad 0x0000000001C00183 + .quad 0x0000000001E00183 + .quad 0x0000000002000183 + .quad 0x0000000002200183 + .quad 0x0000000002400183 + .quad 0x0000000002600183 /* Module mapping starts here */ .fill 492,8,0 diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index 4055c78d2..b04a1add2 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c @@ -73,8 +73,6 @@ static void __init setup_boot_cpu_data(void) boot_cpu_data.x86_mask = eax & 0xf; } -extern char _end[]; - void __init x86_64_start_kernel(char * real_mode_data) { char *s; @@ -82,9 +80,6 @@ void __init x86_64_start_kernel(char * real_mode_data) clear_bss(); pda_init(0); copy_bootdata(real_mode_data); -#ifdef CONFIG_SMP - cpu_set(0, cpu_online_map); -#endif /* default console: */ if (!strstr(saved_command_line, "console=")) strcat(saved_command_line, " console=tty0"); @@ -100,10 +95,6 @@ void __init x86_64_start_kernel(char * real_mode_data) if (strstr(saved_command_line, "disableapic")) disable_apic = 1; #endif - /* You need early console to see that */ - if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE) - panic("Kernel too big for kernel mapping\n"); - setup_boot_cpu_data(); start_kernel(); } diff --git a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c index 6bc3d64e0..1aa4deb43 100644 --- a/arch/x86_64/kernel/i387.c +++ b/arch/x86_64/kernel/i387.c @@ -77,7 +77,7 @@ void init_fpu(struct task_struct *child) * Signal frame handlers. */ -int save_i387(struct _fpstate __user *buf) +int save_i387(struct _fpstate *buf) { struct task_struct *tsk = current; int err = 0; @@ -95,7 +95,7 @@ int save_i387(struct _fpstate __user *buf) return 0; tsk->used_math = 0; /* trigger finit */ if (tsk->thread_info->status & TS_USEDFPU) { - err = save_i387_checking((struct i387_fxsave_struct __user *)buf); + err = save_i387_checking((struct i387_fxsave_struct *)buf); if (err) return err; stts(); } else { @@ -110,14 +110,14 @@ int save_i387(struct _fpstate __user *buf) * ptrace request handlers. */ -int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *tsk) +int get_fpregs(struct user_i387_struct *buf, struct task_struct *tsk) { init_fpu(tsk); - return __copy_to_user(buf, &tsk->thread.i387.fxsave, + return __copy_to_user((void *)buf, &tsk->thread.i387.fxsave, sizeof(struct user_i387_struct)) ? -EFAULT : 0; } -int set_fpregs(struct task_struct *tsk, struct user_i387_struct __user *buf) +int set_fpregs(struct task_struct *tsk, struct user_i387_struct *buf) { if (__copy_from_user(&tsk->thread.i387.fxsave, buf, sizeof(struct user_i387_struct))) diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index bfdb95e8b..732a6f4d3 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c @@ -833,8 +833,7 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, return len; } -static int irq_affinity_write_proc (struct file *file, - const char __user *buffer, +static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { int irq = (long) data, full_count = count, err; @@ -872,8 +871,7 @@ static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, return len; } -static int prof_cpu_mask_write_proc (struct file *file, - const char __user *buffer, +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { unsigned long full_count = count, err; diff --git a/arch/x86_64/kernel/ldt.c b/arch/x86_64/kernel/ldt.c index 4e43e53a1..1b6252c09 100644 --- a/arch/x86_64/kernel/ldt.c +++ b/arch/x86_64/kernel/ldt.c @@ -125,7 +125,7 @@ void destroy_context(struct mm_struct *mm) } } -static int read_ldt(void __user * ptr, unsigned long bytecount) +static int read_ldt(void * ptr, unsigned long bytecount) { int err; unsigned long size; @@ -153,7 +153,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount) return bytecount; } -static int read_default_ldt(void __user * ptr, unsigned long bytecount) +static int read_default_ldt(void * ptr, unsigned long bytecount) { /* Arbitrary number */ /* x86-64 default LDT is all zeros */ @@ -164,7 +164,7 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount) return bytecount; } -static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode) +static int write_ldt(void * ptr, unsigned long bytecount, int oldmode) { struct task_struct *me = current; struct mm_struct * mm = me->mm; @@ -225,7 +225,7 @@ out: return error; } -asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) +asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount) { int ret = -ENOSYS; diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index a34ef6c7b..922d62fcf 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c @@ -26,7 +26,7 @@ static int mce_disabled __initdata; /* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic */ -static int tolerant = 1; +static int tolerant = 2; static int banks; static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL }; @@ -96,8 +96,7 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start) int i; oops_begin(); for (i = 0; i < MCE_LOG_LEN; i++) { - unsigned long tsc = mcelog.entry[i].tsc; - if (time_before(tsc, start)) + if (mcelog.entry[i].tsc < start) continue; print_mce(&mcelog.entry[i]); if (mcelog.entry[i].tsc == backup->tsc) @@ -121,8 +120,8 @@ static int mce_available(struct cpuinfo_x86 *c) void do_machine_check(struct pt_regs * regs, long error_code) { - struct mce m, panicm; - int nowayout = (tolerant < 1); + struct mce m; + int nowayout = 0; int kill_it = 0; u64 mcestart; int i; @@ -150,23 +149,12 @@ void do_machine_check(struct pt_regs * regs, long error_code) for (i = 0; i < banks; i++) { if (!bank[i]) continue; - - /* Did this bank cause the exception? */ - /* XXX: check more flags */ - if ((m.status & MCI_STATUS_PCC)) { - panicm = m; - } else { - m.rip = 0; - m.cs = 0; - } - - m.misc = 0; - m.addr = 0; rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status); if ((m.status & MCI_STATUS_VAL) == 0) continue; + nowayout |= (tolerant < 1); nowayout |= !!(m.status & (MCI_STATUS_OVER|MCI_STATUS_PCC)); kill_it |= !!(m.status & MCI_STATUS_UC); m.bank = i; @@ -188,10 +176,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) if (nowayout) mce_panic("Machine check", &m, mcestart); if (kill_it) { - int user_space = 0; - - if (m.mcgstatus & MCG_STATUS_RIPV) - user_space = m.rip && (m.cs & 3); + int user_space = (m.rip && (m.cs & 3)); /* When the machine was in user space and the CPU didn't get confused it's normally not necessary to panic, unless you @@ -202,7 +187,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) it is best to just halt the machine. */ if ((!user_space && (panic_on_oops || tolerant < 2)) || (unsigned)current->pid <= 1) - mce_panic("Uncorrected machine check", &panicm, mcestart); + mce_panic("Uncorrected machine check", &m, mcestart); /* do_exit takes an awful lot of locks and has as slight risk of deadlocking. If you don't want that don't set tolerant >= 2 */ @@ -222,7 +207,7 @@ static void mce_clear_all(void) * Periodic polling timer for "silent" machine check errors. */ -static int check_interval = 5 * 60; /* 5 minutes */ +static int check_interval = 3600; /* one hour */ static void mcheck_timer(void *data); static DECLARE_WORK(mcheck_work, mcheck_timer, NULL); @@ -312,12 +297,12 @@ static void collect_tscs(void *data) rdtscll(cpu_tsc[smp_processor_id()]); } -static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff_t *off) +static ssize_t mce_read(struct file *filp, char *ubuf, size_t usize, loff_t *off) { unsigned long cpu_tsc[NR_CPUS]; static DECLARE_MUTEX(mce_read_sem); unsigned next; - char __user *buf = ubuf; + char *buf = ubuf; int i, err; down(&mce_read_sem); @@ -363,20 +348,19 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, unsigned long arg) { - int __user *p = (int __user *)arg; if (!capable(CAP_SYS_ADMIN)) return -EPERM; switch (cmd) { case MCE_GET_RECORD_LEN: - return put_user(sizeof(struct mce), p); + return put_user(sizeof(struct mce), (int *)arg); case MCE_GET_LOG_LEN: - return put_user(MCE_LOG_LEN, p); + return put_user(MCE_LOG_LEN, (int *)arg); case MCE_GETCLEAR_FLAGS: { unsigned flags; do { flags = mcelog.flags; } while (cmpxchg(&mcelog.flags, flags, 0) != flags); - return put_user(flags, p); + return put_user(flags, (int *)arg); } default: return -ENOTTY; diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c index c2256e5ac..78ce354a5 100644 --- a/arch/x86_64/kernel/module.c +++ b/arch/x86_64/kernel/module.c @@ -121,7 +121,7 @@ void *module_alloc(unsigned long size) goto fail; } - if (map_vm_area(area, PAGE_KERNEL_EXECUTABLE, &pages)) + if (map_vm_area(area, PAGE_KERNEL_EXEC, &pages)) goto fail; memset(addr, 0, size); diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 7dcc1b51a..27122be57 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c @@ -575,7 +575,6 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) extern void __bad_mpf_size(void); unsigned int *bp = phys_to_virt(base); struct intel_mp_floating *mpf; - static int printed __initdata; Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length); if (sizeof(*mpf) != 16) @@ -599,10 +598,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) bp += 4; length -= 16; } - if (!printed) { - printk(KERN_INFO "No mptable found.\n"); - printed = 1; - } + printk(KERN_INFO "No mptable found.\n"); return 0; } diff --git a/arch/x86_64/kernel/msr.c b/arch/x86_64/kernel/msr.c index 654e4578d..d2e6fff1b 100644 --- a/arch/x86_64/kernel/msr.c +++ b/arch/x86_64/kernel/msr.c @@ -186,10 +186,10 @@ static loff_t msr_seek(struct file *file, loff_t offset, int orig) return ret; } -static ssize_t msr_read(struct file * file, char __user * buf, +static ssize_t msr_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - char __user *tmp = buf; + u32 *tmp = (u32 *)buf; u32 data[2]; size_t rv; u32 reg = *ppos; @@ -205,16 +205,16 @@ static ssize_t msr_read(struct file * file, char __user * buf, return err; if ( copy_to_user(tmp,&data,8) ) return -EFAULT; - tmp += 8; + tmp += 2; } - return tmp - buf; + return ((char *)tmp) - buf; } -static ssize_t msr_write(struct file * file, const char __user * buf, +static ssize_t msr_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { - const char __user *tmp = buf; + const u32 *tmp = (const u32 *)buf; u32 data[2]; size_t rv; u32 reg = *ppos; @@ -230,10 +230,10 @@ static ssize_t msr_write(struct file * file, const char __user * buf, err = do_wrmsr(cpu, reg, data[0], data[1]); if ( err ) return err; - tmp += 8; + tmp += 2; } - return tmp - buf; + return ((char *)tmp) - buf; } static int msr_open(struct inode *inode, struct file *file) @@ -241,7 +241,7 @@ static int msr_open(struct inode *inode, struct file *file) int cpu = iminor(file->f_dentry->d_inode); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; - if (cpu >= NR_CPUS || !cpu_online(cpu)) + if (!cpu_online(cpu)) return -ENXIO; /* No such CPU */ if ( !cpu_has(c, X86_FEATURE_MSR) ) return -EIO; /* MSR not supported */ diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index f7d3cf3ca..6b7861945 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -521,8 +521,7 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct * * sys_execve() executes a new program. */ asmlinkage -long sys_execve(char __user *name, char __user * __user *argv, - char __user * __user *envp, struct pt_regs regs) +long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs) { long error; char * filename; @@ -551,7 +550,7 @@ asmlinkage long sys_fork(struct pt_regs regs) return do_fork(SIGCHLD, regs.rsp, ®s, 0, NULL, NULL); } -asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void __user *parent_tid, void __user *child_tid, struct pt_regs regs) +asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void *parent_tid, void *child_tid, struct pt_regs regs) { if (!newsp) newsp = regs.rsp; @@ -665,7 +664,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) rdmsrl(MSR_FS_BASE, base); } else base = task->thread.fs; - ret = put_user(base, (unsigned long __user *)addr); + ret = put_user(base, (unsigned long *)addr); break; } case ARCH_GET_GS: { @@ -676,7 +675,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) rdmsrl(MSR_KERNEL_GS_BASE, base); } else base = task->thread.gs; - ret = put_user(base, (unsigned long __user *)addr); + ret = put_user(base, (unsigned long *)addr); break; } diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index 5dd7752ae..a97bee6f2 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c @@ -232,7 +232,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data ret = -EIO; if (copied != sizeof(tmp)) break; - ret = put_user(tmp,(unsigned long __user *) data); + ret = put_user(tmp,(unsigned long *) data); break; } @@ -271,7 +271,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data tmp = 0; break; } - ret = put_user(tmp,(unsigned long __user *) data); + ret = put_user(tmp,(unsigned long *) data); break; } @@ -360,20 +360,19 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data don't use it against 64bit processes, use PTRACE_ARCH_PRCTL instead. */ case PTRACE_SET_THREAD_AREA: { - struct user_desc __user *p; int old; - p = (struct user_desc __user *)data; - get_user(old, &p->entry_number); - put_user(addr, &p->entry_number); - ret = do_set_thread_area(&child->thread, p); - put_user(old, &p->entry_number); + get_user(old, &((struct user_desc *)data)->entry_number); + put_user(addr, &((struct user_desc *)data)->entry_number); + ret = do_set_thread_area(&child->thread, + (struct user_desc *)data); + put_user(old, &((struct user_desc *)data)->entry_number); break; case PTRACE_GET_THREAD_AREA: - p = (struct user_desc __user *)data; - get_user(old, &p->entry_number); - put_user(addr, &p->entry_number); - ret = do_get_thread_area(&child->thread, p); - put_user(old, &p->entry_number); + get_user(old, &((struct user_desc *)data)->entry_number); + put_user(addr, &((struct user_desc *)data)->entry_number); + ret = do_get_thread_area(&child->thread, + (struct user_desc *)data); + put_user(old, &((struct user_desc *)data)->entry_number); break; } #endif @@ -429,12 +428,12 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data break; case PTRACE_GETREGS: { /* Get all gp regs from the child. */ - if (!access_ok(VERIFY_WRITE, (unsigned __user *)data, FRAME_SIZE)) { + if (!access_ok(VERIFY_WRITE, (unsigned *)data, FRAME_SIZE)) { ret = -EIO; break; } for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) { - __put_user(getreg(child, ui),(unsigned long __user *) data); + __put_user(getreg(child, ui),(unsigned long *) data); data += sizeof(long); } ret = 0; @@ -443,12 +442,12 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data case PTRACE_SETREGS: { /* Set all gp regs in the child. */ unsigned long tmp; - if (!access_ok(VERIFY_READ, (unsigned __user *)data, FRAME_SIZE)) { + if (!access_ok(VERIFY_READ, (unsigned *)data, FRAME_SIZE)) { ret = -EIO; break; } for (ui = 0; ui < sizeof(struct user_regs_struct); ui += sizeof(long)) { - __get_user(tmp, (unsigned long __user *) data); + __get_user(tmp, (unsigned long *) data); putreg(child, ui, tmp); data += sizeof(long); } @@ -457,23 +456,23 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data } case PTRACE_GETFPREGS: { /* Get the child extended FPU state. */ - if (!access_ok(VERIFY_WRITE, (unsigned __user *)data, + if (!access_ok(VERIFY_WRITE, (unsigned *)data, sizeof(struct user_i387_struct))) { ret = -EIO; break; } - ret = get_fpregs((struct user_i387_struct __user *)data, child); + ret = get_fpregs((struct user_i387_struct *)data, child); break; } case PTRACE_SETFPREGS: { /* Set the child extended FPU state. */ - if (!access_ok(VERIFY_READ, (unsigned __user *)data, + if (!access_ok(VERIFY_READ, (unsigned *)data, sizeof(struct user_i387_struct))) { ret = -EIO; break; } child->used_math = 1; - ret = set_fpregs(child, (struct user_i387_struct __user *)data); + ret = set_fpregs(child, (struct user_i387_struct *)data); break; } diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index fb3a8abdb..09f9c7222 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -909,7 +909,7 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c) c->x86_model += ((tfms >> 16) & 0xF) << 4; } if (c->x86_capability[0] & (1<<19)) - c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; + c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; } else { /* Have CPUID level 0 only - unheard of */ c->x86 = 4; @@ -967,7 +967,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) display_cacheinfo(c); break; } - + select_idle_routine(c); detect_ht(c); diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 9d3137a55..dd0d41548 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c @@ -39,7 +39,7 @@ extern unsigned char __per_cpu_start[], __per_cpu_end[]; extern struct desc_ptr cpu_gdt_descr[]; struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; -char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); +char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned; unsigned long __supported_pte_mask = ~0UL; static int do_not_nx __initdata = 0; @@ -190,8 +190,7 @@ void pda_init(int cpu) pda->irqstackptr += IRQSTACKSIZE-64; } -char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ] -__attribute__((section(".bss.page_aligned"))); +char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ]; void __init syscall_init(void) { diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index d814db6e3..fc81ceb32 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c @@ -40,7 +40,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs); asmlinkage long -sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs regs) +sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs) { sigset_t saveset, newset; @@ -57,7 +57,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs re current->blocked = newset; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); -#ifdef DEBUG_SIG +#if DEBUG_SIG printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n", saveset, newset, ®s, regs.rip); #endif @@ -71,7 +71,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs re } asmlinkage long -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct pt_regs regs) +sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs regs) { return do_sigaltstack(uss, uoss, regs.rsp); } @@ -89,7 +89,7 @@ struct rt_sigframe }; static int -restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned long *prax) +restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, unsigned long *prax) { unsigned int err = 0; @@ -117,7 +117,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned } { - struct _fpstate __user * buf; + struct _fpstate * buf; err |= __get_user(buf, &sc->fpstate); if (buf) { @@ -136,11 +136,10 @@ badframe: asmlinkage long sys_rt_sigreturn(struct pt_regs regs) { - struct rt_sigframe __user *frame; + struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 8); sigset_t set; long eax; - frame = (struct rt_sigframe __user *)(regs.rsp - 8); if (verify_area(VERIFY_READ, frame, sizeof(*frame))) { goto badframe; } @@ -158,7 +157,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs regs) goto badframe; } -#ifdef DEBUG_SIG +#if DEBUG_SIG printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs.rip,regs.rsp,frame,eax); #endif @@ -177,7 +176,7 @@ badframe: */ static inline int -setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me) +setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me) { int err = 0; @@ -214,7 +213,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo * Determine which stack to use.. */ -static void __user * +static void * get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) { unsigned long rsp; @@ -229,20 +228,20 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) rsp = current->sas_ss_sp + current->sas_ss_size; } - return (void __user *)round_down(rsp - size, 16); + return (void *)round_down(rsp - size, 16); } static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs * regs) { - struct rt_sigframe __user *frame; - struct _fpstate __user *fp = NULL; + struct rt_sigframe *frame; + struct _fpstate *fp = NULL; int err = 0; struct task_struct *me = current; if (me->used_math) { fp = get_stack(ka, regs, sizeof(struct _fpstate)); - frame = (void __user *)round_down((u64)fp - sizeof(struct rt_sigframe), 16) - 8; + frame = (void *)round_down((u64)fp - sizeof(struct rt_sigframe), 16) - 8; if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) { goto give_sigsegv; @@ -295,7 +294,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, goto give_sigsegv; } -#ifdef DEBUG_SIG +#if DEBUG_SIG printk("%d old rip %lx old rsp %lx old rax %lx\n", current->pid,regs->rip,regs->rsp,regs->rax); #endif @@ -320,7 +319,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, set_fs(USER_DS); regs->eflags &= ~TF_MASK; -#ifdef DEBUG_SIG +#if DEBUG_SIG printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif @@ -343,7 +342,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, { struct k_sigaction *ka = ¤t->sighand->action[sig-1]; -#ifdef DEBUG_SIG +#if DEBUG_SIG printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", current->pid, sig, regs->rip, regs->rsp, regs); #endif @@ -455,7 +454,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_flags) { -#ifdef DEBUG_SIG +#if DEBUG_SIG printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n", thread_info_flags, regs->rip, regs->rsp, __builtin_return_address(0),signal_pending(current)); #endif @@ -471,7 +470,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_ do_signal(regs,oldset); } -void signal_fault(struct pt_regs *regs, void __user *frame, char *where) +void signal_fault(struct pt_regs *regs, void *frame, char *where) { struct task_struct *me = current; if (exception_trace) diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index ba2cba68d..3ea64ef6d 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -895,17 +895,15 @@ static void __init smp_boot_cpus(unsigned int max_cpus) cpu_set(i, cpu_sibling_map[cpu]); } } - } else { + } else { siblings++; cpu_set(cpu, cpu_sibling_map[cpu]); } - if (siblings != smp_num_siblings) { - printk(KERN_WARNING - "WARNING: %d siblings found for CPU%d, should be %d\n", + if (siblings != smp_num_siblings) + printk(KERN_WARNING + "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); - smp_num_siblings = siblings; - } } Dprintk("Boot done.\n"); diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c index 38a286ca3..e518c1f29 100644 --- a/arch/x86_64/kernel/sys_x86_64.c +++ b/arch/x86_64/kernel/sys_x86_64.c @@ -25,7 +25,7 @@ * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ -asmlinkage long sys_pipe(int __user *fildes) +asmlinkage long sys_pipe(int *fildes) { int fd[2]; int error; @@ -142,7 +142,7 @@ full_search: } } -asmlinkage long sys_uname(struct new_utsname __user * name) +asmlinkage long sys_uname(struct new_utsname * name) { int err; down_read(&uts_sem); @@ -153,13 +153,13 @@ asmlinkage long sys_uname(struct new_utsname __user * name) return err ? -EFAULT : 0; } -asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) +asmlinkage long wrap_sys_shmat(int shmid, char *shmaddr, int shmflg) { unsigned long raddr; return do_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr; } -asmlinkage long sys_time64(long __user * tloc) +asmlinkage long sys_time64(long * tloc) { struct timeval now; int i; diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 21383547b..c612e4d21 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -39,7 +39,6 @@ SECTIONS __bss_start = .; /* BSS */ .bss : { - *(.bss.page_aligned) *(.bss) } __bss_end = .; @@ -76,8 +75,8 @@ SECTIONS . = ALIGN(8192); /* init_task */ .data.init_task : { *(.data.init_task) } - . = ALIGN(4096); - .data.page_aligned : { *(.data.page_aligned) } + . = ALIGN(4096); + .data.boot_pgt : { *(.data.boot_pgt) } . = ALIGN(4096); /* Init code and data */ __init_begin = .; diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index 2b0d63924..a1f892b1e 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c @@ -219,3 +219,6 @@ EXPORT_SYMBOL_GPL(flush_tlb_all); #endif EXPORT_SYMBOL(sys_ioctl); + +EXPORT_SYMBOL(memcpy_toio); +EXPORT_SYMBOL(memcpy_fromio); diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile index 32b206440..f09cbc34c 100644 --- a/arch/x86_64/lib/Makefile +++ b/arch/x86_64/lib/Makefile @@ -4,11 +4,9 @@ CFLAGS_csum-partial.o := -funroll-loops -obj-y := io.o - lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ usercopy.o getuser.o putuser.o \ - thunk.o clear_page.o copy_page.o bitstr.o + thunk.o io.o clear_page.o copy_page.o bitstr.o lib-y += memcpy.o memmove.o memset.o copy_user.o lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o diff --git a/arch/x86_64/lib/csum-wrappers.c b/arch/x86_64/lib/csum-wrappers.c index a8e4c189f..b89aca460 100644 --- a/arch/x86_64/lib/csum-wrappers.c +++ b/arch/x86_64/lib/csum-wrappers.c @@ -19,7 +19,7 @@ * src and dst are best aligned to 64bits. */ unsigned int -csum_partial_copy_from_user(const char __user *src, char *dst, +csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int isum, int *errp) { *errp = 0; @@ -33,7 +33,7 @@ csum_partial_copy_from_user(const char __user *src, char *dst, if (unlikely((unsigned long)src & 6)) { while (((unsigned long)src & 6) && len >= 2) { __u16 val16; - *errp = __get_user(val16, (__u16 __user *)src); + *errp = __get_user(val16, (__u16 *)src); if (*errp) return isum; *(__u16 *)dst = val16; @@ -43,7 +43,7 @@ csum_partial_copy_from_user(const char __user *src, char *dst, len -= 2; } } - isum = csum_partial_copy_generic((void *)src,dst,len,isum,errp,NULL); + isum = csum_partial_copy_generic(src,dst,len,isum,errp,NULL); if (likely(*errp == 0)) return isum; } @@ -66,7 +66,7 @@ EXPORT_SYMBOL(csum_partial_copy_from_user); * src and dst are best aligned to 64bits. */ unsigned int -csum_partial_copy_to_user(const char *src, char __user *dst, +csum_partial_copy_to_user(const char *src, char *dst, int len, unsigned int isum, int *errp) { if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { @@ -78,7 +78,7 @@ csum_partial_copy_to_user(const char *src, char __user *dst, while (((unsigned long)dst & 6) && len >= 2) { __u16 val16 = *(__u16 *)src; isum = add32_with_carry(isum, val16); - *errp = __put_user(val16, (__u16 __user *)dst); + *errp = __put_user(val16, (__u16 *)dst); if (*errp) return isum; src += 2; @@ -88,7 +88,7 @@ csum_partial_copy_to_user(const char *src, char __user *dst, } *errp = 0; - return csum_partial_copy_generic(src, (void *)dst,len,isum,NULL,errp); + return csum_partial_copy_generic(src,dst,len,isum,NULL,errp); } EXPORT_SYMBOL(csum_partial_copy_to_user); diff --git a/arch/x86_64/lib/io.c b/arch/x86_64/lib/io.c index 5950b821d..ca08e3141 100644 --- a/arch/x86_64/lib/io.c +++ b/arch/x86_64/lib/io.c @@ -2,14 +2,12 @@ #include #include -void *__memcpy_toio(unsigned long dst,const void*src,unsigned len) +void *memcpy_toio(void *dst,const void*src,unsigned len) { - return __inline_memcpy((void *) dst,src,len); + return __inline_memcpy(dst,src,len); } -EXPORT_SYMBOL(__memcpy_toio); -void *__memcpy_fromio(void *dst,unsigned long src,unsigned len) +void *memcpy_fromio(void *dst,const void*src,unsigned len) { - return __inline_memcpy(dst,(const void *) src,len); + return __inline_memcpy(dst,src,len); } -EXPORT_SYMBOL(__memcpy_fromio); diff --git a/arch/x86_64/lib/usercopy.c b/arch/x86_64/lib/usercopy.c index c83825e5c..4a8603efa 100644 --- a/arch/x86_64/lib/usercopy.c +++ b/arch/x86_64/lib/usercopy.c @@ -40,7 +40,7 @@ do { \ } while (0) long -__strncpy_from_user(char *dst, const char __user *src, long count) +__strncpy_from_user(char *dst, const char *src, long count) { long res; __do_strncpy_from_user(dst, src, count, res); @@ -48,7 +48,7 @@ __strncpy_from_user(char *dst, const char __user *src, long count) } long -strncpy_from_user(char *dst, const char __user *src, long count) +strncpy_from_user(char *dst, const char *src, long count) { long res = -EFAULT; if (access_ok(VERIFY_READ, src, 1)) @@ -60,7 +60,7 @@ strncpy_from_user(char *dst, const char __user *src, long count) * Zero Userspace */ -unsigned long __clear_user(void __user *addr, unsigned long size) +unsigned long __clear_user(void *addr, unsigned long size) { long __d0; /* no memory constraint because it doesn't change any memory gcc knows @@ -94,7 +94,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size) } -unsigned long clear_user(void __user *to, unsigned long n) +unsigned long clear_user(void *to, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) return __clear_user(to, n); @@ -107,7 +107,7 @@ unsigned long clear_user(void __user *to, unsigned long n) * Return 0 on exception, a value greater than N if too long */ -long strnlen_user(const char __user *s, long n) +long strnlen_user(const char *s, long n) { long res = 0; char c; @@ -127,7 +127,7 @@ long strnlen_user(const char __user *s, long n) } } -long strlen_user(const char __user *s) +long strlen_user(const char *s) { long res = 0; char c; @@ -142,10 +142,10 @@ long strlen_user(const char __user *s) } } -unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len) +unsigned long copy_in_user(void *to, const void *from, unsigned len) { if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { - return copy_user_generic((void *)to, (void *)from, len); + return copy_user_generic(to, from, len); } return len; } diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 186242e13..80266166a 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -512,7 +512,9 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len) /* Should check here against the e820 map to avoid double free */ #ifdef CONFIG_DISCONTIGMEM int nid = phys_to_nid(phys); - reserve_bootmem_node(NODE_DATA(nid), phys, len); + if (phys < HIGH_MEMORY && nid) + panic("reserve of %lx at node %d", phys, nid); + reserve_bootmem_node(NODE_DATA(nid), phys, len); #else reserve_bootmem(phys, len); #endif diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 550770815..00ced1d84 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -32,8 +32,7 @@ static inline pte_t *lookup_address(unsigned long address) return pte; } -static struct page *split_large_page(unsigned long address, pgprot_t prot, - pgprot_t ref_prot) +static struct page *split_large_page(unsigned long address, pgprot_t prot) { int i; unsigned long addr; @@ -46,7 +45,7 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, pbase = (pte_t *)page_address(base); for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) { pbase[i] = pfn_pte(addr >> PAGE_SHIFT, - addr == address ? prot : ref_prot); + addr == address ? prot : PAGE_KERNEL); } return base; } @@ -96,7 +95,7 @@ static inline void save_page(unsigned long address, struct page *fpage) * No more special protections in this 2/4MB area - revert to a * large page again. */ -static void revert_page(unsigned long address, pgprot_t ref_prot) +static void revert_page(struct page *kpte_page, unsigned long address) { pgd_t *pgd; pmd_t *pmd; @@ -105,14 +104,12 @@ static void revert_page(unsigned long address, pgprot_t ref_prot) pgd = pgd_offset_k(address); pmd = pmd_offset(pgd, address); BUG_ON(pmd_val(*pmd) & _PAGE_PSE); - pgprot_val(ref_prot) |= _PAGE_PSE; - large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot); + large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, PAGE_KERNEL_LARGE); set_pte((pte_t *)pmd, large_pte); } static int -__change_page_attr(unsigned long address, struct page *page, pgprot_t prot, - pgprot_t ref_prot) +__change_page_attr(unsigned long address, struct page *page, pgprot_t prot) { pte_t *kpte; struct page *kpte_page; @@ -122,29 +119,29 @@ __change_page_attr(unsigned long address, struct page *page, pgprot_t prot, if (!kpte) return 0; kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); kpte_flags = pte_val(*kpte); - if (pgprot_val(prot) != pgprot_val(ref_prot)) { + if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { if ((kpte_flags & _PAGE_PSE) == 0) { pte_t old = *kpte; - pte_t standard = mk_pte(page, ref_prot); + pte_t standard = mk_pte(page, PAGE_KERNEL); set_pte(kpte, mk_pte(page, prot)); if (pte_same(old,standard)) get_page(kpte_page); } else { - struct page *split = split_large_page(address, prot, ref_prot); + struct page *split = split_large_page(address, prot); if (!split) return -ENOMEM; get_page(kpte_page); - set_pte(kpte,mk_pte(split, ref_prot)); + set_pte(kpte,mk_pte(split, PAGE_KERNEL)); } } else if ((kpte_flags & _PAGE_PSE) == 0) { - set_pte(kpte, mk_pte(page, ref_prot)); + set_pte(kpte, mk_pte(page, PAGE_KERNEL)); __put_page(kpte_page); } if (page_count(kpte_page) == 1) { save_page(address, kpte_page); - revert_page(address, ref_prot); + revert_page(kpte_page, address); } return 0; } @@ -170,17 +167,13 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot) down_write(&init_mm.mmap_sem); for (i = 0; i < numpages; !err && i++, page++) { unsigned long address = (unsigned long)page_address(page); - err = __change_page_attr(address, page, prot, PAGE_KERNEL); + err = __change_page_attr(address, page, prot); if (err) break; - /* Handle kernel mapping too which aliases part of the - * lowmem */ - /* Disabled right now. Fixme */ - if (0 && page_to_phys(page) < KERNEL_TEXT_SIZE) { - unsigned long addr2; - addr2 = __START_KERNEL_map + page_to_phys(page); - err = __change_page_attr(addr2, page, prot, - PAGE_KERNEL_EXECUTABLE); + /* Handle kernel mapping too which aliases part of the lowmem */ + if (page_to_phys(page) < KERNEL_TEXT_SIZE) { + unsigned long addr2 = __START_KERNEL_map + page_to_phys(page); + err = __change_page_attr(addr2, page, prot); } } up_write(&init_mm.mmap_sem); diff --git a/configs/kernel-2.6.6-i586-smp.config b/configs/kernel-2.6.6-i586-smp.config index 2ac8f42d7..bb8957aee 100644 --- a/configs/kernel-2.6.6-i586-smp.config +++ b/configs/kernel-2.6.6-i586-smp.config @@ -21,7 +21,8 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y # CONFIG_IKCONFIG is not set @@ -1104,9 +1105,8 @@ CONFIG_DE600=m CONFIG_DE620=m # -# Gigabit Ethernet (1000/10000 Mbit) +# Ethernet (1000 Mbit) # -CONFIG_NET_GIGE=y CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_DL2K=m @@ -1118,6 +1118,10 @@ CONFIG_YELLOWFIN=m CONFIG_R8169=m CONFIG_SK98LIN=m CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# CONFIG_IXGB=m CONFIG_IXGB_NAPI=y CONFIG_S2IO=m diff --git a/configs/kernel-2.6.6-i586.config b/configs/kernel-2.6.6-i586.config index acf01adf2..8b2db3696 100644 --- a/configs/kernel-2.6.6-i586.config +++ b/configs/kernel-2.6.6-i586.config @@ -22,7 +22,8 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y # CONFIG_IKCONFIG is not set @@ -1100,9 +1101,8 @@ CONFIG_DE600=m CONFIG_DE620=m # -# Gigabit Ethernet (1000/10000 Mbit) +# Ethernet (1000 Mbit) # -CONFIG_NET_GIGE=y CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_DL2K=m @@ -1114,6 +1114,10 @@ CONFIG_YELLOWFIN=m CONFIG_R8169=m CONFIG_SK98LIN=m CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# CONFIG_IXGB=m CONFIG_IXGB_NAPI=y CONFIG_S2IO=m diff --git a/configs/kernel-2.6.6-i686-smp.config b/configs/kernel-2.6.6-i686-smp.config index de7e3e791..340758535 100644 --- a/configs/kernel-2.6.6-i686-smp.config +++ b/configs/kernel-2.6.6-i686-smp.config @@ -21,7 +21,8 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y # CONFIG_IKCONFIG is not set @@ -1108,9 +1109,8 @@ CONFIG_DE600=m CONFIG_DE620=m # -# Gigabit Ethernet (1000/10000 Mbit) +# Ethernet (1000 Mbit) # -CONFIG_NET_GIGE=y CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_DL2K=m @@ -1122,6 +1122,10 @@ CONFIG_YELLOWFIN=m CONFIG_R8169=m CONFIG_SK98LIN=m CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# CONFIG_IXGB=m CONFIG_IXGB_NAPI=y CONFIG_S2IO=m diff --git a/configs/kernel-2.6.6-i686.config b/configs/kernel-2.6.6-i686.config index c245c3d55..d04be48a2 100644 --- a/configs/kernel-2.6.6-i686.config +++ b/configs/kernel-2.6.6-i686.config @@ -22,7 +22,8 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y # CONFIG_IKCONFIG is not set @@ -1101,9 +1102,8 @@ CONFIG_DE600=m CONFIG_DE620=m # -# Gigabit Ethernet (1000/10000 Mbit) +# Ethernet (1000 Mbit) # -CONFIG_NET_GIGE=y CONFIG_ACENIC=m # CONFIG_ACENIC_OMIT_TIGON_I is not set CONFIG_DL2K=m @@ -1115,6 +1115,10 @@ CONFIG_YELLOWFIN=m CONFIG_R8169=m CONFIG_SK98LIN=m CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# CONFIG_IXGB=m CONFIG_IXGB_NAPI=y CONFIG_S2IO=m diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h index 0b2168274..6a9d2ee97 100644 --- a/drivers/atm/fore200e.h +++ b/drivers/atm/fore200e.h @@ -830,17 +830,9 @@ typedef struct fore200e_bus { #if defined(CONFIG_ATM_FORE200E_SBA) # if defined(CONFIG_ATM_FORE200E_PCA) -# if (PCI_DMA_BIDIRECTIONAL == SBUS_DMA_BIDIRECTIONAL) && \ - (PCI_DMA_TODEVICE == SBUS_DMA_TODEVICE) && \ - (PCI_DMA_FROMDEVICE == SBUS_DMA_FROMDEVICE) -# define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL -# define FORE200E_DMA_TODEVICE PCI_DMA_TODEVICE -# define FORE200E_DMA_FROMDEVICE PCI_DMA_FROMDEVICE -# else - /* in that case, we'll need to add an extra indirection, e.g. - fore200e->bus->dma_direction[ fore200e_dma_direction ] */ -# error PCI and SBUS DMA direction flags have different values! -# endif +# define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL +# define FORE200E_DMA_TODEVICE PCI_DMA_TODEVICE +# define FORE200E_DMA_FROMDEVICE PCI_DMA_FROMDEVICE # else # define FORE200E_DMA_BIDIRECTIONAL SBUS_DMA_BIDIRECTIONAL # define FORE200E_DMA_TODEVICE SBUS_DMA_TODEVICE diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 8c46185dc..f6f781898 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -418,7 +418,8 @@ static int cpqarray_register_ctlr( int i, struct pci_dev *pdev) } hba[i]->access.set_intr_mask(hba[i], 0); if (request_irq(hba[i]->intr, do_ida_intr, - SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) + SA_INTERRUPT|SA_SHIRQ|SA_SAMPLE_RANDOM, + hba[i]->devname, hba[i])) { printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", hba[i]->intr, hba[i]->devname); diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index b1b532459..f1db2f86a 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -20,6 +20,8 @@ #define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */ #define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */ +static struct pci_device_id agp_amdk7_pci_table[]; + struct amd_page_map { unsigned long *real; unsigned long *remapped; @@ -41,7 +43,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); @@ -90,7 +92,7 @@ static int amd_create_gatt_pages(int nr_tables) int retval = 0; int i; - tables = kmalloc((nr_tables + 1) * sizeof(struct amd_page_map *), + tables = kmalloc((nr_tables + 1) * sizeof(struct amd_page_map *), GFP_KERNEL); if (tables == NULL) return -ENOMEM; @@ -124,7 +126,7 @@ static int amd_create_gatt_pages(int nr_tables) #define GET_PAGE_DIR_OFF(addr) (addr >> 22) #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \ GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr)) -#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) +#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) #define GET_GATT(addr) (amd_irongate_private.gatt_pages[\ GET_PAGE_DIR_IDX(addr)]->remapped) @@ -174,7 +176,7 @@ static int amd_create_gatt_table(void) static int amd_free_gatt_table(void) { struct amd_page_map page_dir; - + page_dir.real = (unsigned long *)agp_bridge->gatt_table_real; page_dir.remapped = (unsigned long *)agp_bridge->gatt_table; @@ -224,9 +226,9 @@ static int amd_irongate_configure(void) /* Write the Sync register */ pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL, 0x80); - - /* Set indexing mode */ - pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL2, 0x00); + + /* Set indexing mode */ + pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL2, 0x00); /* Write the enable register */ enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE); @@ -394,7 +396,6 @@ static struct agp_device_ids amd_agp_device_ids[] __devinitdata = static int __devinit agp_amdk7_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - struct agp_device_ids *devs = amd_agp_device_ids; struct agp_bridge_data *bridge; u8 cap_ptr; int j; @@ -403,19 +404,10 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev, if (!cap_ptr) return -ENODEV; - for (j = 0; devs[j].chipset_name; j++) { - if (pdev->device == devs[j].device_id) { - printk (KERN_INFO PFX "Detected AMD %s chipset\n", - devs[j].chipset_name); - goto found; - } - } - - printk(KERN_ERR PFX "Unsupported AMD chipset (device id: %04x)\n", - pdev->device); - return -ENODEV; + j = ent - agp_amdk7_pci_table; + printk(KERN_INFO PFX "Detected AMD %s chipset\n", + amd_agp_device_ids[j].chipset_name); -found: bridge = agp_alloc_bridge(); if (!bridge) return -ENOMEM; @@ -442,12 +434,29 @@ static void __devexit agp_amdk7_remove(struct pci_dev *pdev) agp_put_bridge(bridge); } +/* must be the same order as name table above */ static struct pci_device_id agp_amdk7_pci_table[] = { { .class = (PCI_CLASS_BRIDGE_HOST << 8), .class_mask = ~0, .vendor = PCI_VENDOR_ID_AMD, - .device = PCI_ANY_ID, + .device = PCI_DEVICE_ID_AMD_FE_GATE_7006, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_FE_GATE_700E, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_AMD, + .device = PCI_DEVICE_ID_AMD_FE_GATE_700C, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index def65689a..06a7ef269 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -1,7 +1,7 @@ -/* +/* * Copyright 2001-2003 SuSE Labs. * Distributed under the GNU public license, v2. - * + * * This is a GART driver for the AMD Opteron/Athlon64 on-CPU northbridge. * It also includes support for the AMD 8151 AGP bridge, * although it doesn't actually do much, as all the real @@ -194,7 +194,7 @@ static u64 amd64_configure (struct pci_dev *hammer, u64 gatt_table) /* keep CPU's coherent. */ flush_amd64_tlb (hammer); - + return aper_base; } @@ -261,53 +261,53 @@ struct agp_bridge_driver amd_8151_driver = { /* Some basic sanity checks for the aperture. */ static int __devinit aperture_valid(u64 aper, u32 size) -{ +{ u32 pfn, c; - if (aper == 0) { + if (aper == 0) { printk(KERN_ERR PFX "No aperture\n"); - return 0; + return 0; } if (size < 32*1024*1024) { printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20); return 0; } - if (aper + size > 0xffffffff) { - printk(KERN_ERR PFX "Aperture out of bounds\n"); + if (aper + size > 0xffffffff) { + printk(KERN_ERR PFX "Aperture out of bounds\n"); return 0; - } + } pfn = aper >> PAGE_SHIFT; - for (c = 0; c < size/PAGE_SIZE; c++) { + for (c = 0; c < size/PAGE_SIZE; c++) { if (!pfn_valid(pfn + c)) break; - if (!PageReserved(pfn_to_page(pfn + c))) { + if (!PageReserved(pfn_to_page(pfn + c))) { printk(KERN_ERR PFX "Aperture pointing to RAM\n"); return 0; } } /* Request the Aperture. This catches cases when someone else - already put a mapping in there - happens with some very broken BIOS + already put a mapping in there - happens with some very broken BIOS - Maybe better to use pci_assign_resource/pci_enable_device instead trusting - the bridges? */ + Maybe better to use pci_assign_resource/pci_enable_device instead + trusting the bridges? */ if (!aperture_resource && !(aperture_resource = request_mem_region(aper, size, "aperture"))) { - printk(KERN_ERR PFX "Aperture conflicts with PCI mapping.\n"); + printk(KERN_ERR PFX "Aperture conflicts with PCI mapping.\n"); return 0; } return 1; -} +} -/* +/* * W*s centric BIOS sometimes only set up the aperture in the AGP - * bridge, not the northbridge. On AMD64 this is handled early + * bridge, not the northbridge. On AMD64 this is handled early * in aperture.c, but when GART_IOMMU is not enabled or we run - * on a 32bit kernel this needs to be redone. + * on a 32bit kernel this needs to be redone. * Unfortunately it is impossible to fix the aperture here because it's too late * to allocate that much memory. But at least error out cleanly instead of * crashing. - */ -static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, + */ +static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, u16 cap) { u32 aper_low, aper_hi; @@ -316,38 +316,38 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp, u32 nb_order, nb_base; u16 apsize; - pci_read_config_dword(nb, 0x90, &nb_order); + pci_read_config_dword(nb, 0x90, &nb_order); nb_order = (nb_order >> 1) & 7; - pci_read_config_dword(nb, 0x94, &nb_base); - nb_aper = nb_base << 25; - if (aperture_valid(nb_aper, (32*1024*1024)<> 25); + return -1; + + pci_write_config_dword(nb, 0x90, order << 1); + pci_write_config_dword(nb, 0x94, aper >> 25); return 0; -} +} static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) { @@ -355,19 +355,19 @@ static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) int i = 0; /* cache pci_devs of northbridges. */ - while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) + while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) != NULL) { - if (i == MAX_HAMMER_GARTS) { + if (i == MAX_HAMMER_GARTS) { printk(KERN_ERR PFX "Too many northbridges for AGP\n"); return -1; } - if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) { + if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) { printk(KERN_ERR PFX "No usable aperture found.\n"); -#ifdef __x86_64__ +#ifdef __x86_64__ /* should port this to i386 */ printk(KERN_ERR PFX "Consider rebooting with iommu=memaper=2 to get a good aperture.\n"); -#endif - return -1; +#endif + return -1; } hammers[i++] = loop_dev; } @@ -377,8 +377,7 @@ static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) /* Handle AMD 8151 quirks */ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data *bridge) - -{ +{ char *revstring; u8 rev_id; @@ -417,12 +416,12 @@ static struct aper_size_info_32 nforce3_sizes[5] = /* Handle shadow device of the Nvidia NForce3 */ /* CHECK-ME original 2.4 version set up some IORRs. Check if that is needed. */ -static int __devinit nforce3_agp_init(struct pci_dev *pdev) -{ +static int __devinit nforce3_agp_init(struct pci_dev *pdev) +{ u32 tmp, apbase, apbar, aplimit; - struct pci_dev *dev1; + struct pci_dev *dev1; int i; - unsigned size = amd64_fetch_size(); + unsigned size = amd64_fetch_size(); printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n"); @@ -432,17 +431,17 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) "nForce3 chipset, but could not find " "the secondary device.\n"); return -ENODEV; - } + } - for (i = 0; i < ARRAY_SIZE(nforce3_sizes); i++) + for (i = 0; i < ARRAY_SIZE(nforce3_sizes); i++) if (nforce3_sizes[i].size == size) - break; + break; if (i == ARRAY_SIZE(nforce3_sizes)) { - printk(KERN_INFO PFX "No NForce3 size found for %d\n", size); - return -ENODEV; + printk(KERN_INFO PFX "No NForce3 size found for %d\n", size); + return -ENODEV; } - + pci_read_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, &tmp); tmp &= ~(0xf); tmp |= nforce3_sizes[i].size_value; @@ -491,8 +490,7 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, pdev->device == PCI_DEVICE_ID_AMD_8151_0) { amd8151_init(pdev, bridge); } else { - printk(KERN_INFO PFX "Detected AGP bridge %x\n", - pdev->devfn); + printk(KERN_INFO PFX "Detected AGP bridge %x\n", pdev->devfn); } bridge->driver = &amd_8151_driver; @@ -507,10 +505,10 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, return -ENODEV; } - if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { + if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { int ret = nforce3_agp_init(pdev); - if (ret) { - agp_put_bridge(bridge); + if (ret) { + agp_put_bridge(bridge); return ret; } } @@ -523,8 +521,8 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - release_mem_region(virt_to_phys(bridge->gatt_table_real), - amd64_aperture_sizes[bridge->aperture_size_idx].size); + release_mem_region(virt_to_phys(bridge->gatt_table_real), + amd64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); } @@ -581,6 +579,15 @@ static struct pci_device_id agp_amd64_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, + /* SIS 755 */ + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_755, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, { } }; @@ -600,15 +607,15 @@ int __init agp_amd64_init(void) int err = 0; if (agp_off) return -EINVAL; - if (pci_module_init(&agp_amd64_pci_driver) > 0) { + if (pci_module_init(&agp_amd64_pci_driver) > 0) { struct pci_dev *dev; - if (!agp_try_unsupported && !agp_try_unsupported_boot) { + if (!agp_try_unsupported && !agp_try_unsupported_boot) { printk(KERN_INFO PFX "No supported AGP bridge found.\n"); -#ifdef MODULE +#ifdef MODULE printk(KERN_INFO PFX "You can try agp_try_unsupported=1\n"); #else printk(KERN_INFO PFX "You can boot with agp=try_unsupported\n"); -#endif +#endif return -ENODEV; } @@ -622,12 +629,12 @@ int __init agp_amd64_init(void) while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev))) { if (!pci_find_capability(dev, PCI_CAP_ID_AGP)) continue; - /* Only one bridge supported right now */ + /* Only one bridge supported right now */ if (agp_amd64_probe(dev, NULL) == 0) { err = 0; break; - } - } + } + } } return err; } diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 35f71bbf8..bc88d6991 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -131,6 +131,7 @@ static int ati_create_gatt_pages(int nr_tables) i--; } kfree (tables); + tables = NULL; retval = -ENOMEM; break; } diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 7b3f652f6..33e1c707d 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -238,11 +238,14 @@ void agp_put_bridge(struct agp_bridge_data *bridge) } EXPORT_SYMBOL(agp_put_bridge); - + int agp_add_bridge(struct agp_bridge_data *bridge) { int error; + if (agp_off) + return -ENODEV; + if (!bridge->dev) { printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n"); return -EINVAL; @@ -308,9 +311,9 @@ EXPORT_SYMBOL(agp_try_unsupported_boot); static int __init agp_init(void) { - if (!agp_off) - printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n", - AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR); + if (!agp_off) + printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n", + AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR); return 0; } @@ -325,7 +328,7 @@ static __init int agp_setup(char *s) agp_off = 1; if (!strcmp(s,"try_unsupported")) agp_try_unsupported_boot = 1; - return 1; + return 1; } __setup("agp=", agp_setup); #endif diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index db4d3797e..f8b991673 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1233,7 +1233,7 @@ static int find_i810(u16 device, const char *name) name); return 0; } - + intel_i810_private.i810_dev = i810_dev; return 1; } @@ -1382,8 +1382,10 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, name = "E7205"; break; default: - printk(KERN_ERR PFX "Unsupported Intel chipset (device id: %04x)\n", + if (cap_ptr) + printk(KERN_WARNING PFX "Unsupported Intel chipset (device id: %04x)\n", pdev->device); + agp_put_bridge(bridge); return -ENODEV; }; @@ -1406,7 +1408,8 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, if (!r->start && r->end) { if(pci_assign_resource(pdev, 0)) { printk(KERN_ERR PFX "could not assign resource 0\n"); - return (-ENODEV); + agp_put_bridge(bridge); + return -ENODEV; } } @@ -1417,7 +1420,8 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, */ if (pci_enable_device(pdev)) { printk(KERN_ERR PFX "Unable to Enable PCI device\n"); - return (-ENODEV); + agp_put_bridge(bridge); + return -ENODEV; } /* Fill in the mode register */ @@ -1459,14 +1463,36 @@ static int agp_intel_resume(struct pci_dev *pdev) } static struct pci_device_id agp_intel_pci_table[] = { - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, +#define ID(x) \ + { \ + .class = (PCI_CLASS_BRIDGE_HOST << 8), \ + .class_mask = ~0, \ + .vendor = PCI_VENDOR_ID_INTEL, \ + .device = x, \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID, \ + } + ID(PCI_DEVICE_ID_INTEL_82443LX_0), + ID(PCI_DEVICE_ID_INTEL_82443BX_0), + ID(PCI_DEVICE_ID_INTEL_82443GX_0), + ID(PCI_DEVICE_ID_INTEL_82810_MC1), + ID(PCI_DEVICE_ID_INTEL_82810_MC3), + ID(PCI_DEVICE_ID_INTEL_82810E_MC), + ID(PCI_DEVICE_ID_INTEL_82815_MC), + ID(PCI_DEVICE_ID_INTEL_82820_HB), + ID(PCI_DEVICE_ID_INTEL_82820_UP_HB), + ID(PCI_DEVICE_ID_INTEL_82830_HB), + ID(PCI_DEVICE_ID_INTEL_82840_HB), + ID(PCI_DEVICE_ID_INTEL_82845_HB), + ID(PCI_DEVICE_ID_INTEL_82845G_HB), + ID(PCI_DEVICE_ID_INTEL_82850_HB), + ID(PCI_DEVICE_ID_INTEL_82855PM_HB), + ID(PCI_DEVICE_ID_INTEL_82855GM_HB), + ID(PCI_DEVICE_ID_INTEL_82860_HB), + ID(PCI_DEVICE_ID_INTEL_82865_HB), + ID(PCI_DEVICE_ID_INTEL_82875_HB), + ID(PCI_DEVICE_ID_INTEL_7505_0), + ID(PCI_DEVICE_ID_INTEL_7205_0), { } }; diff --git a/drivers/char/agp/intel-mch-agp.c b/drivers/char/agp/intel-mch-agp.c index b8fd444bd..dff4d9933 100644 --- a/drivers/char/agp/intel-mch-agp.c +++ b/drivers/char/agp/intel-mch-agp.c @@ -491,10 +491,9 @@ static int __devinit agp_intelmch_probe(struct pci_dev *pdev, char *name = "(unknown)"; u8 cap_ptr = 0; - if (!boot_cpu_has(X86_FEATURE_LM)) - return -ENODEV; - cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); + if (!cap_ptr) + return -ENODEV; bridge = agp_alloc_bridge(); if (!bridge) @@ -587,7 +586,15 @@ static struct pci_device_id agp_intelmch_pci_table[] = { .class = (PCI_CLASS_BRIDGE_HOST << 8), .class_mask = ~0, .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_ANY_ID, + .device = PCI_DEVICE_ID_INTEL_82865_HB, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82875_HB, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 2981fa1fc..28e7fc4bc 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -380,7 +380,15 @@ static struct pci_device_id agp_nvidia_pci_table[] = { .class = (PCI_CLASS_BRIDGE_HOST << 8), .class_mask = ~0, .vendor = PCI_VENDOR_ID_NVIDIA, - .device = PCI_ANY_ID, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NFORCE2, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 16bfef56a..549149ff5 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -13,6 +13,8 @@ #define SIS_TLBCNTRL 0x97 #define SIS_TLBFLUSH 0x98 +static int __devinitdata agp_sis_force_delay = 0; +static int __devinitdata agp_sis_agp_spec = -1; static int sis_fetch_size(void) { @@ -67,7 +69,7 @@ static void sis_cleanup(void) (previous_size->size_value & ~(0x03))); } -static void sis_648_enable(u32 mode) +static void sis_delayed_enable(u32 mode) { struct pci_dev *device = NULL; u32 command; @@ -94,13 +96,12 @@ static void sis_648_enable(u32 mode) pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command); /* - * Weird: on 648(fx) and 746(fx) chipsets any rate change in the target + * Weird: on some sis chipsets any rate change in the target * command register triggers a 5ms screwup during which the master * cannot be configured */ - if (device->device == PCI_DEVICE_ID_SI_648 || - device->device == PCI_DEVICE_ID_SI_746) { - printk(KERN_INFO PFX "SiS chipset with AGP problems detected. Giving bridge time to recover.\n"); + if (device->device == agp_bridge->dev->device) { + printk(KERN_INFO PFX "SiS delay workaround: giving bridge time to recover.\n"); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout (1+(HZ*10)/1000); } @@ -223,28 +224,35 @@ static struct agp_device_ids sis_agp_device_ids[] __devinitdata = }; +// chipsets that require the 'delay hack' +static int sis_broken_chipsets[] __devinitdata = { + PCI_DEVICE_ID_SI_648, + PCI_DEVICE_ID_SI_746, + 0 // terminator +}; + static void __devinit sis_get_driver(struct agp_bridge_data *bridge) { - if (bridge->dev->device == PCI_DEVICE_ID_SI_648) { - sis_driver.agp_enable=sis_648_enable; - if (agp_bridge->major_version == 3) { - sis_driver.aperture_sizes = agp3_generic_sizes; - sis_driver.size_type = U16_APER_SIZE; - sis_driver.num_aperture_sizes = AGP_GENERIC_SIZES_ENTRIES; - sis_driver.configure = agp3_generic_configure; - sis_driver.fetch_size = agp3_generic_fetch_size; - sis_driver.cleanup = agp3_generic_cleanup; - sis_driver.tlb_flush = agp3_generic_tlbflush; - } - } + int i; - if (bridge->dev->device == PCI_DEVICE_ID_SI_746) { - /* - * We don't know enough about the 746 to enable it properly. - * Though we do know that it needs the 'delay' hack to settle - * after changing modes. - */ - sis_driver.agp_enable=sis_648_enable; + for(i=0; sis_broken_chipsets[i]!=0; ++i) + if(bridge->dev->device==sis_broken_chipsets[i]) + break; + + if(sis_broken_chipsets[i] || agp_sis_force_delay) + sis_driver.agp_enable=sis_delayed_enable; + + // sis chipsets that indicate less than agp3.5 + // are not actually fully agp3 compliant + if ((agp_bridge->major_version == 3 && agp_bridge->minor_version >= 5 + && agp_sis_agp_spec!=0) || agp_sis_agp_spec==1) { + sis_driver.aperture_sizes = agp3_generic_sizes; + sis_driver.size_type = U16_APER_SIZE; + sis_driver.num_aperture_sizes = AGP_GENERIC_SIZES_ENTRIES; + sis_driver.configure = agp3_generic_configure; + sis_driver.fetch_size = agp3_generic_fetch_size; + sis_driver.cleanup = agp3_generic_cleanup; + sis_driver.tlb_flush = agp3_generic_tlbflush; } } @@ -335,4 +343,8 @@ static void __exit agp_sis_cleanup(void) module_init(agp_sis_init); module_exit(agp_sis_cleanup); +MODULE_PARM(agp_sis_force_delay,"i"); +MODULE_PARM_DESC(agp_sis_force_delay,"forces sis delay hack"); +MODULE_PARM(agp_sis_agp_spec,"i"); +MODULE_PARM_DESC(agp_sis_agp_spec,"0=force sis init, 1=force generic agp3 init, default: autodetect"); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index e08c241cd..d3f3e80ff 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -248,26 +248,13 @@ static int serverworks_fetch_size(void) */ static void serverworks_tlbflush(struct agp_memory *temp) { - unsigned long end; - - OUTREG8(serverworks_private.registers, SVWRKS_POSTFLUSH, 0x01); - end = jiffies + 3*HZ; - while(INREG8(serverworks_private.registers, - SVWRKS_POSTFLUSH) == 0x01) { - if((signed)(end - jiffies) <= 0) { - printk(KERN_ERR PFX "Posted write buffer flush took more" - "then 3 seconds\n"); - } - } - OUTREG32(serverworks_private.registers, SVWRKS_DIRFLUSH, 0x00000001); - end = jiffies + 3*HZ; - while(INREG32(serverworks_private.registers, - SVWRKS_DIRFLUSH) == 0x00000001) { - if((signed)(end - jiffies) <= 0) { - printk(KERN_ERR PFX "TLB flush took more" - "then 3 seconds\n"); - } - } + OUTREG8(serverworks_private.registers, SVWRKS_POSTFLUSH, 1); + while(INREG8(serverworks_private.registers, SVWRKS_POSTFLUSH) == 1) + cpu_relax(); + + OUTREG32(serverworks_private.registers, SVWRKS_DIRFLUSH, 1); + while(INREG32(serverworks_private.registers, SVWRKS_DIRFLUSH) == 1) + cpu_relax(); } static int serverworks_configure(void) diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index de9aa85e5..2f5c50c29 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -9,6 +9,8 @@ #include #include "agp.h" +static struct pci_device_id agp_via_pci_table[]; + #define VIA_GARTCTRL 0x80 #define VIA_APSIZE 0x84 #define VIA_ATTBASE 0x88 @@ -378,20 +380,9 @@ static int __devinit agp_via_probe(struct pci_dev *pdev, if (!cap_ptr) return -ENODEV; - /* probe for known chipsets */ - for (j = 0; devs[j].chipset_name; j++) { - if (pdev->device == devs[j].device_id) { - printk (KERN_INFO PFX "Detected VIA %s chipset\n", - devs[j].chipset_name); - goto found; - } - } - - printk(KERN_ERR PFX "Unsupported VIA chipset (device id: %04x)\n", - pdev->device); - return -ENODEV; + j = ent - agp_via_pci_table; + printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name); -found: bridge = agp_alloc_bridge(); if (!bridge) return -ENOMEM; @@ -432,15 +423,40 @@ static void __devexit agp_via_remove(struct pci_dev *pdev) agp_put_bridge(bridge); } +/* must be the same order as name table above */ static struct pci_device_id agp_via_pci_table[] = { - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, +#define ID(x) \ + { \ + .class = (PCI_CLASS_BRIDGE_HOST << 8), \ + .class_mask = ~0, \ + .vendor = PCI_VENDOR_ID_VIA, \ + .device = x, \ + .subvendor = PCI_ANY_ID, \ + .subdevice = PCI_ANY_ID, \ + } + ID(PCI_DEVICE_ID_VIA_82C598_0), + ID(PCI_DEVICE_ID_VIA_8501_0), + ID(PCI_DEVICE_ID_VIA_8601_0), + ID(PCI_DEVICE_ID_VIA_82C691_0), + ID(PCI_DEVICE_ID_VIA_8371_0), + ID(PCI_DEVICE_ID_VIA_8633_0), + ID(PCI_DEVICE_ID_VIA_XN266), + ID(PCI_DEVICE_ID_VIA_8361), + ID(PCI_DEVICE_ID_VIA_8363_0), + ID(PCI_DEVICE_ID_VIA_8753_0), + ID(PCI_DEVICE_ID_VIA_8367_0), + ID(PCI_DEVICE_ID_VIA_8653_0), + ID(PCI_DEVICE_ID_VIA_XM266), + ID(PCI_DEVICE_ID_VIA_862X_0), + ID(PCI_DEVICE_ID_VIA_8377_0), + ID(PCI_DEVICE_ID_VIA_8605_0), + ID(PCI_DEVICE_ID_VIA_8703_51_0), + ID(PCI_DEVICE_ID_VIA_8754C_0), + ID(PCI_DEVICE_ID_VIA_8763_0), + ID(PCI_DEVICE_ID_VIA_8378_0), + ID(PCI_DEVICE_ID_VIA_PT880), + ID(PCI_DEVICE_ID_VIA_8783_0), + ID(PCI_DEVICE_ID_VIA_PX8X0_0), { } }; diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c index f41832054..6f0657b2b 100644 --- a/drivers/char/watchdog/scx200_wdt.c +++ b/drivers/char/watchdog/scx200_wdt.c @@ -221,10 +221,16 @@ static int __init scx200_wdt_init(void) printk(KERN_DEBUG NAME ": NatSemi SCx200 Watchdog Driver\n"); - /* First check that this really is a NatSemi SCx200 CPU */ + /* + * First check that this really is a NatSemi SCx200 CPU or a Geode + * SC1100 processor + */ if ((pci_find_device(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE, - NULL)) == NULL) + NULL)) == NULL + && (pci_find_device(PCI_VENDOR_ID_NS, + PCI_DEVICE_ID_NS_SC1100_BRIDGE, + NULL)) == NULL) return -ENODEV; /* More sanity checks, verify that the configuration block is there */ diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c index 705cbfa9d..7a129302c 100644 --- a/drivers/char/watchdog/w83627hf_wdt.c +++ b/drivers/char/watchdog/w83627hf_wdt.c @@ -72,7 +72,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ static void -wdt_ctrl(int timeout) +w83627hf_select_wd_register(void) { outb_p(0x87, WDT_EFER); /* Enter extended function mode */ outb_p(0x87, WDT_EFER); /* Again according to manual */ @@ -81,23 +81,64 @@ wdt_ctrl(int timeout) outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */ outb_p(0x30, WDT_EFER); /* select CR30 */ outb_p(0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ +} + +static void +w83627hf_unselect_wd_register(void) +{ + outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ +} + +/* tyan motherboards seem to set F5 to 0x4C ? + * So explicitly init to appropriate value. */ +static void +w83627hf_init(void) +{ + unsigned char t; + + w83627hf_select_wd_register(); + + outb_p(0xF5, WDT_EFER); /* Select CRF5 */ + t=inb_p(WDT_EFDR); /* read CRF5 */ + t&=~0x0C; /* set second mode & disable keyboard turning off watchdog */ + outb_p(t, WDT_EFDR); /* Write back to CRF5 */ + + w83627hf_unselect_wd_register(); +} + +static void +wdt_ctrl(int timeout) +{ + w83627hf_select_wd_register(); outb_p(0xF6, WDT_EFER); /* Select CRF6 */ outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF6 */ - outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ + w83627hf_unselect_wd_register(); } -static void +static int wdt_ping(void) { wdt_ctrl(timeout); + return 0; } -static void +static int wdt_disable(void) { wdt_ctrl(0); + return 0; +} + +static int +wdt_set_heartbeat(int t) +{ + if ((t < 1) || (t > 63)) + return -EINVAL; + + timeout = t; + return 0; } static ssize_t @@ -134,7 +175,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 1, - .identity = "Advantech WDT", + .identity = "W83627HF WDT", }; switch (cmd) { @@ -154,9 +195,8 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, case WDIOC_SETTIMEOUT: if (get_user(new_timeout, (int *)arg)) return -EFAULT; - if ((new_timeout < 1) || (new_timeout > 63)) + if (wdt_set_heartbeat(new_timeout)) return -EINVAL; - timeout = new_timeout; wdt_ping(); /* Fall */ @@ -211,8 +251,8 @@ wdt_close(struct inode *inode, struct file *file) printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); wdt_ping(); } - clear_bit(0, &wdt_is_open); expect_close = 0; + clear_bit(0, &wdt_is_open); return 0; } @@ -266,10 +306,10 @@ wdt_init(void) printk(KERN_INFO "WDT driver for the Winbond(TM) W83627HF Super I/O chip initialising.\n"); - if (timeout < 1 || timeout > 63) { - timeout = WATCHDOG_TIMEOUT; - printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n", - timeout); + if (wdt_set_heartbeat(timeout)) { + wdt_set_heartbeat(WATCHDOG_TIMEOUT); + printk (KERN_INFO PFX "timeout value must be 1<=timeout<=63, using %d\n", + WATCHDOG_TIMEOUT); } if (!request_region(wdt_io, 1, WATCHDOG_NAME)) { @@ -279,6 +319,8 @@ wdt_init(void) goto out; } + w83627hf_init(); + ret = register_reboot_notifier(&wdt_notifier); if (ret != 0) { printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 2329dd0e4..e5f41e017 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c @@ -59,8 +59,6 @@ #define dma_unmap_single(d,h,s,dir) sbus_unmap_single(d,h,s,dir) #define dma_map_sg(d,s,n,dir) sbus_map_sg(d,s,n,dir) #define dma_unmap_sg(d,s,n,dir) sbus_unmap_sg(d,s,n,dir) -#define scsi_to_fc_dma_dir(dir) scsi_to_sbus_dma_dir(dir) -#define FC_DMA_BIDIRECTIONAL SBUS_DMA_BIDIRECTIONAL #else #define dma_alloc_consistent(d,s,p) pci_alloc_consistent(d,s,p) #define dma_free_consistent(d,s,v,h) pci_free_consistent(d,s,v,h) @@ -68,8 +66,6 @@ #define dma_unmap_single(d,h,s,dir) pci_unmap_single(d,h,s,dir) #define dma_map_sg(d,s,n,dir) pci_map_sg(d,s,n,dir) #define dma_unmap_sg(d,s,n,dir) pci_unmap_sg(d,s,n,dir) -#define scsi_to_fc_dma_dir(dir) scsi_to_pci_dma_dir(dir) -#define FC_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL #endif #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) @@ -167,7 +163,7 @@ static void fcp_login_done(fc_channel *fc, int i, int status) fcmd = l->fcmds + i; plogi = l->logi + 3 * i; dma_unmap_single (fc->dev, fcmd->cmd, 3 * sizeof(logi), - FC_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); plogi->code = LS_PLOGI; memcpy (&plogi->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn)); memcpy (&plogi->node_wwn, &fc->wwn_node, sizeof(fc_wwn)); @@ -188,7 +184,7 @@ static void fcp_login_done(fc_channel *fc, int i, int status) } #endif fcmd->cmd = dma_map_single (fc->dev, plogi, 3 * sizeof(logi), - FC_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); fcmd->rsp = fcmd->cmd + 2 * sizeof(logi); if (fc->hw_enque (fc, fcmd)) printk ("FC: Cannot enque PLOGI packet on %s\n", fc->name); @@ -212,7 +208,7 @@ static void fcp_login_done(fc_channel *fc, int i, int status) case FC_STATUS_OK: plogi = l->logi + 3 * i; dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), - FC_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); if (!fc->wwn_dest.lo && !fc->wwn_dest.hi) { memcpy (&fc->wwn_dest, &plogi[1].node_wwn, sizeof(fc_wwn)); FCD(("Dest WWN %08x%08x\n", *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo)) @@ -231,7 +227,7 @@ static void fcp_login_done(fc_channel *fc, int i, int status) case FC_STATUS_ERR_OFFLINE: fc->state = FC_STATE_OFFLINE; dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), - FC_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); printk ("%s: FC is offline\n", fc->name); if (atomic_dec_and_test (&l->todo)) up(&l->sem); @@ -256,7 +252,7 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status) switch (status) { case FC_STATUS_OK: /* Ok, let's have a fun on a loop */ dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), - FC_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); p = (fc_al_posmap *)(l->logi + 3 * i); #ifdef FCDEBUG { @@ -306,7 +302,7 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status) FCD(("SID %d DID %d\n", fc->sid, fc->did)) fcmd = l->fcmds + i; dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi), - FC_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); fch = &fcmd->fch; memset(l->logi + 3 * i, 0, 3 * sizeof(logi)); FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT); @@ -317,7 +313,7 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status) fch->param = 0; l->logi [3 * i].code = LS_FLOGI; fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi), - FC_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); fcmd->rsp = fcmd->cmd + sizeof(logi); fcmd->cmdlen = sizeof(logi); fcmd->rsplen = sizeof(logi); @@ -434,11 +430,12 @@ static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hd if (fcmd->data) { if (SCpnt->use_sg) - dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer, SCpnt->use_sg, - scsi_to_fc_dma_dir(SCpnt->sc_data_direction)); + dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer, + SCpnt->use_sg, + SCpnt->sc_data_direction); else dma_unmap_single(fc->dev, fcmd->data, SCpnt->request_bufflen, - scsi_to_fc_dma_dir(SCpnt->sc_data_direction)); + SCpnt->sc_data_direction); } break; default: @@ -579,7 +576,7 @@ int fcp_initialize(fc_channel *fcchain, int count) fc->ls = (void *)l; /* Assumes sizeof(fc_al_posmap) < 3 * sizeof(logi), which is true */ fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi), - FC_DMA_BIDIRECTIONAL); + DMA_BIDIRECTIONAL); fcmd->proto = PROTO_REPORT_AL_MAP; fcmd->token = i; fcmd->fc = fc; @@ -598,7 +595,7 @@ int fcp_initialize(fc_channel *fcchain, int count) } else { fc->state = FC_STATE_OFFLINE; enable_irq(fc->irq); - dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), FC_DMA_BIDIRECTIONAL); + dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), DMA_BIDIRECTIONAL); if (atomic_dec_and_test (&l->todo)) goto all_done; } @@ -615,7 +612,7 @@ int fcp_initialize(fc_channel *fcchain, int count) FCD(("SID %d DID %d\n", fc->sid, fc->did)) fcmd = l->fcmds + i; - dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi), FC_DMA_BIDIRECTIONAL); + dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi), DMA_BIDIRECTIONAL); fch = &fcmd->fch; FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT); FILL_FCHDR_SID(fch, 0); @@ -624,7 +621,7 @@ int fcp_initialize(fc_channel *fcchain, int count) FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); fch->param = 0; l->logi [3 * i].code = LS_FLOGI; - fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi), FC_DMA_BIDIRECTIONAL); + fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi), DMA_BIDIRECTIONAL); fcmd->rsp = fcmd->cmd + sizeof(logi); fcmd->cmdlen = sizeof(logi); fcmd->rsplen = sizeof(logi); @@ -652,7 +649,7 @@ all_done: switch (fc->state) { case FC_STATE_ONLINE: break; case FC_STATE_OFFLINE: break; - default: dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), FC_DMA_BIDIRECTIONAL); + default: dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), DMA_BIDIRECTIONAL); break; } } @@ -821,14 +818,14 @@ static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, i cmd->fcp_data_len = SCpnt->request_bufflen; fcmd->data = dma_map_single (fc->dev, (char *)SCpnt->request_buffer, SCpnt->request_bufflen, - scsi_to_fc_dma_dir(SCpnt->sc_data_direction)); + SCpnt->sc_data_direction); } else { struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer; int nents; FCD(("XXX: Use_sg %d %d\n", SCpnt->use_sg, sg->length)) nents = dma_map_sg (fc->dev, sg, SCpnt->use_sg, - scsi_to_fc_dma_dir(SCpnt->sc_data_direction)); + SCpnt->sc_data_direction); if (nents > 1) printk ("%s: SG for nents %d (use_sg %d) not handled yet\n", fc->name, nents, SCpnt->use_sg); fcmd->data = sg_dma_address(sg); cmd->fcp_data_len = sg_dma_len(sg); @@ -1065,7 +1062,7 @@ static int fc_do_els(fc_channel *fc, unsigned int alpa, void *data, int len) FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0); FILL_FCHDR_OXRX(fch, 0xffff, 0xffff); fch->param = 0; - fcmd->cmd = dma_map_single (fc->dev, data, 2 * len, FC_DMA_BIDIRECTIONAL); + fcmd->cmd = dma_map_single (fc->dev, data, 2 * len, DMA_BIDIRECTIONAL); fcmd->rsp = fcmd->cmd + len; fcmd->cmdlen = len; fcmd->rsplen = len; @@ -1100,7 +1097,7 @@ static int fc_do_els(fc_channel *fc, unsigned int alpa, void *data, int len) clear_bit(fcmd->token, fc->scsi_bitmap); fc->scsi_free++; - dma_unmap_single (fc->dev, fcmd->cmd, 2 * len, FC_DMA_BIDIRECTIONAL); + dma_unmap_single (fc->dev, fcmd->cmd, 2 * len, DMA_BIDIRECTIONAL); return l.status; } diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 61ddd65e5..76a9d68c0 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -43,7 +43,7 @@ MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver"); MODULE_LICENSE("GPL"); #define MAX_DEVICES 4 -static int base[MAX_DEVICES] = { 0x840 }; +static int base[MAX_DEVICES] = { 0x820, 0x840 }; MODULE_PARM(base, "1-4i"); MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers"); @@ -510,7 +510,10 @@ static int __init scx200_acb_init(void) /* Verify that this really is a SCx200 processor */ if (pci_find_device(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE, - NULL) == NULL) + NULL) == NULL + && pci_find_device(PCI_VENDOR_ID_NS, + PCI_DEVICE_ID_NS_SC1100_BRIDGE, + NULL) == NULL) return -ENODEV; rc = -ENXIO; diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 1a649462d..c43ac493d 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -387,8 +387,8 @@ config BLK_DEV_OFFBOARD If in doubt, say N. config BLK_DEV_GENERIC - bool "Generic PCI IDE Chipset Support" - depends on PCI && BLK_DEV_IDEPCI + tristate "Generic PCI IDE Chipset Support" + depends on BLK_DEV_IDEPCI config BLK_DEV_OPTI621 tristate "OPTi 82C621 chipset enhanced support (EXPERIMENTAL)" diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index b66090313..47761a0a5 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1713,7 +1713,22 @@ static void ide_device_shutdown(struct device *dev) { ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); +#ifdef CONFIG_ALPHA + /* On Alpha, halt(8) doesn't actually turn the machine off, + it puts you into the sort of firmware monitor. Typically, + it's used to boot another kernel image, so it's not much + different from reboot(8). Therefore, we don't need to + spin down the disk in this case, especially since Alpha + firmware doesn't handle disks in standby mode properly. + On the other hand, it's reasonably safe to turn the power + off when the shutdown process reaches the firmware prompt, + as the firmware initialization takes rather long time - + at least 10 seconds, which should be sufficient for + the disk to expire its write cache. */ + if (system_state != SYSTEM_POWER_OFF) { +#else if (system_state == SYSTEM_RESTART) { +#endif ide_cacheflush_p(drive); return; } diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index f15f6a310..ed26518c1 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -800,18 +800,12 @@ void probe_hwif (ide_hwif_t *hwif) for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - int enable_dma = 1; if (drive->present) { if (hwif->tuneproc != NULL && drive->autotune == IDE_TUNE_AUTO) /* auto-tune PIO mode */ hwif->tuneproc(drive, 255); - -#ifdef CONFIG_IDEDMA_ONLYDISK - if (drive->media != ide_disk) - enable_dma = 0; -#endif /* * MAJOR HACK BARF :-/ * @@ -831,7 +825,9 @@ void probe_hwif (ide_hwif_t *hwif) * PARANOIA!!! */ hwif->ide_dma_off_quietly(drive); - if (enable_dma) +#ifdef CONFIG_IDEDMA_ONLYDISK + if (drive->media == ide_disk) +#endif hwif->ide_dma_check(drive); } } diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index f474e1dbe..0c3b227fe 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -525,8 +525,6 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi { ide_pci_device_t *d = &aec62xx_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); d->init_setup(dev, d); return 0; } diff --git a/drivers/ide/pci/aec62xx.h b/drivers/ide/pci/aec62xx.h index fe088bc3d..3f272752c 100644 --- a/drivers/ide/pci/aec62xx.h +++ b/drivers/ide/pci/aec62xx.h @@ -78,8 +78,6 @@ static void init_dma_aec62xx(ide_hwif_t *, unsigned long); static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_ARTOP, - .device = PCI_DEVICE_ID_ARTOP_ATP850UF, .name = "AEC6210", .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, @@ -90,8 +88,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, .bootable = OFF_BOARD, },{ /* 1 */ - .vendor = PCI_VENDOR_ID_ARTOP, - .device = PCI_DEVICE_ID_ARTOP_ATP860, .name = "AEC6260", .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, @@ -101,8 +97,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .autodma = NOAUTODMA, .bootable = OFF_BOARD, },{ /* 2 */ - .vendor = PCI_VENDOR_ID_ARTOP, - .device = PCI_DEVICE_ID_ARTOP_ATP860R, .name = "AEC6260R", .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, @@ -113,8 +107,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, .bootable = NEVER_BOARD, },{ /* 3 */ - .vendor = PCI_VENDOR_ID_ARTOP, - .device = PCI_DEVICE_ID_ARTOP_ATP865, .name = "AEC6X80", .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, @@ -124,8 +116,6 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 4 */ - .vendor = PCI_VENDOR_ID_ARTOP, - .device = PCI_DEVICE_ID_ARTOP_ATP865R, .name = "AEC6X80R", .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, diff --git a/drivers/ide/pci/alim15x3.h b/drivers/ide/pci/alim15x3.h index 748114e9a..989bb9be2 100644 --- a/drivers/ide/pci/alim15x3.h +++ b/drivers/ide/pci/alim15x3.h @@ -14,8 +14,6 @@ static void init_dma_ali15x3(ide_hwif_t *, unsigned long); static ide_pci_device_t ali15x3_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_AL, - .device = PCI_DEVICE_ID_AL_M5229, .name = "ALI15X3", .init_chipset = init_chipset_ali15x3, .init_hwif = init_hwif_ali15x3, diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 5093d3cff..d6b052300 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -1,7 +1,8 @@ /* * Version 2.13 * - * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s IDE driver for Linux. + * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 + * IDE driver for Linux. * * Copyright (c) 2000-2002 Vojtech Pavlik * @@ -26,7 +27,8 @@ #include #include "ide-timing.h" -#include "amd74xx.h" + +#define DISPLAY_AMD_TIMINGS #define AMD_IDE_ENABLE (0x00 + amd_config->base) #define AMD_IDE_CONFIG (0x01 + amd_config->base) @@ -68,6 +70,12 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, 0x50, AMD_UDMA_133 }, { 0 } }; @@ -441,11 +449,55 @@ static void __init init_hwif_amd74xx(ide_hwif_t *hwif) hwif->drives[1].autodma = hwif->autodma; } +#define DECLARE_AMD_DEV(name_str) \ + { \ + .name = name_str, \ + .init_chipset = init_chipset_amd74xx, \ + .init_hwif = init_hwif_amd74xx, \ + .channels = 2, \ + .autodma = AUTODMA, \ + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ + .bootable = ON_BOARD, \ + } + +#define DECLARE_NV_DEV(name_str) \ + { \ + .name = name_str, \ + .init_chipset = init_chipset_amd74xx, \ + .init_hwif = init_hwif_amd74xx, \ + .channels = 2, \ + .autodma = AUTODMA, \ + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \ + .bootable = ON_BOARD, \ + } + +static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { + /* 0 */ DECLARE_AMD_DEV("AMD7401"), + /* 1 */ DECLARE_AMD_DEV("AMD7409"), + /* 2 */ DECLARE_AMD_DEV("AMD7411"), + /* 3 */ DECLARE_AMD_DEV("AMD7441"), + /* 4 */ DECLARE_AMD_DEV("AMD8111"), + + /* 5 */ DECLARE_NV_DEV("NFORCE"), + /* 6 */ DECLARE_NV_DEV("NFORCE2"), + /* 7 */ DECLARE_NV_DEV("NFORCE2-U400R"), + /* 8 */ DECLARE_NV_DEV("NFORCE2-U400R-SATA"), + /* 9 */ DECLARE_NV_DEV("NFORCE3-150"), + /* 10 */ DECLARE_NV_DEV("NFORCE3-250"), + /* 11 */ DECLARE_NV_DEV("NFORCE3-250-SATA"), + /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), + /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), + /* 14 */ DECLARE_NV_DEV("NFORCE-CK804-SATA"), + /* 15 */ DECLARE_NV_DEV("NFORCE-CK804-SATA2"), + /* 16 */ DECLARE_NV_DEV("NFORCE-MCP04"), + /* 17 */ DECLARE_NV_DEV("NFORCE-MCP04-SATA"), + /* 18 */ DECLARE_NV_DEV("NFORCE-MCP04-SATA2") +}; + static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) { amd_chipset = amd74xx_chipsets + id->driver_data; amd_config = amd_ide_chips + id->driver_data; - if (dev->device != amd_chipset->device) BUG(); if (dev->device != amd_config->id) BUG(); ide_setup_pci_device(dev, amd_chipset); return 0; @@ -465,6 +517,12 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 18475a89b..bd3708568 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c @@ -458,8 +458,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) static ide_pci_device_t atiixp_pci_info[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_ATI, - .device = PCI_DEVICE_ID_ATI_IXP_IDE, .name = "ATIIXP", .init_chipset = init_chipset_atiixp, .init_hwif = init_hwif_atiixp, @@ -481,11 +479,7 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = { static int __devinit atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &atiixp_pci_info[id->driver_data]; - - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &atiixp_pci_info[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index c04122f8a..1f4d08425 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -746,10 +746,7 @@ static void __init init_hwif_cmd64x (ide_hwif_t *hwif) static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &cmd64x_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/cmd64x.h b/drivers/ide/pci/cmd64x.h index 423e95e8e..f5dde235a 100644 --- a/drivers/ide/pci/cmd64x.h +++ b/drivers/ide/pci/cmd64x.h @@ -65,8 +65,6 @@ static void init_hwif_cmd64x(ide_hwif_t *); static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_CMD, - .device = PCI_DEVICE_ID_CMD_643, .name = "CMD643", .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, @@ -74,8 +72,6 @@ static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 1 */ - .vendor = PCI_VENDOR_ID_CMD, - .device = PCI_DEVICE_ID_CMD_646, .name = "CMD646", .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, @@ -84,8 +80,6 @@ static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { .enablebits = {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, .bootable = ON_BOARD, },{ /* 2 */ - .vendor = PCI_VENDOR_ID_CMD, - .device = PCI_DEVICE_ID_CMD_648, .name = "CMD648", .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, @@ -93,8 +87,6 @@ static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ - .vendor = PCI_VENDOR_ID_CMD, - .device = PCI_DEVICE_ID_CMD_649, .name = "CMD649", .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, diff --git a/drivers/ide/pci/cs5520.h b/drivers/ide/pci/cs5520.h index 339530613..f2cdc5343 100644 --- a/drivers/ide/pci/cs5520.h +++ b/drivers/ide/pci/cs5520.h @@ -13,28 +13,24 @@ static void cs5520_init_setup_dma(struct pci_dev *dev, struct ide_pci_device_s * static ide_pci_device_t cyrix_chipsets[] __devinitdata = { { - .vendor = PCI_VENDOR_ID_CYRIX, - .device = PCI_DEVICE_ID_CYRIX_5510, .name = "Cyrix 5510", .init_chipset = init_chipset_cs5520, .init_setup_dma = cs5520_init_setup_dma, .init_hwif = init_hwif_cs5520, - .isa_ports = 1, .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .flags = IDEPCI_FLAG_ISA_PORTS, }, { - .vendor = PCI_VENDOR_ID_CYRIX, - .device = PCI_DEVICE_ID_CYRIX_5520, .name = "Cyrix 5520", .init_chipset = init_chipset_cs5520, .init_setup_dma = cs5520_init_setup_dma, .init_hwif = init_hwif_cs5520, - .isa_ports = 1, .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .flags = IDEPCI_FLAG_ISA_PORTS, } }; diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 7544904e9..19c97e89a 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -406,10 +406,7 @@ static void __init init_hwif_cs5530 (ide_hwif_t *hwif) static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &cs5530_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &cs5530_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/cs5530.h b/drivers/ide/pci/cs5530.h index cf651f2a9..08fe18a09 100644 --- a/drivers/ide/pci/cs5530.h +++ b/drivers/ide/pci/cs5530.h @@ -12,14 +12,13 @@ static void init_hwif_cs5530(ide_hwif_t *); static ide_pci_device_t cs5530_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_CYRIX, - .device = PCI_DEVICE_ID_CYRIX_5530_IDE, .name = "CS5530", .init_chipset = init_chipset_cs5530, .init_hwif = init_hwif_cs5530, .channels = 2, .autodma = AUTODMA, .bootable = ON_BOARD, + .flags = IDEPCI_FLAG_FORCE_MASTER, } }; diff --git a/drivers/ide/pci/cy82c693.h b/drivers/ide/pci/cy82c693.h index 8a22479f6..cccb69b4d 100644 --- a/drivers/ide/pci/cy82c693.h +++ b/drivers/ide/pci/cy82c693.h @@ -70,8 +70,6 @@ static void init_iops_cy82c693(ide_hwif_t *); static ide_pci_device_t cy82c693_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_CONTAQ, - .device = PCI_DEVICE_ID_CONTAQ_82C693, .name = "CY82C693", .init_chipset = init_chipset_cy82c693, .init_iops = init_iops_cy82c693, diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index ca9997738..e73279563 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -77,8 +77,6 @@ static void __init init_hwif_generic (ide_hwif_t *hwif) if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { ide_pci_device_t *unknown = unknown_chipset; -// unknown->vendor = dev->vendor; -// unknown->device = dev->device; init_setup_unknown(dev, unknown); return 1; } @@ -99,15 +97,13 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi ide_pci_device_t *d = &generic_chipsets[id->driver_data]; u16 command; - if (dev->device != d->device) - BUG(); - if ((d->vendor == PCI_VENDOR_ID_UMC) && - (d->device == PCI_DEVICE_ID_UMC_UM8886A) && + if (dev->vendor == PCI_VENDOR_ID_UMC && + dev->device == PCI_DEVICE_ID_UMC_UM8886A && (!(PCI_FUNC(dev->devfn) & 1))) return 1; /* UM8886A/BF pair */ - if ((d->vendor == PCI_VENDOR_ID_OPTI) && - (d->device == PCI_DEVICE_ID_OPTI_82C558) && + if (dev->vendor == PCI_VENDOR_ID_OPTI && + dev->device == PCI_DEVICE_ID_OPTI_82C558 && (!(PCI_FUNC(dev->devfn) & 1))) return 1; diff --git a/drivers/ide/pci/generic.h b/drivers/ide/pci/generic.h index fdaaf2113..a66692026 100644 --- a/drivers/ide/pci/generic.h +++ b/drivers/ide/pci/generic.h @@ -10,8 +10,6 @@ static void init_hwif_generic(ide_hwif_t *); static ide_pci_device_t generic_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_NS, - .device = PCI_DEVICE_ID_NS_87410, .name = "NS87410", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -20,8 +18,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, .bootable = ON_BOARD, },{ /* 1 */ - .vendor = PCI_VENDOR_ID_PCTECH, - .device = PCI_DEVICE_ID_PCTECH_SAMURAI_IDE, .name = "SAMURAI", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -29,8 +25,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 2 */ - .vendor = PCI_VENDOR_ID_HOLTEK, - .device = PCI_DEVICE_ID_HOLTEK_6565, .name = "HT6565", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -38,8 +32,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 3 */ - .vendor = PCI_VENDOR_ID_UMC, - .device = PCI_DEVICE_ID_UMC_UM8673F, .name = "UM8673F", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -47,8 +39,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = NODMA, .bootable = ON_BOARD, },{ /* 4 */ - .vendor = PCI_VENDOR_ID_UMC, - .device = PCI_DEVICE_ID_UMC_UM8886A, .name = "UM8886A", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -56,8 +46,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = NODMA, .bootable = ON_BOARD, },{ /* 5 */ - .vendor = PCI_VENDOR_ID_UMC, - .device = PCI_DEVICE_ID_UMC_UM8886BF, .name = "UM8886BF", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -65,8 +53,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = NODMA, .bootable = ON_BOARD, },{ /* 6 */ - .vendor = PCI_VENDOR_ID_HINT, - .device = PCI_DEVICE_ID_HINT_VXPROII_IDE, .name = "HINT_IDE", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -74,8 +60,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 7 */ - .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_DEVICE_ID_VIA_82C561, .name = "VIA_IDE", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -83,8 +67,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 8 */ - .vendor = PCI_VENDOR_ID_OPTI, - .device = PCI_DEVICE_ID_OPTI_82C558, .name = "OPTI621V", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -92,8 +74,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 9 */ - .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_DEVICE_ID_VIA_8237_SATA, .name = "VIA8237SATA", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -101,8 +81,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 10 */ - .vendor = PCI_VENDOR_ID_TOSHIBA, - .device = PCI_DEVICE_ID_TOSHIBA_PICCOLO, .name = "Piccolo0102", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -110,8 +88,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 11 */ - .vendor = PCI_VENDOR_ID_TOSHIBA, - .device = PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, .name = "Piccolo0103", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -119,8 +95,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .autodma = NOAUTODMA, .bootable = ON_BOARD, },{ /* 12 */ - .vendor = PCI_VENDOR_ID_TOSHIBA, - .device = PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, .name = "Piccolo0105", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, @@ -133,8 +107,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { #if 0 static ide_pci_device_t unknown_chipset[] __devinitdata = { { /* 0 */ - .vendor = 0, - .device = 0, .name = "PCI_IDE", .init_chipset = init_chipset_generic, .init_hwif = init_hwif_generic, diff --git a/drivers/ide/pci/hpt34x.h b/drivers/ide/pci/hpt34x.h index 9fa3813a5..465f56715 100644 --- a/drivers/ide/pci/hpt34x.h +++ b/drivers/ide/pci/hpt34x.h @@ -18,8 +18,6 @@ static void init_hwif_hpt34x(ide_hwif_t *); static ide_pci_device_t hpt34x_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_TTI, - .device = PCI_DEVICE_ID_TTI_HPT343, .name = "HPT34X", .init_chipset = init_chipset_hpt34x, .init_hwif = init_hwif_hpt34x, diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index d3129b2a9..5ca4a581f 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1241,8 +1241,6 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic { ide_pci_device_t *d = &hpt366_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); d->init_setup(dev, d); return 0; } diff --git a/drivers/ide/pci/hpt366.h b/drivers/ide/pci/hpt366.h index 8987b25c8..7b3d8b410 100644 --- a/drivers/ide/pci/hpt366.h +++ b/drivers/ide/pci/hpt366.h @@ -425,8 +425,6 @@ static void init_dma_hpt366(ide_hwif_t *, unsigned long); static ide_pci_device_t hpt366_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_TTI, - .device = PCI_DEVICE_ID_TTI_HPT366, .name = "HPT366", .init_setup = init_setup_hpt366, .init_chipset = init_chipset_hpt366, @@ -437,8 +435,6 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .extra = 240 },{ /* 1 */ - .vendor = PCI_VENDOR_ID_TTI, - .device = PCI_DEVICE_ID_TTI_HPT372, .name = "HPT372A", .init_setup = init_setup_hpt37x, .init_chipset = init_chipset_hpt366, @@ -448,8 +444,6 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 2 */ - .vendor = PCI_VENDOR_ID_TTI, - .device = PCI_DEVICE_ID_TTI_HPT302, .name = "HPT302", .init_setup = init_setup_hpt37x, .init_chipset = init_chipset_hpt366, @@ -459,8 +453,6 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 3 */ - .vendor = PCI_VENDOR_ID_TTI, - .device = PCI_DEVICE_ID_TTI_HPT371, .name = "HPT371", .init_setup = init_setup_hpt37x, .init_chipset = init_chipset_hpt366, @@ -470,8 +462,6 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 4 */ - .vendor = PCI_VENDOR_ID_TTI, - .device = PCI_DEVICE_ID_TTI_HPT374, .name = "HPT374", .init_setup = init_setup_hpt374, .init_chipset = init_chipset_hpt366, diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c index 873e56e6a..b65ce0877 100644 --- a/drivers/ide/pci/it8172.c +++ b/drivers/ide/pci/it8172.c @@ -288,11 +288,10 @@ static void __init init_hwif_it8172 (ide_hwif_t *hwif) static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &it8172_chipsets[id->driver_data]; if ((!(PCI_FUNC(dev->devfn) & 1) || (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))) return 1; /* IT8172 is more than only a IDE controller */ - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &it8172_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/it8172.h b/drivers/ide/pci/it8172.h index e80bc6283..fbc2b6400 100644 --- a/drivers/ide/pci/it8172.h +++ b/drivers/ide/pci/it8172.h @@ -20,8 +20,6 @@ static void init_hwif_it8172(ide_hwif_t *); static ide_pci_device_t it8172_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_ITE, - .device = PCI_DEVICE_ID_ITE_IT8172G, .name = "IT8172G", .init_setup = init_setup_it8172, .init_chipset = init_chipset_it8172, diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 279c0323c..1809edddb 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -219,10 +219,7 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif) static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &ns87415_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &ns87415_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/ns87415.h b/drivers/ide/pci/ns87415.h index 8c4c1b8fc..a2594c7fd 100644 --- a/drivers/ide/pci/ns87415.h +++ b/drivers/ide/pci/ns87415.h @@ -9,8 +9,6 @@ static void init_hwif_ns87415(ide_hwif_t *); static ide_pci_device_t ns87415_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_NS, - .device = PCI_DEVICE_ID_NS_87415, .name = "NS87415", .init_hwif = init_hwif_ns87415, .channels = 2, diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index 8a6c31649..3ca7db7d5 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c @@ -355,10 +355,7 @@ static void __init init_setup_opti621 (struct pci_dev *dev, ide_pci_device_t *d) static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &opti621_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/opti621.h b/drivers/ide/pci/opti621.h index 8860eeb8a..a0e6504c3 100644 --- a/drivers/ide/pci/opti621.h +++ b/drivers/ide/pci/opti621.h @@ -10,8 +10,6 @@ static void init_hwif_opti621(ide_hwif_t *); static ide_pci_device_t opti621_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_OPTI, - .device = PCI_DEVICE_ID_OPTI_82C621, .name = "OPTI621", .init_setup = init_setup_opti621, .init_hwif = init_hwif_opti621, @@ -20,8 +18,6 @@ static ide_pci_device_t opti621_chipsets[] __devinitdata = { .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, .bootable = ON_BOARD, },{ /* 1 */ - .vendor = PCI_VENDOR_ID_OPTI, - .device = PCI_DEVICE_ID_OPTI_82C825, .name = "OPTI621X", .init_setup = init_setup_opti621, .init_hwif = init_hwif_opti621, diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index f753c6316..fbc0bd81e 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -514,8 +514,6 @@ static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_de { ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); d->init_setup(dev, d); return 0; } diff --git a/drivers/ide/pci/pdc202xx_new.h b/drivers/ide/pci/pdc202xx_new.h index d651f8bba..0abec0ed7 100644 --- a/drivers/ide/pci/pdc202xx_new.h +++ b/drivers/ide/pci/pdc202xx_new.h @@ -53,8 +53,6 @@ static void init_hwif_pdc202new(ide_hwif_t *); static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20268, .name = "PDC20268", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, @@ -63,8 +61,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 1 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20269, .name = "PDC20269", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, @@ -73,8 +69,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 2 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20270, .name = "PDC20270", .init_setup = init_setup_pdc20270, .init_chipset = init_chipset_pdcnew, @@ -86,8 +80,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { #endif .bootable = OFF_BOARD, },{ /* 3 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20271, .name = "PDC20271", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, @@ -96,8 +88,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 4 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20275, .name = "PDC20275", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, @@ -106,8 +96,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = OFF_BOARD, },{ /* 5 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20276, .name = "PDC20276", .init_setup = init_setup_pdc20276, .init_chipset = init_chipset_pdcnew, @@ -119,8 +107,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { #endif .bootable = OFF_BOARD, },{ /* 6 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20277, .name = "PDC20277", .init_setup = init_setup_pdcnew, .init_chipset = init_chipset_pdcnew, diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index aa04a13c1..99fbe04ec 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -884,8 +884,6 @@ static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_dev { ide_pci_device_t *d = &pdc202xx_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); d->init_setup(dev, d); return 0; } diff --git a/drivers/ide/pci/pdc202xx_old.h b/drivers/ide/pci/pdc202xx_old.h index b8a5ed65f..95ea2c8aa 100644 --- a/drivers/ide/pci/pdc202xx_old.h +++ b/drivers/ide/pci/pdc202xx_old.h @@ -180,8 +180,6 @@ static void init_dma_pdc202xx(ide_hwif_t *, unsigned long); static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20246, .name = "PDC20246", .init_setup = init_setup_pdc202ata4, .init_chipset = init_chipset_pdc202xx, @@ -195,8 +193,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .extra = 16, },{ /* 1 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20262, .name = "PDC20262", .init_setup = init_setup_pdc202ata4, .init_chipset = init_chipset_pdc202xx, @@ -209,9 +205,8 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { #endif .bootable = OFF_BOARD, .extra = 48, + .flags = IDEPCI_FLAG_FORCE_PDC, },{ /* 2 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20263, .name = "PDC20263", .init_setup = init_setup_pdc202ata4, .init_chipset = init_chipset_pdc202xx, @@ -225,8 +220,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { .bootable = OFF_BOARD, .extra = 48, },{ /* 3 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20265, .name = "PDC20265", .init_setup = init_setup_pdc20265, .init_chipset = init_chipset_pdc202xx, @@ -239,9 +232,8 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { #endif .bootable = OFF_BOARD, .extra = 48, + .flags = IDEPCI_FLAG_FORCE_PDC, },{ /* 4 */ - .vendor = PCI_VENDOR_ID_PROMISE, - .device = PCI_DEVICE_ID_PROMISE_20267, .name = "PDC20267", .init_setup = init_setup_pdc202xx, .init_chipset = init_chipset_pdc202xx, diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index c7d68784d..3d21a5b5e 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -744,8 +744,6 @@ static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_ { ide_pci_device_t *d = &piix_pci_info[id->driver_data]; - if (dev->device != d->device) - BUG(); d->init_setup(dev, d); return 0; } diff --git a/drivers/ide/pci/piix.h b/drivers/ide/pci/piix.h index a30353b16..f71db14ae 100644 --- a/drivers/ide/pci/piix.h +++ b/drivers/ide/pci/piix.h @@ -13,10 +13,8 @@ static void init_setup_piix(struct pci_dev *, ide_pci_device_t *); static unsigned int __devinit init_chipset_piix(struct pci_dev *, const char *); static void init_hwif_piix(ide_hwif_t *); -#define DECLARE_PIIX_DEV(pci_id, name_str) \ +#define DECLARE_PIIX_DEV(name_str) \ { \ - .vendor = PCI_VENDOR_ID_INTEL, \ - .device = pci_id, \ .name = name_str, \ .init_setup = init_setup_piix, \ .init_chipset = init_chipset_piix, \ @@ -33,12 +31,10 @@ static void init_hwif_piix(ide_hwif_t *); */ static ide_pci_device_t piix_pci_info[] __devinitdata = { - /* 0 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82371FB_0, "PIIXa"), - /* 1 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82371FB_1, "PIIXb"), + /* 0 */ DECLARE_PIIX_DEV("PIIXa"), + /* 1 */ DECLARE_PIIX_DEV("PIIXb"), { /* 2 */ - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_ID_INTEL_82371MX, .name = "MPIIX", .init_setup = init_setup_piix, .init_hwif = init_hwif_piix, @@ -48,24 +44,24 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = { .bootable = ON_BOARD, }, - /* 3 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82371SB_1, "PIIX3"), - /* 4 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82371AB, "PIIX4"), - /* 5 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801AB_1, "ICH0"), - /* 6 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82443MX_1, "PIIX4"), - /* 7 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801AA_1, "ICH"), - /* 8 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82372FB_1, "PIIX4"), - /* 9 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82451NX, "PIIX4"), - /* 10 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801BA_9, "ICH2"), - /* 11 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801BA_8, "ICH2M"), - /* 12 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801CA_10, "ICH3M"), - /* 13 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801CA_11, "ICH3"), - /* 14 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801DB_11, "ICH4"), - /* 15 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801EB_11, "ICH5"), - /* 16 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801E_11, "C-ICH"), - /* 17 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801DB_10, "ICH4"), - /* 18 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801EB_1, "ICH5-SATA"), - /* 19 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_ESB_2, "ICH5"), - /* 20 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_ICH6_19, "ICH6") + /* 3 */ DECLARE_PIIX_DEV("PIIX3"), + /* 4 */ DECLARE_PIIX_DEV("PIIX4"), + /* 5 */ DECLARE_PIIX_DEV("ICH0"), + /* 6 */ DECLARE_PIIX_DEV("PIIX4"), + /* 7 */ DECLARE_PIIX_DEV("ICH"), + /* 8 */ DECLARE_PIIX_DEV("PIIX4"), + /* 9 */ DECLARE_PIIX_DEV("PIIX4"), + /* 10 */ DECLARE_PIIX_DEV("ICH2"), + /* 11 */ DECLARE_PIIX_DEV("ICH2M"), + /* 12 */ DECLARE_PIIX_DEV("ICH3M"), + /* 13 */ DECLARE_PIIX_DEV("ICH3"), + /* 14 */ DECLARE_PIIX_DEV("ICH4"), + /* 15 */ DECLARE_PIIX_DEV("ICH5"), + /* 16 */ DECLARE_PIIX_DEV("C-ICH"), + /* 17 */ DECLARE_PIIX_DEV("ICH4"), + /* 18 */ DECLARE_PIIX_DEV("ICH5-SATA"), + /* 19 */ DECLARE_PIIX_DEV("ICH5"), + /* 20 */ DECLARE_PIIX_DEV("ICH6") }; #endif /* PIIX_H */ diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c index 963b8458b..78669068d 100644 --- a/drivers/ide/pci/rz1000.c +++ b/drivers/ide/pci/rz1000.c @@ -56,10 +56,7 @@ static void __init init_hwif_rz1000 (ide_hwif_t *hwif) static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &rz1000_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &rz1000_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/rz1000.h b/drivers/ide/pci/rz1000.h index 0f4575eed..5c7c611c5 100644 --- a/drivers/ide/pci/rz1000.h +++ b/drivers/ide/pci/rz1000.h @@ -8,17 +8,13 @@ static void init_hwif_rz1000(ide_hwif_t *); static ide_pci_device_t rz1000_chipsets[] __devinitdata = { -{ - .vendor = PCI_VENDOR_ID_PCTECH, - .device = PCI_DEVICE_ID_PCTECH_RZ1000, + { .name = "RZ1000", .init_hwif = init_hwif_rz1000, .channels = 2, .autodma = NODMA, .bootable = ON_BOARD, },{ - .vendor = PCI_VENDOR_ID_PCTECH, - .device = PCI_DEVICE_ID_PCTECH_RZ1001, .name = "RZ1001", .init_hwif = init_hwif_rz1000, .channels = 2, diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 29a263add..58d1e5874 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -547,10 +547,7 @@ static void __init init_hwif_sc1200 (ide_hwif_t *hwif) static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &sc1200_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &sc1200_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/sc1200.h b/drivers/ide/pci/sc1200.h index 22e303d77..c58e68988 100644 --- a/drivers/ide/pci/sc1200.h +++ b/drivers/ide/pci/sc1200.h @@ -12,8 +12,6 @@ static void init_hwif_sc1200(ide_hwif_t *); static ide_pci_device_t sc1200_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_NS, - .device = PCI_DEVICE_ID_NS_SCx200_IDE, .name = "SC1200", .init_chipset = init_chipset_sc1200, .init_hwif = init_hwif_sc1200, diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 3418232fc..27d907c9b 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -777,8 +777,8 @@ static void __init init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d) d->autodma = AUTODMA; #endif - d->channels = (((d->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (d->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) && + d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || + dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && (!(PCI_FUNC(dev->devfn) & 1))) ? 1 : 2; ide_setup_pci_device(dev, d); @@ -798,8 +798,6 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device { ide_pci_device_t *d = &serverworks_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); d->init_setup(dev, d); return 0; } diff --git a/drivers/ide/pci/serverworks.h b/drivers/ide/pci/serverworks.h index 8a1d9fe18..aa8bd8b9d 100644 --- a/drivers/ide/pci/serverworks.h +++ b/drivers/ide/pci/serverworks.h @@ -31,8 +31,6 @@ static void init_dma_svwks(ide_hwif_t *, unsigned long); static ide_pci_device_t serverworks_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_SERVERWORKS, - .device = PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, .name = "SvrWks OSB4", .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, @@ -41,8 +39,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 1 */ - .vendor = PCI_VENDOR_ID_SERVERWORKS, - .device = PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, .name = "SvrWks CSB5", .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, @@ -52,8 +48,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 2 */ - .vendor = PCI_VENDOR_ID_SERVERWORKS, - .device = PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, .name = "SvrWks CSB6", .init_setup = init_setup_csb6, .init_chipset = init_chipset_svwks, @@ -63,8 +57,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 3 */ - .vendor = PCI_VENDOR_ID_SERVERWORKS, - .device = PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, .name = "SvrWks CSB6", .init_setup = init_setup_csb6, .init_chipset = init_chipset_svwks, diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index d8e739f1c..0187aafac 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -757,8 +757,6 @@ pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d) static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { { /* Channel 0 */ - .vendor = PCI_VENDOR_ID_SGI, - .device = PCI_DEVICE_ID_SGI_IOC4, .name = "SGIIOC4", .init_hwif = ide_init_sgiioc4, .init_dma = ide_dma_sgiioc4, @@ -772,16 +770,7 @@ static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { static int __devinit sgiioc4_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &sgiioc4_chipsets[id->driver_data]; - if (dev->device != d->device) { - printk(KERN_ERR "Error in %s(dev 0x%p | id 0x%p )\n", - __FUNCTION__, (void *) dev, (void *) id); - BUG(); - } - - if (pci_init_sgiioc4(dev, d)) - return 0; - + pci_init_sgiioc4(dev, &sgiioc4_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index ff530bf14..5b2ab769b 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -21,7 +21,6 @@ * if neccessary */ -#include #include #include #include @@ -34,15 +33,6 @@ #include "siimage.h" -#if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) -#include - -static u8 siimage_proc = 0; -#define SIIMAGE_MAX_DEVS 16 -static struct pci_dev *siimage_devs[SIIMAGE_MAX_DEVS]; -static int n_siimage_devs; -#endif /* defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) */ - /** * pdev_is_sata - check if device is SATA * @pdev: PCI device to check @@ -121,67 +111,6 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) return base; } -#if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) -/** - * print_siimage_get_info - print minimal proc information - * @buf: buffer to write into (kernel space) - * @dev: PCI device we are describing - * @index: Controller number - * - * Print the basic information for the state of the CMD680/SI3112 - * channel. We don't actually dump a lot of information out for - * this controller although we could expand it if we needed. - */ - -static char *print_siimage_get_info (char *buf, struct pci_dev *dev, int index) -{ - char *p = buf; - u8 mmio = (pci_get_drvdata(dev) != NULL) ? 1 : 0; - unsigned long bmdma = pci_resource_start(dev, 4); - - if(mmio) - bmdma = pci_resource_start(dev, 5); - - p += sprintf(p, "\nController: %d\n", index); - p += sprintf(p, "SiI%x Chipset.\n", dev->device); - if (mmio) - p += sprintf(p, "MMIO Base 0x%lx\n", bmdma); - p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma); - p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma+8); - return (char *)p; -} - -/** - * siimage_get_info - proc callback - * @buffer: kernel buffer to complete - * @addr: written with base of data to return - * offset: seek offset - * count: bytes to fill in - * - * Called when the user reads data from the virtual file for this - * controller from /proc - */ - -static int siimage_get_info (char *buffer, char **addr, off_t offset, int count) -{ - char *p = buffer; - int len; - u16 i; - - p += sprintf(p, "\n"); - for (i = 0; i < n_siimage_devs; i++) { - struct pci_dev *dev = siimage_devs[i]; - p = print_siimage_get_info(p, dev, i); - } - /* p - buffer must be less than 4k! */ - len = (p - buffer) - offset; - *addr = buffer + offset; - - return len > count ? count : len; -} - -#endif /* defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) */ - /** * siimage_ratemask - Compute available modes * @drive: IDE drive @@ -779,15 +708,6 @@ static void proc_reports_siimage (struct pci_dev *dev, u8 clocking, const char * case 0x00: printk("== 100\n"); break; } } - -#if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) - siimage_devs[n_siimage_devs++] = dev; - - if (!siimage_proc) { - siimage_proc = 1; - ide_pci_create_host_proc("siimage", siimage_get_info); - } -#endif /* DISPLAY_SIIMAGE_TIMINGS && CONFIG_PROC_FS */ } /** @@ -1183,10 +1103,7 @@ static void __init init_hwif_siimage (ide_hwif_t *hwif) static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &siimage_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &siimage_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/siimage.h b/drivers/ide/pci/siimage.h index 1f0885e61..b83b4c336 100644 --- a/drivers/ide/pci/siimage.h +++ b/drivers/ide/pci/siimage.h @@ -1,14 +1,11 @@ #ifndef SIIMAGE_H #define SIIMAGE_H -#include #include #include #include -#define DISPLAY_SIIMAGE_TIMINGS - #undef SIIMAGE_VIRTUAL_DMAPIO #undef SIIMAGE_BUFFERED_TASKFILE #undef SIIMAGE_LARGE_DMA @@ -27,8 +24,6 @@ static void init_hwif_siimage(ide_hwif_t *); static ide_pci_device_t siimage_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_CMD, - .device = PCI_DEVICE_ID_SII_680, .name = "SiI680", .init_chipset = init_chipset_siimage, .init_iops = init_iops_siimage, @@ -37,8 +32,6 @@ static ide_pci_device_t siimage_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 1 */ - .vendor = PCI_VENDOR_ID_CMD, - .device = PCI_DEVICE_ID_SII_3112, .name = "SiI3112 Serial ATA", .init_chipset = init_chipset_siimage, .init_iops = init_iops_siimage, @@ -47,8 +40,6 @@ static ide_pci_device_t siimage_chipsets[] __devinitdata = { .autodma = AUTODMA, .bootable = ON_BOARD, },{ /* 2 */ - .vendor = PCI_VENDOR_ID_CMD, - .device = PCI_DEVICE_ID_SII_1210SA, .name = "Adaptec AAR-1210SA", .init_chipset = init_chipset_siimage, .init_iops = init_iops_siimage, diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 6c56f5670..6254eab6d 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -946,10 +946,7 @@ static void __init init_hwif_sis5513 (ide_hwif_t *hwif) static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &sis5513_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &sis5513_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/sis5513.h b/drivers/ide/pci/sis5513.h index 5627097b2..d66e9a74b 100644 --- a/drivers/ide/pci/sis5513.h +++ b/drivers/ide/pci/sis5513.h @@ -12,8 +12,6 @@ static void init_hwif_sis5513(ide_hwif_t *); static ide_pci_device_t sis5513_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_5513, .name = "SIS5513", .init_chipset = init_chipset_sis5513, .init_hwif = init_hwif_sis5513, diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 516f799cb..4706ebfba 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -483,10 +483,7 @@ static void __init init_hwif_sl82c105(ide_hwif_t *hwif) static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &sl82c105_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &sl82c105_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/sl82c105.h b/drivers/ide/pci/sl82c105.h index a4e6e46f6..f2d34a254 100644 --- a/drivers/ide/pci/sl82c105.h +++ b/drivers/ide/pci/sl82c105.h @@ -11,8 +11,6 @@ static void init_dma_sl82c105(ide_hwif_t *, unsigned long); static ide_pci_device_t sl82c105_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_WINBOND, - .device = PCI_DEVICE_ID_WINBOND_82C105, .name = "W82C105", .init_chipset = init_chipset_sl82c105, .init_hwif = init_hwif_sl82c105, diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 7fa07e13a..784224270 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -366,10 +366,7 @@ static void __init init_hwif_slc90e66 (ide_hwif_t *hwif) static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &slc90e66_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &slc90e66_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/slc90e66.h b/drivers/ide/pci/slc90e66.h index 077163768..57017958c 100644 --- a/drivers/ide/pci/slc90e66.h +++ b/drivers/ide/pci/slc90e66.h @@ -14,8 +14,6 @@ static void init_hwif_slc90e66(ide_hwif_t *); static ide_pci_device_t slc90e66_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_EFAR, - .device = PCI_DEVICE_ID_EFAR_SLC90E66_1, .name = "SLC90E66", .init_chipset = init_chipset_slc90e66, .init_hwif = init_hwif_slc90e66, diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index f7ff2f4d1..fc6186531 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -220,13 +220,9 @@ static unsigned int __init init_chipset_triflex(struct pci_dev *dev, static int __devinit triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &triflex_devices[id->driver_data]; - if (dev->device != d->device) - BUG(); - - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &triflex_devices[id->driver_data]); triflex_dev = dev; - + return 0; } diff --git a/drivers/ide/pci/triflex.h b/drivers/ide/pci/triflex.h index d99496e83..f826608f5 100644 --- a/drivers/ide/pci/triflex.h +++ b/drivers/ide/pci/triflex.h @@ -17,8 +17,6 @@ static void init_hwif_triflex(ide_hwif_t *); static ide_pci_device_t triflex_devices[] __devinitdata = { { - .vendor = PCI_VENDOR_ID_COMPAQ, - .device = PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE, .name = "TRIFLEX", .init_chipset = init_chipset_triflex, .init_hwif = init_hwif_triflex, diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c index 8a1f88fac..c07408908 100644 --- a/drivers/ide/pci/trm290.c +++ b/drivers/ide/pci/trm290.c @@ -397,10 +397,7 @@ void __init init_hwif_trm290 (ide_hwif_t *hwif) static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &trm290_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &trm290_chipsets[id->driver_data]); return 0; } diff --git a/drivers/ide/pci/trm290.h b/drivers/ide/pci/trm290.h index f633c0fa4..6c001d4d5 100644 --- a/drivers/ide/pci/trm290.h +++ b/drivers/ide/pci/trm290.h @@ -9,8 +9,6 @@ extern void init_hwif_trm290(ide_hwif_t *); static ide_pci_device_t trm290_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_TEKRAM, - .device = PCI_DEVICE_ID_TEKRAM_DC290, .name = "TRM290", .init_hwif = init_hwif_trm290, .channels = 2, diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 044b6c492..47c241d26 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -609,16 +609,13 @@ static void __init init_hwif_via82cxxx(ide_hwif_t *hwif) static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &via82cxxx_chipsets[id->driver_data]; - if (dev->device != d->device) - BUG(); - ide_setup_pci_device(dev, d); + ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]); return 0; } static struct pci_device_id via_pci_tbl[] = { { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, via_pci_tbl); diff --git a/drivers/ide/pci/via82cxxx.h b/drivers/ide/pci/via82cxxx.h index 151c30a7a..6504ca08a 100644 --- a/drivers/ide/pci/via82cxxx.h +++ b/drivers/ide/pci/via82cxxx.h @@ -12,18 +12,6 @@ static void init_hwif_via82cxxx(ide_hwif_t *); static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { { /* 0 */ - .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_DEVICE_ID_VIA_82C576_1, - .name = "VP_IDE", - .init_chipset = init_chipset_via82cxxx, - .init_hwif = init_hwif_via82cxxx, - .channels = 2, - .autodma = NOAUTODMA, - .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, - .bootable = ON_BOARD, - },{ /* 1 */ - .vendor = PCI_VENDOR_ID_VIA, - .device = PCI_DEVICE_ID_VIA_82C586_1, .name = "VP_IDE", .init_chipset = init_chipset_via82cxxx, .init_hwif = init_hwif_via82cxxx, diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 993e030c8..b485e6b70 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -285,14 +285,8 @@ second_chance_to_dma: void ide_setup_pci_noise (struct pci_dev *dev, ide_pci_device_t *d) { - if ((d->vendor != dev->vendor) && (d->device != dev->device)) { - printk(KERN_INFO "%s: unknown IDE controller at PCI slot " - "%s, VID=%04x, DID=%04x\n", - d->name, pci_name(dev), dev->vendor, dev->device); - } else { - printk(KERN_INFO "%s: IDE controller at PCI slot %s\n", - d->name, pci_name(dev)); - } + printk(KERN_INFO "%s: IDE controller at PCI slot %s\n", + d->name, pci_name(dev)); } EXPORT_SYMBOL_GPL(ide_setup_pci_noise); @@ -422,8 +416,7 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d, unsigned long ctl = 0, base = 0; ide_hwif_t *hwif; - if(!d->isa_ports) - { + if ((d->flags & IDEPCI_FLAG_ISA_PORTS) == 0) { /* Possibly we should fail if these checks report true */ ide_pci_check_iomem(dev, d, 2*port); ide_pci_check_iomem(dev, d, 2*port+1); @@ -495,9 +488,7 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi * Set up BM-DMA capability * (PnP BIOS should have done this) */ - if (!((d->device == PCI_DEVICE_ID_CYRIX_5530_IDE && d->vendor == PCI_VENDOR_ID_CYRIX) - ||(d->device == PCI_DEVICE_ID_NS_SCx200_IDE && d->vendor == PCI_VENDOR_ID_NS))) - { + if ((d->flags & IDEPCI_FLAG_FORCE_MASTER) == 0) { /* * default DMA off if we had to * configure it here @@ -613,9 +604,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int autodma, * by the bios for raid purposes. * Skip the normal "is it enabled" test for those. */ - if (((d->vendor == PCI_VENDOR_ID_PROMISE) && - ((d->device == PCI_DEVICE_ID_PROMISE_20262) || - (d->device == PCI_DEVICE_ID_PROMISE_20265))) && + if ((d->flags & IDEPCI_FLAG_FORCE_PDC) && (secondpdc++==1) && (port==1)) goto controller_ok; diff --git a/drivers/md/md.c b/drivers/md/md.c index c451c8dba..7992b2106 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1607,7 +1607,7 @@ static int do_md_run(mddev_t * mddev) spin_lock(&pers_lock); if (!pers[pnum] || !try_module_get(pers[pnum]->owner)) { spin_unlock(&pers_lock); - printk(KERN_ERR "md: personality %d is not loaded!\n", + printk(KERN_WARNING "md: personality %d is not loaded!\n", pnum); return -EINVAL; } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 589ab0564..346f595b6 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1873,25 +1873,12 @@ endmenu # Gigabit Ethernet # -menu "Gigabit Ethernet (1000/10000 Mbit)" +menu "Ethernet (1000 Mbit)" depends on NETDEVICES -config NET_GIGE - bool "Gigabit Ethernet (1000/10000 Mbit) controller support" - depends on NETDEVICES && NET_ETHERNET && (PCI || SBUS) - help - Gigabit ethernet. It's yummy and fast, fast, fast. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about this class of network cards. If you say Y, you - will be asked for your specific card in the following questions. - - If you are unsure, say Y. - config ACENIC tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support" - depends on PCI && NET_GIGE + depends on PCI ---help--- Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet @@ -1918,7 +1905,7 @@ config ACENIC_OMIT_TIGON_I config DL2K tristate "D-Link DL2000-based Gigabit Ethernet support" - depends on PCI && NET_GIGE + depends on PCI select CRC32 help This driver supports D-Link 2000-based gigabit ethernet cards, which @@ -1931,7 +1918,7 @@ config DL2K config E1000 tristate "Intel(R) PRO/1000 Gigabit Ethernet support" - depends on PCI && NET_GIGE + depends on PCI ---help--- This driver supports Intel(R) PRO/1000 gigabit ethernet family of adapters, which includes: @@ -1978,7 +1965,7 @@ config E1000_NAPI config MYRI_SBUS tristate "MyriCOM Gigabit Ethernet support" - depends on SBUS && NET_GIGE + depends on SBUS help This driver supports MyriCOM Sbus gigabit Ethernet cards. @@ -1987,7 +1974,7 @@ config MYRI_SBUS config NS83820 tristate "National Semiconduct DP83820 support" - depends on PCI && NET_GIGE + depends on PCI help This is a driver for the National Semiconductor DP83820 series of gigabit ethernet MACs. Cards using this chipset include @@ -1997,7 +1984,7 @@ config NS83820 config HAMACHI tristate "Packet Engines Hamachi GNIC-II support" - depends on PCI && NET_GIGE + depends on PCI select MII help If you have a Gigabit Ethernet card of this type, say Y and read @@ -2010,7 +1997,7 @@ config HAMACHI config YELLOWFIN tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL && NET_GIGE + depends on PCI && EXPERIMENTAL select CRC32 ---help--- Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet @@ -2024,7 +2011,7 @@ config YELLOWFIN config R8169 tristate "Realtek 8169 gigabit ethernet support" - depends on PCI && NET_GIGE + depends on PCI select CRC32 ---help--- Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter. @@ -2034,7 +2021,7 @@ config R8169 config SK98LIN tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support" - depends on PCI && NET_GIGE + depends on PCI ---help--- Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter. The following adapters are supported @@ -2113,16 +2100,25 @@ config SK98LIN config TIGON3 tristate "Broadcom Tigon3 support" - depends on PCI && NET_GIGE + depends on PCI help This driver supports Broadcom Tigon3 based gigabit Ethernet cards. To compile this driver as a module, choose M here: the module will be called tg3. This is recommended. +endmenu + +# +# 10 Gigabit Ethernet +# + +menu "Ethernet (10000 Mbit)" + depends on NETDEVICES + config IXGB tristate "Intel(R) PRO/10GbE support" - depends on PCI && NET_GIGE + depends on PCI ---help--- This driver supports Intel(R) PRO/10GbE family of adapters, which includes: @@ -2154,7 +2150,7 @@ config IXGB_NAPI config S2IO tristate "S2IO 10Gbe XFrame NIC" - depends on PCI && NET_GIGE + depends on PCI ---help--- This driver supports the 10Gbe XFrame NIC of S2IO. For help regarding driver compilation, installation and diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index c5fd371c9..634cb049c 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -461,6 +461,11 @@ static void veth_statemachine(void *p) if (cnx->msgs) for (i = 0; i < VETH_NUMBUFFERS; ++i) veth_recycle_msg(cnx, cnx->msgs + i); + spin_unlock_irq(&cnx->lock); + veth_flush_pending(cnx); + spin_lock_irq(&cnx->lock); + if (cnx->state & VETH_STATE_RESET) + goto restart; } if (cnx->state & VETH_STATE_SHUTDOWN) @@ -796,6 +801,48 @@ static int veth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EOPNOTSUPP; } +static void veth_tx_timeout(struct net_device *dev) +{ + struct veth_port *port = (struct veth_port *)dev->priv; + struct net_device_stats *stats = &port->stats; + unsigned long flags; + int i; + + stats->tx_errors++; + + spin_lock_irqsave(&port->pending_gate, flags); + + printk(KERN_WARNING "%s: Tx timeout! Resetting lp connections: %08x\n", + dev->name, port->pending_lpmask); + + /* If we've timed out the queue must be stopped, which should + * only ever happen when there is a pending packet. */ + WARN_ON(! port->pending_lpmask); + + for (i = 0; i < HVMAXARCHITECTEDLPS; i++) { + struct veth_lpar_connection *cnx = veth_cnx[i]; + + if (! (port->pending_lpmask & (1<lock); + cnx->state |= VETH_STATE_RESET; + veth_kick_statemachine(cnx); + spin_unlock(&cnx->lock); + } + + spin_unlock_irqrestore(&port->pending_gate, flags); +} + struct net_device * __init veth_probe_one(int vlan) { struct net_device *dev; @@ -843,6 +890,9 @@ struct net_device * __init veth_probe_one(int vlan) dev->set_multicast_list = veth_set_multicast_list; dev->do_ioctl = veth_ioctl; + dev->watchdog_timeo = 2 * (VETH_ACKTIMEOUT * HZ / 1000000); + dev->tx_timeout = veth_tx_timeout; + rc = register_netdev(dev); if (rc != 0) { veth_printk(KERN_ERR, @@ -938,19 +988,10 @@ static HvLpIndexMap veth_transmit_to_many(struct sk_buff *skb, int rc; for (i = 0; i < HVMAXARCHITECTEDLPS; i++) { - struct sk_buff *clone; - if ((lpmask & (1 << i)) == 0) continue; - clone = skb_clone(skb, GFP_ATOMIC); - if (! clone) { - veth_error("%s: skb_clone failed %p\n", - dev->name, skb); - continue; - } - - rc = veth_transmit_to_one(clone, i, dev); + rc = veth_transmit_to_one(skb_get(skb), i, dev); if (! rc) lpmask &= ~(1<lpar_map; } + spin_lock_irqsave(&port->pending_gate, flags); + lpmask = veth_transmit_to_many(skb, lpmask, dev); if (! lpmask) { dev_kfree_skb(skb); } else { - spin_lock_irqsave(&port->pending_gate, flags); if (port->pending_skb) { veth_error("%s: Tx while skb was pending!\n", dev->name); dev_kfree_skb(skb); - spin_unlock_irqrestore(&port->pending_gate, flags); + spin_unlock_irqrestore(&port->pending_gate, flags); return 1; } port->pending_skb = skb; port->pending_lpmask = lpmask; netif_stop_queue(dev); - - spin_unlock_irqrestore(&port->pending_gate, flags); } + spin_unlock_irqrestore(&port->pending_gate, flags); + return 0; } @@ -1058,7 +1100,7 @@ static void veth_flush_pending(struct veth_lpar_connection *cnx) if (! port->pending_lpmask) { dev_kfree_skb_any(port->pending_skb); port->pending_skb = NULL; - netif_start_queue(dev); + netif_wake_queue(dev); } } spin_unlock_irqrestore(&port->pending_gate, flags); diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 4b8256c64..31bbff4f0 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -1219,6 +1219,9 @@ plip_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) struct net_local *nl = netdev_priv(dev); struct plipconf *pc = (struct plipconf *) &rq->ifr_data; + if (cmd != SIOCDEVPLIP) + return -EOPNOTSUPP; + switch(pc->pcmd) { case PLIP_GET_TIMEOUT: pc->trigger = nl->trigger; diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 338f2cde7..0394ee0ad 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -205,10 +205,10 @@ ppp_asynctty_close(struct tty_struct *tty) { struct asyncppp *ap; - write_lock(&disc_data_lock); + write_lock_irq(&disc_data_lock); ap = tty->disc_data; tty->disc_data = 0; - write_unlock(&disc_data_lock); + write_unlock_irq(&disc_data_lock); if (ap == 0) return; diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index fc93451e6..0e1e057a8 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -251,10 +251,10 @@ ppp_sync_close(struct tty_struct *tty) { struct syncppp *ap; - write_lock(&disc_data_lock); + write_lock_irq(&disc_data_lock); ap = tty->disc_data; tty->disc_data = 0; - write_unlock(&disc_data_lock); + write_unlock_irq(&disc_data_lock); if (ap == 0) return; diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile index 6372def26..ce6c56b90 100644 --- a/drivers/net/wan/Makefile +++ b/drivers/net/wan/Makefile @@ -61,6 +61,9 @@ obj-$(CONFIG_C101) += c101.o obj-$(CONFIG_WANXL) += wanxl.o obj-$(CONFIG_PCI200SYN) += pci200syn.o +clean-files := wanxlfw.inc +$(obj)/wanxl.o: $(obj)/wanxlfw.inc + ifeq ($(CONFIG_WANXL_BUILD_FIRMWARE),y) ifeq ($(ARCH),m68k) AS68K = $(AS) @@ -72,12 +75,12 @@ endif quiet_cmd_build_wanxlfw = BLD FW $@ cmd_build_wanxlfw = \ - $(CPP) -Wp,-MD,$(depfile) -Iinclude $(obj)/wanxlfw.S | $(AS68K) -m68360 -o $(obj)/wanxlfw.o; \ + $(CPP) -Wp,-MD,$(depfile) -I$(srctree)/include $< | $(AS68K) -m68360 -o $(obj)/wanxlfw.o; \ $(LD68K) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \ hexdump -ve '"\n" 16/1 "0x%02X,"' $(obj)/wanxlfw.bin | sed 's/0x ,//g;1s/^/static u8 firmware[]={/;$$s/,$$/\n};\n/' >$(obj)/wanxlfw.inc; \ rm -f $(obj)/wanxlfw.bin $(obj)/wanxlfw.o -$(obj)/wanxlfw.inc: $(obj)/wanxlfw.S +$(obj)/wanxlfw.inc: $(src)/wanxlfw.S $(call if_changed_dep,build_wanxlfw) targets += wanxlfw.inc endif diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index a5445c1a6..7f4718040 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -379,8 +379,6 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) return result; } - /* XXX: are we OK with having that done when card is already up? */ - sca_init_sync_port(card); /* Set up C101 memory */ hdlc_set_carrier(!(sca_in(MSCI1_OFFSET + ST3, card) & ST3_DCD), dev); diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index 43e8bf3ce..31b379da2 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -180,7 +180,8 @@ static int cisco_rx(struct sk_buff *skb) case CISCO_KEEPALIVE_REQ: hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); - if (ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { + if (hdlc->state.cisco.request_sent && + ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { hdlc->state.cisco.last_poll = jiffies; if (!hdlc->state.cisco.up) { u32 sec, min, hrs, days; @@ -192,8 +193,9 @@ static int cisco_rx(struct sk_buff *skb) "uptime %ud%uh%um%us)\n", dev->name, days, hrs, min, sec); + netif_carrier_on(dev); + hdlc->state.cisco.up = 1; } - hdlc->state.cisco.up = 1; } dev_kfree_skb_any(skb); @@ -219,17 +221,18 @@ static void cisco_timer(unsigned long arg) struct net_device *dev = (struct net_device *)arg; hdlc_device *hdlc = dev_to_hdlc(dev); - if (hdlc->state.cisco.up && jiffies - hdlc->state.cisco.last_poll >= - hdlc->state.cisco.settings.timeout * HZ) { + if (hdlc->state.cisco.up && + time_after(jiffies, hdlc->state.cisco.last_poll + + hdlc->state.cisco.settings.timeout * HZ)) { hdlc->state.cisco.up = 0; printk(KERN_INFO "%s: Link down\n", dev->name); - if (netif_carrier_ok(dev)) - netif_carrier_off(dev); + netif_carrier_off(dev); } cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, ++hdlc->state.cisco.txseq, hdlc->state.cisco.rxseq); + hdlc->state.cisco.request_sent = 1; hdlc->state.cisco.timer.expires = jiffies + hdlc->state.cisco.settings.interval * HZ; hdlc->state.cisco.timer.function = cisco_timer; @@ -242,8 +245,8 @@ static void cisco_timer(unsigned long arg) static void cisco_start(struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); - hdlc->state.cisco.last_poll = 0; hdlc->state.cisco.up = 0; + hdlc->state.cisco.request_sent = 0; hdlc->state.cisco.txseq = hdlc->state.cisco.rxseq = 0; init_timer(&hdlc->state.cisco.timer); @@ -257,9 +260,12 @@ static void cisco_start(struct net_device *dev) static void cisco_stop(struct net_device *dev) { - del_timer_sync(&dev_to_hdlc(dev)->state.cisco.timer); + hdlc_device *hdlc = dev_to_hdlc(dev); + del_timer_sync(&hdlc->state.cisco.timer); if (netif_carrier_ok(dev)) netif_carrier_off(dev); + hdlc->state.cisco.up = 0; + hdlc->state.cisco.request_sent = 0; } diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index e9c995ea1..8feed459c 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -584,8 +584,9 @@ static void fr_timer(unsigned long arg) u32 list; if (hdlc->state.fr.settings.dce) - reliable = (jiffies - hdlc->state.fr.last_poll < - hdlc->state.fr.settings.t392 * HZ); + reliable = hdlc->state.fr.request && + time_before(jiffies, hdlc->state.fr.last_poll + + hdlc->state.fr.settings.t392 * HZ); else { hdlc->state.fr.last_errors <<= 1; /* Shift the list */ if (hdlc->state.fr.request) { @@ -617,6 +618,7 @@ static void fr_timer(unsigned long arg) fr_lmi_send(dev, hdlc->state.fr.n391cnt == 0); + hdlc->state.fr.last_poll = jiffies; hdlc->state.fr.request = 1; hdlc->state.fr.timer.expires = jiffies + hdlc->state.fr.settings.t391 * HZ; @@ -689,6 +691,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) dev->name, reptype); return 1; } + hdlc->state.fr.last_poll = jiffies; } error = 0; @@ -728,7 +731,12 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) /* DTE */ - if (reptype != LMI_FULLREP || error) + hdlc->state.fr.request = 0; /* got response, no request pending */ + + if (error) + return 0; + + if (reptype != LMI_FULLREP) return 0; stat_len = 3; @@ -829,9 +837,6 @@ static int fr_rx(struct sk_buff *skb) if (fr_lmi_recv(ndev, skb)) goto rx_error; else { - /* No request pending */ - hdlc->state.fr.request = 0; - hdlc->state.fr.last_poll = jiffies; dev_kfree_skb_any(skb); return NET_RX_SUCCESS; } @@ -946,9 +951,6 @@ static void fr_start(struct net_device *dev) printk(KERN_DEBUG "fr_start\n"); #endif if (hdlc->state.fr.settings.lmi != LMI_NONE) { - if (netif_carrier_ok(dev)) - netif_carrier_off(dev); - hdlc->state.fr.last_poll = 0; hdlc->state.fr.reliable = 0; hdlc->state.fr.dce_changed = 1; hdlc->state.fr.request = 0; diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c index 2aa4ae046..6ed064cb4 100644 --- a/drivers/net/wan/hdlc_generic.c +++ b/drivers/net/wan/hdlc_generic.c @@ -15,6 +15,11 @@ * * X.25 * * Use sethdlc utility to set line parameters, protocol and PVCs + * + * How does it work: + * - proto.open(), close(), start(), stop() calls are serialized. + * The order is: open, [ start, stop ... ] close ... + * - proto.start() and stop() are called with spin_lock_irq held. */ #include @@ -33,7 +38,7 @@ #include -static const char* version = "HDLC support module revision 1.16"; +static const char* version = "HDLC support module revision 1.17"; #undef DEBUG_LINK @@ -69,51 +74,75 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, +static void __hdlc_set_carrier_on(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + if (hdlc->proto.start) + return hdlc->proto.start(dev); +#ifdef DEBUG_LINK + if (netif_carrier_ok(dev)) + printk(KERN_ERR "hdlc_set_carrier_on(): already on\n"); +#endif + netif_carrier_on(dev); +} + + + +static void __hdlc_set_carrier_off(struct net_device *dev) +{ + hdlc_device *hdlc = dev_to_hdlc(dev); + if (hdlc->proto.stop) + return hdlc->proto.stop(dev); + +#ifdef DEBUG_LINK + if (!netif_carrier_ok(dev)) + printk(KERN_ERR "hdlc_set_carrier_off(): already off\n"); +#endif + netif_carrier_off(dev); +} + + + void hdlc_set_carrier(int on, struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); + unsigned long flags; on = on ? 1 : 0; #ifdef DEBUG_LINK printk(KERN_DEBUG "hdlc_set_carrier %i\n", on); #endif - spin_lock_irq(&hdlc->state_lock); + spin_lock_irqsave(&hdlc->state_lock, flags); if (hdlc->carrier == on) goto carrier_exit; /* no change in DCD line level */ - printk(KERN_INFO "%s: carrier %s\n", dev->name, - on ? "ON" : "off"); +#ifdef DEBUG_LINK + printk(KERN_INFO "%s: carrier %s\n", dev->name, on ? "ON" : "off"); +#endif hdlc->carrier = on; if (!hdlc->open) goto carrier_exit; - if (hdlc->carrier) { - if (hdlc->proto.start) - hdlc->proto.start(dev); - else if (!netif_carrier_ok(dev)) - netif_carrier_on(dev); - - } else { /* no carrier */ - if (hdlc->proto.stop) - hdlc->proto.stop(dev); - else if (netif_carrier_ok(dev)) - netif_carrier_off(dev); - } + if (hdlc->carrier) + __hdlc_set_carrier_on(dev); + else + __hdlc_set_carrier_off(dev); - carrier_exit: - spin_unlock_irq(&hdlc->state_lock); +carrier_exit: + spin_unlock_irqrestore(&hdlc->state_lock, flags); } + /* Must be called by hardware driver when HDLC device is being opened */ int hdlc_open(struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); #ifdef DEBUG_LINK - printk(KERN_DEBUG "hdlc_open carrier %i open %i\n", + printk(KERN_DEBUG "hdlc_open() carrier %i open %i\n", hdlc->carrier, hdlc->open); #endif @@ -128,14 +157,8 @@ int hdlc_open(struct net_device *dev) spin_lock_irq(&hdlc->state_lock); - if (hdlc->carrier) { - if (hdlc->proto.start) - hdlc->proto.start(dev); - else if (!netif_carrier_ok(dev)) - netif_carrier_on(dev); - - } else if (netif_carrier_ok(dev)) - netif_carrier_off(dev); + if (hdlc->carrier) + __hdlc_set_carrier_on(dev); hdlc->open = 1; @@ -150,15 +173,15 @@ void hdlc_close(struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); #ifdef DEBUG_LINK - printk(KERN_DEBUG "hdlc_close carrier %i open %i\n", + printk(KERN_DEBUG "hdlc_close() carrier %i open %i\n", hdlc->carrier, hdlc->open); #endif spin_lock_irq(&hdlc->state_lock); hdlc->open = 0; - if (hdlc->carrier && hdlc->proto.stop) - hdlc->proto.stop(dev); + if (hdlc->carrier) + __hdlc_set_carrier_off(dev); spin_unlock_irq(&hdlc->state_lock); @@ -185,7 +208,7 @@ void hdlc_close(struct net_device *dev) #endif #ifndef CONFIG_HDLC_FR -#define hdlc_fr_ioctl(dev, ifr) -ENOSYS +#define hdlc_fr_ioctl(dev, ifr) -ENOSYS #endif #ifndef CONFIG_HDLC_X25 @@ -257,25 +280,7 @@ struct net_device *alloc_hdlcdev(void *priv) int register_hdlc_device(struct net_device *dev) { - int result; - hdlc_device *hdlc = dev_to_hdlc(dev); - - dev->get_stats = hdlc_get_stats; - dev->change_mtu = hdlc_change_mtu; - dev->mtu = HDLC_MAX_MTU; - - dev->type = ARPHRD_RAWHDLC; - dev->hard_header_len = 16; - - dev->flags = IFF_POINTOPOINT | IFF_NOARP; - - hdlc->proto.id = -1; - hdlc->proto.detach = NULL; - hdlc->carrier = 1; - hdlc->open = 0; - spin_lock_init(&hdlc->state_lock); - - result = dev_alloc_name(dev, "hdlc%d"); + int result = dev_alloc_name(dev, "hdlc%d"); if (result < 0) return result; @@ -283,6 +288,9 @@ int register_hdlc_device(struct net_device *dev) if (result != 0) return -EIO; + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); /* no carrier until DCD goes up */ + return 0; } diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c index bbda5cde4..2e669a643 100644 --- a/drivers/net/wireless/prism54/isl_38xx.c +++ b/drivers/net/wireless/prism54/isl_38xx.c @@ -1,4 +1,4 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_38xx.c,v 1.22 2004/02/28 03:06:07 mcgrof Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2003-2004 Luis R. Rodriguez _ diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h index ea954f17f..5f644836f 100644 --- a/drivers/net/wireless/prism54/isl_38xx.h +++ b/drivers/net/wireless/prism54/isl_38xx.h @@ -1,4 +1,4 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_38xx.h,v 1.22 2004/02/28 03:06:07 mcgrof Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index e1261e534..426fc2e3e 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -1,7 +1,7 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.c,v 1.140 2004/02/28 03:06:07 mcgrof Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. - * (C) 2003 Aurelien Alleaume + * (C) 2003,2004 Aurelien Alleaume * (C) 2003 Herbert Valerio Riedel * (C) 2003 Luis R. Rodriguez * @@ -87,9 +87,9 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode) /* For now, just catch early the Repeater and Secondary modes here */ if (iw_mode == IW_MODE_REPEAT || iw_mode == IW_MODE_SECOND) { - printk(KERN_DEBUG "%s(): Sorry, Repeater mode and Secondary mode " - "are not yet supported by this driver.\n", - __FUNCTION__); + printk(KERN_DEBUG + "%s(): Sorry, Repeater mode and Secondary mode " + "are not yet supported by this driver.\n", __FUNCTION__); return -EINVAL; } @@ -143,8 +143,8 @@ prism54_mib_init(islpci_private *priv) { u32 t; struct obj_buffer psm_buffer = { - .size = cpu_to_le32(PSM_BUFFER_SIZE), - .addr = cpu_to_le32(priv->device_psm_buffer) + .size = PSM_BUFFER_SIZE, + .addr = priv->device_psm_buffer }; mgt_set(priv, DOT11_OID_CHANNEL, &init_channel); @@ -285,7 +285,7 @@ prism54_commit(struct net_device *ndev, struct iw_request_info *info, /* Commit in Monitor mode is not necessary, also setting essid * in Monitor mode does not make sense and isn't allowed for this * device's firmware */ - if(priv->iw_mode != IW_MODE_MONITOR) + if (priv->iw_mode != IW_MODE_MONITOR) return mgt_set_request(priv, DOT11_OID_SSID, 0, NULL); return 0; } @@ -327,34 +327,15 @@ prism54_set_freq(struct net_device *ndev, struct iw_request_info *info, { islpci_private *priv = netdev_priv(ndev); int rvalue; - u32 c = 0; + u32 c; - /* prepare the structure for the set object */ if (fwrq->m < 1000) - /* structure value contains a channel indication */ + /* we have a channel number */ c = fwrq->m; - else { - /* structure contains a frequency indication and fwrq->e = 1 */ - int f = fwrq->m / 100000; - - if (fwrq->e != 1) - return -EINVAL; - if ((f >= 2412) && (f <= 2484)) { - while ((c < 14) && (f != frequency_list_bg[c])) - c++; - if (c >= 14) - return -EINVAL; - } else if ((f >= (int) 5170) && (f <= (int) 5320)) { - while ((c < 12) && (f != frequency_list_a[c])) - c++; - if (c >= 12) - return -EINVAL; - } else - return -EINVAL; - c++; - } + else + c = (fwrq->e == 1) ? channel_of_freq(fwrq->m / 100000) : 0; - rvalue = mgt_set_request(priv, DOT11_OID_CHANNEL, 0, &c); + rvalue = c ? mgt_set_request(priv, DOT11_OID_CHANNEL, 0, &c) : -EINVAL; /* Call commit handler */ return (rvalue ? rvalue : -EINPROGRESS); @@ -410,7 +391,7 @@ prism54_set_mode(struct net_device *ndev, struct iw_request_info *info, mgt_commit(priv); priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) - ? ARPHRD_IEEE80211 : ARPHRD_ETHER; + ? priv->monitor_type : ARPHRD_ETHER; up_write(&priv->mib_sem); return 0; @@ -531,20 +512,20 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info, mgt_get_request(priv, DOT11_OID_SUPPORTEDFREQUENCIES, 0, NULL, &r); freq = r.ptr; - range->num_channels = le16_to_cpu(freq->nr); - range->num_frequency = le16_to_cpu(freq->nr); + range->num_channels = freq->nr; + range->num_frequency = freq->nr; /* Frequencies are not listed in the right order. The reordering is probably * firmware dependant and thus should work for everyone. */ - m = min(IW_MAX_FREQUENCIES, (int) le16_to_cpu(freq->nr)); + m = min(IW_MAX_FREQUENCIES, (int) freq->nr); for (i = 0; i < m - 12; i++) { - range->freq[i].m = le16_to_cpu(freq->mhz[12 + i]); + range->freq[i].m = freq->mhz[12 + i]; range->freq[i].e = 6; range->freq[i].i = i + 1; } for (i = m - 12; i < m; i++) { - range->freq[i].m = le16_to_cpu(freq->mhz[i - m + 12]); + range->freq[i].m = freq->mhz[i - m + 12]; range->freq[i].e = 6; range->freq[i].i = i + 23; } @@ -655,7 +636,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, #define CAP_CRYPT 0x10 /* Mode */ - cap = le16_to_cpu(bss->capinfo); + cap = bss->capinfo; iwe.u.mode = 0; if (cap & CAP_ESS) iwe.u.mode = IW_MODE_MASTER; @@ -747,7 +728,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info, bsslist = r.ptr; /* ok now, scan the list and translate its info */ - for (i = 0; i < min(IW_MAX_AP, (int) le32_to_cpu(bsslist->nr)); i++) + for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++) current_ev = prism54_translate_bss(ndev, current_ev, extra + IW_SCAN_MAX_DATA, &(bsslist->bsslist[i]), @@ -869,25 +850,26 @@ prism54_set_rate(struct net_device *ndev, return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile); } - if((ret = mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r))) + if ((ret = + mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r))) return ret; rate = (u32) (vwrq->value / 500000); data = r.ptr; i = 0; - while(data[i]) { - if(rate && (data[i] == rate)) { + while (data[i]) { + if (rate && (data[i] == rate)) { break; } - if(vwrq->value == i) { + if (vwrq->value == i) { break; } data[i] |= 0x80; i++; } - if(!data[i]) { + if (!data[i]) { return -EINVAL; } @@ -931,12 +913,12 @@ prism54_get_rate(struct net_device *ndev, union oid_res_t r; /* Get the current bit rate */ - if((rvalue = mgt_get_request(priv, GEN_OID_LINKSTATE, 0, NULL, &r))) + if ((rvalue = mgt_get_request(priv, GEN_OID_LINKSTATE, 0, NULL, &r))) return rvalue; vwrq->value = r.u * 500000; /* request the device for the enabled rates */ - if((rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r))) + if ((rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r))) return rvalue; data = r.ptr; vwrq->fixed = (data[0] != 0) && (data[1] == 0); @@ -1225,7 +1207,7 @@ prism54_get_txpower(struct net_device *ndev, struct iw_request_info *info, rvalue = mgt_get_request(priv, OID_INL_OUTPUTPOWER, 0, NULL, &r); /* intersil firmware operates in 0.25 dBm (1/4 dBm) */ - vwrq->value = (s32)r.u / 4; + vwrq->value = (s32) r.u / 4; vwrq->fixed = 1; /* radio is not turned of * btw: how is possible to turn off only the radio @@ -1271,28 +1253,41 @@ prism54_reset(struct net_device *ndev, struct iw_request_info *info, } static int -prism54_set_beacon(struct net_device *ndev, struct iw_request_info *info, - __u32 * uwrq, char *extra) +prism54_get_oid(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) { - int rvalue = mgt_set_request((islpci_private *) netdev_priv(ndev), - DOT11_OID_BEACONPERIOD, 0, uwrq); + union oid_res_t r; + int rvalue; + enum oid_num_t n = dwrq->flags; - return (rvalue ? rvalue : -EINPROGRESS); + rvalue = mgt_get_request((islpci_private *) ndev->priv, n, 0, NULL, &r); + dwrq->length = mgt_response_to_str(n, &r, extra); + if ((isl_oid[n].flags & OID_FLAG_TYPE) != OID_TYPE_U32) + kfree(r.ptr); + return rvalue; } static int -prism54_get_beacon(struct net_device *ndev, struct iw_request_info *info, +prism54_set_u32(struct net_device *ndev, struct iw_request_info *info, __u32 * uwrq, char *extra) { - union oid_res_t r; - int rvalue; + /* + u32 *i = (int *) extra; + int param = *i; + int u = *(i + 1); + */ + u32 oid = uwrq[0], u = uwrq[1]; - rvalue = - mgt_get_request((islpci_private *) netdev_priv(ndev), - DOT11_OID_BEACONPERIOD, 0, NULL, &r); - *uwrq = r.u; + return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u); +} - return rvalue; +static int +prism54_set_raw(struct net_device *ndev, struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + u32 oid = dwrq->flags; + + return mgt_set_request((islpci_private *) ndev->priv, oid, 0, extra); } void @@ -1511,8 +1506,9 @@ prism54_kick_all(struct net_device *ndev, struct iw_request_info *info, return -ENOMEM; /* Tell the card to kick every client */ - mlme->id = cpu_to_le16(0); - rvalue = mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme); + mlme->id = 0; + rvalue = + mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme); kfree(mlme); return rvalue; @@ -1535,8 +1531,9 @@ prism54_kick_mac(struct net_device *ndev, struct iw_request_info *info, /* Tell the card to only kick the corresponding bastard */ memcpy(mlme->address, addr->sa_data, ETH_ALEN); - mlme->id = cpu_to_le16(-1); - rvalue = mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme); + mlme->id = -1; + rvalue = + mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme); kfree(mlme); @@ -1551,12 +1548,12 @@ format_event(islpci_private *priv, char *dest, const char *str, { const u8 *a = mlme->address; int n = snprintf(dest, IW_CUSTOM_MAX, - "%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s", + "%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s (%2.2X)", str, - ((priv->iw_mode == IW_MODE_MASTER) ? "to" : "from"), + ((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"), a[0], a[1], a[2], a[3], a[4], a[5], (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ") - : "")); + : ""), mlme->code); BUG_ON(n > IW_CUSTOM_MAX); *length = n; } @@ -1598,14 +1595,15 @@ link_changed(struct net_device *ndev, u32 bitrate) { islpci_private *priv = netdev_priv(ndev); - if (le32_to_cpu(bitrate)) { + if (bitrate) { if (priv->iw_mode == IW_MODE_INFRA) { union iwreq_data uwrq; prism54_get_wap(ndev, NULL, (struct sockaddr *) &uwrq, NULL); wireless_send_event(ndev, SIOCGIWAP, &uwrq, NULL); } else - send_simple_event(netdev_priv(ndev), "Link established"); + send_simple_event(netdev_priv(ndev), + "Link established"); } else send_simple_event(netdev_priv(ndev), "Link lost"); } @@ -1765,15 +1763,14 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr, static void handle_request(islpci_private *priv, struct obj_mlme *mlme, enum oid_num_t oid) { - if (((le16_to_cpu(mlme->state) == DOT11_STATE_AUTHING) || - (le16_to_cpu(mlme->state) == DOT11_STATE_ASSOCING)) + if (((mlme->state == DOT11_STATE_AUTHING) || + (mlme->state == DOT11_STATE_ASSOCING)) && mgt_mlme_answer(priv)) { /* Someone is requesting auth and we must respond. Just send back * the trap with error code set accordingly. */ - mlme->code = cpu_to_le16(prism54_mac_accept(&priv->acl, - mlme-> - address) ? 0 : 1); + mlme->code = prism54_mac_accept(&priv->acl, + mlme->address) ? 0 : 1; mgt_set_request(priv, oid, 0, mlme); } } @@ -1797,6 +1794,13 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, * suited. We use the more flexible custom event facility. */ + /* I fear prism54_process_bss_data won't work with big endian data */ + if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE)) + prism54_process_bss_data(priv, oid, mlme->address, + payload, len); + + mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme); + switch (oid) { case GEN_OID_LINKSTATE: @@ -1831,8 +1835,6 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, break; case DOT11_OID_BEACON: - prism54_process_bss_data(priv, oid, mlme->address, - payload, len); send_formatted_event(priv, "Received a beacon from an unkown AP", mlme, 0); @@ -1840,8 +1842,6 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, case DOT11_OID_PROBE: /* we received a probe from a client. */ - prism54_process_bss_data(priv, oid, mlme->address, - payload, len); send_formatted_event(priv, "Received a probe from client", mlme, 0); break; @@ -1914,13 +1914,6 @@ prism54_set_mac_address(struct net_device *ndev, void *addr) return ret; } -int -prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) -{ - /* should we really support this old stuff ? */ - return -EOPNOTSUPP; -} - int prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info, __u32 * uwrq, char *extra) @@ -1950,9 +1943,31 @@ prism54_get_wpa(struct net_device *ndev, struct iw_request_info *info, return 0; } +int +prism54_set_prismhdr(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_private *priv = netdev_priv(ndev); + priv->monitor_type = + (*uwrq ? ARPHRD_IEEE80211_PRISM : ARPHRD_IEEE80211); + if (priv->iw_mode == IW_MODE_MONITOR) + priv->ndev->type = priv->monitor_type; + + return 0; +} + +int +prism54_get_prismhdr(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) +{ + islpci_private *priv = netdev_priv(ndev); + *uwrq = (priv->monitor_type == ARPHRD_IEEE80211_PRISM); + return 0; +} + int prism54_set_maxframeburst(struct net_device *ndev, struct iw_request_info *info, - __u32 *uwrq, char *extra) + __u32 * uwrq, char *extra) { islpci_private *priv = netdev_priv(ndev); u32 max_burst; @@ -1965,7 +1980,7 @@ prism54_set_maxframeburst(struct net_device *ndev, struct iw_request_info *info, int prism54_get_maxframeburst(struct net_device *ndev, struct iw_request_info *info, - __u32 *uwrq, char *extra) + __u32 * uwrq, char *extra) { islpci_private *priv = netdev_priv(ndev); union oid_res_t r; @@ -1979,7 +1994,7 @@ prism54_get_maxframeburst(struct net_device *ndev, struct iw_request_info *info, int prism54_set_profile(struct net_device *ndev, struct iw_request_info *info, - __u32 *uwrq, char *extra) + __u32 * uwrq, char *extra) { islpci_private *priv = netdev_priv(ndev); u32 profile; @@ -1992,7 +2007,7 @@ prism54_set_profile(struct net_device *ndev, struct iw_request_info *info, int prism54_get_profile(struct net_device *ndev, struct iw_request_info *info, - __u32 *uwrq, char *extra) + __u32 * uwrq, char *extra) { islpci_private *priv = netdev_priv(ndev); union oid_res_t r; @@ -2005,8 +2020,8 @@ prism54_get_profile(struct net_device *ndev, struct iw_request_info *info, } int -prism54_oid(struct net_device *ndev, struct iw_request_info *info, - __u32 *uwrq, char *extra) +prism54_debug_oid(struct net_device *ndev, struct iw_request_info *info, + __u32 * uwrq, char *extra) { islpci_private *priv = netdev_priv(ndev); @@ -2017,7 +2032,7 @@ prism54_oid(struct net_device *ndev, struct iw_request_info *info, } int -prism54_get_oid(struct net_device *ndev, struct iw_request_info *info, +prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info, struct iw_point *data, char *extra) { islpci_private *priv = netdev_priv(ndev); @@ -2028,11 +2043,15 @@ prism54_get_oid(struct net_device *ndev, struct iw_request_info *info, data->length = 0; if (islpci_get_state(priv) >= PRV_STATE_INIT) { - ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, priv->priv_oid, extra, 256, &response); + ret = + islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, + priv->priv_oid, extra, 256, + &response); response_op = response->header->operation; printk("%s: ret: %i\n", ndev->name, ret); printk("%s: response_op: %i\n", ndev->name, response_op); - if (ret || !response || response->header->operation == PIMFOR_OP_ERROR) { + if (ret || !response + || response->header->operation == PIMFOR_OP_ERROR) { if (response) { islpci_mgt_release(response); } @@ -2051,21 +2070,26 @@ prism54_get_oid(struct net_device *ndev, struct iw_request_info *info, } int -prism54_set_oid(struct net_device *ndev, struct iw_request_info *info, +prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info, struct iw_point *data, char *extra) { islpci_private *priv = netdev_priv(ndev); struct islpci_mgmtframe *response = NULL; int ret = 0, response_op = PIMFOR_OP_ERROR; - printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid, data->length); + printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid, + data->length); if (islpci_get_state(priv) >= PRV_STATE_INIT) { - ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, priv->priv_oid, extra, data->length, &response); + ret = + islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, + priv->priv_oid, extra, data->length, + &response); printk("%s: ret: %i\n", ndev->name, ret); if (!ret) { response_op = response->header->operation; - printk("%s: response_op: %i\n", ndev->name, response_op); + printk("%s: response_op: %i\n", ndev->name, + response_op); islpci_mgt_release(response); } if (ret || response_op == PIMFOR_OP_ERROR) { @@ -2077,6 +2101,31 @@ prism54_set_oid(struct net_device *ndev, struct iw_request_info *info, return ret; } +static int +prism54_set_spy(struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *uwrq, char *extra) +{ + islpci_private *priv = netdev_priv(ndev); + u32 u, oid = OID_INL_CONFIG; + + down_write(&priv->mib_sem); + mgt_get(priv, OID_INL_CONFIG, &u); + + if ((uwrq->data.length == 0) && (priv->spy_data.spy_number > 0)) + /* disable spy */ + u &= ~INL_CONFIG_RXANNEX; + else if ((uwrq->data.length > 0) && (priv->spy_data.spy_number == 0)) + /* enable spy */ + u |= INL_CONFIG_RXANNEX; + + mgt_set(priv, OID_INL_CONFIG, &u); + mgt_commit_list(priv, &oid, 1); + up_write(&priv->mib_sem); + + return iw_handler_set_spy(ndev, info, uwrq, extra); +} + static const iw_handler prism54_handler[] = { (iw_handler) prism54_commit, /* SIOCSIWCOMMIT */ (iw_handler) prism54_get_name, /* SIOCGIWNAME */ @@ -2094,7 +2143,7 @@ static const iw_handler prism54_handler[] = { (iw_handler) NULL, /* SIOCGIWPRIV */ (iw_handler) NULL, /* SIOCSIWSTATS */ (iw_handler) NULL, /* SIOCGIWSTATS */ - iw_handler_set_spy, /* SIOCSIWSPY */ + prism54_set_spy, /* SIOCSIWSPY */ iw_handler_get_spy, /* SIOCGIWSPY */ iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ @@ -2129,33 +2178,50 @@ static const iw_handler prism54_handler[] = { /* The low order bit identify a SET (0) or a GET (1) ioctl. */ #define PRISM54_RESET SIOCIWFIRSTPRIV -#define PRISM54_GET_BEACON SIOCIWFIRSTPRIV+1 -#define PRISM54_SET_BEACON SIOCIWFIRSTPRIV+2 -#define PRISM54_GET_POLICY SIOCIWFIRSTPRIV+3 -#define PRISM54_SET_POLICY SIOCIWFIRSTPRIV+4 -#define PRISM54_GET_MAC SIOCIWFIRSTPRIV+5 -#define PRISM54_ADD_MAC SIOCIWFIRSTPRIV+6 +#define PRISM54_GET_POLICY SIOCIWFIRSTPRIV+1 +#define PRISM54_SET_POLICY SIOCIWFIRSTPRIV+2 +#define PRISM54_GET_MAC SIOCIWFIRSTPRIV+3 +#define PRISM54_ADD_MAC SIOCIWFIRSTPRIV+4 + +#define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+6 -#define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+8 +#define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+8 -#define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+10 +#define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+10 -#define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+12 +#define PRISM54_GET_WPA SIOCIWFIRSTPRIV+11 +#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12 -#define PRISM54_GET_WPA SIOCIWFIRSTPRIV+13 -#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+14 +#define PRISM54_DBG_OID SIOCIWFIRSTPRIV+14 +#define PRISM54_DBG_GET_OID SIOCIWFIRSTPRIV+15 +#define PRISM54_DBG_SET_OID SIOCIWFIRSTPRIV+16 -#define PRISM54_OID SIOCIWFIRSTPRIV+16 #define PRISM54_GET_OID SIOCIWFIRSTPRIV+17 -#define PRISM54_SET_OID SIOCIWFIRSTPRIV+18 +#define PRISM54_SET_OID_U32 SIOCIWFIRSTPRIV+18 +#define PRISM54_SET_OID_STR SIOCIWFIRSTPRIV+20 +#define PRISM54_SET_OID_ADDR SIOCIWFIRSTPRIV+22 + +#define PRISM54_GET_PRISMHDR SIOCIWFIRSTPRIV+23 +#define PRISM54_SET_PRISMHDR SIOCIWFIRSTPRIV+24 + +#define IWPRIV_SET_U32(n,x) { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x } +#define IWPRIV_SET_SSID(n,x) { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x } +#define IWPRIV_SET_ADDR(n,x) { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x } +#define IWPRIV_GET(n,x) { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "get_"x } + +#define IWPRIV_U32(n,x) IWPRIV_SET_U32(n,x), IWPRIV_GET(n,x) +#define IWPRIV_SSID(n,x) IWPRIV_SET_SSID(n,x), IWPRIV_GET(n,x) +#define IWPRIV_ADDR(n,x) IWPRIV_SET_ADDR(n,x), IWPRIV_GET(n,x) + +/* Note : limited to 128 private ioctls */ static const struct iw_priv_args prism54_private_args[] = { /*{ cmd, set_args, get_args, name } */ {PRISM54_RESET, 0, 0, "reset"}, - {PRISM54_GET_BEACON, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "getBeaconPeriod"}, - {PRISM54_SET_BEACON, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, - "setBeaconPeriod"}, + {PRISM54_GET_PRISMHDR, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_prismhdr"}, + {PRISM54_SET_PRISMHDR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "set_prismhdr"}, {PRISM54_GET_POLICY, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getPolicy"}, {PRISM54_SET_POLICY, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, @@ -2172,15 +2238,77 @@ static const struct iw_priv_args prism54_private_args[] = { "get_wpa"}, {PRISM54_SET_WPA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_wpa"}, - {PRISM54_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "oid"}, - {PRISM54_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "get_oid"}, - {PRISM54_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "set_oid"}, + {PRISM54_DBG_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "dbg_oid"}, + {PRISM54_DBG_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "dbg_get_oid"}, + {PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_get_oid"}, + /* --- sub-ioctls handlers --- */ + {PRISM54_GET_OID, + 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, ""}, + {PRISM54_SET_OID_U32, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""}, + {PRISM54_SET_OID_STR, + IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, ""}, + {PRISM54_SET_OID_ADDR, + IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, ""}, + /* --- sub-ioctls definitions --- */ + IWPRIV_ADDR(GEN_OID_MACADDRESS, "addr"), + IWPRIV_GET(GEN_OID_LINKSTATE, "linkstate"), + IWPRIV_U32(DOT11_OID_BSSTYPE, "bsstype"), + IWPRIV_ADDR(DOT11_OID_BSSID, "bssid"), + IWPRIV_U32(DOT11_OID_STATE, "state"), + IWPRIV_U32(DOT11_OID_AID, "aid"), + + IWPRIV_SSID(DOT11_OID_SSIDOVERRIDE, "ssidoverride"), + + IWPRIV_U32(DOT11_OID_MEDIUMLIMIT, "medlimit"), + IWPRIV_U32(DOT11_OID_BEACONPERIOD, "beacon"), + IWPRIV_U32(DOT11_OID_DTIMPERIOD, "dtimperiod"), + + IWPRIV_U32(DOT11_OID_AUTHENABLE, "authenable"), + IWPRIV_U32(DOT11_OID_PRIVACYINVOKED, "privinvok"), + IWPRIV_U32(DOT11_OID_EXUNENCRYPTED, "exunencrypt"), + + IWPRIV_U32(DOT11_OID_REKEYTHRESHOLD, "rekeythresh"), + + IWPRIV_U32(DOT11_OID_MAXTXLIFETIME, "maxtxlife"), + IWPRIV_U32(DOT11_OID_MAXRXLIFETIME, "maxrxlife"), + IWPRIV_U32(DOT11_OID_ALOFT_FIXEDRATE, "fixedrate"), + IWPRIV_U32(DOT11_OID_MAXFRAMEBURST, "frameburst"), + IWPRIV_U32(DOT11_OID_PSM, "psm"), + + IWPRIV_U32(DOT11_OID_BRIDGELOCAL, "bridge"), + IWPRIV_U32(DOT11_OID_CLIENTS, "clients"), + IWPRIV_U32(DOT11_OID_CLIENTSASSOCIATED, "clientassoc"), + IWPRIV_U32(DOT11_OID_DOT1XENABLE, "dot1xenable"), + IWPRIV_U32(DOT11_OID_ANTENNARX, "rxant"), + IWPRIV_U32(DOT11_OID_ANTENNATX, "txant"), + IWPRIV_U32(DOT11_OID_ANTENNADIVERSITY, "antdivers"), + IWPRIV_U32(DOT11_OID_EDTHRESHOLD, "edthresh"), + IWPRIV_U32(DOT11_OID_PREAMBLESETTINGS, "preamble"), + IWPRIV_GET(DOT11_OID_RATES, "rates"), + IWPRIV_U32(DOT11_OID_OUTPUTPOWER, ".11outpower"), + IWPRIV_GET(DOT11_OID_SUPPORTEDRATES, "supprates"), + IWPRIV_GET(DOT11_OID_SUPPORTEDFREQUENCIES, "suppfreq"), + + IWPRIV_U32(DOT11_OID_NOISEFLOOR, "noisefloor"), + IWPRIV_GET(DOT11_OID_FREQUENCYACTIVITY, "freqactivity"), + IWPRIV_U32(DOT11_OID_NONERPPROTECTION, "nonerpprotec"), + IWPRIV_U32(DOT11_OID_PROFILES, "profile"), + IWPRIV_GET(DOT11_OID_EXTENDEDRATES, "extrates"), + IWPRIV_U32(DOT11_OID_MLMEAUTOLEVEL, "mlmelevel"), + + IWPRIV_GET(DOT11_OID_BSSS, "bsss"), + IWPRIV_GET(DOT11_OID_BSSLIST, "bsslist"), + IWPRIV_U32(OID_INL_MODE, "mode"), + IWPRIV_U32(OID_INL_CONFIG, "config"), + IWPRIV_U32(OID_INL_DOT11D_CONFORMANCE, ".11dconform"), + IWPRIV_GET(OID_INL_PHYCAPABILITIES, "phycapa"), + IWPRIV_U32(OID_INL_OUTPUTPOWER, "outpower"), }; static const iw_handler prism54_private_handler[] = { (iw_handler) prism54_reset, - (iw_handler) prism54_get_beacon, - (iw_handler) prism54_set_beacon, (iw_handler) prism54_get_policy, (iw_handler) prism54_set_policy, (iw_handler) prism54_get_mac, @@ -2194,9 +2322,17 @@ static const iw_handler prism54_private_handler[] = { (iw_handler) prism54_get_wpa, (iw_handler) prism54_set_wpa, (iw_handler) NULL, - (iw_handler) prism54_oid, + (iw_handler) prism54_debug_oid, + (iw_handler) prism54_debug_get_oid, + (iw_handler) prism54_debug_set_oid, (iw_handler) prism54_get_oid, - (iw_handler) prism54_set_oid, + (iw_handler) prism54_set_u32, + (iw_handler) NULL, + (iw_handler) prism54_set_raw, + (iw_handler) NULL, + (iw_handler) prism54_set_raw, + (iw_handler) prism54_get_prismhdr, + (iw_handler) prism54_set_prismhdr, }; const struct iw_handler_def prism54_handler_def = { @@ -2207,5 +2343,13 @@ const struct iw_handler_def prism54_handler_def = { .standard = (iw_handler *) prism54_handler, .private = (iw_handler *) prism54_private_handler, .private_args = (struct iw_priv_args *) prism54_private_args, + .spy_offset = offsetof(islpci_private, spy_data), }; +/* For ioctls that don't work with the new API */ + +int +prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) +{ + return -EOPNOTSUPP; +} diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h index 0e43dea95..d5170c478 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.h +++ b/drivers/net/wireless/prism54/isl_ioctl.h @@ -1,4 +1,4 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.h,v 1.30 2004/01/30 16:24:00 ajfa Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * (C) 2003 Aurelien Alleaume diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h index 25732d28d..c4b27d24d 100644 --- a/drivers/net/wireless/prism54/isl_oid.h +++ b/drivers/net/wireless/prism54/isl_oid.h @@ -1,8 +1,9 @@ /* - * $Id: isl_oid.h,v 1.3 2004/03/09 09:05:27 mcgrof Exp $ + * * * Copyright (C) 2003 Herbert Valerio Riedel * Copyright (C) 2004 Luis R. Rodriguez + * Copyright (C) 2004 Aurelien Alleaume * * 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 @@ -457,16 +458,29 @@ enum oid_num_t { OID_NUM_LAST }; -/* We could add more flags. eg: in which mode are they allowed, ro, rw, ...*/ -#define OID_FLAG_CACHED 0x01 -#define OID_FLAG_U32 0x02 -#define OID_FLAG_MLMEEX 0x04 /* this type is special because of a variable - size field when sending. Not yet implemented (not used in driver). */ +#define OID_FLAG_CACHED 0x80 +#define OID_FLAG_TYPE 0x7f + +#define OID_TYPE_U32 0x01 +#define OID_TYPE_SSID 0x02 +#define OID_TYPE_KEY 0x03 +#define OID_TYPE_BUFFER 0x04 +#define OID_TYPE_BSS 0x05 +#define OID_TYPE_BSSLIST 0x06 +#define OID_TYPE_FREQUENCIES 0x07 +#define OID_TYPE_MLME 0x08 +#define OID_TYPE_MLMEEX 0x09 +#define OID_TYPE_ADDR 0x0A +#define OID_TYPE_RAW 0x0B + +/* OID_TYPE_MLMEEX is special because of a variable size field when sending. + * Not yet implemented (not used in driver anyway). + */ struct oid_t { enum oid_num_t oid; short range; /* to define a range of oid */ - short size; /* size of the associated data */ + short size; /* max size of the associated data */ char flags; }; @@ -478,6 +492,7 @@ union oid_res_t { #define IWMAX_BITRATES 20 #define IWMAX_BSS 24 #define IWMAX_FREQ 30 +#define PRIV_STR_SIZE 1024 #endif /* !defined(_ISL_OID_H) */ /* EOF */ diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index e1545f646..157193918 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -1,4 +1,4 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.c,v 1.68 2004/02/28 03:06:07 mcgrof Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2003 Herbert Valerio Riedel @@ -715,9 +715,9 @@ islpci_setup(struct pci_dev *pdev) priv = netdev_priv(ndev); priv->ndev = ndev; priv->pdev = pdev; - + priv->monitor_type = ARPHRD_IEEE80211; priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ? - ARPHRD_IEEE80211: ARPHRD_ETHER; + priv->monitor_type : ARPHRD_ETHER; /* save the start and end address of the PCI memory area */ ndev->mem_start = (unsigned long) priv->device_base; @@ -743,9 +743,11 @@ islpci_setup(struct pci_dev *pdev) /* initialize workqueue's */ INIT_WORK(&priv->stats_work, (void (*)(void *)) prism54_update_stats, priv); - priv->stats_timestamp = 0; + INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv); + priv->reset_task_pending = 0; + /* allocate various memory areas */ if (islpci_alloc_memory(priv)) goto do_free_netdev; diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h index 65f696c89..de92b4ea6 100644 --- a/drivers/net/wireless/prism54/islpci_dev.h +++ b/drivers/net/wireless/prism54/islpci_dev.h @@ -1,8 +1,9 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v 1.53 2004/02/28 03:06:07 mcgrof Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2003 Herbert Valerio Riedel * Copyright (C) 2003 Luis R. Rodriguez + * Copyright (C) 2003 Aurelien Alleaume * * 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 @@ -25,6 +26,7 @@ #include #include #include +#include #include #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) @@ -110,6 +112,10 @@ typedef struct { struct iw_statistics local_iwstatistics; struct iw_statistics iwstatistics; + struct iw_spy_data spy_data; /* iwspy support */ + + int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */ + struct islpci_acl acl; /* PCI bus allocation & configuration members */ @@ -187,6 +193,9 @@ typedef struct { struct list_head bss_wpa_list; int num_bss_wpa; struct semaphore wpa_sem; + + struct work_struct reset_task; + int reset_task_pending; } islpci_private; static inline islpci_state_t diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 3bc6c5f0c..c18c42d0c 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c @@ -1,7 +1,7 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v 1.27 2004/01/30 16:24:00 ajfa Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. - * + * Copyright (C) 2004 Aurelien Alleaume * 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 @@ -24,10 +24,12 @@ #include #include #include +#include #include "isl_38xx.h" #include "islpci_eth.h" #include "islpci_mgt.h" +#include "oid_mgt.h" /****************************************************************************** Network Interface functions @@ -246,6 +248,69 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev) return err; } +static inline int +islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb) +{ + /* The card reports full 802.11 packets but with a 20 bytes + * header and without the FCS. But there a is a bit that + * indicates if the packet is corrupted :-) */ + struct rfmon_header *hdr = (struct rfmon_header *) (*skb)->data; + if (hdr->flags & 0x01) + /* This one is bad. Drop it ! */ + return -1; + if (priv->ndev->type == ARPHRD_IEEE80211_PRISM) { + struct avs_80211_1_header *avs; + /* extract the relevant data from the header */ + u32 clock = hdr->clock; + u8 rate = hdr->rate; + u16 freq = be16_to_cpu(hdr->freq); + u8 rssi = hdr->rssi; + + skb_pull(*skb, sizeof (struct rfmon_header)); + + if (skb_headroom(*skb) < sizeof (struct avs_80211_1_header)) { + struct sk_buff *newskb = skb_copy_expand(*skb, + sizeof (struct + avs_80211_1_header), + 0, GFP_ATOMIC); + if (newskb) { + kfree_skb(*skb); + *skb = newskb; + } else + return -1; + /* This behavior is not very subtile... */ + } + + /* make room for the new header and fill it. */ + avs = + (struct avs_80211_1_header *) skb_push(*skb, + sizeof (struct + avs_80211_1_header)); + + avs->version = htonl(P80211CAPTURE_VERSION); + avs->length = htonl(sizeof (struct avs_80211_1_header)); + avs->mactime = __cpu_to_be64(clock); + avs->hosttime = __cpu_to_be64(jiffies); + avs->phytype = htonl(6); /*OFDM: 6 for (g), 8 for (a) */ + avs->channel = htonl(channel_of_freq(freq)); + avs->datarate = htonl(rate * 5); + avs->antenna = htonl(0); /*unknown */ + avs->priority = htonl(0); /*unknown */ + avs->ssi_type = htonl(2); /*2: dBm, 3: raw RSSI */ + avs->ssi_signal = htonl(rssi); + avs->ssi_noise = htonl(priv->local_iwstatistics.qual.noise); /*better than 'undefined', I assume */ + avs->preamble = htonl(0); /*unknown */ + avs->encoding = htonl(0); /*unknown */ + } else + skb_pull(*skb, sizeof (struct rfmon_header)); + + (*skb)->protocol = htons(ETH_P_802_2); + (*skb)->mac.raw = (*skb)->data; + (*skb)->pkt_type = PACKET_OTHERHOST; + + return 0; +} + int islpci_eth_receive(islpci_private *priv) { @@ -266,7 +331,8 @@ islpci_eth_receive(islpci_private *priv) index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE; size = le16_to_cpu(control_block->rx_data_low[index].size); skb = priv->data_low_rx[index]; - offset = ((unsigned long) le32_to_cpu(control_block->rx_data_low[index].address) - + offset = ((unsigned long) + le32_to_cpu(control_block->rx_data_low[index].address) - (unsigned long) skb->data) & 3; #if VERBOSE > SHOW_ERROR_MESSAGES @@ -314,29 +380,32 @@ islpci_eth_receive(islpci_private *priv) /* do some additional sk_buff and network layer parameters */ skb->dev = ndev; - /* take care of monitor mode */ - if (priv->iw_mode == IW_MODE_MONITOR) { - /* The card reports full 802.11 packets but with a 20 bytes - * header and without the FCS. But there a is a bit that - * indicates if the packet is corrupted :-) */ - /* int i; */ - if (skb->data[8] & 0x01){ - /* This one is bad. Drop it !*/ - discard = 1; - /* printk("BAD\n");*/ + /* take care of monitor mode and spy monitoring. */ + if (priv->iw_mode == IW_MODE_MONITOR) + discard = islpci_monitor_rx(priv, &skb); + else { + if (skb->data[2 * ETH_ALEN] == 0) { + /* The packet has a rx_annex. Read it for spy monitoring, Then + * remove it, while keeping the 2 leading MAC addr. + */ + struct iw_quality wstats; + struct rx_annex_header *annex = + (struct rx_annex_header *) skb->data; + wstats.level = annex->rfmon.rssi; + /* The noise value can be a bit outdated if nobody's + * reading wireless stats... */ + wstats.noise = priv->local_iwstatistics.qual.noise; + wstats.qual = wstats.level - wstats.noise; + wstats.updated = 0x07; + /* Update spy records */ + wireless_spy_update(ndev, annex->addr2, &wstats); + + memcpy(skb->data + sizeof (struct rfmon_header), + skb->data, 2 * ETH_ALEN); + skb_pull(skb, sizeof (struct rfmon_header)); } - /* - for(i=0;i<50;i++) - printk("%2.2X:",skb->data[i]); - printk("\n"); - */ - skb_pull(skb, 20); - skb->protocol = htons(ETH_P_802_2); - skb->mac.raw = skb->data; - skb->pkt_type = PACKET_OTHERHOST; - } else skb->protocol = eth_type_trans(skb, ndev); - + } skb->ip_summed = CHECKSUM_NONE; priv->statistics.rx_packets++; priv->statistics.rx_bytes += size; @@ -351,8 +420,7 @@ islpci_eth_receive(islpci_private *priv) if (discard) { dev_kfree_skb(skb); skb = NULL; - } - else + } else netif_rx(skb); /* increment the read index for the rx data low queue */ @@ -403,7 +471,7 @@ islpci_eth_receive(islpci_private *priv) wmb(); /* increment the driver read pointer */ - add_le32p((u32 *) & control_block-> + add_le32p((u32 *) &control_block-> driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1); } @@ -413,6 +481,15 @@ islpci_eth_receive(islpci_private *priv) return 0; } +void +islpci_do_reset_and_wake(void *data) +{ + islpci_private *priv = (islpci_private *) data; + islpci_reset(priv, 1); + netif_wake_queue(priv->ndev); + priv->reset_task_pending = 0; +} + void islpci_eth_tx_timeout(struct net_device *ndev) { @@ -422,13 +499,11 @@ islpci_eth_tx_timeout(struct net_device *ndev) /* increment the transmit error counter */ statistics->tx_errors++; -#if 0 - /* don't do this here! we are not allowed to sleep since we are in interrupt context */ - if (islpci_reset(priv)) - printk(KERN_ERR "%s: error on TX timeout card reset!\n", - ndev->name); -#endif + if (!priv->reset_task_pending) { + priv->reset_task_pending = 1; + netif_stop_queue(ndev); + schedule_work(&priv->reset_task); + } - /* netif_wake_queue(ndev); */ return; } diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h index 35845f247..bc9d7a60b 100644 --- a/drivers/net/wireless/prism54/islpci_eth.h +++ b/drivers/net/wireless/prism54/islpci_eth.h @@ -1,4 +1,4 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.h,v 1.5 2004/01/12 22:16:32 jmaurer Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * @@ -23,9 +23,51 @@ #include "isl_38xx.h" #include "islpci_dev.h" +struct rfmon_header { + u16 unk0; /* = 0x0000 */ + u16 length; /* = 0x1400 */ + u32 clock; /* 1MHz clock */ + u8 flags; + u8 unk1; + u8 rate; + u8 unk2; + u16 freq; + u16 unk3; + u8 rssi; + u8 padding[3]; +} __attribute__ ((packed)); + +struct rx_annex_header { + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + struct rfmon_header rfmon; +} __attribute__ ((packed)); + +/* wlan-ng (and hopefully others) AVS header, version one. Fields in + * network byte order. */ +#define P80211CAPTURE_VERSION 0x80211001 + +struct avs_80211_1_header { + uint32_t version; + uint32_t length; + uint64_t mactime; + uint64_t hosttime; + uint32_t phytype; + uint32_t channel; + uint32_t datarate; + uint32_t antenna; + uint32_t priority; + uint32_t ssi_type; + int32_t ssi_signal; + int32_t ssi_noise; + uint32_t preamble; + uint32_t encoding; +}; + void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *); int islpci_eth_transmit(struct sk_buff *, struct net_device *); int islpci_eth_receive(islpci_private *); void islpci_eth_tx_timeout(struct net_device *); +void islpci_do_reset_and_wake(void *data); #endif /* _ISL_GEN_H */ diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c index 5cd7da48d..34b3b59fe 100644 --- a/drivers/net/wireless/prism54/islpci_hotplug.c +++ b/drivers/net/wireless/prism54/islpci_hotplug.c @@ -1,4 +1,4 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_hotplug.c,v 1.56 2004/02/26 23:33:02 mcgrof Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2003 Herbert Valerio Riedel diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c index 3dbe20813..bdf77d6c5 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.c +++ b/drivers/net/wireless/prism54/islpci_mgt.c @@ -1,4 +1,4 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_mgt.c,v 1.40 2004/02/01 10:57:23 mcgrof Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * Copyright 2004 Jens Maurer diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h index cb2ea6fe5..80337f926 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.h +++ b/drivers/net/wireless/prism54/islpci_mgt.h @@ -1,4 +1,4 @@ -/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_mgt.h,v 1.22 2004/01/30 16:24:00 ajfa Exp $ +/* * * Copyright (C) 2002 Intersil Americas Inc. * Copyright (C) 2003 Luis R. Rodriguez diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c index 29aa1361e..cfa541ca2 100644 --- a/drivers/net/wireless/prism54/oid_mgt.c +++ b/drivers/net/wireless/prism54/oid_mgt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 Aurelien Alleaume + * Copyright (C) 2003,2004 Aurelien Alleaume * * 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 @@ -31,182 +31,210 @@ const int frequency_list_a[] = { 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, 5260, 5280, 5300, 5320 }; -#define OID_U32(x) {x, 0, sizeof(u32), OID_FLAG_U32} -#define OID_U32_C(x) {x, 0, sizeof(u32), OID_FLAG_U32 | OID_FLAG_CACHED} -#define OID_STRUCT(x,s) {x, 0, sizeof(s), 0} -#define OID_STRUCT_C(x,s) {x, 0, sizeof(s), OID_FLAG_CACHED} -#define OID_STRUCT_MLME(x){x, 0, sizeof(struct obj_mlme), 0} -#define OID_STRUCT_MLMEEX(x){x, 0, sizeof(struct obj_mlmeex), OID_FLAG_MLMEEX} +int +channel_of_freq(int f) +{ + int c = 0; + + if ((f >= 2412) && (f <= 2484)) { + while ((c < 14) && (f != frequency_list_bg[c])) + c++; + if (c >= 14) + return 0; + } else if ((f >= (int) 5170) && (f <= (int) 5320)) { + while ((c < 12) && (f != frequency_list_a[c])) + c++; + if (c >= 12) + return 0; + } else + return 0; + + return ++c; +} + +#define OID_STRUCT(name,oid,s,t) [name] = {oid, 0, sizeof(s), t} +#define OID_STRUCT_C(name,oid,s,t) OID_STRUCT(name,oid,s,t | OID_FLAG_CACHED) +#define OID_U32(name,oid) OID_STRUCT(name,oid,u32,OID_TYPE_U32) +#define OID_U32_C(name,oid) OID_STRUCT_C(name,oid,u32,OID_TYPE_U32) +#define OID_STRUCT_MLME(name,oid) OID_STRUCT(name,oid,struct obj_mlme,OID_TYPE_MLME) +#define OID_STRUCT_MLMEEX(name,oid) OID_STRUCT(name,oid,struct obj_mlmeex,OID_TYPE_MLMEEX) -#define OID_UNKNOWN(x) {x, 0, 0, 0} +#define OID_UNKNOWN(name,oid) OID_STRUCT(name,oid,0,0) struct oid_t isl_oid[] = { - [GEN_OID_MACADDRESS] = OID_STRUCT(0x00000000, u8[6]), - [GEN_OID_LINKSTATE] = OID_U32(0x00000001), - [GEN_OID_WATCHDOG] = OID_UNKNOWN(0x00000002), - [GEN_OID_MIBOP] = OID_UNKNOWN(0x00000003), - [GEN_OID_OPTIONS] = OID_UNKNOWN(0x00000004), - [GEN_OID_LEDCONFIG] = OID_UNKNOWN(0x00000005), + OID_STRUCT(GEN_OID_MACADDRESS, 0x00000000, u8[6], OID_TYPE_ADDR), + OID_U32(GEN_OID_LINKSTATE, 0x00000001), + OID_UNKNOWN(GEN_OID_WATCHDOG, 0x00000002), + OID_UNKNOWN(GEN_OID_MIBOP, 0x00000003), + OID_UNKNOWN(GEN_OID_OPTIONS, 0x00000004), + OID_UNKNOWN(GEN_OID_LEDCONFIG, 0x00000005), /* 802.11 */ - [DOT11_OID_BSSTYPE] = OID_U32_C(0x10000000), - [DOT11_OID_BSSID] = OID_STRUCT_C(0x10000001, u8[6]), - [DOT11_OID_SSID] = OID_STRUCT_C(0x10000002, struct obj_ssid), - [DOT11_OID_STATE] = OID_U32(0x10000003), - [DOT11_OID_AID] = OID_U32(0x10000004), - [DOT11_OID_COUNTRYSTRING] = OID_STRUCT(0x10000005, u8[4]), - [DOT11_OID_SSIDOVERRIDE] = OID_STRUCT_C(0x10000006, struct obj_ssid), - - [DOT11_OID_MEDIUMLIMIT] = OID_U32(0x11000000), - [DOT11_OID_BEACONPERIOD] = OID_U32_C(0x11000001), - [DOT11_OID_DTIMPERIOD] = OID_U32(0x11000002), - [DOT11_OID_ATIMWINDOW] = OID_U32(0x11000003), - [DOT11_OID_LISTENINTERVAL] = OID_U32(0x11000004), - [DOT11_OID_CFPPERIOD] = OID_U32(0x11000005), - [DOT11_OID_CFPDURATION] = OID_U32(0x11000006), - - [DOT11_OID_AUTHENABLE] = OID_U32_C(0x12000000), - [DOT11_OID_PRIVACYINVOKED] = OID_U32_C(0x12000001), - [DOT11_OID_EXUNENCRYPTED] = OID_U32_C(0x12000002), - [DOT11_OID_DEFKEYID] = OID_U32_C(0x12000003), - [DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key), OID_FLAG_CACHED}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */ - [DOT11_OID_STAKEY] = OID_UNKNOWN(0x12000008), - [DOT11_OID_REKEYTHRESHOLD] = OID_U32(0x12000009), - [DOT11_OID_STASC] = OID_UNKNOWN(0x1200000a), - - [DOT11_OID_PRIVTXREJECTED] = OID_U32(0x1a000000), - [DOT11_OID_PRIVRXPLAIN] = OID_U32(0x1a000001), - [DOT11_OID_PRIVRXFAILED] = OID_U32(0x1a000002), - [DOT11_OID_PRIVRXNOKEY] = OID_U32(0x1a000003), - - [DOT11_OID_RTSTHRESH] = OID_U32_C(0x13000000), - [DOT11_OID_FRAGTHRESH] = OID_U32_C(0x13000001), - [DOT11_OID_SHORTRETRIES] = OID_U32_C(0x13000002), - [DOT11_OID_LONGRETRIES] = OID_U32_C(0x13000003), - [DOT11_OID_MAXTXLIFETIME] = OID_U32_C(0x13000004), - [DOT11_OID_MAXRXLIFETIME] = OID_U32(0x13000005), - [DOT11_OID_AUTHRESPTIMEOUT] = OID_U32(0x13000006), - [DOT11_OID_ASSOCRESPTIMEOUT] = OID_U32(0x13000007), - - [DOT11_OID_ALOFT_TABLE] = OID_UNKNOWN(0x1d000000), - [DOT11_OID_ALOFT_CTRL_TABLE] = OID_UNKNOWN(0x1d000001), - [DOT11_OID_ALOFT_RETREAT] = OID_UNKNOWN(0x1d000002), - [DOT11_OID_ALOFT_PROGRESS] = OID_UNKNOWN(0x1d000003), - [DOT11_OID_ALOFT_FIXEDRATE] = OID_U32(0x1d000004), - [DOT11_OID_ALOFT_RSSIGRAPH] = OID_UNKNOWN(0x1d000005), - [DOT11_OID_ALOFT_CONFIG] = OID_UNKNOWN(0x1d000006), + OID_U32_C(DOT11_OID_BSSTYPE, 0x10000000), + OID_STRUCT_C(DOT11_OID_BSSID, 0x10000001, u8[6], OID_TYPE_SSID), + OID_STRUCT_C(DOT11_OID_SSID, 0x10000002, struct obj_ssid, + OID_TYPE_SSID), + OID_U32(DOT11_OID_STATE, 0x10000003), + OID_U32(DOT11_OID_AID, 0x10000004), + OID_STRUCT(DOT11_OID_COUNTRYSTRING, 0x10000005, u8[4], OID_TYPE_RAW), + OID_STRUCT_C(DOT11_OID_SSIDOVERRIDE, 0x10000006, struct obj_ssid, + OID_TYPE_SSID), + + OID_U32(DOT11_OID_MEDIUMLIMIT, 0x11000000), + OID_U32_C(DOT11_OID_BEACONPERIOD, 0x11000001), + OID_U32(DOT11_OID_DTIMPERIOD, 0x11000002), + OID_U32(DOT11_OID_ATIMWINDOW, 0x11000003), + OID_U32(DOT11_OID_LISTENINTERVAL, 0x11000004), + OID_U32(DOT11_OID_CFPPERIOD, 0x11000005), + OID_U32(DOT11_OID_CFPDURATION, 0x11000006), + + OID_U32_C(DOT11_OID_AUTHENABLE, 0x12000000), + OID_U32_C(DOT11_OID_PRIVACYINVOKED, 0x12000001), + OID_U32_C(DOT11_OID_EXUNENCRYPTED, 0x12000002), + OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003), + [DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key), + OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */ + OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008), + OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009), + OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a), + + OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000), + OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001), + OID_U32(DOT11_OID_PRIVRXFAILED, 0x1a000002), + OID_U32(DOT11_OID_PRIVRXNOKEY, 0x1a000003), + + OID_U32_C(DOT11_OID_RTSTHRESH, 0x13000000), + OID_U32_C(DOT11_OID_FRAGTHRESH, 0x13000001), + OID_U32_C(DOT11_OID_SHORTRETRIES, 0x13000002), + OID_U32_C(DOT11_OID_LONGRETRIES, 0x13000003), + OID_U32_C(DOT11_OID_MAXTXLIFETIME, 0x13000004), + OID_U32(DOT11_OID_MAXRXLIFETIME, 0x13000005), + OID_U32(DOT11_OID_AUTHRESPTIMEOUT, 0x13000006), + OID_U32(DOT11_OID_ASSOCRESPTIMEOUT, 0x13000007), + + OID_UNKNOWN(DOT11_OID_ALOFT_TABLE, 0x1d000000), + OID_UNKNOWN(DOT11_OID_ALOFT_CTRL_TABLE, 0x1d000001), + OID_UNKNOWN(DOT11_OID_ALOFT_RETREAT, 0x1d000002), + OID_UNKNOWN(DOT11_OID_ALOFT_PROGRESS, 0x1d000003), + OID_U32(DOT11_OID_ALOFT_FIXEDRATE, 0x1d000004), + OID_UNKNOWN(DOT11_OID_ALOFT_RSSIGRAPH, 0x1d000005), + OID_UNKNOWN(DOT11_OID_ALOFT_CONFIG, 0x1d000006), [DOT11_OID_VDCFX] = {0x1b000000, 7, 0, 0}, - [DOT11_OID_MAXFRAMEBURST] = OID_U32(0x1b000008), /* in microseconds */ + OID_U32(DOT11_OID_MAXFRAMEBURST, 0x1b000008), - [DOT11_OID_PSM] = OID_U32(0x14000000), - [DOT11_OID_CAMTIMEOUT] = OID_U32(0x14000001), - [DOT11_OID_RECEIVEDTIMS] = OID_U32(0x14000002), - [DOT11_OID_ROAMPREFERENCE] = OID_U32(0x14000003), + OID_U32(DOT11_OID_PSM, 0x14000000), + OID_U32(DOT11_OID_CAMTIMEOUT, 0x14000001), + OID_U32(DOT11_OID_RECEIVEDTIMS, 0x14000002), + OID_U32(DOT11_OID_ROAMPREFERENCE, 0x14000003), - [DOT11_OID_BRIDGELOCAL] = OID_U32(0x15000000), - [DOT11_OID_CLIENTS] = OID_U32(0x15000001), - [DOT11_OID_CLIENTSASSOCIATED] = OID_U32(0x15000002), + OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000), + OID_U32(DOT11_OID_CLIENTS, 0x15000001), + OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002), [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */ - [DOT11_OID_CLIENTFIND] = OID_STRUCT(0x150007DB, u8[6]), - [DOT11_OID_WDSLINKADD] = OID_STRUCT(0x150007DC, u8[6]), - [DOT11_OID_WDSLINKREMOVE] = OID_STRUCT(0x150007DD, u8[6]), - [DOT11_OID_EAPAUTHSTA] = OID_STRUCT(0x150007DE, u8[6]), - [DOT11_OID_EAPUNAUTHSTA] = OID_STRUCT(0x150007DF, u8[6]), - [DOT11_OID_DOT1XENABLE] = OID_U32_C(0x150007E0), - [DOT11_OID_MICFAILURE] = OID_UNKNOWN(0x150007E1), - [DOT11_OID_REKEYINDICATE] = OID_UNKNOWN(0x150007E2), - - [DOT11_OID_MPDUTXSUCCESSFUL] = OID_U32(0x16000000), - [DOT11_OID_MPDUTXONERETRY] = OID_U32(0x16000001), - [DOT11_OID_MPDUTXMULTIPLERETRIES] = OID_U32(0x16000002), - [DOT11_OID_MPDUTXFAILED] = OID_U32(0x16000003), - [DOT11_OID_MPDURXSUCCESSFUL] = OID_U32(0x16000004), - [DOT11_OID_MPDURXDUPS] = OID_U32(0x16000005), - [DOT11_OID_RTSSUCCESSFUL] = OID_U32(0x16000006), - [DOT11_OID_RTSFAILED] = OID_U32(0x16000007), - [DOT11_OID_ACKFAILED] = OID_U32(0x16000008), - [DOT11_OID_FRAMERECEIVES] = OID_U32(0x16000009), - [DOT11_OID_FRAMEERRORS] = OID_U32(0x1600000A), - [DOT11_OID_FRAMEABORTS] = OID_U32(0x1600000B), - [DOT11_OID_FRAMEABORTSPHY] = OID_U32(0x1600000C), - - [DOT11_OID_SLOTTIME] = OID_U32(0x17000000), - [DOT11_OID_CWMIN] = OID_U32(0x17000001), - [DOT11_OID_CWMAX] = OID_U32(0x17000002), - [DOT11_OID_ACKWINDOW] = OID_U32(0x17000003), - [DOT11_OID_ANTENNARX] = OID_U32(0x17000004), - [DOT11_OID_ANTENNATX] = OID_U32(0x17000005), - [DOT11_OID_ANTENNADIVERSITY] = OID_U32(0x17000006), - [DOT11_OID_CHANNEL] = OID_U32_C(0x17000007), - [DOT11_OID_EDTHRESHOLD] = OID_U32_C(0x17000008), - [DOT11_OID_PREAMBLESETTINGS] = OID_U32(0x17000009), - [DOT11_OID_RATES] = OID_STRUCT(0x1700000A, u8[IWMAX_BITRATES + 1]), - [DOT11_OID_CCAMODESUPPORTED] = OID_U32(0x1700000B), - [DOT11_OID_CCAMODE] = OID_U32(0x1700000C), - [DOT11_OID_RSSIVECTOR] = OID_U32(0x1700000D), - [DOT11_OID_OUTPUTPOWERTABLE] = OID_U32(0x1700000E), - [DOT11_OID_OUTPUTPOWER] = OID_U32_C(0x1700000F), - [DOT11_OID_SUPPORTEDRATES] = - OID_STRUCT(0x17000010, u8[IWMAX_BITRATES + 1]), - [DOT11_OID_FREQUENCY] = OID_U32_C(0x17000011), - [DOT11_OID_SUPPORTEDFREQUENCIES] = {0x17000012, 0, sizeof (struct - obj_frequencies) - + sizeof (u16) * IWMAX_FREQ, 0}, - - [DOT11_OID_NOISEFLOOR] = OID_U32(0x17000013), - [DOT11_OID_FREQUENCYACTIVITY] = - OID_STRUCT(0x17000014, u8[IWMAX_FREQ + 1]), - [DOT11_OID_IQCALIBRATIONTABLE] = OID_UNKNOWN(0x17000015), - [DOT11_OID_NONERPPROTECTION] = OID_U32(0x17000016), - [DOT11_OID_SLOTSETTINGS] = OID_U32(0x17000017), - [DOT11_OID_NONERPTIMEOUT] = OID_U32(0x17000018), - [DOT11_OID_PROFILES] = OID_U32(0x17000019), - [DOT11_OID_EXTENDEDRATES] = - OID_STRUCT(0x17000020, u8[IWMAX_BITRATES + 1]), - - [DOT11_OID_DEAUTHENTICATE] = OID_STRUCT_MLME(0x18000000), - [DOT11_OID_AUTHENTICATE] = OID_STRUCT_MLME(0x18000001), - [DOT11_OID_DISASSOCIATE] = OID_STRUCT_MLME(0x18000002), - [DOT11_OID_ASSOCIATE] = OID_STRUCT_MLME(0x18000003), - [DOT11_OID_SCAN] = OID_UNKNOWN(0x18000004), - [DOT11_OID_BEACON] = OID_STRUCT_MLMEEX(0x18000005), - [DOT11_OID_PROBE] = OID_STRUCT_MLMEEX(0x18000006), - [DOT11_OID_DEAUTHENTICATEEX] = OID_STRUCT_MLMEEX(0x18000007), - [DOT11_OID_AUTHENTICATEEX] = OID_STRUCT_MLMEEX(0x18000008), - [DOT11_OID_DISASSOCIATEEX] = OID_STRUCT_MLMEEX(0x18000009), - [DOT11_OID_ASSOCIATEEX] = OID_STRUCT_MLMEEX(0x1800000A), - [DOT11_OID_REASSOCIATE] = OID_STRUCT_MLMEEX(0x1800000B), - [DOT11_OID_REASSOCIATEEX] = OID_STRUCT_MLMEEX(0x1800000C), - - [DOT11_OID_NONERPSTATUS] = OID_U32(0x1E000000), - - [DOT11_OID_STATIMEOUT] = OID_U32(0x19000000), - [DOT11_OID_MLMEAUTOLEVEL] = OID_U32_C(0x19000001), - [DOT11_OID_BSSTIMEOUT] = OID_U32(0x19000002), - [DOT11_OID_ATTACHMENT] = OID_UNKNOWN(0x19000003), - [DOT11_OID_PSMBUFFER] = OID_STRUCT_C(0x19000004, struct obj_buffer), - - [DOT11_OID_BSSS] = OID_U32(0x1C000000), - [DOT11_OID_BSSX] = {0x1C000001, 63, sizeof (struct obj_bss), 0}, /*DOT11_OID_BSS1,...,DOT11_OID_BSS64 */ - [DOT11_OID_BSSFIND] = OID_STRUCT(0x1C000042, struct obj_bss), + OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR), + OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR), + OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR), + OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR), + OID_STRUCT(DOT11_OID_EAPUNAUTHSTA, 0x150007DF, u8[6], OID_TYPE_ADDR), + OID_U32_C(DOT11_OID_DOT1XENABLE, 0x150007E0), + OID_UNKNOWN(DOT11_OID_MICFAILURE, 0x150007E1), + OID_UNKNOWN(DOT11_OID_REKEYINDICATE, 0x150007E2), + + OID_U32(DOT11_OID_MPDUTXSUCCESSFUL, 0x16000000), + OID_U32(DOT11_OID_MPDUTXONERETRY, 0x16000001), + OID_U32(DOT11_OID_MPDUTXMULTIPLERETRIES, 0x16000002), + OID_U32(DOT11_OID_MPDUTXFAILED, 0x16000003), + OID_U32(DOT11_OID_MPDURXSUCCESSFUL, 0x16000004), + OID_U32(DOT11_OID_MPDURXDUPS, 0x16000005), + OID_U32(DOT11_OID_RTSSUCCESSFUL, 0x16000006), + OID_U32(DOT11_OID_RTSFAILED, 0x16000007), + OID_U32(DOT11_OID_ACKFAILED, 0x16000008), + OID_U32(DOT11_OID_FRAMERECEIVES, 0x16000009), + OID_U32(DOT11_OID_FRAMEERRORS, 0x1600000A), + OID_U32(DOT11_OID_FRAMEABORTS, 0x1600000B), + OID_U32(DOT11_OID_FRAMEABORTSPHY, 0x1600000C), + + OID_U32(DOT11_OID_SLOTTIME, 0x17000000), + OID_U32(DOT11_OID_CWMIN, 0x17000001), + OID_U32(DOT11_OID_CWMAX, 0x17000002), + OID_U32(DOT11_OID_ACKWINDOW, 0x17000003), + OID_U32(DOT11_OID_ANTENNARX, 0x17000004), + OID_U32(DOT11_OID_ANTENNATX, 0x17000005), + OID_U32(DOT11_OID_ANTENNADIVERSITY, 0x17000006), + OID_U32_C(DOT11_OID_CHANNEL, 0x17000007), + OID_U32_C(DOT11_OID_EDTHRESHOLD, 0x17000008), + OID_U32(DOT11_OID_PREAMBLESETTINGS, 0x17000009), + OID_STRUCT(DOT11_OID_RATES, 0x1700000A, u8[IWMAX_BITRATES + 1], + OID_TYPE_RAW), + OID_U32(DOT11_OID_CCAMODESUPPORTED, 0x1700000B), + OID_U32(DOT11_OID_CCAMODE, 0x1700000C), + OID_UNKNOWN(DOT11_OID_RSSIVECTOR, 0x1700000D), + OID_UNKNOWN(DOT11_OID_OUTPUTPOWERTABLE, 0x1700000E), + OID_U32(DOT11_OID_OUTPUTPOWER, 0x1700000F), + OID_STRUCT(DOT11_OID_SUPPORTEDRATES, 0x17000010, + u8[IWMAX_BITRATES + 1], OID_TYPE_RAW), + OID_U32_C(DOT11_OID_FREQUENCY, 0x17000011), + [DOT11_OID_SUPPORTEDFREQUENCIES] = + {0x17000012, 0, sizeof (struct obj_frequencies) + + sizeof (u16) * IWMAX_FREQ, OID_TYPE_FREQUENCIES}, + + OID_U32(DOT11_OID_NOISEFLOOR, 0x17000013), + OID_STRUCT(DOT11_OID_FREQUENCYACTIVITY, 0x17000014, u8[IWMAX_FREQ + 1], + OID_TYPE_RAW), + OID_UNKNOWN(DOT11_OID_IQCALIBRATIONTABLE, 0x17000015), + OID_U32(DOT11_OID_NONERPPROTECTION, 0x17000016), + OID_U32(DOT11_OID_SLOTSETTINGS, 0x17000017), + OID_U32(DOT11_OID_NONERPTIMEOUT, 0x17000018), + OID_U32(DOT11_OID_PROFILES, 0x17000019), + OID_STRUCT(DOT11_OID_EXTENDEDRATES, 0x17000020, + u8[IWMAX_BITRATES + 1], OID_TYPE_RAW), + + OID_STRUCT_MLME(DOT11_OID_DEAUTHENTICATE, 0x18000000), + OID_STRUCT_MLME(DOT11_OID_AUTHENTICATE, 0x18000001), + OID_STRUCT_MLME(DOT11_OID_DISASSOCIATE, 0x18000002), + OID_STRUCT_MLME(DOT11_OID_ASSOCIATE, 0x18000003), + OID_UNKNOWN(DOT11_OID_SCAN, 0x18000004), + OID_STRUCT_MLMEEX(DOT11_OID_BEACON, 0x18000005), + OID_STRUCT_MLMEEX(DOT11_OID_PROBE, 0x18000006), + OID_STRUCT_MLMEEX(DOT11_OID_DEAUTHENTICATEEX, 0x18000007), + OID_STRUCT_MLMEEX(DOT11_OID_AUTHENTICATEEX, 0x18000008), + OID_STRUCT_MLMEEX(DOT11_OID_DISASSOCIATEEX, 0x18000009), + OID_STRUCT_MLMEEX(DOT11_OID_ASSOCIATEEX, 0x1800000A), + OID_STRUCT_MLMEEX(DOT11_OID_REASSOCIATE, 0x1800000B), + OID_STRUCT_MLMEEX(DOT11_OID_REASSOCIATEEX, 0x1800000C), + + OID_U32(DOT11_OID_NONERPSTATUS, 0x1E000000), + + OID_U32(DOT11_OID_STATIMEOUT, 0x19000000), + OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001), + OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002), + OID_UNKNOWN(DOT11_OID_ATTACHMENT, 0x19000003), + OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer, + OID_TYPE_BUFFER), + + OID_U32(DOT11_OID_BSSS, 0x1C000000), + [DOT11_OID_BSSX] = {0x1C000001, 63, sizeof (struct obj_bss), + OID_TYPE_BSS}, /*DOT11_OID_BSS1,...,DOT11_OID_BSS64 */ + OID_STRUCT(DOT11_OID_BSSFIND, 0x1C000042, struct obj_bss, OID_TYPE_BSS), [DOT11_OID_BSSLIST] = {0x1C000043, 0, sizeof (struct obj_bsslist) + - sizeof (struct obj_bss[IWMAX_BSS]), 0}, - - [OID_INL_TUNNEL] = OID_UNKNOWN(0xFF020000), - [OID_INL_MEMADDR] = OID_UNKNOWN(0xFF020001), - [OID_INL_MEMORY] = OID_UNKNOWN(0xFF020002), - [OID_INL_MODE] = OID_U32_C(0xFF020003), - [OID_INL_COMPONENT_NR] = OID_UNKNOWN(0xFF020004), - [OID_INL_VERSION] = OID_UNKNOWN(0xFF020005), - [OID_INL_INTERFACE_ID] = OID_UNKNOWN(0xFF020006), - [OID_INL_COMPONENT_ID] = OID_UNKNOWN(0xFF020007), - [OID_INL_CONFIG] = OID_U32_C(0xFF020008), - [OID_INL_DOT11D_CONFORMANCE] = OID_U32_C(0xFF02000C), - [OID_INL_PHYCAPABILITIES] = OID_U32(0xFF02000D), - [OID_INL_OUTPUTPOWER] = OID_U32_C(0xFF02000F), + sizeof (struct obj_bss[IWMAX_BSS]), + OID_TYPE_BSSLIST}, + + OID_UNKNOWN(OID_INL_TUNNEL, 0xFF020000), + OID_UNKNOWN(OID_INL_MEMADDR, 0xFF020001), + OID_UNKNOWN(OID_INL_MEMORY, 0xFF020002), + OID_U32_C(OID_INL_MODE, 0xFF020003), + OID_UNKNOWN(OID_INL_COMPONENT_NR, 0xFF020004), + OID_UNKNOWN(OID_INL_VERSION, 0xFF020005), + OID_UNKNOWN(OID_INL_INTERFACE_ID, 0xFF020006), + OID_UNKNOWN(OID_INL_COMPONENT_ID, 0xFF020007), + OID_U32_C(OID_INL_CONFIG, 0xFF020008), + OID_U32_C(OID_INL_DOT11D_CONFORMANCE, 0xFF02000C), + OID_U32(OID_INL_PHYCAPABILITIES, 0xFF02000D), + OID_U32_C(OID_INL_OUTPUTPOWER, 0xFF02000F), }; @@ -257,6 +285,134 @@ mgt_clean(islpci_private *priv) priv->mib = NULL; } +void +mgt_le_to_cpu(int type, void *data) +{ + switch (type) { + case OID_TYPE_U32: + *(u32 *) data = le32_to_cpu(*(u32 *) data); + break; + case OID_TYPE_BUFFER:{ + struct obj_buffer *buff = data; + buff->size = le32_to_cpu(buff->size); + buff->addr = le32_to_cpu(buff->addr); + break; + } + case OID_TYPE_BSS:{ + struct obj_bss *bss = data; + bss->age = le16_to_cpu(bss->age); + bss->channel = le16_to_cpu(bss->channel); + bss->capinfo = le16_to_cpu(bss->capinfo); + bss->rates = le16_to_cpu(bss->rates); + bss->basic_rates = le16_to_cpu(bss->basic_rates); + break; + } + case OID_TYPE_BSSLIST:{ + struct obj_bsslist *list = data; + int i; + list->nr = le32_to_cpu(list->nr); + for (i = 0; i < list->nr; i++) + mgt_le_to_cpu(OID_TYPE_BSS, &list->bsslist[i]); + break; + } + case OID_TYPE_FREQUENCIES:{ + struct obj_frequencies *freq = data; + int i; + freq->nr = le16_to_cpu(freq->nr); + for (i = 0; i < freq->nr; i++) + freq->mhz[i] = le16_to_cpu(freq->mhz[i]); + break; + } + case OID_TYPE_MLME:{ + struct obj_mlme *mlme = data; + mlme->id = le16_to_cpu(mlme->id); + mlme->state = le16_to_cpu(mlme->state); + mlme->code = le16_to_cpu(mlme->code); + break; + } + case OID_TYPE_MLMEEX:{ + struct obj_mlmeex *mlme = data; + mlme->id = le16_to_cpu(mlme->id); + mlme->state = le16_to_cpu(mlme->state); + mlme->code = le16_to_cpu(mlme->code); + mlme->size = le16_to_cpu(mlme->size); + break; + } + case OID_TYPE_SSID: + case OID_TYPE_KEY: + case OID_TYPE_ADDR: + case OID_TYPE_RAW: + break; + default: + BUG(); + } +} + +static void +mgt_cpu_to_le(int type, void *data) +{ + switch (type) { + case OID_TYPE_U32: + *(u32 *) data = cpu_to_le32(*(u32 *) data); + break; + case OID_TYPE_BUFFER:{ + struct obj_buffer *buff = data; + buff->size = cpu_to_le32(buff->size); + buff->addr = cpu_to_le32(buff->addr); + break; + } + case OID_TYPE_BSS:{ + struct obj_bss *bss = data; + bss->age = cpu_to_le16(bss->age); + bss->channel = cpu_to_le16(bss->channel); + bss->capinfo = cpu_to_le16(bss->capinfo); + bss->rates = cpu_to_le16(bss->rates); + bss->basic_rates = cpu_to_le16(bss->basic_rates); + break; + } + case OID_TYPE_BSSLIST:{ + struct obj_bsslist *list = data; + int i; + list->nr = cpu_to_le32(list->nr); + for (i = 0; i < list->nr; i++) + mgt_cpu_to_le(OID_TYPE_BSS, &list->bsslist[i]); + break; + } + case OID_TYPE_FREQUENCIES:{ + struct obj_frequencies *freq = data; + int i; + freq->nr = cpu_to_le16(freq->nr); + for (i = 0; i < freq->nr; i++) + freq->mhz[i] = cpu_to_le16(freq->mhz[i]); + break; + } + case OID_TYPE_MLME:{ + struct obj_mlme *mlme = data; + mlme->id = cpu_to_le16(mlme->id); + mlme->state = cpu_to_le16(mlme->state); + mlme->code = cpu_to_le16(mlme->code); + break; + } + case OID_TYPE_MLMEEX:{ + struct obj_mlmeex *mlme = data; + mlme->id = cpu_to_le16(mlme->id); + mlme->state = cpu_to_le16(mlme->state); + mlme->code = cpu_to_le16(mlme->code); + mlme->size = cpu_to_le16(mlme->size); + break; + } + case OID_TYPE_SSID: + case OID_TYPE_KEY: + case OID_TYPE_ADDR: + case OID_TYPE_RAW: + break; + default: + BUG(); + } +} + +/* Note : data is modified during this function */ + int mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) { @@ -265,7 +421,7 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) int response_op = PIMFOR_OP_ERROR; int dlen; void *cache, *_data = data; - u32 oid, u; + u32 oid; BUG_ON(OID_NUM_LAST <= n); BUG_ON(extra > isl_oid[n].range); @@ -279,13 +435,11 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) cache += (cache ? extra * dlen : 0); oid = isl_oid[n].oid + extra; - if (data == NULL) + if (_data == NULL) /* we are requested to re-set a cached value */ _data = cache; - if ((isl_oid[n].flags & OID_FLAG_U32) && data) { - u = cpu_to_le32(*(u32 *) data); - _data = &u; - } + else + mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, _data); /* If we are going to write to the cache, we don't want anyone to read * it -> acquire write lock. * Else we could acquire a read lock to be sure we don't bother the @@ -313,6 +467,10 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) up_write(&priv->mib_sem); } + /* re-set given data to what it was */ + if (data) + mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data); + return ret; } @@ -326,7 +484,7 @@ mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data, struct islpci_mgmtframe *response = NULL; int dlen; - void *cache, *_res=NULL; + void *cache, *_res = NULL; u32 oid; BUG_ON(OID_NUM_LAST <= n); @@ -362,20 +520,19 @@ mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data, _res = cache; ret = 0; } - if (isl_oid[n].flags & OID_FLAG_U32) { - if (ret) - res->u = 0; - else - res->u = le32_to_cpu(*(u32 *) _res); - } else { + if ((isl_oid[n].flags & OID_FLAG_TYPE) == OID_TYPE_U32) + res->u = ret ? 0 : le32_to_cpu(*(u32 *) _res); + else { res->ptr = kmalloc(reslen, GFP_KERNEL); BUG_ON(res->ptr == NULL); if (ret) memset(res->ptr, 0, reslen); - else + else { memcpy(res->ptr, _res, reslen); + mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, + res->ptr); + } } - if (cache) up_read(&priv->mib_sem); @@ -404,7 +561,7 @@ mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n) int j = 0; u32 oid = t->oid; BUG_ON(data == NULL); - while (j <= t->range){ + while (j <= t->range) { response = NULL; ret |= islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, data, t->size, @@ -431,13 +588,21 @@ mgt_set(islpci_private *priv, enum oid_num_t n, void *data) BUG_ON(priv->mib[n] == NULL); memcpy(priv->mib[n], data, isl_oid[n].size); - if (isl_oid[n].flags & OID_FLAG_U32) - *(u32 *) priv->mib[n] = cpu_to_le32(*(u32 *) priv->mib[n]); + mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, priv->mib[n]); } -/* Commits the cache. If something goes wrong, it restarts the device. Lock - * outside - */ +void +mgt_get(islpci_private *priv, enum oid_num_t n, void *res) +{ + BUG_ON(OID_NUM_LAST <= n); + BUG_ON(priv->mib[n] == NULL); + BUG_ON(res == NULL); + + memcpy(res, priv->mib[n], isl_oid[n].size); + mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, res); +} + +/* Commits the cache. Lock outside. */ static enum oid_num_t commit_part1[] = { OID_INL_CONFIG, @@ -530,3 +695,102 @@ mgt_oidtonum(u32 oid) return 0; } + +int +mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str) +{ + switch (isl_oid[n].flags & OID_FLAG_TYPE) { + case OID_TYPE_U32: + return snprintf(str, PRIV_STR_SIZE, "%u\n", r->u); + break; + case OID_TYPE_BUFFER:{ + struct obj_buffer *buff = r->ptr; + return snprintf(str, PRIV_STR_SIZE, + "size=%u\naddr=0x%X\n", buff->size, + buff->addr); + } + break; + case OID_TYPE_BSS:{ + struct obj_bss *bss = r->ptr; + return snprintf(str, PRIV_STR_SIZE, + "age=%u\nchannel=%u\n\ + capinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n", bss->age, bss->channel, bss->capinfo, bss->rates, bss->basic_rates); + } + break; + case OID_TYPE_BSSLIST:{ + struct obj_bsslist *list = r->ptr; + int i, k; + k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr); + for (i = 0; i < list->nr; i++) + k += snprintf(str + k, PRIV_STR_SIZE - k, + "bss[%u] : \nage=%u\nchannel=%u\ncapinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n", + i, list->bsslist[i].age, + list->bsslist[i].channel, + list->bsslist[i].capinfo, + list->bsslist[i].rates, + list->bsslist[i].basic_rates); + return k; + } + break; + case OID_TYPE_FREQUENCIES:{ + struct obj_frequencies *freq = r->ptr; + int i, t; + printk("nr : %u\n", freq->nr); + t = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", freq->nr); + for (i = 0; i < freq->nr; i++) + t += snprintf(str + t, PRIV_STR_SIZE - t, + "mhz[%u]=%u\n", i, freq->mhz[i]); + return t; + } + break; + case OID_TYPE_MLME:{ + struct obj_mlme *mlme = r->ptr; + return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\ + code=0x%X\n", mlme->id, mlme->state, + mlme->code); + } + break; + case OID_TYPE_MLMEEX:{ + struct obj_mlmeex *mlme = r->ptr; + return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\ + code=0x%X\nsize=0x%X\n", mlme->id, mlme->state, + mlme->code, mlme->size); + } + break; + case OID_TYPE_SSID:{ + struct obj_ssid *ssid = r->ptr; + return snprintf(str, PRIV_STR_SIZE, + "length=%u\noctets=%s\n", + ssid->length, ssid->octets); + } + break; + case OID_TYPE_KEY:{ + struct obj_key *key = r->ptr; + int t, i; + t = snprintf(str, PRIV_STR_SIZE, + "type=0x%X\nlength=0x%X\nkey=0x", + key->type, key->length); + for (i = 0; i < key->length; i++) + t += snprintf(str + t, PRIV_STR_SIZE - t, + "%02X:", key->key[i]); + t += snprintf(str + t, PRIV_STR_SIZE - t, "\n"); + return t; + } + break; + case OID_TYPE_RAW: + case OID_TYPE_ADDR:{ + unsigned char *buff = r->ptr; + int t, i; + t = snprintf(str, PRIV_STR_SIZE, "hex data="); + for (i = 0; i < isl_oid[n].size; i++) + t += snprintf(str + t, PRIV_STR_SIZE - t, + "%02X:", buff[i]); + t += snprintf(str + t, PRIV_STR_SIZE - t, "\n"); + return t; + } + break; + default: + BUG(); + } + return 0; +} diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h index d00af1892..cd8167e29 100644 --- a/drivers/net/wireless/prism54/oid_mgt.h +++ b/drivers/net/wireless/prism54/oid_mgt.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2003 Aurelien Alleaume * * This program is free software; you can redistribute it and/or modify @@ -28,9 +28,12 @@ int mgt_init(islpci_private *); void mgt_clean(islpci_private *); +/* I don't know where to put these 3 */ extern const int frequency_list_bg[]; - extern const int frequency_list_a[]; +int channel_of_freq(int); + +void mgt_le_to_cpu(int, void *); int mgt_set_request(islpci_private *, enum oid_num_t, int, void *); @@ -41,11 +44,15 @@ int mgt_commit_list(islpci_private *, enum oid_num_t *, int); void mgt_set(islpci_private *, enum oid_num_t, void *); +void mgt_get(islpci_private *, enum oid_num_t, void *); + void mgt_commit(islpci_private *); int mgt_mlme_answer(islpci_private *); enum oid_num_t mgt_oidtonum(u32 oid); +int mgt_response_to_str(enum oid_num_t, union oid_res_t *, char *); + #endif /* !defined(_OID_MGT_H) */ /* EOF */ diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index d595ba757..ef574afa0 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -113,24 +113,24 @@ static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock ) return 0; } -static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int lclk) +static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int clk) { struct soc_pcmcia_timing timing; int sock = skt->nr; soc_common_pcmcia_get_timing(skt, &timing); - pxa2xx_pcmcia_set_mcmem(sock, timing.mem, lclk); - pxa2xx_pcmcia_set_mcatt(sock, timing.attr, lclk); - pxa2xx_pcmcia_set_mcio(sock, timing.io, lclk); + pxa2xx_pcmcia_set_mcmem(sock, timing.mem, clk); + pxa2xx_pcmcia_set_mcatt(sock, timing.attr, clk); + pxa2xx_pcmcia_set_mcio(sock, timing.io, clk); return 0; } static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) { - unsigned int lclk = get_lclk_frequency_10khz(); - return pxa2xx_pcmcia_set_mcxx(skt, lclk); + unsigned int clk = get_memclk_frequency_10khz(); + return pxa2xx_pcmcia_set_mcxx(skt, clk); } int pxa2xx_drv_pcmcia_probe(struct device *dev) diff --git a/drivers/pnp/pnpbios/Kconfig b/drivers/pnp/pnpbios/Kconfig index 58eb94971..ff17c7e96 100644 --- a/drivers/pnp/pnpbios/Kconfig +++ b/drivers/pnp/pnpbios/Kconfig @@ -3,7 +3,7 @@ # config PNPBIOS bool "Plug and Play BIOS support (EXPERIMENTAL)" - depends on PNP && EXPERIMENTAL + depends on PNP && X86 && EXPERIMENTAL ---help--- Linux uses the PNPBIOS as defined in "Plug and Play BIOS Specification Version 1.0A May 5, 1994" to autodetect built-in diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c index 427d18755..5237cad18 100644 --- a/drivers/scsi/esp.c +++ b/drivers/scsi/esp.c @@ -26,8 +26,6 @@ #include #include -#include "scsi.h" -#include #include "esp.h" #include @@ -366,7 +364,7 @@ static char *phase_string(int phase) } #ifdef DEBUG_STATE_MACHINE -static inline void esp_advance_phase(Scsi_Cmnd *s, int newphase) +static inline void esp_advance_phase(struct scsi_cmnd *s, int newphase) { ESPLOG(("<%s>", phase_string(newphase))); s->SCp.sent_command = s->SCp.phase; @@ -419,48 +417,48 @@ static inline void esp_cmd(struct esp *esp, u8 cmd) * Note that these are per-ESP queues, not global queues like * the aha152x driver uses. */ -static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC) +static inline void append_SC(struct scsi_cmnd **SC, struct scsi_cmnd *new_SC) { - Scsi_Cmnd *end; + struct scsi_cmnd *end; new_SC->host_scribble = (unsigned char *) NULL; if (!*SC) *SC = new_SC; else { - for (end=*SC;end->host_scribble;end=(Scsi_Cmnd *)end->host_scribble) + for (end=*SC;end->host_scribble;end=(struct scsi_cmnd *)end->host_scribble) ; end->host_scribble = (unsigned char *) new_SC; } } -static inline void prepend_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC) +static inline void prepend_SC(struct scsi_cmnd **SC, struct scsi_cmnd *new_SC) { new_SC->host_scribble = (unsigned char *) *SC; *SC = new_SC; } -static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC) +static inline struct scsi_cmnd *remove_first_SC(struct scsi_cmnd **SC) { - Scsi_Cmnd *ptr; + struct scsi_cmnd *ptr; ptr = *SC; if (ptr) - *SC = (Scsi_Cmnd *) (*SC)->host_scribble; + *SC = (struct scsi_cmnd *) (*SC)->host_scribble; return ptr; } -static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun) +static inline struct scsi_cmnd *remove_SC(struct scsi_cmnd **SC, int target, int lun) { - Scsi_Cmnd *ptr, *prev; + struct scsi_cmnd *ptr, *prev; for (ptr = *SC, prev = NULL; ptr && ((ptr->device->id != target) || (ptr->device->lun != lun)); - prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble) + prev = ptr, ptr = (struct scsi_cmnd *) ptr->host_scribble) ; if (ptr) { if (prev) prev->host_scribble=ptr->host_scribble; else - *SC=(Scsi_Cmnd *)ptr->host_scribble; + *SC=(struct scsi_cmnd *)ptr->host_scribble; } return ptr; } @@ -1062,7 +1060,7 @@ static void __init esp_init_swstate(struct esp *esp) esp->prev_hme_dmacsr = 0xffffffff; } -static int __init detect_one_esp(Scsi_Host_Template *tpnt, struct sbus_dev *esp_dev, +static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_dev *esp_dev, struct sbus_dev *espdma, struct sbus_bus *sbus, int id, int hme) { @@ -1137,7 +1135,7 @@ fail_unlink: #include -static int __init esp_detect(Scsi_Host_Template *tpnt) +static int __init esp_detect(struct scsi_host_template *tpnt) { static struct sbus_dev esp_dev; int esps_in_use = 0; @@ -1162,7 +1160,7 @@ static int __init esp_detect(Scsi_Host_Template *tpnt) #else /* !CONFIG_SUN4 */ -static int __init esp_detect(Scsi_Host_Template *tpnt) +static int __init esp_detect(struct scsi_host_template *tpnt) { struct sbus_bus *sbus; struct sbus_dev *esp_dev, *sbdev_iter; @@ -1428,7 +1426,7 @@ static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off return esp_host_info(esp, buffer, offset, length); } -static void esp_get_dmabufs(struct esp *esp, Scsi_Cmnd *sp) +static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp) { if (sp->use_sg == 0) { sp->SCp.this_residual = sp->request_bufflen; @@ -1437,7 +1435,7 @@ static void esp_get_dmabufs(struct esp *esp, Scsi_Cmnd *sp) if (sp->request_bufflen) { sp->SCp.have_data_in = sbus_map_single(esp->sdev, sp->SCp.buffer, sp->SCp.this_residual, - scsi_to_sbus_dma_dir(sp->sc_data_direction)); + sp->sc_data_direction); sp->SCp.ptr = (char *) ((unsigned long)sp->SCp.have_data_in); } else { sp->SCp.ptr = NULL; @@ -1447,26 +1445,26 @@ static void esp_get_dmabufs(struct esp *esp, Scsi_Cmnd *sp) sp->SCp.buffers_residual = sbus_map_sg(esp->sdev, sp->SCp.buffer, sp->use_sg, - scsi_to_sbus_dma_dir(sp->sc_data_direction)); + sp->sc_data_direction); sp->SCp.this_residual = sg_dma_len(sp->SCp.buffer); sp->SCp.ptr = (char *) ((unsigned long)sg_dma_address(sp->SCp.buffer)); } } -static void esp_release_dmabufs(struct esp *esp, Scsi_Cmnd *sp) +static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp) { if (sp->use_sg) { sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg, - scsi_to_sbus_dma_dir(sp->sc_data_direction)); + sp->sc_data_direction); } else if (sp->request_bufflen) { sbus_unmap_single(esp->sdev, sp->SCp.have_data_in, sp->request_bufflen, - scsi_to_sbus_dma_dir(sp->sc_data_direction)); + sp->sc_data_direction); } } -static void esp_restore_pointers(struct esp *esp, Scsi_Cmnd *sp) +static void esp_restore_pointers(struct esp *esp, struct scsi_cmnd *sp) { struct esp_pointers *ep = &esp->data_pointers[sp->device->id]; @@ -1476,7 +1474,7 @@ static void esp_restore_pointers(struct esp *esp, Scsi_Cmnd *sp) sp->SCp.buffers_residual = ep->saved_buffers_residual; } -static void esp_save_pointers(struct esp *esp, Scsi_Cmnd *sp) +static void esp_save_pointers(struct esp *esp, struct scsi_cmnd *sp) { struct esp_pointers *ep = &esp->data_pointers[sp->device->id]; @@ -1506,7 +1504,7 @@ static void esp_save_pointers(struct esp *esp, Scsi_Cmnd *sp) * case where we could see an interrupt is where we have disconnected * commands active and they are trying to reselect us. */ -static inline void esp_check_cmd(struct esp *esp, Scsi_Cmnd *sp) +static inline void esp_check_cmd(struct esp *esp, struct scsi_cmnd *sp) { switch (sp->cmd_len) { case 6: @@ -1557,8 +1555,8 @@ static inline void build_wide_nego_msg(struct esp *esp, int size) static void esp_exec_cmd(struct esp *esp) { - Scsi_Cmnd *SCptr; - Scsi_Device *SDptr; + struct scsi_cmnd *SCptr; + struct scsi_device *SDptr; struct esp_device *esp_dev; volatile u8 *cmdp = esp->esp_command; u8 the_esp_command; @@ -1834,7 +1832,7 @@ after_nego_msg_built: } /* Queue a SCSI command delivered from the mid-level Linux SCSI code. */ -static int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) +static int esp_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { struct esp *esp; @@ -1871,7 +1869,7 @@ static int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) } /* Dump driver state. */ -static void esp_dump_cmd(Scsi_Cmnd *SCptr) +static void esp_dump_cmd(struct scsi_cmnd *SCptr) { ESPLOG(("[tgt<%02x> lun<%02x> " "pphase<%s> cphase<%s>]", @@ -1882,7 +1880,7 @@ static void esp_dump_cmd(Scsi_Cmnd *SCptr) static void esp_dump_state(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; #ifdef DEBUG_ESP_CMDS int i; #endif @@ -1921,13 +1919,13 @@ static void esp_dump_state(struct esp *esp) ESPLOG(("esp%d: disconnected ", esp->esp_id)); while (SCptr) { esp_dump_cmd(SCptr); - SCptr = (Scsi_Cmnd *) SCptr->host_scribble; + SCptr = (struct scsi_cmnd *) SCptr->host_scribble; } ESPLOG(("\n")); } /* Abort a command. The host_lock is acquired by caller. */ -static int esp_abort(Scsi_Cmnd *SCptr) +static int esp_abort(struct scsi_cmnd *SCptr) { struct esp *esp = (struct esp *) SCptr->device->host->hostdata; int don; @@ -1957,14 +1955,14 @@ static int esp_abort(Scsi_Cmnd *SCptr) ESP_INTSOFF(esp->dregs); } if (esp->issue_SC) { - Scsi_Cmnd **prev, *this; + struct scsi_cmnd **prev, *this; for (prev = (&esp->issue_SC), this = esp->issue_SC; this != NULL; - prev = (Scsi_Cmnd **) &(this->host_scribble), - this = (Scsi_Cmnd *) this->host_scribble) { + prev = (struct scsi_cmnd **) &(this->host_scribble), + this = (struct scsi_cmnd *) this->host_scribble) { if (this == SCptr) { - *prev = (Scsi_Cmnd *) this->host_scribble; + *prev = (struct scsi_cmnd *) this->host_scribble; this->host_scribble = NULL; esp_release_dmabufs(esp, this); @@ -2010,7 +2008,7 @@ static int esp_abort(Scsi_Cmnd *SCptr) */ static int esp_finish_reset(struct esp *esp) { - Scsi_Cmnd *sp = esp->current_SC; + struct scsi_cmnd *sp = esp->current_SC; /* Clean up currently executing command, if any. */ if (sp != NULL) { @@ -2059,7 +2057,7 @@ static int esp_do_resetbus(struct esp *esp) * * The host_lock is acquired by caller. */ -static int esp_reset(Scsi_Cmnd *SCptr) +static int esp_reset(struct scsi_cmnd *SCptr) { struct esp *esp = (struct esp *) SCptr->device->host->hostdata; @@ -2077,7 +2075,7 @@ static int esp_reset(Scsi_Cmnd *SCptr) /* Internal ESP done function. */ static void esp_done(struct esp *esp, int error) { - Scsi_Cmnd *done_SC = esp->current_SC; + struct scsi_cmnd *done_SC = esp->current_SC; esp->current_SC = NULL; @@ -2168,7 +2166,7 @@ static inline void hme_fifo_push(struct esp *esp, u8 *bytes, u8 count) /* We try to avoid some interrupts by jumping ahead and see if the ESP * has gotten far enough yet. Hence the following. */ -static inline int skipahead1(struct esp *esp, Scsi_Cmnd *scp, +static inline int skipahead1(struct esp *esp, struct scsi_cmnd *scp, int prev_phase, int new_phase) { if (scp->SCp.sent_command != prev_phase) @@ -2202,7 +2200,7 @@ static inline int skipahead1(struct esp *esp, Scsi_Cmnd *scp, return do_intr_end; } -static inline int skipahead2(struct esp *esp, Scsi_Cmnd *scp, +static inline int skipahead2(struct esp *esp, struct scsi_cmnd *scp, int prev_phase1, int prev_phase2, int new_phase) { if (scp->SCp.sent_command != prev_phase1 && @@ -2318,7 +2316,7 @@ static inline void dma_flashclear(struct esp *esp) dma_invalidate(esp); } -static int dma_can_transfer(struct esp *esp, Scsi_Cmnd *sp) +static int dma_can_transfer(struct esp *esp, struct scsi_cmnd *sp) { __u32 base, end, sz; @@ -2379,7 +2377,7 @@ static int dma_can_transfer(struct esp *esp, Scsi_Cmnd *sp) * tell the ESP to eat the extraneous byte so that we can proceed * to the next phase. */ -static int esp100_sync_hwbug(struct esp *esp, Scsi_Cmnd *sp, int fifocnt) +static int esp100_sync_hwbug(struct esp *esp, struct scsi_cmnd *sp, int fifocnt) { /* Do not touch this piece of code. */ if ((!(esp->erev == esp100)) || @@ -2479,7 +2477,7 @@ static inline int reconnect_lun(struct esp *esp) /* This puts the driver in a state where it can revitalize a command that * is being continued due to reselection. */ -static inline void esp_connect(struct esp *esp, Scsi_Cmnd *sp) +static inline void esp_connect(struct esp *esp, struct scsi_cmnd *sp) { struct esp_device *esp_dev = sp->device->hostdata; @@ -2502,7 +2500,7 @@ static inline void esp_connect(struct esp *esp, Scsi_Cmnd *sp) /* This will place the current working command back into the issue queue * if we are to receive a reselection amidst a selection attempt. */ -static inline void esp_reconnect(struct esp *esp, Scsi_Cmnd *sp) +static inline void esp_reconnect(struct esp *esp, struct scsi_cmnd *sp) { if (!esp->disconnected_SC) ESPLOG(("esp%d: Weird, being reselected but disconnected " @@ -2540,7 +2538,7 @@ static inline int esp_bytes_sent(struct esp *esp, int fifo_count) return rval - fifo_count; } -static inline void advance_sg(Scsi_Cmnd *sp) +static inline void advance_sg(struct scsi_cmnd *sp) { ++sp->SCp.buffer; --sp->SCp.buffers_residual; @@ -2568,7 +2566,7 @@ static inline void advance_sg(Scsi_Cmnd *sp) */ static int esp_do_data(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; int thisphase, hmuch; ESPDATA(("esp_do_data: ")); @@ -2619,7 +2617,7 @@ static int esp_do_data(struct esp *esp) /* See how successful the data transfer was. */ static int esp_do_data_finale(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; struct esp_device *esp_dev = SCptr->device->hostdata; int bogus_data = 0, bytes_sent = 0, fifocnt, ecount = 0; @@ -2800,7 +2798,7 @@ static int esp_do_data_finale(struct esp *esp) * a tape, we don't want to go into a loop re-negotiating * synchronous capabilities over and over. */ -static int esp_should_clear_sync(Scsi_Cmnd *sp) +static int esp_should_clear_sync(struct scsi_cmnd *sp) { u8 cmd1 = sp->cmnd[0]; u8 cmd2 = sp->data_cmnd[0]; @@ -2834,7 +2832,7 @@ static int esp_should_clear_sync(Scsi_Cmnd *sp) */ static int esp_do_freebus(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; struct esp_device *esp_dev = SCptr->device->hostdata; int rval; @@ -2905,7 +2903,7 @@ static int esp_do_freebus(struct esp *esp) */ static int esp_bad_reconnect(struct esp *esp) { - Scsi_Cmnd *sp; + struct scsi_cmnd *sp; ESPLOG(("esp%d: Eieeee, reconnecting unknown command!\n", esp->esp_id)); @@ -2914,7 +2912,7 @@ static int esp_bad_reconnect(struct esp *esp) ESPLOG(("esp%d: issue_SC[", esp->esp_id)); while (sp) { ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun)); - sp = (Scsi_Cmnd *) sp->host_scribble; + sp = (struct scsi_cmnd *) sp->host_scribble; } ESPLOG(("]\n")); sp = esp->current_SC; @@ -2928,7 +2926,7 @@ static int esp_bad_reconnect(struct esp *esp) ESPLOG(("esp%d: disconnected_SC[", esp->esp_id)); while (sp) { ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun)); - sp = (Scsi_Cmnd *) sp->host_scribble; + sp = (struct scsi_cmnd *) sp->host_scribble; } ESPLOG(("]\n")); return do_reset_bus; @@ -2938,7 +2936,7 @@ static int esp_bad_reconnect(struct esp *esp) static int esp_do_reconnect(struct esp *esp) { int lun, target; - Scsi_Cmnd *SCptr; + struct scsi_cmnd *SCptr; /* Check for all bogus conditions first. */ target = reconnect_target(esp); @@ -2988,7 +2986,7 @@ static int esp_do_reconnect(struct esp *esp) */ static int esp_do_status(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; int intr, rval; rval = skipahead1(esp, SCptr, in_the_dark, in_status); @@ -3133,7 +3131,7 @@ static int esp_enter_status(struct esp *esp) static int esp_disconnect_amidst_phases(struct esp *esp) { - Scsi_Cmnd *sp = esp->current_SC; + struct scsi_cmnd *sp = esp->current_SC; struct esp_device *esp_dev = sp->device->hostdata; /* This means real problems if we see this @@ -3226,7 +3224,7 @@ static int esp_do_phase_determine(struct esp *esp) /* First interrupt after exec'ing a cmd comes here. */ static int esp_select_complete(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; struct esp_device *esp_dev = SCptr->device->hostdata; int cmd_bytes_sent, fcnt; @@ -3582,7 +3580,7 @@ static int check_singlebyte_msg(struct esp *esp) * this because so many initiators cannot cope with this occurring. */ static int target_with_ants_in_pants(struct esp *esp, - Scsi_Cmnd *SCptr, + struct scsi_cmnd *SCptr, struct esp_device *esp_dev) { if (esp_dev->sync || SCptr->device->borken) { @@ -3641,7 +3639,7 @@ static void sync_report(struct esp *esp) static int check_multibyte_msg(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; struct esp_device *esp_dev = SCptr->device->hostdata; u8 regval = 0; int message_out = 0; @@ -3822,7 +3820,7 @@ finish: static int esp_do_msgindone(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; int message_out = 0, it = 0, rval; rval = skipahead1(esp, SCptr, in_msgin, in_msgindone); @@ -3904,7 +3902,7 @@ static int esp_do_msgindone(struct esp *esp) static int esp_do_cmdbegin(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; esp_advance_phase(SCptr, in_cmdend); if (esp->erev == fashme) { @@ -4125,7 +4123,7 @@ static espfunc_t bus_vector[] = { /* This is the second tier in our dual-level SCSI state machine. */ static int esp_work_bus(struct esp *esp) { - Scsi_Cmnd *SCptr = esp->current_SC; + struct scsi_cmnd *SCptr = esp->current_SC; unsigned int phase; ESPBUS(("esp_work_bus: ")); @@ -4153,7 +4151,7 @@ static espfunc_t isvc_vector[] = { /* Main interrupt handler for an esp adapter. */ static void esp_handle(struct esp *esp) { - Scsi_Cmnd *SCptr; + struct scsi_cmnd *SCptr; int what_next = do_intr_end; SCptr = esp->current_SC; @@ -4353,7 +4351,7 @@ static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs) return IRQ_HANDLED; } -static int esp_slave_alloc(Scsi_Device *SDptr) +static int esp_slave_alloc(struct scsi_device *SDptr) { struct esp_device *esp_dev = kmalloc(sizeof(struct esp_device), GFP_ATOMIC); @@ -4365,7 +4363,7 @@ static int esp_slave_alloc(Scsi_Device *SDptr) return 0; } -static void esp_slave_destroy(Scsi_Device *SDptr) +static void esp_slave_destroy(struct scsi_device *SDptr) { struct esp *esp = (struct esp *) SDptr->host->hostdata; @@ -4374,7 +4372,7 @@ static void esp_slave_destroy(Scsi_Device *SDptr) SDptr->hostdata = NULL; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "esp", .proc_info = esp_proc_info, .name = "Sun ESP 100/100a/200", diff --git a/drivers/scsi/esp.h b/drivers/scsi/esp.h index df6d41a09..295739469 100644 --- a/drivers/scsi/esp.h +++ b/drivers/scsi/esp.h @@ -10,9 +10,20 @@ #include +/* #include "scsi.h" */ +#include +#include +#include +#include +#include +#include +#include + /* For dvma controller register definitions. */ #include +#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir)) + /* The ESP SCSI controllers have their register sets in three * "classes": * @@ -181,9 +192,9 @@ struct esp { int bursts; /* Burst sizes our DVMA supports */ /* Our command queues, only one cmd lives in the current_SC queue. */ - Scsi_Cmnd *issue_SC; /* Commands to be issued */ - Scsi_Cmnd *current_SC; /* Who is currently working the bus */ - Scsi_Cmnd *disconnected_SC;/* Commands disconnected from the bus */ + struct scsi_cmnd *issue_SC; /* Commands to be issued */ + struct scsi_cmnd *current_SC; /* Who is currently working the bus */ + struct scsi_cmnd *disconnected_SC;/* Commands disconnected from the bus */ /* Message goo */ u8 cur_msgout[16]; diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 246639fe6..fed311e81 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -1156,6 +1156,7 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, switch(scsicmd[0]) { /* no-op's, complete with success */ + case SYNCHRONIZE_CACHE: /* FIXME: temporary */ case REZERO_UNIT: case SEEK_6: case SEEK_10: diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 250380ca1..29522c4f5 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -26,8 +26,6 @@ #include -#include "scsi.h" -#include #include "qlogicpti.h" #include @@ -809,7 +807,7 @@ static int __init qpti_map_queues(struct qlogicpti *qpti) } /* Detect all PTI Qlogic ISP's in the machine. */ -static int __init qlogicpti_detect(Scsi_Host_Template *tpnt) +static int __init qlogicpti_detect(struct scsi_host_template *tpnt) { struct qlogicpti *qpti; struct Scsi_Host *qpti_host; @@ -878,7 +876,7 @@ static int __init qlogicpti_detect(Scsi_Host_Template *tpnt) qpti_get_bursts(qpti); qpti_get_clock(qpti); - /* Clear out Scsi_Cmnd array. */ + /* Clear out scsi_cmnd array. */ memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots)); if (qpti_map_queues(qpti) < 0) @@ -997,7 +995,7 @@ static inline void marker_frob(struct Command_Entry *cmd) marker->rsvd = 0; } -static inline void cmd_frob(struct Command_Entry *cmd, Scsi_Cmnd *Cmnd, +static inline void cmd_frob(struct Command_Entry *cmd, struct scsi_cmnd *Cmnd, struct qlogicpti *qpti) { memset(cmd, 0, sizeof(struct Command_Entry)); @@ -1027,7 +1025,7 @@ static inline void cmd_frob(struct Command_Entry *cmd, Scsi_Cmnd *Cmnd, } /* Do it to it baby. */ -static inline int load_cmd(Scsi_Cmnd *Cmnd, struct Command_Entry *cmd, +static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd, struct qlogicpti *qpti, u_int in_ptr, u_int out_ptr) { struct dataseg *ds; @@ -1038,7 +1036,7 @@ static inline int load_cmd(Scsi_Cmnd *Cmnd, struct Command_Entry *cmd, int sg_count; sg = (struct scatterlist *) Cmnd->buffer; - sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, scsi_to_sbus_dma_dir(Cmnd->sc_data_direction)); + sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction); ds = cmd->dataseg; cmd->segment_cnt = sg_count; @@ -1081,7 +1079,7 @@ static inline int load_cmd(Scsi_Cmnd *Cmnd, struct Command_Entry *cmd, sbus_map_single(qpti->sdev, Cmnd->request_buffer, Cmnd->request_bufflen, - scsi_to_sbus_dma_dir(Cmnd->sc_data_direction)); + Cmnd->sc_data_direction); cmd->dataseg[0].d_base = (u32) ((unsigned long)Cmnd->SCp.ptr); cmd->dataseg[0].d_count = Cmnd->request_bufflen; @@ -1115,11 +1113,11 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int /* * Until we scan the entire bus with inquiries, go throught this fella... */ -static void ourdone(Scsi_Cmnd *Cmnd) +static void ourdone(struct scsi_cmnd *Cmnd) { struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; int tgt = Cmnd->device->id; - void (*done) (Scsi_Cmnd *); + void (*done) (struct scsi_cmnd *); /* This grot added by DaveM, blame him for ugliness. * The issue is that in the 2.3.x driver we use the @@ -1127,7 +1125,7 @@ static void ourdone(Scsi_Cmnd *Cmnd) * completion linked list at interrupt service time, * so we have to store the done function pointer elsewhere. */ - done = (void (*)(Scsi_Cmnd *)) + done = (void (*)(struct scsi_cmnd *)) (((unsigned long) Cmnd->SCp.Message) #ifdef __sparc_v9__ | ((unsigned long) Cmnd->SCp.Status << 32UL) @@ -1164,10 +1162,10 @@ static void ourdone(Scsi_Cmnd *Cmnd) done(Cmnd); } -static int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)); +static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *)); -static int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, - void (*done)(Scsi_Cmnd *)) +static int qlogicpti_queuecommand_slow(struct scsi_cmnd *Cmnd, + void (*done)(struct scsi_cmnd *)) { struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; @@ -1238,7 +1236,7 @@ static int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, * * "This code must fly." -davem */ -static int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) +static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *)) { struct Scsi_Host *host = Cmnd->device->host; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; @@ -1351,9 +1349,9 @@ static int qlogicpti_return_status(struct Status_Entry *sts, int id) return (sts->scsi_status & STATUS_MASK) | (host_status << 16); } -static Scsi_Cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) +static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) { - Scsi_Cmnd *Cmnd, *done_queue = NULL; + struct scsi_cmnd *Cmnd, *done_queue = NULL; struct Status_Entry *sts; u_int in_ptr, out_ptr; @@ -1412,12 +1410,12 @@ static Scsi_Cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) sbus_unmap_sg(qpti->sdev, (struct scatterlist *)Cmnd->buffer, Cmnd->use_sg, - scsi_to_sbus_dma_dir(Cmnd->sc_data_direction)); + Cmnd->sc_data_direction); } else { sbus_unmap_single(qpti->sdev, (__u32)((unsigned long)Cmnd->SCp.ptr), Cmnd->request_bufflen, - scsi_to_sbus_dma_dir(Cmnd->sc_data_direction)); + Cmnd->sc_data_direction); } qpti->cmd_count[Cmnd->device->id]--; sbus_writew(out_ptr, qpti->qregs + MBOX5); @@ -1433,16 +1431,16 @@ static irqreturn_t qpti_intr(int irq, void *dev_id, struct pt_regs *regs) { struct qlogicpti *qpti = dev_id; unsigned long flags; - Scsi_Cmnd *dq; + struct scsi_cmnd *dq; spin_lock_irqsave(qpti->qhost->host_lock, flags); dq = qlogicpti_intr_handler(qpti); if (dq != NULL) { do { - Scsi_Cmnd *next; + struct scsi_cmnd *next; - next = (Scsi_Cmnd *) dq->host_scribble; + next = (struct scsi_cmnd *) dq->host_scribble; dq->scsi_done(dq); dq = next; } while (dq != NULL); @@ -1452,7 +1450,7 @@ static irqreturn_t qpti_intr(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -static int qlogicpti_abort(Scsi_Cmnd *Cmnd) +static int qlogicpti_abort(struct scsi_cmnd *Cmnd) { u_short param[6]; struct Scsi_Host *host = Cmnd->device->host; @@ -1489,7 +1487,7 @@ static int qlogicpti_abort(Scsi_Cmnd *Cmnd) return return_status; } -static int qlogicpti_reset(Scsi_Cmnd *Cmnd) +static int qlogicpti_reset(struct scsi_cmnd *Cmnd) { u_short param[6]; struct Scsi_Host *host = Cmnd->device->host; @@ -1513,7 +1511,7 @@ static int qlogicpti_reset(Scsi_Cmnd *Cmnd) return return_status; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .detect = qlogicpti_detect, .release = qlogicpti_release, .info = qlogicpti_info, diff --git a/drivers/scsi/qlogicpti.h b/drivers/scsi/qlogicpti.h index 942e286e1..91dead6ad 100644 --- a/drivers/scsi/qlogicpti.h +++ b/drivers/scsi/qlogicpti.h @@ -8,6 +8,17 @@ #include +/* #include "scsi.h" */ +#include +#include +#include +#include +#include +#include +#include + +#define scsi_to_sbus_dma_dir(scsi_dir) ((int)(scsi_dir)) + /* Qlogic/SBUS controller registers. */ #define SBUS_CFG1 0x006UL #define SBUS_CTRL 0x008UL @@ -352,7 +363,7 @@ struct qlogicpti { * Ex000 sparc64 machines with >4GB of ram we just keep track of the * scsi command pointers here. This is essentially what Matt Jacob does. -DaveM */ - Scsi_Cmnd *cmd_slots[QLOGICPTI_REQ_QUEUE_LEN + 1]; + struct scsi_cmnd *cmd_slots[QLOGICPTI_REQ_QUEUE_LEN + 1]; /* The rest of the elements are unimportant for performance. */ struct qlogicpti *next; diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 94954eb88..268b2c345 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -457,14 +457,14 @@ static void pdc_dma_start(struct ata_queued_cmd *qc) static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) { - if (tf->protocol == ATA_PROT_PIO) + if (tf->protocol != ATA_PROT_DMA) ata_tf_load_mmio(ap, tf); } static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf) { - if (tf->protocol == ATA_PROT_PIO) + if (tf->protocol != ATA_PROT_DMA) ata_exec_command_mmio(ap, tf); } diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 75013729e..3268fdf7e 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c @@ -826,14 +826,14 @@ out: static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) { - if (tf->protocol == ATA_PROT_PIO) + if (tf->protocol != ATA_PROT_DMA) ata_tf_load_mmio(ap, tf); } static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf) { - if (tf->protocol == ATA_PROT_PIO) + if (tf->protocol != ATA_PROT_DMA) ata_exec_command_mmio(ap, tf); } diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c index c87a43f7b..82614b4b4 100644 --- a/drivers/video/aty/radeon_accel.c +++ b/drivers/video/aty/radeon_accel.c @@ -13,7 +13,10 @@ static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */ | GMC_BRUSH_SOLID_COLOR | ROP3_P); - OUTREG(DP_BRUSH_FRGD_CLR, region->color); + if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP) + OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]); + else + OUTREG(DP_BRUSH_FRGD_CLR, region->color); OUTREG(DP_WRITE_MSK, 0xffffffff); OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 8bc80fa6f..c5e37bdbb 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c @@ -867,7 +867,7 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, u32 state) } /* Blank display and LCD */ - radeonfb_blank(VESA_POWERDOWN+1, info); + radeonfb_blank(VESA_POWERDOWN, info); /* Sleep */ rinfo->asleep = 1; diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 0c86ff989..bfa3f8b58 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -432,7 +432,7 @@ static inline unsigned int get_pcd(unsigned int pixclock) * (DPC) bit? or perhaps set it based on the various clock * speeds */ - pcd = (unsigned long long)get_lclk_frequency_10khz() * (unsigned long long)pixclock; + pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock; pcd /= 100000000 * 2; /* no need for this, since we should subtract 1 anyway. they cancel */ /* pcd += 1; */ /* make up for integer math truncations */ diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 9b75ded90..b8cb97508 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -207,7 +207,7 @@ int __init vesafb_setup(char *options) mtrr=1; else if (! strcmp(this_opt, "nomtrr")) mtrr=0; - else if (! strncmp(this_opt, "vram=", 5)) + else if (! strncmp(this_opt, "vram:", 5)) vram = simple_strtoul(this_opt+5, NULL, 0); } return 0; diff --git a/fs/aio.c b/fs/aio.c index 574eeaf5d..a2cf98648 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -538,19 +538,25 @@ struct kioctx *lookup_ioctx(unsigned long ctx_id) static void use_mm(struct mm_struct *mm) { - struct mm_struct *active_mm = current->active_mm; + struct mm_struct *active_mm; + atomic_inc(&mm->mm_count); + task_lock(current); + active_mm = current->active_mm; current->mm = mm; if (mm != active_mm) { current->active_mm = mm; activate_mm(active_mm, mm); } + task_unlock(current); mmdrop(active_mm); } static void unuse_mm(struct mm_struct *mm) { + task_lock(current); current->mm = NULL; + task_unlock(current); /* active_mm is still 'mm' */ enter_lazy_tlb(mm, current); } @@ -608,7 +614,7 @@ void fastcall kick_iocb(struct kiocb *iocb) spin_lock_irqsave(&ctx->ctx_lock, flags); list_add_tail(&iocb->ki_run_list, &ctx->run_list); spin_unlock_irqrestore(&ctx->ctx_lock, flags); - schedule_work(&ctx->wq); + queue_work(aio_wq, &ctx->wq); } } diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 908661518..b69d18a77 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -737,10 +737,10 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) #ifdef __i386__ /* - * In the exec-shield-disabled case turn off the CS limit - * completely: + * Turn off the CS limit completely if exec-shield disabled or + * NX active: */ - if (!exec_shield) + if (!exec_shield || use_nx) arch_add_exec_range(current->mm, -1); #endif diff --git a/fs/compat.c b/fs/compat.c index 94fe0001f..689fdd017 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -744,9 +744,9 @@ extern int copy_mount_options (const void __user *, unsigned long *); #define SMBFS_NAME "smbfs" #define NCPFS_NAME "ncpfs" -asmlinkage int compat_sys_mount(char __user * dev_name, char __user * dir_name, - char __user * type, unsigned long flags, - void __user * data) +asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, + char __user * type, unsigned long flags, + void __user * data) { unsigned long type_page; unsigned long data_page; diff --git a/fs/dcache.c b/fs/dcache.c index b90d3813f..cf32eb26f 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -59,6 +59,9 @@ static unsigned int d_hash_shift; static struct hlist_head *dentry_hashtable; static LIST_HEAD(dentry_unused); +static void prune_dcache(int count); + + /* Statistics gathering. */ struct dentry_stat_t dentry_stat = { .age_limit = 45, @@ -685,6 +688,19 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) struct dentry *dentry; char *dname; +#define DENTRY_UNUSED_THRESHOLD 30000 +#define DENTRY_BATCH_COUNT 32 + + if (dentry_stat.nr_unused > DENTRY_UNUSED_THRESHOLD) { + int doit = 1; + spin_lock(&dcache_lock); + if (dentry_stat.nr_unused < DENTRY_UNUSED_THRESHOLD) + doit = 0; + spin_unlock(&dcache_lock); + if (doit) + prune_dcache(DENTRY_BATCH_COUNT); + } + dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); if (!dentry) return NULL; diff --git a/fs/direct-io.c b/fs/direct-io.c index 0831f490f..a2910fbd6 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -690,8 +690,11 @@ out: static void clean_blockdev_aliases(struct dio *dio) { unsigned i; + unsigned nblocks; - for (i = 0; i < dio->blocks_available; i++) { + nblocks = dio->map_bh.b_size >> dio->inode->i_blkbits; + + for (i = 0; i < nblocks; i++) { unmap_underlying_metadata(dio->map_bh.b_bdev, dio->map_bh.b_blocknr + i); } diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 6362e20fb..0e73e3086 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -535,6 +535,9 @@ void write_inode_now(struct inode *inode, int sync) .sync_mode = WB_SYNC_ALL, }; + if (inode->i_mapping->backing_dev_info->memory_backed) + return; + spin_lock(&inode_lock); __writeback_single_inode(inode, &wbc); spin_unlock(&inode_lock); diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index db1c17583..abfd24a7b 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -725,7 +725,7 @@ struct file *hugetlb_zero_setup(size_t size) struct qstr quick_string; char buf[16]; - if (!capable(CAP_IPC_LOCK)) + if (!can_do_mlock()) return ERR_PTR(-EPERM); if (!is_hugepage_mem_enough(size)) diff --git a/fs/inode.c b/fs/inode.c index e5ee5a79b..3a7475548 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -98,13 +98,36 @@ struct inodes_stat_t inodes_stat; static kmem_cache_t * inode_cachep; +static void prune_icache(int nr_to_scan); + + +#define INODE_UNUSED_THRESHOLD 15000 +#define PRUNE_BATCH_COUNT 32 + +void try_to_clip_inodes(void) +{ + unsigned long count = 0; + /* if there are a LOT of unused inodes in cache, better shrink a few first */ + + /* check lockless first to not take the lock always here; racing occasionally isn't a big deal */ + if (inodes_stat.nr_unused > INODE_UNUSED_THRESHOLD) { + spin_lock(&inode_lock); + if (inodes_stat.nr_unused > INODE_UNUSED_THRESHOLD) + count = inodes_stat.nr_unused - INODE_UNUSED_THRESHOLD; + spin_unlock(&inode_lock); + if (count) + prune_icache(count); + } +} + + static struct inode *alloc_inode(struct super_block *sb) { static struct address_space_operations empty_aops; static struct inode_operations empty_iops; static struct file_operations empty_fops; struct inode *inode; - + if (sb->s_op->alloc_inode) inode = sb->s_op->alloc_inode(sb); else diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a252cac5a..3c57bc31f 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -567,7 +567,7 @@ nfsd_sync_dir(struct dentry *dp) static spinlock_t ra_lock = SPIN_LOCK_UNLOCKED; static inline struct raparms * -nfsd_get_raparms(dev_t dev, ino_t ino) +nfsd_get_raparms(dev_t dev, ino_t ino, struct address_space *mapping) { struct raparms *ra, **rap, **frap = NULL; int depth = 0; @@ -589,7 +589,7 @@ nfsd_get_raparms(dev_t dev, ino_t ino) ra = *frap; ra->p_dev = dev; ra->p_ino = ino; - memset(&ra->p_ra, 0, sizeof(ra->p_ra)); + file_ra_state_init(&ra->p_ra, mapping); found: if (rap != &raparm_cache) { *rap = ra->p_next; @@ -661,7 +661,8 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, #endif /* Get readahead parameters */ - ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino); + ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino, + inode->i_mapping->host->i_mapping); if (ra) file.f_ra = ra->p_ra; @@ -677,9 +678,12 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, } /* Write back readahead params */ - if (ra) + if (ra) { + spin_lock(&ra_lock); ra->p_ra = file.f_ra; - + ra->p_count--; + spin_unlock(&ra_lock); + } if (err >= 0) { nfsdstats.io_read += err; *count = err; diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index cdb894cb1..097555ba1 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -25,6 +25,22 @@ ToDo: sufficient for synchronisation here. We then just need to make sure ntfs_readpage/writepage/truncate interoperate properly with us. +2.1.12 - Fix the second fix to the decompression engine and some cleanups. + + - Add a new address space operations struct, ntfs_mst_aops, for mst + protected attributes. This is because the default ntfs_aops do not + make sense with mst protected data and were they to write anything to + such an attribute they would cause data corruption so we provide + ntfs_mst_aops which does not have any write related operations set. + - Cleanup dirty ntfs inode handling (fs/ntfs/inode.[hc]) which also + includes an adapted ntfs_commit_inode() and an implementation of + ntfs_write_inode() which for now just cleans dirty inodes without + writing them (it does emit a warning that this is happening). + - Undo the second decompression engine fix (see 2.1.9 release ChangeLog + entry) as it was only fixing a theoretical bug but at the same time + it badly broke the handling of sparse and uncompressed compression + blocks. + 2.1.11 - Driver internal cleanups. - Only build logfile.o if building the driver with read-write support. diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile index 545d4ed94..715dc2c85 100644 --- a/fs/ntfs/Makefile +++ b/fs/ntfs/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs.o ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \ mst.o namei.o super.o sysctl.o unistr.o upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.11\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.12\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index 797846b8d..f7f561a1a 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -1788,3 +1788,12 @@ struct address_space_operations ntfs_aops = { #endif }; +/** + * ntfs_mst_aops - general address space operations for mst protecteed inodes + * and attributes + */ +struct address_space_operations ntfs_mst_aops = { + .readpage = ntfs_readpage, /* Fill page with data. */ + .sync_page = block_sync_page, /* Currently, just unplugs the + disk request queue. */ +}; diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c index 2959ef191..5836232f2 100644 --- a/fs/ntfs/compress.c +++ b/fs/ntfs/compress.c @@ -507,7 +507,7 @@ int ntfs_read_compressed_block(struct page *page) */ unsigned int nr_pages = (end_vcn - start_vcn) << vol->cluster_size_bits >> PAGE_CACHE_SHIFT; - unsigned int xpage, max_page, max_ofs, cur_page, cur_ofs, i; + unsigned int xpage, max_page, cur_page, cur_ofs, i; unsigned int cb_clusters, cb_max_ofs; int block, max_block, cb_max_page, bhs_size, nr_bhs, err = 0; struct page **pages; @@ -550,11 +550,8 @@ int ntfs_read_compressed_block(struct page *page) */ max_page = ((VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) - offset; - max_ofs = (VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) & ~PAGE_CACHE_MASK; - if (nr_pages < max_page) { + if (nr_pages < max_page) max_page = nr_pages; - max_ofs = 0; - } for (i = 0; i < max_page; i++, offset++) { if (i != xpage) pages[i] = grab_cache_page_nowait(mapping, offset); @@ -722,14 +719,8 @@ lock_retry_remap: cb_max_page >>= PAGE_CACHE_SHIFT; /* Catch end of file inside a compression block. */ - if (cb_max_page >= max_page) { - if (cb_max_page > max_page) { - cb_max_page = max_page; - cb_max_ofs = max_ofs; - } else if (cb_max_ofs > max_ofs) { - cb_max_ofs = max_ofs; - } - } + if (cb_max_page > max_page) + cb_max_page = max_page; if (vcn == start_vcn - cb_clusters) { /* Sparse cb, zero out page range overlapping the cb. */ @@ -897,7 +888,8 @@ lock_retry_remap: if (page) { ntfs_error(vol->sb, "Still have pages left! " "Terminating them with extreme " - "prejudice."); + "prejudice. Inode 0x%lx, page index " + "0x%lx.", ni->mft_no, page->index); if (cur_page == xpage && !xpage_done) SetPageError(page); flush_dcache_page(page); diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 65f74d358..470a1e9c0 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c @@ -1196,7 +1196,7 @@ skip_index_root: ia_mapping = vdir->i_mapping; bmp_vi = ndir->itype.index.bmp_ino; if (unlikely(!bmp_vi)) { - ntfs_debug("Inode %lu, regetting index bitmap.", vdir->i_ino); + ntfs_debug("Inode 0x%lx, regetting index bitmap.", vdir->i_ino); bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); if (unlikely(IS_ERR(bmp_vi))) { ntfs_error(sb, "Failed to get bitmap attribute."); diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 273e4c384..0bb39d87d 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -872,7 +872,7 @@ skip_large_dir_stuff: /* Setup the operations for this inode. */ vi->i_op = &ntfs_dir_inode_ops; vi->i_fop = &ntfs_dir_ops; - vi->i_mapping->a_ops = &ntfs_aops; + vi->i_mapping->a_ops = &ntfs_mst_aops; } else { /* It is a file. */ reinit_attr_search_ctx(ctx); @@ -1249,7 +1249,10 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) /* Setup the operations for this attribute inode. */ vi->i_op = NULL; vi->i_fop = NULL; - vi->i_mapping->a_ops = &ntfs_aops; + if (NInoMstProtected(ni)) + vi->i_mapping->a_ops = &ntfs_mst_aops; + else + vi->i_mapping->a_ops = &ntfs_aops; if (!NInoCompressed(ni)) vi->i_blocks = ni->allocated_size >> 9; @@ -1339,7 +1342,7 @@ int ntfs_read_inode_mount(struct inode *vi) ni->name_len = 0; /* - * This sets up our little cheat allowing us to reuse the async io + * This sets up our little cheat allowing us to reuse the async read io * completion handler for directories. */ ni->itype.index.block_size = vol->mft_record_size; @@ -1702,18 +1705,6 @@ err_out: return -1; } -/** - * ntfs_commit_inode - write out a dirty inode - * @ni: inode to write out - * - */ -int ntfs_commit_inode(ntfs_inode *ni) -{ - ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); - NInoClearDirty(ni); - return 0; -} - /** * ntfs_put_inode - handler for when the inode reference count is decremented * @vi: vfs inode @@ -1742,34 +1733,6 @@ void ntfs_put_inode(struct inode *vi) void __ntfs_clear_inode(ntfs_inode *ni) { - int err; - - ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); - if (NInoDirty(ni)) { - err = ntfs_commit_inode(ni); - if (err) { - ntfs_error(ni->vol->sb, "Failed to commit dirty " - "inode synchronously."); - // FIXME: Do something!!! - } - } - /* Synchronize with ntfs_commit_inode(). */ - down(&ni->mrec_lock); - up(&ni->mrec_lock); - if (NInoDirty(ni)) { - ntfs_error(ni->vol->sb, "Failed to commit dirty inode " - "asynchronously."); - // FIXME: Do something!!! - } - /* No need to lock at this stage as no one else has a reference. */ - if (ni->nr_extents > 0) { - int i; - - // FIXME: Handle dirty case for each extent inode! - for (i = 0; i < ni->nr_extents; i++) - ntfs_clear_extent_inode(ni->ext.extent_ntfs_inos[i]); - kfree(ni->ext.extent_ntfs_inos); - } /* Free all alocated memory. */ down_write(&ni->run_list.lock); if (ni->run_list.rl) { @@ -1799,6 +1762,20 @@ void __ntfs_clear_inode(ntfs_inode *ni) void ntfs_clear_extent_inode(ntfs_inode *ni) { + ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); + + BUG_ON(NInoAttr(ni)); + BUG_ON(ni->nr_extents != -1); + +#ifdef NTFS_RW + if (NInoDirty(ni)) { + if (!is_bad_inode(VFS_I(ni->ext.base_ntfs_ino))) + ntfs_error(ni->vol->sb, "Clearing dirty extent inode! " + "Losing data! This is a BUG!!!"); + // FIXME: Do something!!! + } +#endif /* NTFS_RW */ + __ntfs_clear_inode(ni); /* Bye, bye... */ @@ -1819,6 +1796,30 @@ void ntfs_clear_big_inode(struct inode *vi) { ntfs_inode *ni = NTFS_I(vi); +#ifdef NTFS_RW + if (NInoDirty(ni)) { + BOOL was_bad = (is_bad_inode(vi)); + + /* Committing the inode also commits all extent inodes. */ + ntfs_commit_inode(vi); + + if (!was_bad && (is_bad_inode(vi) || NInoDirty(ni))) { + ntfs_error(vi->i_sb, "Failed to commit dirty inode " + "0x%lx. Losing data!", vi->i_ino); + // FIXME: Do something!!! + } + } +#endif /* NTFS_RW */ + + /* No need to lock at this stage as no one else has a reference. */ + if (ni->nr_extents > 0) { + int i; + + for (i = 0; i < ni->nr_extents; i++) + ntfs_clear_extent_inode(ni->ext.extent_ntfs_inos[i]); + kfree(ni->ext.extent_ntfs_inos); + } + __ntfs_clear_inode(ni); if (NInoAttr(ni)) { @@ -1959,4 +1960,49 @@ trunc_err: return err; } -#endif +void ntfs_write_inode(struct inode *vi, int sync) +{ + ntfs_inode *ni = NTFS_I(vi); + + ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "", + vi->i_ino); + + /* + * Dirty attribute inodes are written via their real inodes so just + * clean them here. + */ + if (NInoAttr(ni)) { + NInoClearDirty(ni); + return; + } + + /* Write this base mft record. */ + if (NInoDirty(ni)) { + ntfs_warning(vi->i_sb, "Cleaning dirty inode 0x%lx without " + "writing to disk as this is not yet " + "implemented.", vi->i_ino); + NInoClearDirty(ni); + } + + /* Write all attached extent mft records. */ + down(&ni->extent_lock); + if (ni->nr_extents > 0) { + int i; + ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos; + + for (i = 0; i < ni->nr_extents; i++) { + ntfs_inode *tni = extent_nis[i]; + + if (NInoDirty(tni)) { + ntfs_warning(vi->i_sb, "Cleaning dirty extent " + "inode 0x%lx without writing " + "to disk as this is not yet " + "implemented.", tni->mft_no); + NInoClearDirty(tni); + } + } + } + up(&ni->extent_lock); +} + +#endif /* NTFS_RW */ diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h index 7346ebd46..59af63e6c 100644 --- a/fs/ntfs/inode.h +++ b/fs/ntfs/inode.h @@ -281,6 +281,15 @@ extern void ntfs_truncate(struct inode *vi); extern int ntfs_setattr(struct dentry *dentry, struct iattr *attr); +extern void ntfs_write_inode(struct inode *vi, int sync); + +static inline void ntfs_commit_inode(struct inode *vi) +{ + if (!is_bad_inode(vi)) + ntfs_write_inode(vi, 1); + return; +} + #endif /* NTFS_RW */ #endif /* _LINUX_NTFS_INODE_H */ diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h index 58bc6b4c6..c4ccbc9b6 100644 --- a/fs/ntfs/ntfs.h +++ b/fs/ntfs/ntfs.h @@ -62,6 +62,7 @@ extern kmem_cache_t *ntfs_attr_ctx_cache; /* The various operations structs defined throughout the driver files. */ extern struct super_operations ntfs_sops; extern struct address_space_operations ntfs_aops; +extern struct address_space_operations ntfs_mst_aops; extern struct address_space_operations ntfs_mft_aops; extern struct file_operations ntfs_file_ops; diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index a5d65cb34..22939a515 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -763,7 +763,7 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol) /* The $MFTMirr, like the $MFT is multi sector transfer protected. */ NInoSetMstProtected(tmp_ni); /* - * Set up our little cheat allowing us to reuse the async io + * Set up our little cheat allowing us to reuse the async read io * completion handler for directories. */ tmp_ni->itype.index.block_size = vol->mft_record_size; @@ -1142,7 +1142,7 @@ get_ctx_vol_failed: #ifdef NTFS_RW /* Make sure that no unsupported volume flags are set. */ if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { - static const char *es1 = "Volume has unsupported flags set "; + static const char *es1 = "Volume has unsupported flags set"; static const char *es2 = ". Run chkdsk and mount in Windows."; /* If a read-write mount, convert it to a read-only mount. */ diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h index 6624e5422..68934a259 100644 --- a/include/asm-alpha/ide.h +++ b/include/asm-alpha/ide.h @@ -19,6 +19,8 @@ #define MAX_HWIFS CONFIG_IDE_MAX_HWIFS #endif +#define IDE_ARCH_OBSOLETE_DEFAULTS + static inline int ide_default_irq(unsigned long base) { switch (base) { diff --git a/include/asm-alpha/resource.h b/include/asm-alpha/resource.h index 686b9558d..558d177cc 100644 --- a/include/asm-alpha/resource.h +++ b/include/asm-alpha/resource.h @@ -39,7 +39,7 @@ {INR_OPEN, INR_OPEN}, /* RLIMIT_NOFILE */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_AS */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_NPROC */ \ - {LONG_MAX, LONG_MAX}, /* RLIMIT_MEMLOCK */ \ + {PAGE_SIZE,PAGE_SIZE}, /* RLIMIT_MEMLOCK */ \ {LONG_MAX, LONG_MAX}, /* RLIMIT_LOCKS */ \ } diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index 94380f509..bd600bd0e 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -83,9 +83,10 @@ typedef struct { volatile u32 offset[4096]; } __regbase; extern void pxa_gpio_mode( int gpio_mode ); /* - * return current lclk frequency in units of 10kHz + * return current memory and LCD clock frequency in units of 10kHz */ -extern unsigned int get_lclk_frequency_10khz(void); +extern unsigned int get_memclk_frequency_10khz(void); +extern unsigned int get_lcdclk_frequency_10khz(void); #endif diff --git a/include/asm-arm/ide.h b/include/asm-arm/ide.h index d43dee139..b2b9b3da6 100644 --- a/include/asm-arm/ide.h +++ b/include/asm-arm/ide.h @@ -21,13 +21,6 @@ # include /* obsolete + broken */ #endif -/* - * We always use the new IDE port registering, - * so these are fixed here. - */ -#define ide_default_io_base(i) (0) -#define ide_default_irq(b) (0) - #if !defined(CONFIG_ARCH_L7200) && !defined(CONFIG_ARCH_LH7A40X) # define IDE_ARCH_OBSOLETE_INIT # ifdef CONFIG_ARCH_CLPS7500 @@ -37,8 +30,6 @@ # endif #endif /* !ARCH_L7200 && !ARCH_LH7A40X */ -#define ide_init_default_irq(base) (0) - #define __ide_mm_insw(port,addr,len) readsw(port,addr,len) #define __ide_mm_insl(port,addr,len) readsl(port,addr,len) #define __ide_mm_outsw(port,addr,len) writesw(port,addr,len) diff --git a/include/asm-arm/resource.h b/include/asm-arm/resource.h index 9da87b622..0e42fa868 100644 --- a/include/asm-arm/resource.h +++ b/include/asm-arm/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-arm26/ide.h b/include/asm-arm26/ide.h index 2d29108ec..db804d751 100644 --- a/include/asm-arm26/ide.h +++ b/include/asm-arm26/ide.h @@ -26,15 +26,6 @@ #define __ide_mm_outsw(port,addr,len) writesw(port,addr,len) #define __ide_mm_outsl(port,addr,len) writesl(port,addr,len) -#define ide_init_default_irq(base) (0) - -/* - * We always use the new IDE port registering, - * so these are fixed here. - */ -#define ide_default_io_base(i) (0) -#define ide_default_irq(b) (0) - #define IDE_ARCH_OBSOLETE_INIT #define ide_default_io_ctl(base) (0) diff --git a/include/asm-arm26/resource.h b/include/asm-arm26/resource.h index 9da87b622..118700868 100644 --- a/include/asm-arm26/resource.h +++ b/include/asm-arm26/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-cris/arch-v10/cache.h b/include/asm-cris/arch-v10/cache.h index 1e796271e..1d1d1ba65 100644 --- a/include/asm-cris/arch-v10/cache.h +++ b/include/asm-cris/arch-v10/cache.h @@ -3,6 +3,7 @@ /* Etrax 100LX have 32-byte cache-lines. */ #define L1_CACHE_BYTES 32 +#define L1_CACHE_SHIFT 5 #define L1_CACHE_SHIFT_MAX 5 #endif /* _ASM_ARCH_CACHE_H */ diff --git a/include/asm-cris/arch-v10/irq.h b/include/asm-cris/arch-v10/irq.h index f657c75dd..a2a6e1533 100644 --- a/include/asm-cris/arch-v10/irq.h +++ b/include/asm-cris/arch-v10/irq.h @@ -8,6 +8,11 @@ #include #define NR_IRQS 32 + +/* The first vector number used for IRQs in v10 is really 0x20 */ +/* but all the code and constants are offseted to make 0 the first */ +#define FIRST_IRQ 0 + #define SOME_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, some) /* 0 ? */ #define NMI_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, nmi) /* 1 */ #define TIMER0_IRQ_NBR IO_BITNR(R_VECT_MASK_RD, timer0) /* 2 */ diff --git a/include/asm-cris/arch-v10/offset.h b/include/asm-cris/arch-v10/offset.h index 87901a752..fcbd77eab 100644 --- a/include/asm-cris/arch-v10/offset.h +++ b/include/asm-cris/arch-v10/offset.h @@ -25,7 +25,7 @@ #define THREAD_usp 4 /* offsetof(struct thread_struct, usp) */ #define THREAD_dccr 8 /* offsetof(struct thread_struct, dccr) */ -#define TASK_pid 121 /* offsetof(struct task_struct, pid) */ +#define TASK_pid 133 /* offsetof(struct task_struct, pid) */ #define LCLONE_VM 256 /* CLONE_VM */ #define LCLONE_UNTRACED 8388608 /* CLONE_UNTRACED */ diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h index f74010366..d7861115d 100644 --- a/include/asm-cris/bitops.h +++ b/include/asm-cris/bitops.h @@ -295,6 +295,50 @@ extern inline int find_next_zero_bit (void * addr, int size, int offset) return result + ffz(tmp); } +/** + * find_next_bit - find the first set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static __inline__ int find_next_bit(void *addr, int size, int offset) +{ + unsigned long *p = ((unsigned long *) addr) + (offset >> 5); + unsigned long result = offset & ~31UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *(p++); + tmp &= (~0UL << offset); + if (size < 32) + goto found_first; + if (tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size & ~31UL) { + if ((tmp = *(p++))) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= (~0UL >> (32 - size)); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); +} + /** * find_first_zero_bit - find the first zero bit in a memory region * @addr: The address to start the search at @@ -306,6 +350,8 @@ extern inline int find_next_zero_bit (void * addr, int size, int offset) #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) +#define find_first_bit(addr, size) \ + find_next_bit((addr), (size), 0) #define ext2_set_bit test_and_set_bit #define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h index e7e16901f..0d770f601 100644 --- a/include/asm-cris/dma-mapping.h +++ b/include/asm-cris/dma-mapping.h @@ -1 +1,125 @@ -#include +#ifndef _ASM_CRIS_DMA_MAPPING_H +#define _ASM_CRIS_DMA_MAPPING_H + +#include "scatterlist.h" + +static inline int +dma_supported(struct device *dev, u64 mask) +{ + BUG(); + return 0; +} + +static inline int +dma_set_mask(struct device *dev, u64 dma_mask) +{ + BUG(); + return 1; +} + +static inline void * +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, + int flag) +{ + BUG(); + return NULL; +} + +static inline void +dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t dma_handle) +{ + BUG(); +} + +static inline dma_addr_t +dma_map_single(struct device *dev, void *cpu_addr, size_t size, + enum dma_data_direction direction) +{ + BUG(); + return 0; +} + +static inline void +dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline dma_addr_t +dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + BUG(); + return 0; +} + +static inline void +dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline int +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction) +{ + BUG(); + return 1; +} + +static inline void +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline void +dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline void +dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, + enum dma_data_direction direction) +{ + BUG(); +} + +/* Now for the API extensions over the pci_ one */ + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) +#define dma_is_consistent(d) (1) + +static inline int +dma_get_cache_alignment(void) +{ + /* no easy way to get cache size on all processors, so return + * the maximum possible, to be safe */ + return (1 << L1_CACHE_SHIFT_MAX); +} + +static inline void +dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, + unsigned long offset, size_t size, + enum dma_data_direction direction) +{ + BUG(); +} + +static inline void +dma_cache_sync(void *vaddr, size_t size, + enum dma_data_direction direction) +{ + BUG(); +} + +#endif + diff --git a/include/asm-cris/fasttimer.h b/include/asm-cris/fasttimer.h index 10a770647..69522028b 100644 --- a/include/asm-cris/fasttimer.h +++ b/include/asm-cris/fasttimer.h @@ -1,4 +1,4 @@ -/* $Id: fasttimer.h,v 1.2 2002/12/11 13:03:43 starvik Exp $ +/* $Id: fasttimer.h,v 1.3 2004/05/14 10:19:19 starvik Exp $ * linux/include/asm-cris/fasttimer.h * * Fast timers for ETRAX100LX @@ -24,6 +24,8 @@ struct fast_timer{ /* Close to timer_list */ const char *name; }; +extern struct fast_timer *fast_timer_list; + void start_one_shot_timer(struct fast_timer *t, fast_timer_function_type *function, unsigned long data, diff --git a/include/asm-cris/io.h b/include/asm-cris/io.h index b89c1f93b..ac8807b36 100644 --- a/include/asm-cris/io.h +++ b/include/asm-cris/io.h @@ -72,6 +72,8 @@ extern void iounmap(void *addr); #define IO_SPACE_LIMIT 0xffff #define inb(x) (0) +#define inw(x) (0) +#define inl(x) (0) #define outb(x,y) #define outw(x,y) #define outl(x,y) diff --git a/include/asm-cris/ioctl.h b/include/asm-cris/ioctl.h index bb12a105c..be2d8f667 100644 --- a/include/asm-cris/ioctl.h +++ b/include/asm-cris/ioctl.h @@ -53,11 +53,18 @@ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) +/* provoke compile error for invalid uses of size argument */ +extern int __invalid_size_argument_for_IOC; +#define _IOC_TYPECHECK(t) \ + ((sizeof(t) == sizeof(t[1]) && \ + sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ + sizeof(t) : __invalid_size_argument_for_IOC) + /* used to create numbers */ #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) /* used to decode ioctl numbers.. */ #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h index 05dc15526..bebb8890d 100644 --- a/include/asm-cris/page.h +++ b/include/asm-cris/page.h @@ -6,7 +6,11 @@ /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 13 +#ifndef __ASSEMBLY__ #define PAGE_SIZE (1UL << PAGE_SHIFT) +#else +#define PAGE_SIZE (1 << PAGE_SHIFT) +#endif #define PAGE_MASK (~(PAGE_SIZE-1)) #ifdef __KERNEL__ @@ -20,10 +24,12 @@ /* * These are used to make use of C type-checking.. */ +#ifndef __ASSEMBLY__ typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; +#endif #define pte_val(x) ((x).pte) #define pmd_val(x) ((x).pmd) @@ -51,7 +57,7 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define virt_to_page(kaddr) (mem_map + (((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT)) #define VALID_PAGE(page) (((page) - mem_map) < max_mapnr) -#define virt_addr_valid(kaddr) pfn_valid((kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid((unsigned)(kaddr) >> PAGE_SHIFT) /* convert a page (based on mem_map and forward) to a physical address * do this by figuring out the virtual address and then use __pa @@ -72,8 +78,6 @@ typedef struct { unsigned long pgprot; } pgprot_t; BUG(); \ } while (0) -#endif /* __ASSEMBLY__ */ - /* Pure 2^n version of get_order */ static inline int get_order(unsigned long size) { @@ -87,6 +91,7 @@ static inline int get_order(unsigned long size) } while (size); return order; } +#endif /* __ASSEMBLY__ */ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) diff --git a/include/asm-cris/pci.h b/include/asm-cris/pci.h index e080860b4..c61041531 100644 --- a/include/asm-cris/pci.h +++ b/include/asm-cris/pci.h @@ -1,9 +1,13 @@ #ifndef __ASM_CRIS_PCI_H #define __ASM_CRIS_PCI_H +#include +#include + /* ETRAX chips don't have a PCI bus. This file is just here because some stupid .c code * includes it even if CONFIG_PCI is not set. */ +#define PCI_DMA_BUS_IS_PHYS (1) #endif /* __ASM_CRIS_PCI_H */ diff --git a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h index e4bdb23e0..4a08ed86e 100644 --- a/include/asm-cris/pgtable.h +++ b/include/asm-cris/pgtable.h @@ -5,9 +5,11 @@ #ifndef _CRIS_PGTABLE_H #define _CRIS_PGTABLE_H +#ifndef __ASSEMBLY__ #include #include #include +#endif #include /* @@ -21,8 +23,9 @@ * This file contains the functions and defines necessary to modify and use * the CRIS page table tree. */ - +#ifndef __ASSEMBLY__ extern void paging_init(void); +#endif /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following @@ -72,8 +75,10 @@ extern void paging_init(void); #define FIRST_USER_PGD_NR 0 /* zero page used for uninitialized stuff */ +#ifndef __ASSEMBLY__ extern unsigned long empty_zero_page; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) +#endif /* number of bits that fit into a memory pointer */ #define BITS_PER_PTR (8*sizeof(unsigned long)) @@ -104,6 +109,8 @@ extern unsigned long empty_zero_page; #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) #define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0) +#ifndef __ASSEMBLY__ + /* * The "pgd_xxx()" functions here are trivial for a folded two-level * setup: the pgd is never bad, and a pmd always exists (as it's folded @@ -337,4 +344,5 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma, #define pte_to_pgoff(x) (pte_val(x) >> 6) #define pgoff_to_pte(x) __pte(((x) << 6) | _PAGE_FILE) +#endif /* __ASSEMBLY__ */ #endif /* _CRIS_PGTABLE_H */ diff --git a/include/asm-cris/ptrace.h b/include/asm-cris/ptrace.h index 79045e36d..7a8c2880e 100644 --- a/include/asm-cris/ptrace.h +++ b/include/asm-cris/ptrace.h @@ -3,8 +3,10 @@ #include +#ifdef __KERNEL__ /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 +#endif #endif /* _CRIS_PTRACE_H */ diff --git a/include/asm-cris/resource.h b/include/asm-cris/resource.h index 83561dab9..78848fbb6 100644 --- a/include/asm-cris/resource.h +++ b/include/asm-cris/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-cris/rtc.h b/include/asm-cris/rtc.h index 382081c4a..97c130398 100644 --- a/include/asm-cris/rtc.h +++ b/include/asm-cris/rtc.h @@ -100,6 +100,8 @@ struct rtc_time { #define RTC_RD_TIME _IOR(RTC_MAGIC, 0x09, struct rtc_time) /* Read RTC time. */ #define RTC_SET_TIME _IOW(RTC_MAGIC, 0x0a, struct rtc_time) /* Set RTC time. */ #define RTC_SET_CHARGE _IOW(RTC_MAGIC, 0x0b, int) -#define RTC_MAX_IOCTL 0x0b +#define RTC_VLOW_RD _IOR(RTC_MAGIC, 0x11, int) /* Voltage Low detector */ +#define RTC_VLOW_SET _IO(RTC_MAGIC, 0x12) /* Clear voltage low information */ +#define RTC_MAX_IOCTL 0x12 #endif /* __RTC_H__ */ diff --git a/include/asm-cris/semaphore-helper.h b/include/asm-cris/semaphore-helper.h index 461c5e4fc..dbd0f30b8 100644 --- a/include/asm-cris/semaphore-helper.h +++ b/include/asm-cris/semaphore-helper.h @@ -52,7 +52,7 @@ extern inline int waking_non_zero_interruptible(struct semaphore *sem, dec(&sem->waking); ret = 1; } else if (signal_pending(tsk)) { - count_inc(&sem->count); + inc(&sem->count); ret = -EINTR; } local_irq_restore(flags); @@ -67,7 +67,7 @@ extern inline int waking_non_zero_trylock(struct semaphore *sem) local_save_flags(flags); local_irq_disable(); if (read(&sem->waking) <= 0) - count_inc(&sem->count); + inc(&sem->count); else { dec(&sem->waking); ret = 0; diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h index d0821f6ce..9ee66b9d5 100644 --- a/include/asm-cris/semaphore.h +++ b/include/asm-cris/semaphore.h @@ -21,7 +21,7 @@ int printk(const char *fmt, ...); struct semaphore { - int count; /* not atomic_t since we do the atomicity here already */ + atomic_t count; atomic_t waking; wait_queue_head_t wait; #if WAITQUEUE_DEBUG @@ -36,7 +36,7 @@ struct semaphore { #endif #define __SEMAPHORE_INITIALIZER(name,count) \ - { count, ATOMIC_INIT(0), \ + { ATOMIC_INIT(count), ATOMIC_INIT(0), \ __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ __SEM_DEBUG_INIT(name) } @@ -84,7 +84,7 @@ extern inline void down(struct semaphore * sem) /* atomically decrement the semaphores count, and if its negative, we wait */ local_save_flags(flags); local_irq_disable(); - failed = --(sem->count) < 0; + failed = --(sem->count.counter) < 0; local_irq_restore(flags); if(failed) { __down(sem); @@ -110,7 +110,7 @@ extern inline int down_interruptible(struct semaphore * sem) /* atomically decrement the semaphores count, and if its negative, we wait */ local_save_flags(flags); local_irq_disable(); - failed = --(sem->count) < 0; + failed = --(sem->count.counter) < 0; local_irq_restore(flags); if(failed) failed = __down_interruptible(sem); @@ -128,7 +128,7 @@ extern inline int down_trylock(struct semaphore * sem) local_save_flags(flags); local_irq_disable(); - failed = --(sem->count) < 0; + failed = --(sem->count.counter) < 0; local_irq_restore(flags); if(failed) failed = __down_trylock(sem); @@ -153,7 +153,7 @@ extern inline void up(struct semaphore * sem) /* atomically increment the semaphores count, and if it was negative, we wake people */ local_save_flags(flags); local_irq_disable(); - wakeup = ++(sem->count) <= 0; + wakeup = ++(sem->count.counter) <= 0; local_irq_restore(flags); if(wakeup) { __up(sem); diff --git a/include/asm-cris/termbits.h b/include/asm-cris/termbits.h index 118e9b8fc..16d9a491f 100644 --- a/include/asm-cris/termbits.h +++ b/include/asm-cris/termbits.h @@ -154,7 +154,7 @@ struct termios { #define B6250000 0010007 /* etrax 200 supports this as well */ #define B12500000 0010010 -#define CIBAUD 002003600000 /* input baud rate */ +#define CIBAUD 002003600000 /* input baud rate (used in v32) */ /* The values for CIBAUD bits are the same as the values for CBAUD and CBAUDEX * shifted left IBSHIFT bits. */ diff --git a/include/asm-cris/types.h b/include/asm-cris/types.h index bd329ffeb..41a0d450b 100644 --- a/include/asm-cris/types.h +++ b/include/asm-cris/types.h @@ -50,6 +50,7 @@ typedef unsigned long long u64; /* Dma addresses are 32-bits wide, just like our other addresses. */ typedef u32 dma_addr_t; +typedef u32 dma64_addr_t; typedef unsigned int kmem_bufctl_t; diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h index 433691142..71b7f6946 100644 --- a/include/asm-cris/unistd.h +++ b/include/asm-cris/unistd.h @@ -275,8 +275,21 @@ #define __NR_clock_nanosleep (__NR_timer_create+8) #define __NR_statfs64 268 #define __NR_fstatfs64 269 +#define __NR_tgkill 270 +#define __NR_utimes 271 +#define __NR_fadvise64_64 272 +#define __NR_vserver 273 +#define __NR_mbind 274 +#define __NR_get_mempolicy 275 +#define __NR_set_mempolicy 276 +#define __NR_mq_open 277 +#define __NR_mq_unlink (__NR_mq_open+1) +#define __NR_mq_timedsend (__NR_mq_open+2) +#define __NR_mq_timedreceive (__NR_mq_open+3) +#define __NR_mq_notify (__NR_mq_open+4) +#define __NR_mq_getsetattr (__NR_mq_open+5) -#define NR_syscalls 270 +#define NR_syscalls 283 #ifdef __KERNEL__ @@ -307,6 +320,7 @@ #include #include +#include /* * we need this inline - forking from kernel space will result diff --git a/include/asm-h8300/ide.h b/include/asm-h8300/ide.h index b24fc9be1..f8535ce74 100644 --- a/include/asm-h8300/ide.h +++ b/include/asm-h8300/ide.h @@ -16,11 +16,6 @@ #ifdef __KERNEL__ /****************************************************************************/ -#define ide_default_irq(base) (0) -#define ide_default_io_base(index) (0) - -#define ide_init_default_irq(base) (0) - #define MAX_HWIFS 1 #include diff --git a/include/asm-h8300/resource.h b/include/asm-h8300/resource.h index 38b8e942a..278f104a6 100644 --- a/include/asm-h8300/resource.h +++ b/include/asm-h8300/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-i386/atomic_kmap.h b/include/asm-i386/atomic_kmap.h index 150ffb993..5a1b90130 100644 --- a/include/asm-i386/atomic_kmap.h +++ b/include/asm-i386/atomic_kmap.h @@ -20,6 +20,7 @@ extern pte_t *kmap_pte; #define kmap_prot PAGE_KERNEL +#define kmap_prot_nocache PAGE_KERNEL_NOCACHE #define PKMAP_BASE (0xff000000UL) #define NR_SHARED_PMDS ((0xffffffff-PKMAP_BASE+1)/PMD_SIZE) diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h index 114ac7ac3..2c6a7bb1e 100644 --- a/include/asm-i386/bitops.h +++ b/include/asm-i386/bitops.h @@ -290,7 +290,7 @@ static __inline__ int find_first_zero_bit(const unsigned long *addr, unsigned si "shll $3,%%edi\n\t" "addl %%edi,%%edx" :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) - :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); return res; } @@ -318,7 +318,7 @@ static __inline__ int find_first_bit(const unsigned long *addr, unsigned size) "shll $3,%%edi\n\t" "addl %%edi,%%eax" :"=a" (res), "=&c" (d0), "=&D" (d1) - :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); return res; } diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index a6fceb3ce..d6005e6e8 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h @@ -47,6 +47,7 @@ /* Don't duplicate feature flags which are redundant with Intel! */ #define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */ #define X86_FEATURE_MP (1*32+19) /* MP Capable. */ +#define X86_FEATURE_NX (1*32+20) /* Execute Disable */ #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ #define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ #define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ @@ -100,6 +101,7 @@ #define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) #define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) #define cpu_has_mp boot_cpu_has(X86_FEATURE_MP) +#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) #define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR) #define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR) #define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR) diff --git a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h index 916b23b2d..baf5b5aae 100644 --- a/include/asm-i386/highmem.h +++ b/include/asm-i386/highmem.h @@ -53,6 +53,7 @@ extern void FASTCALL(kunmap_high(struct page *page)); void *kmap(struct page *page); void kunmap(struct page *page); void *kmap_atomic(struct page *page, enum km_type type); +void *kmap_atomic_nocache_pfn(unsigned long pfn, enum km_type type); void kunmap_atomic(void *kvaddr, enum km_type type); struct page *kmap_atomic_to_page(void *ptr); diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h index d13334817..0409c22f1 100644 --- a/include/asm-i386/ide.h +++ b/include/asm-i386/ide.h @@ -23,6 +23,8 @@ # endif #endif +#define IDE_ARCH_OBSOLETE_DEFAULTS + static __inline__ int ide_default_irq(unsigned long base) { switch (base) { diff --git a/include/asm-i386/kmap_types.h b/include/asm-i386/kmap_types.h index 03fb6b160..a82d62fd0 100644 --- a/include/asm-i386/kmap_types.h +++ b/include/asm-i386/kmap_types.h @@ -29,10 +29,7 @@ enum km_type { KM_IRQ1, KM_SOFTIRQ0, KM_SOFTIRQ1, - /* - * Be wary when adding entries: - * the 4G/4G virtual stack must be THREAD_SIZE aligned on each cpu. - */ KM_TYPE_NR }; + #endif diff --git a/include/asm-i386/msr.h b/include/asm-i386/msr.h index ffdeea9d1..3589c36b8 100644 --- a/include/asm-i386/msr.h +++ b/include/asm-i386/msr.h @@ -217,6 +217,15 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val) #define MSR_K7_FID_VID_CTL 0xC0010041 #define MSR_K7_FID_VID_STATUS 0xC0010042 +/* extended feature register */ +#define MSR_EFER 0xc0000080 + +/* EFER bits: */ + +/* Execute Disable enable */ +#define _EFER_NX 11 +#define EFER_NX (1<<_EFER_NX) + /* Centaur-Hauls/IDT defined MSRs. */ #define MSR_IDT_FCR1 0x107 #define MSR_IDT_FCR2 0x108 diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index f3d21c142..627420ff1 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -41,15 +41,18 @@ * These are used to make use of C type-checking.. */ #ifdef CONFIG_X86_PAE +extern unsigned long long __supported_pte_mask; typedef struct { unsigned long pte_low, pte_high; } pte_t; typedef struct { unsigned long long pmd; } pmd_t; typedef struct { unsigned long long pgd; } pgd_t; +typedef struct { unsigned long long pgprot; } pgprot_t; #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) #define HPAGE_SHIFT 21 #else typedef struct { unsigned long pte_low; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; #define boot_pte_t pte_t /* or would you rather have a typedef */ #define pte_val(x) ((x).pte_low) #define HPAGE_SHIFT 22 @@ -62,7 +65,6 @@ typedef struct { unsigned long pgd; } pgd_t; #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) #endif -typedef struct { unsigned long pgprot; } pgprot_t; #define pmd_val(x) ((x).pmd) #define pgd_val(x) ((x).pgd) diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h index 147acd853..a4c24db82 100644 --- a/include/asm-i386/pgtable-3level.h +++ b/include/asm-i386/pgtable-3level.h @@ -101,18 +101,24 @@ static inline unsigned long pte_pfn(pte_t pte) (pte.pte_high << (32 - PAGE_SHIFT)); } +extern unsigned long long __supported_pte_mask; + static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) { pte_t pte; - pte.pte_high = page_nr >> (32 - PAGE_SHIFT); - pte.pte_low = (page_nr << PAGE_SHIFT) | pgprot_val(pgprot); + pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \ + (pgprot_val(pgprot) >> 32); + pte.pte_high &= (__supported_pte_mask >> 32); + pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \ + __supported_pte_mask; return pte; } static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) { - return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot)); + return __pmd((((unsigned long long)page_nr << PAGE_SHIFT) | \ + pgprot_val(pgprot)) & __supported_pte_mask); } /* diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 790b3c47b..dd0bb8a2d 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -118,6 +118,7 @@ extern void entry_trampoline_setup(void); #define _PAGE_BIT_UNUSED1 9 /* available for programmer */ #define _PAGE_BIT_UNUSED2 10 #define _PAGE_BIT_UNUSED3 11 +#define _PAGE_BIT_NX 63 #define _PAGE_PRESENT 0x001 #define _PAGE_RW 0x002 @@ -134,28 +135,51 @@ extern void entry_trampoline_setup(void); #define _PAGE_FILE 0x040 /* set:pagecache unset:swap */ #define _PAGE_PROTNONE 0x080 /* If not present */ +#ifdef CONFIG_X86_PAE +#define _PAGE_NX (1ULL<<_PAGE_BIT_NX) +#else +#define _PAGE_NX 0 +#endif #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_NONE \ + __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED \ + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) + +#define PAGE_SHARED_EXEC \ + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY_NOEXEC \ + __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_COPY_EXEC \ + __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_COPY \ + PAGE_COPY_NOEXEC +#define PAGE_READONLY \ + __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_READONLY_EXEC \ + __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define _PAGE_KERNEL \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) +#define _PAGE_KERNEL_EXEC \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) -extern unsigned long __PAGE_KERNEL; -#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) -#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD) -#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) +extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; +#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) +#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD) +#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) +#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) #define PAGE_KERNEL __pgprot(__PAGE_KERNEL) #define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) +#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) /* * The i386 can't do page protection for execute, and considers that @@ -166,19 +190,19 @@ extern unsigned long __PAGE_KERNEL; #define __P001 PAGE_READONLY #define __P010 PAGE_COPY #define __P011 PAGE_COPY -#define __P100 PAGE_READONLY -#define __P101 PAGE_READONLY -#define __P110 PAGE_COPY -#define __P111 PAGE_COPY +#define __P100 PAGE_READONLY_EXEC +#define __P101 PAGE_READONLY_EXEC +#define __P110 PAGE_COPY_EXEC +#define __P111 PAGE_COPY_EXEC #define __S000 PAGE_NONE #define __S001 PAGE_READONLY #define __S010 PAGE_SHARED #define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY -#define __S101 PAGE_READONLY -#define __S110 PAGE_SHARED -#define __S111 PAGE_SHARED +#define __S100 PAGE_READONLY_EXEC +#define __S101 PAGE_READONLY_EXEC +#define __S110 PAGE_SHARED_EXEC +#define __S111 PAGE_SHARED_EXEC /* * Define this if things work differently on an i386 and an i486: @@ -253,6 +277,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte.pte_low &= _PAGE_CHG_MASK; pte.pte_low |= pgprot_val(newprot); +#ifdef CONFIG_X86_PAE + /* + * Chop off the NX bit (if present), and add the NX portion of + * the newprot (if present): + */ + pte.pte_high &= -1 ^ (1 << (_PAGE_BIT_NX - 32)); + pte.pte_high |= (pgprot_val(newprot) >> 32) & \ + (__supported_pte_mask >> 32); +#endif return pte; } diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index a34e7533e..efdbf17c2 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -473,6 +473,8 @@ load_esp0(struct tss_struct *tss, struct thread_struct *thread) } } +extern int use_nx; + #define start_thread(regs, new_eip, new_esp) do { \ __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \ set_fs(USER_DS); \ diff --git a/include/asm-i386/resource.h b/include/asm-i386/resource.h index e0da3ad1d..afa2eec75 100644 --- a/include/asm-i386/resource.h +++ b/include/asm-i386/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h index 9e31639f9..d3ac37f4c 100644 --- a/include/asm-i386/uaccess.h +++ b/include/asm-i386/uaccess.h @@ -35,10 +35,6 @@ #define segment_eq(a,b) ((a).seg == (b).seg) -extern long not_a_user_address; -#define check_user_ptr(x) \ - (void) ({ void __user * __userptr = (__typeof__(*(x)) *)¬_a_user_address; __userptr; }) - /* * movsl can be slow when source and dest are not both 8-byte aligned */ @@ -61,7 +57,7 @@ extern struct movsl_mask { */ #define __range_ok(addr,size) ({ \ unsigned long flag,sum; \ - check_user_ptr(addr); \ + __chk_user_ptr(addr); \ asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \ :"=&r" (flag), "=r" (sum) \ :"1" (addr),"g" ((int)(size)),"g" (current_thread_info()->addr_limit.seg)); \ @@ -215,7 +211,7 @@ extern int zero_user_size(unsigned int size, void *ptr); */ #define direct_get_user(x,ptr) \ ({ int __ret_gu,__val_gu; \ - check_user_ptr(ptr); \ + __chk_user_ptr(ptr); \ switch(sizeof (*(ptr))) { \ case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ @@ -334,7 +330,7 @@ extern void __put_user_bad(void); #define __put_user_size(x,ptr,size,retval,errret) \ do { \ retval = 0; \ - check_user_ptr(ptr); \ + __chk_user_ptr(ptr); \ switch (size) { \ case 1: __put_user_asm(x,ptr,retval,"b","b","iq",errret);break; \ case 2: __put_user_asm(x,ptr,retval,"w","w","ir",errret);break; \ @@ -393,7 +389,7 @@ extern long __get_user_bad(void); #define __get_user_size(x,ptr,size,retval,errret) \ do { \ retval = 0; \ - check_user_ptr(ptr); \ + __chk_user_ptr(ptr); \ switch (size) { \ case 1: __get_user_asm(x,ptr,retval,"b","b","=q",errret);break; \ case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \ diff --git a/include/asm-ia64/ide.h b/include/asm-ia64/ide.h index 2adbd91a4..e62b95301 100644 --- a/include/asm-ia64/ide.h +++ b/include/asm-ia64/ide.h @@ -25,6 +25,8 @@ # endif #endif +#define IDE_ARCH_OBSOLETE_DEFAULTS + static inline int ide_default_irq(unsigned long base) { switch (base) { diff --git a/include/asm-ia64/resource.h b/include/asm-ia64/resource.h index 06d11777d..eb171fcef 100644 --- a/include/asm-ia64/resource.h +++ b/include/asm-ia64/resource.h @@ -44,7 +44,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h index bcb701506..36118fd01 100644 --- a/include/asm-m68k/ide.h +++ b/include/asm-m68k/ide.h @@ -50,32 +50,6 @@ #define MAX_HWIFS 4 /* same as the other archs */ #endif - -static __inline__ int ide_default_irq(unsigned long base) -{ - return 0; -} - -static __inline__ unsigned long ide_default_io_base(int index) -{ - return 0; -} - - -/* - * Set up a hw structure for a specified data port, control port and IRQ. - * This should follow whatever the default interface uses. - */ -static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, - unsigned long data_port, - unsigned long ctrl_port, int *irq) -{ - if (data_port || ctrl_port) - printk("ide_init_hwif_ports: must not be called\n"); -} - -#define ide_init_default_irq(base) (0) - /* * Get rid of defs from io.h - ide has its private and conflicting versions * Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we diff --git a/include/asm-m68k/resource.h b/include/asm-m68k/resource.h index e2ad93f6a..8b6e74a35 100644 --- a/include/asm-m68k/resource.h +++ b/include/asm-m68k/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h index b70b1ec05..fa2760afa 100644 --- a/include/asm-mips/mach-generic/ide.h +++ b/include/asm-mips/mach-generic/ide.h @@ -20,6 +20,8 @@ # endif #endif +#define IDE_ARCH_OBSOLETE_DEFAULTS + static inline int ide_default_irq(unsigned long base) { switch (base) { diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h index c2df5fce0..15a9374c1 100644 --- a/include/asm-parisc/ide.h +++ b/include/asm-parisc/ide.h @@ -19,14 +19,9 @@ #define MAX_HWIFS 2 #endif -#define ide_default_irq(base) (0) -#define ide_default_io_base(index) (0) - #define IDE_ARCH_OBSOLETE_INIT #define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ -#define ide_init_default_irq(base) (0) - #define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) #define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) #define ide_check_region(from,extent) check_region((from), (extent)) diff --git a/include/asm-parisc/resource.h b/include/asm-parisc/resource.h index f9088848f..8b0fab7e3 100644 --- a/include/asm-parisc/resource.h +++ b/include/asm-parisc/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h index fbcddf33c..6c091582d 100644 --- a/include/asm-ppc/ide.h +++ b/include/asm-ppc/ide.h @@ -43,6 +43,8 @@ extern struct ide_machdep_calls ppc_ide_md; #undef SUPPORT_SLOW_DATA_PORTS #define SUPPORT_SLOW_DATA_PORTS 0 +#define IDE_ARCH_OBSOLETE_DEFAULTS + static __inline__ int ide_default_irq(unsigned long base) { if (ppc_ide_md.default_irq) diff --git a/include/asm-ppc/resource.h b/include/asm-ppc/resource.h index 956b34602..475f3095e 100644 --- a/include/asm-ppc/resource.h +++ b/include/asm-ppc/resource.h @@ -34,7 +34,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h index a8ee7d165..928dc5e39 100644 --- a/include/asm-ppc64/eeh.h +++ b/include/asm-ppc64/eeh.h @@ -47,16 +47,16 @@ void *eeh_ioremap(unsigned long addr, void *vaddr); void __init pci_addr_cache_build(void); /** - * eeh_add_device - perform EEH initialization for the indicated pci device - * @dev: pci device for which to set up EEH + * eeh_add_device_early + * eeh_add_device_late * - * This routine can be used to perform EEH initialization for PCI - * devices that were added after system boot (e.g. hotplug, dlpar). - * Whether this actually enables EEH or not for this device depends - * on the type of the device, on earlier boot command-line - * arguments & etc. + * Perform eeh initialization for devices added after boot. + * Call eeh_add_device_early before doing any i/o to the + * device (including config space i/o). Call eeh_add_device_late + * to finish the eeh setup for this device. */ -void eeh_add_device(struct pci_dev *); +void eeh_add_device_early(struct device_node *); +void eeh_add_device_late(struct pci_dev *); /** * eeh_remove_device - undo EEH setup for the indicated pci device diff --git a/include/asm-ppc64/ide.h b/include/asm-ppc64/ide.h index a06fef9f9..00df66e0e 100644 --- a/include/asm-ppc64/ide.h +++ b/include/asm-ppc64/ide.h @@ -22,14 +22,9 @@ # define MAX_HWIFS 4 #endif -static inline int ide_default_irq(unsigned long base) { return 0; } -static inline unsigned long ide_default_io_base(int index) { return 0; } - #define IDE_ARCH_OBSOLETE_INIT #define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ -#define ide_init_default_irq(base) (0) - #endif /* __KERNEL__ */ #endif /* __ASMPPC64_IDE_H */ diff --git a/include/asm-ppc64/mmu_context.h b/include/asm-ppc64/mmu_context.h index 51196458b..505ad13b3 100644 --- a/include/asm-ppc64/mmu_context.h +++ b/include/asm-ppc64/mmu_context.h @@ -172,8 +172,14 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, * After we have set current->mm to a new value, this activates * the context for the new mm so we see the new mappings. */ -#define activate_mm(active_mm, mm) \ - switch_mm(active_mm, mm, current); +static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) +{ + unsigned long flags; + + local_irq_save(flags); + switch_mm(prev, next, current); + local_irq_restore(flags); +} #define VSID_RANDOMIZER 42470972311UL #define VSID_MASK 0xfffffffffUL diff --git a/include/asm-ppc64/naca.h b/include/asm-ppc64/naca.h index a50189402..3c0b8d3a5 100644 --- a/include/asm-ppc64/naca.h +++ b/include/asm-ppc64/naca.h @@ -30,7 +30,7 @@ struct naca_struct { u64 log; /* Ptr to log buffer 0x30 */ u64 serialPortAddr; /* Phy addr of serial port 0x38 */ u64 interrupt_controller; /* Type of int controller 0x40 */ - u64 slb_size; /* SLB size in entries 0x48 */ + u64 unused1; /* was SLB size in entries 0x48 */ u64 pftSize; /* Log 2 of page table size 0x50 */ void *systemcfg; /* Pointer to systemcfg data 0x58 */ u32 dCacheL1LogLineSize; /* L1 d-cache line size Log2 0x60 */ diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 64b606aae..428080919 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -634,4 +634,10 @@ static inline void prefetchw(const void *x) #endif /* ASSEMBLY */ +/* + * Number of entries in the SLB. If this ever changes we should handle + * it with a use a cpu feature fixup. + */ +#define SLB_NUM_ENTRIES 64 + #endif /* __ASM_PPC64_PROCESSOR_H */ diff --git a/include/asm-ppc64/resource.h b/include/asm-ppc64/resource.h index b43a4ea0a..691a3fa3e 100644 --- a/include/asm-ppc64/resource.h +++ b/include/asm-ppc64/resource.h @@ -43,7 +43,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h index 5b949d28d..9423be5ad 100644 --- a/include/asm-ppc64/uaccess.h +++ b/include/asm-ppc64/uaccess.h @@ -16,10 +16,6 @@ #define VERIFY_READ 0 #define VERIFY_WRITE 1 -extern long not_a_user_address; -#define check_user_ptr(x) \ - (void) ({ void __user * __userptr = (__typeof__(*(x)) *)¬_a_user_address; __userptr; }) - /* * The fs value determines whether argument validity checking should be * performed or not. If get_fs() == USER_DS, checking is performed, with @@ -120,7 +116,7 @@ extern long __put_user_bad(void); #define __put_user_nocheck(x,ptr,size) \ ({ \ long __pu_err; \ - check_user_ptr(ptr); \ + __chk_user_ptr(ptr); \ __put_user_size((x),(ptr),(size),__pu_err,-EFAULT); \ __pu_err; \ }) @@ -192,7 +188,7 @@ extern long __get_user_bad(void); do { \ might_sleep(); \ retval = 0; \ - check_user_ptr(ptr); \ + __chk_user_ptr(ptr); \ switch (size) { \ case 1: __get_user_asm(x,ptr,retval,"lbz",errret); break; \ case 2: __get_user_asm(x,ptr,retval,"lhz",errret); break; \ diff --git a/include/asm-s390/resource.h b/include/asm-s390/resource.h index bc2520e1d..5ecbcbc57 100644 --- a/include/asm-s390/resource.h +++ b/include/asm-s390/resource.h @@ -45,7 +45,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h index ca4afdd6e..dd57b3f8f 100644 --- a/include/asm-s390/types.h +++ b/include/asm-s390/types.h @@ -93,9 +93,10 @@ typedef u64 sector_t; #define HAVE_SECTOR_T #endif +#endif /* ! __s390x__ */ + typedef unsigned int kmem_bufctl_t; -#endif /* ! __s390x__ */ #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _S390_TYPES_H */ diff --git a/include/asm-sh/ide.h b/include/asm-sh/ide.h index c88ba763c..7758b3ec3 100644 --- a/include/asm-sh/ide.h +++ b/include/asm-sh/ide.h @@ -22,6 +22,8 @@ #define MAX_HWIFS 2 #endif +#define IDE_ARCH_OBSOLETE_DEFAULTS + static inline int ide_default_irq_hp600(unsigned long base) { switch (base) { diff --git a/include/asm-sh/resource.h b/include/asm-sh/resource.h index 574b64488..42faf5b28 100644 --- a/include/asm-sh/resource.h +++ b/include/asm-sh/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h index 6e8468f96..64d810385 100644 --- a/include/asm-sparc/ide.h +++ b/include/asm-sparc/ide.h @@ -19,21 +19,9 @@ #undef MAX_HWIFS #define MAX_HWIFS 2 -static __inline__ int ide_default_irq(unsigned long base) -{ - return 0; -} - -static __inline__ unsigned long ide_default_io_base(int index) -{ - return 0; -} - #define IDE_ARCH_OBSOLETE_INIT #define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ -#define ide_init_default_irq(base) (0) - #define __ide_insl(data_reg, buffer, wcount) \ __ide_insw(data_reg, buffer, (wcount)<<1) #define __ide_outsl(data_reg, buffer, wcount) \ diff --git a/include/asm-sparc/resource.h b/include/asm-sparc/resource.h index 8237763e5..b6a5aca2a 100644 --- a/include/asm-sparc/resource.h +++ b/include/asm-sparc/resource.h @@ -42,7 +42,7 @@ { 0, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {INR_OPEN, INR_OPEN}, {0, 0}, \ - {RLIM_INFINITY, RLIM_INFINITY}, \ + {PAGE_SIZE, PAGE_SIZE}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY} \ } diff --git a/include/asm-sparc/sbus.h b/include/asm-sparc/sbus.h index 2fb2291db..4072875c7 100644 --- a/include/asm-sparc/sbus.h +++ b/include/asm-sparc/sbus.h @@ -7,6 +7,7 @@ #ifndef _SPARC_SBUS_H #define _SPARC_SBUS_H +#include #include #include @@ -106,10 +107,10 @@ extern void sbus_set_sbus64(struct sbus_dev *, int); extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp); extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32); -#define SBUS_DMA_BIDIRECTIONAL 0 -#define SBUS_DMA_TODEVICE 1 -#define SBUS_DMA_FROMDEVICE 2 -#define SBUS_DMA_NONE 3 +#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL +#define SBUS_DMA_TODEVICE DMA_TO_DEVICE +#define SBUS_DMA_FROMDEVICE DMA_FROM_DEVICE +#define SBUS_DMA_NONE DMA_NONE /* All the rest use streaming mode mappings. */ extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int); diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h index 9d1b75ccf..8ef47f13c 100644 --- a/include/asm-sparc/uaccess.h +++ b/include/asm-sparc/uaccess.h @@ -83,10 +83,6 @@ extern unsigned long search_extables_range(unsigned long addr, unsigned long *g2 extern void __ret_efault(void); -extern long not_a_user_address; -#define check_user_ptr(x) \ - (void) ({ void __user * __userptr = (__typeof__(*(x)) *)¬_a_user_address; __userptr; }) - /* Uh, these should become the main single-value transfer routines.. * They automatically use the right size if we just have the right * pointer type.. @@ -98,12 +94,12 @@ extern long not_a_user_address; */ #define put_user(x,ptr) ({ \ unsigned long __pu_addr = (unsigned long)(ptr); \ -check_user_ptr(ptr); \ +__chk_user_ptr(ptr); \ __put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); }) #define get_user(x,ptr) ({ \ unsigned long __gu_addr = (unsigned long)(ptr); \ -check_user_ptr(ptr); \ +__chk_user_ptr(ptr); \ __get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); }) /* diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h index f4e62012c..f850b61ab 100644 --- a/include/asm-sparc64/ide.h +++ b/include/asm-sparc64/ide.h @@ -24,21 +24,9 @@ # endif #endif -static __inline__ int ide_default_irq(unsigned long base) -{ - return 0; -} - -static __inline__ unsigned long ide_default_io_base(int index) -{ - return 0; -} - #define IDE_ARCH_OBSOLETE_INIT #define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */ -#define ide_init_default_irq(base) (0) - #define __ide_insl(data_reg, buffer, wcount) \ __ide_insw(data_reg, buffer, (wcount)<<1) #define __ide_outsl(data_reg, buffer, wcount) \ diff --git a/include/asm-sparc64/resource.h b/include/asm-sparc64/resource.h index 06150c09f..0ae54dc7f 100644 --- a/include/asm-sparc64/resource.h +++ b/include/asm-sparc64/resource.h @@ -41,7 +41,7 @@ { 0, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {INR_OPEN, INR_OPEN}, {0, 0}, \ - {RLIM_INFINITY, RLIM_INFINITY}, \ + {PAGE_SIZE, PAGE_SIZE }, \ {RLIM_INFINITY, RLIM_INFINITY}, \ {RLIM_INFINITY, RLIM_INFINITY} \ } diff --git a/include/asm-sparc64/sbus.h b/include/asm-sparc64/sbus.h index 2d669b1de..48279e10f 100644 --- a/include/asm-sparc64/sbus.h +++ b/include/asm-sparc64/sbus.h @@ -7,6 +7,7 @@ #ifndef _SPARC64_SBUS_H #define _SPARC64_SBUS_H +#include #include #include @@ -99,10 +100,10 @@ extern void sbus_set_sbus64(struct sbus_dev *, int); extern void *sbus_alloc_consistent(struct sbus_dev *, size_t, dma_addr_t *dma_addrp); extern void sbus_free_consistent(struct sbus_dev *, size_t, void *, dma_addr_t); -#define SBUS_DMA_BIDIRECTIONAL 0 -#define SBUS_DMA_TODEVICE 1 -#define SBUS_DMA_FROMDEVICE 2 -#define SBUS_DMA_NONE 3 +#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL +#define SBUS_DMA_TODEVICE DMA_TO_DEVICE +#define SBUS_DMA_FROMDEVICE DMA_FROM_DEVICE +#define SBUS_DMA_NONE DMA_NONE /* All the rest use streaming mode mappings. */ extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int); diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h index 680391dae..e1ce87c86 100644 --- a/include/asm-sparc64/uaccess.h +++ b/include/asm-sparc64/uaccess.h @@ -90,10 +90,6 @@ unsigned long search_extables_range(unsigned long addr, unsigned long *g2); extern void __ret_efault(void); -extern long not_a_user_address; -#define check_user_ptr(x) \ - (void) ({ void __user * __userptr = (__typeof__(*(x)) *)¬_a_user_address; __userptr; }) - /* Uh, these should become the main single-value transfer routines.. * They automatically use the right size if we just have the right * pointer type.. @@ -105,12 +101,12 @@ extern long not_a_user_address; */ #define put_user(x,ptr) ({ \ unsigned long __pu_addr = (unsigned long)(ptr); \ -check_user_ptr(ptr); \ +__chk_user_ptr(ptr); \ __put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); }) #define get_user(x,ptr) ({ \ unsigned long __gu_addr = (unsigned long)(ptr); \ -check_user_ptr(ptr); \ +__chk_user_ptr(ptr); \ __get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); }) #define __put_user(x,ptr) put_user(x,ptr) diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 1309641df..0ce57c1b4 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -446,7 +446,6 @@ static __inline__ _syscall1(int,dup,int,fd) static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp) static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode) static __inline__ _syscall1(int,close,int,fd) -static __inline__ _syscall1(int,_exit,int,exitcode) static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) #include diff --git a/include/asm-v850/resource.h b/include/asm-v850/resource.h index 6f59c85fe..0203d2e7a 100644 --- a/include/asm-v850/resource.h +++ b/include/asm-v850/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE, PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h index c91f028db..ae42bca73 100644 --- a/include/asm-x86_64/bitops.h +++ b/include/asm-x86_64/bitops.h @@ -337,15 +337,16 @@ static __inline__ int find_first_bit(const unsigned long * addr, unsigned size) "repe; scasl\n\t" "jz 1f\n\t" "leaq -4(%%rdi),%%rdi\n\t" - "bsfl (%%rdi),%%eax\n" - "1:\tsubq %%rbx,%%rdi\n\t" + "bsfq (%%rdi),%%rax\n" + "1:\tsubl %%ebx,%%edi\n\t" "shll $3,%%edi\n\t" "addl %%edi,%%eax" :"=a" (res), "=&c" (d0), "=&D" (d1) - :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); return res; } + /** * find_next_bit - find the first set bit in a memory region * @addr: The address to base the search on diff --git a/include/asm-x86_64/checksum.h b/include/asm-x86_64/checksum.h index abcabbce9..3718a8fbb 100644 --- a/include/asm-x86_64/checksum.h +++ b/include/asm-x86_64/checksum.h @@ -139,9 +139,9 @@ extern unsigned long csum_partial_copy_generic(const char *src, const char *dst, int *src_err_ptr, int *dst_err_ptr); -extern unsigned int csum_partial_copy_from_user(const char __user *src, char *dst, +extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int isum, int *errp); -extern unsigned int csum_partial_copy_to_user(const char *src, char __user *dst, +extern unsigned int csum_partial_copy_to_user(const char *src, char *dst, int len, unsigned int isum, int *errp); extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum); diff --git a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h index c1e04aa5a..c4f520987 100644 --- a/include/asm-x86_64/compat.h +++ b/include/asm-x86_64/compat.h @@ -186,15 +186,15 @@ struct compat_shmid64_ds { */ typedef u32 compat_uptr_t; -static inline void __user *compat_ptr(compat_uptr_t uptr) +static inline void *compat_ptr(compat_uptr_t uptr) { - return (void __user *)(unsigned long)uptr; + return (void *)(unsigned long)uptr; } -static __inline__ void __user *compat_alloc_user_space(long len) +static __inline__ void *compat_alloc_user_space(long len) { struct pt_regs *regs = (void *)current->thread.rsp0 - sizeof(struct pt_regs); - return (void __user *)regs->rsp - len; + return (void *)regs->rsp - len; } #endif /* _ASM_X86_64_COMPAT_H */ diff --git a/include/asm-x86_64/floppy.h b/include/asm-x86_64/floppy.h index bca9b28a1..2f2df23b6 100644 --- a/include/asm-x86_64/floppy.h +++ b/include/asm-x86_64/floppy.h @@ -170,7 +170,7 @@ static unsigned long vdma_mem_alloc(unsigned long size) static void _fd_dma_mem_free(unsigned long addr, unsigned long size) { if((unsigned long) addr >= (unsigned long) high_memory) - vfree((void *)addr); + return vfree((void *)addr); else free_pages(addr, get_order(size)); } diff --git a/include/asm-x86_64/fpu32.h b/include/asm-x86_64/fpu32.h index 4153db5c0..244ffe2a0 100644 --- a/include/asm-x86_64/fpu32.h +++ b/include/asm-x86_64/fpu32.h @@ -3,8 +3,8 @@ struct _fpstate_ia32; -int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, int fsave); -int save_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, +int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, int fsave); +int save_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, struct pt_regs *regs, int fsave); #endif diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h index 0518b4d56..bb5edc3cd 100644 --- a/include/asm-x86_64/i387.h +++ b/include/asm-x86_64/i387.h @@ -23,7 +23,7 @@ extern void fpu_init(void); extern unsigned int mxcsr_feature_mask; extern void mxcsr_feature_mask_init(void); extern void init_fpu(struct task_struct *child); -extern int save_i387(struct _fpstate __user *buf); +extern int save_i387(struct _fpstate *buf); static inline int need_signal_i387(struct task_struct *me) { @@ -57,10 +57,10 @@ static inline int need_signal_i387(struct task_struct *me) /* * ptrace request handers... */ -extern int get_fpregs(struct user_i387_struct __user *buf, +extern int get_fpregs(struct user_i387_struct *buf, struct task_struct *tsk); extern int set_fpregs(struct task_struct *tsk, - struct user_i387_struct __user *buf); + struct user_i387_struct *buf); /* * i387 state interaction @@ -93,7 +93,7 @@ static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) return err; } -static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) +static inline int save_i387_checking(struct i387_fxsave_struct *fx) { int err; asm volatile("1: rex64 ; fxsave (%[fx])\n\t" @@ -136,7 +136,7 @@ static inline void save_init_fpu( struct task_struct *tsk ) /* * This restores directly out of user space. Exceptions are handled. */ -static inline int restore_i387(struct _fpstate __user *buf) +static inline int restore_i387(struct _fpstate *buf) { return restore_fpu_checking((struct i387_fxsave_struct *)buf); } diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h index a680d0356..b29899e3c 100644 --- a/include/asm-x86_64/ia32.h +++ b/include/asm-x86_64/ia32.h @@ -168,8 +168,8 @@ struct ustat32 { #ifdef __KERNEL__ struct user_desc; struct siginfo_t; -int do_get_thread_area(struct thread_struct *t, struct user_desc __user *info); -int do_set_thread_area(struct thread_struct *t, struct user_desc __user *info); +int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info); +int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info); int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs); int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from); int ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from); diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h index ff0309c2e..5facf5648 100644 --- a/include/asm-x86_64/ia32_unistd.h +++ b/include/asm-x86_64/ia32_unistd.h @@ -288,8 +288,7 @@ #define __NR_ia32_mq_timedreceive (__NR_ia32_mq_open+3) #define __NR_ia32_mq_notify (__NR_ia32_mq_open+4) #define __NR_ia32_mq_getsetattr (__NR_ia32_mq_open+5) -#define __NR_ia32_kexec 283 -#define IA32_NR_syscalls 287 /* must be > than biggest syscall! */ +#define IA32_NR_syscalls 285 /* must be > than biggest syscall! */ #endif /* _ASM_X86_64_IA32_UNISTD_H_ */ diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h index 1ddce4b4a..b0ce61de4 100644 --- a/include/asm-x86_64/io.h +++ b/include/asm-x86_64/io.h @@ -195,13 +195,8 @@ extern void iounmap(void *addr); #define __raw_writel writel #define __raw_writeq writeq -void *__memcpy_fromio(void*,unsigned long,unsigned); -void *__memcpy_toio(unsigned long,const void*,unsigned); - -#define memcpy_fromio(to,from,len) \ - __memcpy_fromio((to),(unsigned long)(from),(len)) -#define memcpy_toio(to,from,len) \ - __memcpy_toio((unsigned long)(to),(from),(len)) +void *memcpy_fromio(void*,const void*,unsigned); +void *memcpy_toio(void*,const void*,unsigned); #define memset_io(a,b,c) memset((void *)(a),(b),(c)) /* diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index 381661952..8f0b0f3d8 100644 --- a/include/asm-x86_64/page.h +++ b/include/asm-x86_64/page.h @@ -65,26 +65,21 @@ extern unsigned long vm_stack_flags, vm_stack_flags32; extern unsigned long vm_data_default_flags, vm_data_default_flags32; extern unsigned long vm_force_exec32; -#define __START_KERNEL 0xffffffff80100000UL -#define __START_KERNEL_map 0xffffffff80000000UL -#define __PAGE_OFFSET 0x0000010000000000UL /* 1 << 40 */ - -#else -#define __START_KERNEL 0xffffffff80100000 -#define __START_KERNEL_map 0xffffffff80000000 -#define __PAGE_OFFSET 0x0000010000000000 /* 1 << 40 */ #endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) /* See Documentation/x86_64/mm.txt for a description of the memory map. */ +#define __START_KERNEL 0xffffffff80100000 +#define __START_KERNEL_map 0xffffffff80000000 +#define __PAGE_OFFSET 0x0000010000000000 /* 1 << 40 */ #define __PHYSICAL_MASK_SHIFT 40 #define __PHYSICAL_MASK ((1UL << __PHYSICAL_MASK_SHIFT) - 1) #define __VIRTUAL_MASK_SHIFT 48 #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) -#define KERNEL_TEXT_SIZE (10UL*1024*1024) +#define KERNEL_TEXT_SIZE (40UL*1024*1024) #define KERNEL_TEXT_START 0xffffffff80000000UL #ifndef __ASSEMBLY__ diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 37ebbad00..5555b9cf6 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -124,13 +124,13 @@ static inline void set_pml4(pml4_t *dst, pml4_t val) #ifndef __ASSEMBLY__ -#define VMALLOC_START 0xffffff0000000000UL -#define VMALLOC_END 0xffffff7fffffffffUL -#define MODULES_VADDR 0xffffffffa0000000UL -#define MODULES_END 0xffffffffafffffffUL +#define VMALLOC_START 0xffffff0000000000 +#define VMALLOC_END 0xffffff7fffffffff +#define MODULES_VADDR 0xffffffffa0000000 +#define MODULES_END 0xffffffffafffffff #define MODULES_LEN (MODULES_END - MODULES_VADDR) -#define IOMAP_START 0xfffffe8000000000UL +#define IOMAP_START 0xfffffe8000000000 #define _PAGE_BIT_PRESENT 0 #define _PAGE_BIT_RW 1 @@ -172,7 +172,7 @@ static inline void set_pml4(pml4_t *dst, pml4_t val) #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define __PAGE_KERNEL \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) -#define __PAGE_KERNEL_EXECUTABLE \ +#define __PAGE_KERNEL_EXEC \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) #define __PAGE_KERNEL_NOCACHE \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX) @@ -188,7 +188,7 @@ static inline void set_pml4(pml4_t *dst, pml4_t val) #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL) #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL) -#define PAGE_KERNEL_EXECUTABLE MAKE_GLOBAL(__PAGE_KERNEL_EXECUTABLE) +#define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC) #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL) @@ -383,20 +383,6 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define update_mmu_cache(vma,address,pte) do { } while (0) -/* We only update the dirty/accessed state if we set - * the dirty bit by hand in the kernel, since the hardware - * will do the accessed bit for us, and we don't want to - * race with other CPU's that might be updating the dirty - * bit at the same time. */ -#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS -#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ - do { \ - if (__dirty) { \ - set_pte(__ptep, __entry); \ - flush_tlb_page(__vma, __address); \ - } \ - } while (0) - /* Encode and de-code a swap entry */ #define __swp_type(x) (((x).val >> 1) & 0x3f) #define __swp_offset(x) ((x).val >> 8) diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index ec696b271..7a253a830 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h @@ -166,7 +166,7 @@ static inline void clear_in_cr4 (unsigned long mask) /* * User space process size: 512GB - 1GB (default). */ -#define TASK_SIZE (0x0000007fc0000000UL) +#define TASK_SIZE (0x0000007fc0000000) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. diff --git a/include/asm-x86_64/ptrace.h b/include/asm-x86_64/ptrace.h index cbc19a778..3c5c3a4fc 100644 --- a/include/asm-x86_64/ptrace.h +++ b/include/asm-x86_64/ptrace.h @@ -83,7 +83,7 @@ struct pt_regs { #if defined(__KERNEL__) && !defined(__ASSEMBLY__) #define user_mode(regs) (!!((regs)->cs & 3)) #define instruction_pointer(regs) ((regs)->rip) -void signal_fault(struct pt_regs *regs, void __user *frame, char *where); +void signal_fault(struct pt_regs *regs, void *frame, char *where); enum { EF_CF = 0x00000001, diff --git a/include/asm-x86_64/resource.h b/include/asm-x86_64/resource.h index b430c854b..f88aee8af 100644 --- a/include/asm-x86_64/resource.h +++ b/include/asm-x86_64/resource.h @@ -37,7 +37,7 @@ { RLIM_INFINITY, RLIM_INFINITY }, \ { 0, 0 }, \ { INR_OPEN, INR_OPEN }, \ - { RLIM_INFINITY, RLIM_INFINITY }, \ + { PAGE_SIZE , PAGE_SIZE }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ { RLIM_INFINITY, RLIM_INFINITY }, \ } diff --git a/include/asm-x86_64/semaphore.h b/include/asm-x86_64/semaphore.h index 278883422..5fe25482f 100644 --- a/include/asm-x86_64/semaphore.h +++ b/include/asm-x86_64/semaphore.h @@ -47,12 +47,12 @@ struct semaphore { atomic_t count; int sleepers; wait_queue_head_t wait; -#ifdef WAITQUEUE_DEBUG +#if WAITQUEUE_DEBUG long __magic; #endif }; -#ifdef WAITQUEUE_DEBUG +#if WAITQUEUE_DEBUG # define __SEM_DEBUG_INIT(name) \ , (int)&(name).__magic #else @@ -83,7 +83,7 @@ static inline void sema_init (struct semaphore *sem, int val) atomic_set(&sem->count, val); sem->sleepers = 0; init_waitqueue_head(&sem->wait); -#ifdef WAITQUEUE_DEBUG +#if WAITQUEUE_DEBUG sem->__magic = (int)&sem->__magic; #endif } @@ -115,7 +115,7 @@ asmlinkage void __up(struct semaphore * sem); */ static inline void down(struct semaphore * sem) { -#ifdef WAITQUEUE_DEBUG +#if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif might_sleep(); @@ -142,7 +142,7 @@ static inline int down_interruptible(struct semaphore * sem) { int result; -#ifdef WAITQUEUE_DEBUG +#if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif might_sleep(); @@ -171,7 +171,7 @@ static inline int down_trylock(struct semaphore * sem) { int result; -#ifdef WAITQUEUE_DEBUG +#if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif @@ -199,7 +199,7 @@ static inline int down_trylock(struct semaphore * sem) */ static inline void up(struct semaphore * sem) { -#ifdef WAITQUEUE_DEBUG +#if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); #endif __asm__ __volatile__( diff --git a/include/asm-x86_64/sigcontext.h b/include/asm-x86_64/sigcontext.h index b4e402366..6a624087d 100644 --- a/include/asm-x86_64/sigcontext.h +++ b/include/asm-x86_64/sigcontext.h @@ -2,7 +2,6 @@ #define _ASM_X86_64_SIGCONTEXT_H #include -#include /* FXSAVE frame */ /* Note: reserved1/2 may someday contain valuable data. Always save/restore @@ -48,7 +47,7 @@ struct sigcontext { unsigned long trapno; unsigned long oldmask; unsigned long cr2; - struct _fpstate __user *fpstate; /* zero when no FPU context */ + struct _fpstate *fpstate; /* zero when no FPU context */ unsigned long reserved1[8]; }; diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h index 779c74260..9b4c018aa 100644 --- a/include/asm-x86_64/uaccess.h +++ b/include/asm-x86_64/uaccess.h @@ -24,7 +24,7 @@ #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFFFFFFFFFUL) +#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFFFFFFFFF) #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) #define get_ds() (KERNEL_DS) @@ -33,16 +33,6 @@ #define segment_eq(a,b) ((a).seg == (b).seg) -#ifdef __CHECKER__ -#define CHECK_UPTR(ptr) do { \ - __typeof__(*(ptr)) *__dummy_check_uptr = \ - (void __user *)&__dummy_check_uptr; \ -} while(0) -#else -#define CHECK_UPTR(ptr) -#endif - - #define __addr_ok(addr) (!((unsigned long)(addr) & (current_thread_info()->addr_limit.seg))) /* @@ -50,16 +40,15 @@ */ #define __range_not_ok(addr,size) ({ \ unsigned long flag,sum; \ - CHECK_UPTR(addr); \ asm("# range_ok\n\r" \ "addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0" \ :"=&r" (flag), "=r" (sum) \ :"1" (addr),"g" ((long)(size)),"g" (current_thread_info()->addr_limit.seg)); \ flag; }) -#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0) +#define access_ok(type,addr,size) (__range_not_ok(addr,size) == 0) -extern inline int verify_area(int type, const void __user * addr, unsigned long size) +extern inline int verify_area(int type, const void * addr, unsigned long size) { return access_ok(type,addr,size) ? 0 : -EFAULT; } @@ -114,7 +103,6 @@ extern void __get_user_8(void); #define get_user(x,ptr) \ ({ long __val_gu; \ int __ret_gu; \ - CHECK_UPTR(ptr); \ switch(sizeof (*(ptr))) { \ case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ @@ -150,7 +138,6 @@ extern void __put_user_bad(void); #define __put_user_nocheck(x,ptr,size) \ ({ \ int __pu_err; \ - CHECK_UPTR(ptr); \ __put_user_size((x),(ptr),(size),__pu_err); \ __pu_err; \ }) @@ -206,7 +193,6 @@ struct __large_struct { unsigned long buf[100]; }; ({ \ int __gu_err; \ long __gu_val; \ - CHECK_UPTR(ptr); \ __get_user_size(__gu_val,(ptr),(size),__gu_err); \ (x) = (__typeof__(*(ptr)))__gu_val; \ __gu_err; \ @@ -249,15 +235,15 @@ do { \ /* Handles exceptions in both to and from, but doesn't do access_ok */ extern unsigned long copy_user_generic(void *to, const void *from, unsigned len); -extern unsigned long copy_to_user(void __user *to, const void *from, unsigned len); -extern unsigned long copy_from_user(void *to, const void __user *from, unsigned len); -extern unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len); +extern unsigned long copy_to_user(void *to, const void *from, unsigned len); +extern unsigned long copy_from_user(void *to, const void *from, unsigned len); +extern unsigned long copy_in_user(void *to, const void *from, unsigned len); -static inline int __copy_from_user(void *dst, const void __user *src, unsigned size) +static inline int __copy_from_user(void *dst, const void *src, unsigned size) { int ret = 0; if (!__builtin_constant_p(size)) - return copy_user_generic(dst,(void *)src,size); + return copy_user_generic(dst,src,size); switch (size) { case 1:__get_user_asm(*(u8*)dst,(u8 *)src,ret,"b","b","=q",1); return ret; @@ -278,15 +264,15 @@ static inline int __copy_from_user(void *dst, const void __user *src, unsigned s __get_user_asm(*(u64*)(8+(char*)dst),(u64*)(8+(char*)src),ret,"q","","=r",8); return ret; default: - return copy_user_generic(dst,(void *)src,size); + return copy_user_generic(dst,src,size); } } -static inline int __copy_to_user(void __user *dst, const void *src, unsigned size) +static inline int __copy_to_user(void *dst, const void *src, unsigned size) { int ret = 0; if (!__builtin_constant_p(size)) - return copy_user_generic((void *)dst,src,size); + return copy_user_generic(dst,src,size); switch (size) { case 1:__put_user_asm(*(u8*)src,(u8 *)dst,ret,"b","b","iq",1); return ret; @@ -309,16 +295,16 @@ static inline int __copy_to_user(void __user *dst, const void *src, unsigned siz __put_user_asm(1[(u64*)src],1+(u64*)dst,ret,"q","","ir",8); return ret; default: - return copy_user_generic((void *)dst,src,size); + return copy_user_generic(dst,src,size); } } -static inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size) +static inline int __copy_in_user(void *dst, const void *src, unsigned size) { int ret = 0; if (!__builtin_constant_p(size)) - return copy_user_generic((void *)dst,(void *)src,size); + return copy_user_generic(dst,src,size); switch (size) { case 1: { u8 tmp; @@ -350,15 +336,15 @@ static inline int __copy_in_user(void __user *dst, const void __user *src, unsig return ret; } default: - return copy_user_generic((void *)dst,(void *)src,size); + return copy_user_generic(dst,src,size); } } -long strncpy_from_user(char *dst, const char __user *src, long count); -long __strncpy_from_user(char *dst, const char __user *src, long count); -long strnlen_user(const char __user *str, long n); -long strlen_user(const char __user *str); -unsigned long clear_user(void __user *mem, unsigned long len); -unsigned long __clear_user(void __user *mem, unsigned long len); +long strncpy_from_user(char *dst, const char *src, long count); +long __strncpy_from_user(char *dst, const char *src, long count); +long strnlen_user(const char *str, long n); +long strlen_user(const char *str); +unsigned long clear_user(void *mem, unsigned long len); +unsigned long __clear_user(void *mem, unsigned long len); #endif /* __X86_64_UACCESS_H */ diff --git a/include/linux/aio.h b/include/linux/aio.h index 6e88c87c9..b03ebead2 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h @@ -149,11 +149,11 @@ struct mm_struct; extern void FASTCALL(exit_aio(struct mm_struct *mm)); extern struct kioctx *lookup_ioctx(unsigned long ctx_id); extern int FASTCALL(io_submit_one(struct kioctx *ctx, - struct iocb __user *user_iocb, struct iocb *iocb)); + struct iocb *user_iocb, struct iocb *iocb)); /* semi private, but used by the 32bit emulations: */ struct kioctx *lookup_ioctx(unsigned long ctx_id); -int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, +int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb *user_iocb, struct iocb *iocb)); #define get_ioctx(kioctx) do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index fb8676817..c68809546 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -6,11 +6,13 @@ # define __kernel /* default address space */ # define __safe __attribute__((safe)) # define __force __attribute__((force)) +extern void __chk_user_ptr(void __user *); #else # define __user # define __kernel # define __safe # define __force +# define __chk_user_ptr(x) (void)0 #endif #ifdef __KERNEL__ diff --git a/include/linux/elf.h b/include/linux/elf.h index fe2527b42..f8115ac02 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -37,8 +37,6 @@ typedef __s64 Elf64_Sxword; #define PT_GNU_STACK (PT_LOOS + 0x474e551) -#define PT_GNU_STACK (PT_LOOS + 0x474e551) - /* These constants define the different elf file types */ #define ET_NONE 0 #define ET_REL 1 diff --git a/include/linux/futex.h b/include/linux/futex.h index 87f4b2541..65d6cfdb6 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -8,9 +8,10 @@ #define FUTEX_WAKE (1) #define FUTEX_FD (2) #define FUTEX_REQUEUE (3) - +#define FUTEX_CMP_REQUEUE (4) long do_futex(unsigned long uaddr, int op, int val, - unsigned long timeout, unsigned long uaddr2, int val2); + unsigned long timeout, unsigned long uaddr2, int val2, + int val3); #endif diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h index 4b925472a..41e79a7f5 100644 --- a/include/linux/hdlc.h +++ b/include/linux/hdlc.h @@ -134,7 +134,7 @@ typedef struct hdlc_device_struct { int dce_pvc_count; struct timer_list timer; - int last_poll; + unsigned long last_poll; int reliable; int dce_changed; int request; @@ -149,8 +149,9 @@ typedef struct hdlc_device_struct { cisco_proto settings; struct timer_list timer; - int last_poll; + unsigned long last_poll; int up; + int request_sent; u32 txseq; /* TX sequence number */ u32 rxseq; /* RX sequence number */ }cisco; diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 232d8fdb5..e334a5fdd 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -28,9 +28,10 @@ static inline void *kmap(struct page *page) #define kunmap(page) do { (void) (page); } while (0) -#define kmap_atomic(page, idx) page_address(page) -#define kunmap_atomic(addr, idx) do { } while (0) -#define kmap_atomic_to_page(ptr) virt_to_page(ptr) +#define kmap_atomic(page, idx) page_address(page) +#define kmap_atomic_nocache_pfn(pfn, idx) pfn_to_kaddr(pfn) +#define kunmap_atomic(addr, idx) do { } while (0) +#define kmap_atomic_to_page(ptr) virt_to_page(ptr) #endif /* CONFIG_HIGHMEM */ diff --git a/include/linux/ide.h b/include/linux/ide.h index 0aef41843..8a773de2c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -305,14 +305,17 @@ static inline void ide_std_init_ports(hw_regs_t *hw, #include +/* needed on alpha, x86/x86_64, ia64, mips, ppc32 and sh */ +#ifndef IDE_ARCH_OBSOLETE_DEFAULTS +# define ide_default_io_base(index) (0) +# define ide_default_irq(base) (0) +# define ide_init_default_irq(base) (0) +#endif + /* * ide_init_hwif_ports() is OBSOLETE and will be removed in 2.7 series. * New ports shouldn't define IDE_ARCH_OBSOLETE_INIT in . - * - * m68k, m68knommu (broken) and i386-pc9800 (broken) - * still have their own versions. */ -#ifndef CONFIG_M68K #ifdef IDE_ARCH_OBSOLETE_INIT static inline void ide_init_hwif_ports(hw_regs_t *hw, unsigned long io_addr, @@ -335,9 +338,15 @@ static inline void ide_init_hwif_ports(hw_regs_t *hw, #endif } #else -# define ide_init_hwif_ports(hw, io, ctl, irq) do {} while (0) +static inline void ide_init_hwif_ports(hw_regs_t *hw, + unsigned long io_addr, + unsigned long ctl_addr, + int *irq) +{ + if (io_addr || ctl_addr) + printk(KERN_WARNING "%s: must not be called\n", __FUNCTION__); +} #endif /* IDE_ARCH_OBSOLETE_INIT */ -#endif /* !M68K */ /* Currently only m68k, apus and m8xx need it */ #ifndef IDE_ARCH_ACK_INTR @@ -1552,9 +1561,15 @@ typedef struct ide_pci_enablebit_s { u8 val; /* value of masked reg when "enabled" */ } ide_pci_enablebit_t; +enum { + /* Uses ISA control ports not PCI ones. */ + IDEPCI_FLAG_ISA_PORTS = (1 << 0), + + IDEPCI_FLAG_FORCE_MASTER = (1 << 1), + IDEPCI_FLAG_FORCE_PDC = (1 << 2), +}; + typedef struct ide_pci_device_s { - u16 vendor; - u16 device; char *name; void (*init_setup)(struct pci_dev *, struct ide_pci_device_s *); void (*init_setup_dma)(struct pci_dev *, struct ide_pci_device_s *, ide_hwif_t *); @@ -1568,7 +1583,7 @@ typedef struct ide_pci_device_s { u8 bootable; unsigned int extra; struct ide_pci_device_s *next; - u8 isa_ports; /* Uses ISA control ports not PCI ones */ + u8 flags; } ide_pci_device_t; extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *); diff --git a/include/linux/mca.h b/include/linux/mca.h index b1289a792..554bbcf71 100644 --- a/include/linux/mca.h +++ b/include/linux/mca.h @@ -144,7 +144,7 @@ static inline void mca_do_proc_init(void) { } -static inline void mca_set_adapter_procfn(int slot, MCA_ProcFn *fn, void* dev) +static inline void mca_set_adapter_procfn(int slot, MCA_ProcFn fn, void* dev) { } #endif diff --git a/include/linux/mm.h b/include/linux/mm.h index 09e6742dd..cf78dd6dc 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -495,9 +495,19 @@ int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new); struct mempolicy *shmem_get_policy(struct vm_area_struct *vma, unsigned long addr); struct file *shmem_file_setup(char * name, loff_t size, unsigned long flags); -void shmem_lock(struct file * file, int lock); +int shmem_lock(struct file * file, int lock); int shmem_zero_setup(struct vm_area_struct *); +static inline int can_do_mlock(void) +{ + if (capable(CAP_IPC_LOCK)) + return 1; + if (current->rlim[RLIMIT_MEMLOCK].rlim_cur != 0) + return 1; + return 0; +} + + /* * Parameter block passed down to zap_pte_range in exceptional cases. */ @@ -710,6 +720,8 @@ extern unsigned int nr_used_zone_pages(void); extern struct page * vmalloc_to_page(void *addr); extern struct page * follow_page(struct mm_struct *mm, unsigned long address, int write); +extern struct page * follow_page_pfn(struct mm_struct *mm, + unsigned long address, int write, unsigned long *pfn); extern int remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, unsigned long size, pgprot_t prot); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 2b983a75e..b43a7f89f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -373,6 +373,7 @@ #define PCI_DEVICE_ID_NS_SCx200_AUDIO 0x0503 #define PCI_DEVICE_ID_NS_SCx200_VIDEO 0x0504 #define PCI_DEVICE_ID_NS_SCx200_XBUS 0x0505 +#define PCI_DEVICE_ID_NS_SC1100_BRIDGE 0x0510 #define PCI_DEVICE_ID_NS_87410 0xd001 #define PCI_VENDOR_ID_TSENG 0x100c @@ -1057,6 +1058,12 @@ #define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029 #define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C #define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e +#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085 diff --git a/include/linux/timer.h b/include/linux/timer.h index 8efb6bcdc..90db1cc62 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -4,6 +4,7 @@ #include #include #include +#include struct tvec_t_base_s; diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 570778dde..bad993c16 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -23,6 +23,7 @@ struct vm_struct { * Highlevel APIs for driver use */ extern void *vmalloc(unsigned long size); +extern void *vmalloc_exec(unsigned long size); extern void *vmalloc_32(unsigned long size); extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot); extern void vfree(void *addr); diff --git a/include/net/ip.h b/include/net/ip.h index 0caf7bc57..94ea1eda3 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -150,7 +150,7 @@ struct ipv4_config }; extern struct ipv4_config ipv4_config; -DECLARE_SNMP_STAT(struct ip_mib, ip_statistics); +DECLARE_SNMP_STAT(struct ipstats_mib, ip_statistics); #define IP_INC_STATS(field) SNMP_INC_STATS(ip_statistics, field) #define IP_INC_STATS_BH(field) SNMP_INC_STATS_BH(ip_statistics, field) #define IP_INC_STATS_USER(field) SNMP_INC_STATS_USER(ip_statistics, field) diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index d0ca2230a..14d41c4ba 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -57,6 +57,8 @@ struct rt6_info struct rt6_info *next; } u; + struct inet6_dev *rt6i_idev; + #define rt6i_dev u.dst.dev #define rt6i_nexthop u.dst.neighbour #define rt6i_expires u.dst.expires diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 37876f73b..06b350cef 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -111,7 +111,7 @@ extern int sysctl_ipv6_bindv6only; extern int sysctl_mld_max_msf; /* MIBs */ -DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics); +DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); #define IP6_INC_STATS(field) SNMP_INC_STATS(ipv6_statistics, field) #define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field) #define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field) diff --git a/include/net/route.h b/include/net/route.h index 7a851de92..0e7210e6d 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -55,6 +55,8 @@ struct rtable struct rtable *rt_next; } u; + struct in_device *idev; + unsigned rt_flags; unsigned rt_type; diff --git a/include/net/snmp.h b/include/net/snmp.h index 67e22b82e..c702dda23 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -41,61 +41,52 @@ * cacheline machine it makes a *lot* of sense -AK */ - +struct snmp_item { + char *name; + int offset; +}; + +#define SNMP_ITEM(mib,entry,procname) { \ + .name = procname, \ + .offset = offsetof(mib, entry), \ +} + +#define SNMP_ITEM_SENTINEL { \ + .name = NULL, \ + .offset = 0, \ +} + /* * RFC 1213: MIB-II * RFC 2011 (updates 1213): SNMPv2-MIB-IP * RFC 2863: Interfaces Group MIB - */ -struct ip_mib -{ - unsigned long IpInReceives; - unsigned long IpInHdrErrors; - unsigned long IpInAddrErrors; - unsigned long IpForwDatagrams; - unsigned long IpInUnknownProtos; - unsigned long IpInDiscards; - unsigned long IpInDelivers; - unsigned long IpOutRequests; - unsigned long IpOutDiscards; - unsigned long IpOutNoRoutes; - unsigned long IpReasmTimeout; - unsigned long IpReasmReqds; - unsigned long IpReasmOKs; - unsigned long IpReasmFails; - unsigned long IpFragOKs; - unsigned long IpFragFails; - unsigned long IpFragCreates; - unsigned long __pad[0]; -}; - -/* * RFC 2465: IPv6 MIB: General Group + * draft-ietf-ipv6-rfc2011-update-10.txt: MIB for IP: IP Statistics Tables */ -struct ipv6_mib +struct ipstats_mib { - unsigned long Ip6InReceives; - unsigned long Ip6InHdrErrors; - unsigned long Ip6InTooBigErrors; - unsigned long Ip6InNoRoutes; - unsigned long Ip6InAddrErrors; - unsigned long Ip6InUnknownProtos; - unsigned long Ip6InTruncatedPkts; - unsigned long Ip6InDiscards; - unsigned long Ip6InDelivers; - unsigned long Ip6OutForwDatagrams; - unsigned long Ip6OutRequests; - unsigned long Ip6OutDiscards; - unsigned long Ip6OutNoRoutes; - unsigned long Ip6ReasmTimeout; - unsigned long Ip6ReasmReqds; - unsigned long Ip6ReasmOKs; - unsigned long Ip6ReasmFails; - unsigned long Ip6FragOKs; - unsigned long Ip6FragFails; - unsigned long Ip6FragCreates; - unsigned long Ip6InMcastPkts; - unsigned long Ip6OutMcastPkts; + unsigned long InReceives; + unsigned long InHdrErrors; + unsigned long InTooBigErrors; + unsigned long InNoRoutes; + unsigned long InAddrErrors; + unsigned long InUnknownProtos; + unsigned long InTruncatedPkts; + unsigned long InDiscards; + unsigned long InDelivers; + unsigned long OutForwDatagrams; + unsigned long OutRequests; + unsigned long OutDiscards; + unsigned long OutNoRoutes; + unsigned long ReasmTimeout; + unsigned long ReasmReqds; + unsigned long ReasmOKs; + unsigned long ReasmFails; + unsigned long FragOKs; + unsigned long FragFails; + unsigned long FragCreates; + unsigned long InMcastPkts; + unsigned long OutMcastPkts; unsigned long __pad[0]; }; diff --git a/init/Kconfig b/init/Kconfig index f9d4ecc47..f0c5a2318 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -92,7 +92,7 @@ config SYSVIPC config POSIX_MQUEUE bool "POSIX Message Queues" - depends on EXPERIMENTAL + depends on NET && EXPERIMENTAL ---help--- POSIX variant of message queues is a part of IPC. In POSIX message queues every message has a priority which decides about succession diff --git a/ipc/shm.c b/ipc/shm.c index 9761e3bcb..18d8ebaff 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -504,14 +504,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) case SHM_LOCK: case SHM_UNLOCK: { -/* Allow superuser to lock segment in memory */ -/* Should the pages be faulted in here or leave it to user? */ -/* need to determine interaction with current->swappable */ - if (!capable(CAP_IPC_LOCK)) { + /* Allow superuser to lock segment in memory */ + if (!can_do_mlock()) { err = -EPERM; goto out; } - shp = shm_lock(shmid); if(shp==NULL) { err = -EINVAL; @@ -526,9 +523,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) goto out_unlock; if(cmd==SHM_LOCK) { - if (!is_file_hugepages(shp->shm_file)) - shmem_lock(shp->shm_file, 1); - shp->shm_flags |= SHM_LOCKED; + if (!is_file_hugepages(shp->shm_file)) { + err = shmem_lock(shp->shm_file, 1); + if (!err) + shp->shm_flags |= SHM_LOCKED; + } } else { if (!is_file_hugepages(shp->shm_file)) shmem_lock(shp->shm_file, 0); diff --git a/ipc/util.c b/ipc/util.c index 81a145ede..77e718915 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -377,8 +377,11 @@ int ipcperms (struct kern_ipc_perm *ipcp, short flag) granted_mode >>= 3; /* is there some bit set in requested_mode but not in granted_mode? */ if ((requested_mode & ~granted_mode & 0007) && - !capable(CAP_IPC_OWNER)) - return -1; + !capable(CAP_IPC_OWNER)) { + if (!can_do_mlock()) { + return -1; + } + } return security_ipc_permission(ipcp, flag); } diff --git a/kernel/compat.c b/kernel/compat.c index 9dccddd33..540574ce8 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -210,7 +210,8 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, #ifdef CONFIG_FUTEX asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, int val, - struct compat_timespec __user *utime, u32 __user *uaddr2) + struct compat_timespec __user *utime, u32 __user *uaddr2, + int val3) { struct timespec t; unsigned long timeout = MAX_SCHEDULE_TIMEOUT; @@ -221,11 +222,11 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, int val, return -EFAULT; timeout = timespec_to_jiffies(&t) + 1; } - if (op == FUTEX_REQUEUE) + if (op >= FUTEX_REQUEUE) val2 = (int) (long) utime; return do_futex((unsigned long)uaddr, op, val, timeout, - (unsigned long)uaddr2, val2); + (unsigned long)uaddr2, val2, val3); } #endif @@ -398,8 +399,8 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, return ret; } -asmlinkage int compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, - compat_ulong_t __user *user_mask_ptr) +asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, + compat_ulong_t __user *user_mask_ptr) { unsigned long kernel_mask; mm_segment_t old_fs; diff --git a/kernel/exit.c b/kernel/exit.c index c80a44115..c8611f1de 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -736,6 +736,14 @@ static void exit_notify(struct task_struct *tsk) tsk->state = state; tsk->flags |= PF_DEAD; + /* + * Clear these here so that update_process_times() won't try to deliver + * itimer, profile or rlimit signals to this task while it is in late exit. + */ + tsk->it_virt_incr = 0; + tsk->it_prof_value = 0; + tsk->rlim[RLIMIT_CPU].rlim_cur = RLIM_INFINITY; + /* * In the preemption case it must be impossible for the task * to get runnable again, so use "_raw_" unlock to keep diff --git a/kernel/futex.c b/kernel/futex.c index 18d5119d2..f7afaf5d3 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -96,6 +96,7 @@ struct futex_q { */ struct futex_hash_bucket { spinlock_t lock; + unsigned int nqueued; struct list_head chain; }; @@ -318,13 +319,14 @@ out: * physical page. */ static int futex_requeue(unsigned long uaddr1, unsigned long uaddr2, - int nr_wake, int nr_requeue) + int nr_wake, int nr_requeue, int *valp) { union futex_key key1, key2; struct futex_hash_bucket *bh1, *bh2; struct list_head *head1; struct futex_q *this, *next; int ret, drop_count = 0; + unsigned int nqueued; down_read(¤t->mm->mmap_sem); @@ -338,12 +340,41 @@ static int futex_requeue(unsigned long uaddr1, unsigned long uaddr2, bh1 = hash_futex(&key1); bh2 = hash_futex(&key2); + nqueued = bh1->nqueued; + if (likely(valp != NULL)) { + int curval; + + /* In order to avoid doing get_user while + holding bh1->lock and bh2->lock, nqueued + (monotonically increasing field) must be first + read, then *uaddr1 fetched from userland and + after acquiring lock nqueued field compared with + the stored value. The smp_mb () below + makes sure that bh1->nqueued is read from memory + before *uaddr1. */ + smp_mb(); + + if (get_user(curval, (int *)uaddr1) != 0) { + ret = -EFAULT; + goto out; + } + if (curval != *valp) { + ret = -EAGAIN; + goto out; + } + } + if (bh1 < bh2) spin_lock(&bh1->lock); spin_lock(&bh2->lock); if (bh1 > bh2) spin_lock(&bh1->lock); + if (unlikely(nqueued != bh1->nqueued && valp != NULL)) { + ret = -EAGAIN; + goto out_unlock; + } + head1 = &bh1->chain; list_for_each_entry_safe(this, next, head1, list) { if (!match_futex (&this->key, &key1)) @@ -365,6 +396,7 @@ static int futex_requeue(unsigned long uaddr1, unsigned long uaddr2, } } +out_unlock: spin_unlock(&bh1->lock); if (bh1 != bh2) spin_unlock(&bh2->lock); @@ -398,6 +430,7 @@ static void queue_me(struct futex_q *q, int fd, struct file *filp) q->lock_ptr = &bh->lock; spin_lock(&bh->lock); + bh->nqueued++; list_add_tail(&q->list, &bh->chain); spin_unlock(&bh->lock); } @@ -625,7 +658,7 @@ out: } long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout, - unsigned long uaddr2, int val2) + unsigned long uaddr2, int val2, int val3) { int ret; @@ -641,7 +674,10 @@ long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout, ret = futex_fd(uaddr, val); break; case FUTEX_REQUEUE: - ret = futex_requeue(uaddr, uaddr2, val, val2); + ret = futex_requeue(uaddr, uaddr2, val, val2, NULL); + break; + case FUTEX_CMP_REQUEUE: + ret = futex_requeue(uaddr, uaddr2, val, val2, &val3); break; default: ret = -ENOSYS; @@ -651,7 +687,8 @@ long do_futex(unsigned long uaddr, int op, int val, unsigned long timeout, asmlinkage long sys_futex(u32 __user *uaddr, int op, int val, - struct timespec __user *utime, u32 __user *uaddr2) + struct timespec __user *utime, u32 __user *uaddr2, + int val3) { struct timespec t; unsigned long timeout = MAX_SCHEDULE_TIMEOUT; @@ -665,11 +702,11 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, int val, /* * requeue parameter in 'utime' if op == FUTEX_REQUEUE. */ - if (op == FUTEX_REQUEUE) + if (op >= FUTEX_REQUEUE) val2 = (int) (long) utime; return do_futex((unsigned long)uaddr, op, val, timeout, - (unsigned long)uaddr2, val2); + (unsigned long)uaddr2, val2, val3); } static struct super_block * diff --git a/kernel/kthread.c b/kernel/kthread.c index 2e60249d4..da0ec5b25 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -11,6 +11,7 @@ #include #include #include +#include #include struct kthread_create_info @@ -41,7 +42,7 @@ int kthread_should_stop(void) { return (kthread_stop_info.k == current); } - +EXPORT_SYMBOL(kthread_should_stop); static void kthread_exit_files(void) { @@ -144,6 +145,7 @@ struct task_struct *kthread_create(int (*threadfn)(void *data), return create.result; } +EXPORT_SYMBOL(kthread_create); void kthread_bind(struct task_struct *k, unsigned int cpu) { @@ -153,6 +155,7 @@ void kthread_bind(struct task_struct *k, unsigned int cpu) set_task_cpu(k, cpu); k->cpus_allowed = cpumask_of_cpu(cpu); } +EXPORT_SYMBOL(kthread_bind); int kthread_stop(struct task_struct *k) { @@ -180,3 +183,4 @@ int kthread_stop(struct task_struct *k) return ret; } +EXPORT_SYMBOL(kthread_stop); diff --git a/kernel/sched.c b/kernel/sched.c index 02f9f2253..305bdfa3b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1664,11 +1664,8 @@ static runqueue_t *find_busiest_queue(struct sched_group *group) * tasks if there is an imbalance. * * Called with this_rq unlocked. - * - * This function is marked noinline to work around a compiler - * bug with gcc 3.3.3-hammer on x86-64. */ -static int noinline load_balance(int this_cpu, runqueue_t *this_rq, +static int load_balance(int this_cpu, runqueue_t *this_rq, struct sched_domain *sd, enum idle_type idle) { struct sched_group *group; @@ -1685,6 +1682,11 @@ static int noinline load_balance(int this_cpu, runqueue_t *this_rq, busiest = find_busiest_queue(group); if (!busiest) goto out_balanced; + /* + * This should be "impossible", but since load + * balancing is inherently racy and statistical, + * it could happen in theory. + */ if (unlikely(busiest == this_rq)) { WARN_ON(1); goto out_balanced; @@ -1848,6 +1850,15 @@ static void active_load_balance(runqueue_t *busiest, int busiest_cpu) } rq = cpu_rq(push_cpu); + + /* + * This condition is "impossible", but since load + * balancing is inherently a bit racy and statistical, + * it can trigger.. Reported by Bjorn Helgaas on a + * 128-cpu setup. + */ + if (unlikely(busiest == rq)) + goto next_group; double_lock_balance(busiest, rq); move_tasks(rq, push_cpu, busiest, 1, sd, IDLE); spin_unlock(&rq->lock); diff --git a/kernel/signal.c b/kernel/signal.c index d1f7f609b..a8d18f402 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2211,7 +2211,7 @@ sys_kill(int pid, int sig) } /** - * sys_tkill - send signal to one specific thread + * sys_tgkill - send signal to one specific thread * @tgid: the thread group ID of the thread * @pid: the PID of the thread * @sig: signal to be sent @@ -2512,6 +2512,8 @@ out: return error; } +#endif /* SIGPROCMASK */ + #ifndef __sparc__ asmlinkage long sys_rt_sigaction(int sig, @@ -2541,7 +2543,6 @@ out: return ret; } #endif /* __sparc__ */ -#endif #ifdef __ARCH_WANT_SYS_SGETMASK diff --git a/kernel/sys.c b/kernel/sys.c index d22fd2d12..1bbc66a60 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -274,6 +274,7 @@ cond_syscall(compat_sys_mq_getsetattr) cond_syscall(sys_mbind) cond_syscall(sys_get_mempolicy) cond_syscall(sys_set_mempolicy) +cond_syscall(compat_get_mempolicy) /* arch-specific weak syscall entries */ cond_syscall(sys_pciconfig_read) diff --git a/mm/memory.c b/mm/memory.c index 4e9684aba..0f2a1e6f4 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -662,6 +662,64 @@ out: return NULL; } +struct page * +follow_page_pfn(struct mm_struct *mm, unsigned long address, int write, + unsigned long *pfn_ptr) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + unsigned long pfn; + struct page *page; + + *pfn_ptr = 0; + page = follow_huge_addr(mm, address, write); + if (!IS_ERR(page)) + return page; + + pgd = pgd_offset(mm, address); + if (pgd_none(*pgd) || pgd_bad(*pgd)) + goto out; + + pmd = pmd_offset(pgd, address); + if (pmd_none(*pmd)) + goto out; + if (pmd_huge(*pmd)) + return follow_huge_pmd(mm, address, pmd, write); + if (pmd_bad(*pmd)) + goto out; + + ptep = pte_offset_map(pmd, address); + if (!ptep) + goto out; + + pte = *ptep; + pte_unmap(ptep); + if (pte_present(pte)) { + if (write && !pte_write(pte)) + goto out; + if (write && !pte_dirty(pte)) { + struct page *page = pte_page(pte); + if (!PageDirty(page)) + set_page_dirty(page); + } + pfn = pte_pfn(pte); + if (pfn_valid(pfn)) { + struct page *page = pfn_to_page(pfn); + + mark_page_accessed(page); + return page; + } else { + *pfn_ptr = pfn; + return NULL; + } + } + +out: + return NULL; +} + + /* * Given a physical address, is there a useful struct page pointing to * it? This may become more complex in the future if we start dealing diff --git a/mm/mlock.c b/mm/mlock.c index a9e37161d..e15aef89e 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -60,7 +60,7 @@ static int do_mlock(unsigned long start, size_t len, int on) struct vm_area_struct * vma, * next; int error; - if (on && !capable(CAP_IPC_LOCK)) + if (on && !can_do_mlock()) return -EPERM; len = PAGE_ALIGN(len); end = start + len; @@ -118,7 +118,7 @@ asmlinkage long sys_mlock(unsigned long start, size_t len) lock_limit >>= PAGE_SHIFT; /* check against resource limits */ - if (locked <= lock_limit) + if ( (locked <= lock_limit) || capable(CAP_IPC_LOCK)) error = do_mlock(start, len, 1); up_write(¤t->mm->mmap_sem); return error; @@ -142,7 +142,7 @@ static int do_mlockall(int flags) unsigned int def_flags; struct vm_area_struct * vma; - if (!capable(CAP_IPC_LOCK)) + if (!can_do_mlock()) return -EPERM; def_flags = 0; @@ -177,7 +177,7 @@ asmlinkage long sys_mlockall(int flags) lock_limit >>= PAGE_SHIFT; ret = -ENOMEM; - if (current->mm->total_vm <= lock_limit) + if ((current->mm->total_vm <= lock_limit) || capable(CAP_IPC_LOCK)) ret = do_mlockall(flags); out: up_write(¤t->mm->mmap_sem); diff --git a/mm/mmap.c b/mm/mmap.c index d6005880b..b00732b04 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -344,8 +344,9 @@ __insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) validate_mm(mm); } -static inline void __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, - struct vm_area_struct *prev) +static inline void +__vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, + struct vm_area_struct *prev) { prev->vm_next = vma->vm_next; rb_erase(&vma->vm_rb, &mm->mm_rb); @@ -772,15 +773,17 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; if (flags & MAP_LOCKED) { - if (!capable(CAP_IPC_LOCK)) + if (!can_do_mlock()) return -EPERM; vm_flags |= VM_LOCKED; } /* mlock MCL_FUTURE? */ if (vm_flags & VM_LOCKED) { - unsigned long locked = mm->locked_vm << PAGE_SHIFT; + unsigned long locked, lock_limit; + locked = mm->locked_vm << PAGE_SHIFT; + lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; locked += len; - if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) return -EAGAIN; } @@ -1370,6 +1373,7 @@ no_mmaps: static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area) { size_t len = area->vm_end - area->vm_start; + unsigned long old_end = area->vm_end; area->vm_mm->total_vm -= len >> PAGE_SHIFT; if (area->vm_flags & VM_LOCKED) @@ -1385,10 +1389,9 @@ static void unmap_vma(struct mm_struct *mm, struct vm_area_struct *area) */ if (area->vm_start > area->vm_mm->non_executable_cache) area->vm_mm->non_executable_cache = area->vm_start; - remove_vm_struct(area); if (unlikely(area->vm_flags & VM_EXEC)) - arch_remove_exec_range(mm, area->vm_end); + arch_remove_exec_range(mm, old_end); } /* @@ -1477,11 +1480,8 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, /* most fields are the same, copy all, and then fixup */ *new = *vma; - if (new_below) { - if (vma->vm_flags & VM_EXEC) - arch_remove_exec_range(mm, new->vm_end); + if (new_below) new->vm_end = addr; - } else { new->vm_start = addr; new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); @@ -1500,10 +1500,14 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, if (new->vm_ops && new->vm_ops->open) new->vm_ops->open(new); - if (new_below) + if (new_below) { + unsigned long old_end = vma->vm_end; + vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff + ((addr - new->vm_start) >> PAGE_SHIFT), new); - else + if (vma->vm_flags & VM_EXEC) + arch_remove_exec_range(mm, old_end); + } else vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); return 0; @@ -1619,9 +1623,11 @@ unsigned long do_brk(unsigned long addr, unsigned long len) * mlock MCL_FUTURE? */ if (mm->def_flags & VM_LOCKED) { - unsigned long locked = mm->locked_vm << PAGE_SHIFT; + unsigned long locked, lock_limit; + locked = mm->locked_vm << PAGE_SHIFT; + lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; locked += len; - if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) return -EAGAIN; } diff --git a/mm/mprotect.c b/mm/mprotect.c index b9d4f20b0..7dbb64d1b 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -114,7 +114,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, unsigned long start, unsigned long end, unsigned int newflags) { struct mm_struct * mm = vma->vm_mm; - unsigned long charged = 0; + unsigned long charged = 0, old_end = vma->vm_end; pgprot_t newprot; unsigned int oldflags; pgoff_t pgoff; @@ -181,7 +181,7 @@ success: vma->vm_flags = newflags; vma->vm_page_prot = newprot; if (oldflags & VM_EXEC) - arch_remove_exec_range(current->mm, vma->vm_end); + arch_remove_exec_range(current->mm, old_end); change_protection(vma, start, end, newprot); return 0; diff --git a/mm/mremap.c b/mm/mremap.c index 329190677..33b41cb05 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -325,10 +325,12 @@ unsigned long do_mremap(unsigned long addr, goto out; } if (vma->vm_flags & VM_LOCKED) { - unsigned long locked = current->mm->locked_vm << PAGE_SHIFT; + unsigned long locked, lock_limit; + locked = current->mm->locked_vm << PAGE_SHIFT; + lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; locked += new_len - old_len; ret = -EAGAIN; - if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) + if (locked > lock_limit && !capable(CAP_IPC_LOCK)) goto out; } ret = -ENOMEM; diff --git a/mm/pdflush.c b/mm/pdflush.c index 1e682bed9..09e62cf1c 100644 --- a/mm/pdflush.c +++ b/mm/pdflush.c @@ -88,6 +88,8 @@ struct pdflush_work { unsigned long when_i_went_to_sleep; }; +void try_to_clip_inodes(void); + static int __pdflush(struct pdflush_work *my_work) { current->flags |= PF_FLUSHER; @@ -125,6 +127,8 @@ static int __pdflush(struct pdflush_work *my_work) spin_unlock_irq(&pdflush_lock); (*my_work->fn)(my_work->arg0); + + try_to_clip_inodes(); /* * Thread creation: For how long have there been zero diff --git a/mm/shmem.c b/mm/shmem.c index 21d58bd46..ada4f735c 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1161,17 +1161,36 @@ shmem_get_policy(struct vm_area_struct *vma, unsigned long addr) } #endif -void shmem_lock(struct file *file, int lock) +int shmem_lock(struct file *file, int lock) { struct inode *inode = file->f_dentry->d_inode; struct shmem_inode_info *info = SHMEM_I(inode); + struct mm_struct *mm = current->mm; + unsigned long lock_limit, locked; + int retval = -ENOMEM; spin_lock(&info->lock); + if (lock && !(info->flags & VM_LOCKED)) { + locked = inode->i_size >> PAGE_SHIFT; + locked += mm->locked_vm; + lock_limit = current->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit >>= PAGE_SHIFT; + if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) + goto out_nomem; + mm->locked_vm = locked; + } + if (!lock && (info->flags & VM_LOCKED) && mm) { + locked = inode->i_size >> PAGE_SHIFT; + mm->locked_vm -= locked; + } if (lock) info->flags |= VM_LOCKED; else info->flags &= ~VM_LOCKED; + retval = 0; +out_nomem: spin_unlock(&info->lock); + return retval; } static int shmem_mmap(struct file *file, struct vm_area_struct *vma) diff --git a/mm/slab.c b/mm/slab.c index 7e9deede9..4f6ba9021 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -477,10 +477,12 @@ struct cache_sizes malloc_sizes[] = { EXPORT_SYMBOL(malloc_sizes); /* Must match cache_sizes above. Out of line to keep cache footprint low. */ -static struct cache_names { +struct cache_names { char *name; char *name_dma; -} cache_names[] = { +}; + +static struct cache_names __initdata cache_names[] = { #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" }, #include { 0, } diff --git a/mm/usercopy.c b/mm/usercopy.c index 0ca0c9caa..a22b81fab 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -24,7 +24,8 @@ /* * Get kernel address of the user page and pin it. */ -static inline struct page *pin_page(unsigned long addr, int write) +static inline struct page *pin_page(unsigned long addr, int write, + unsigned long *pfn) { struct mm_struct *mm = current->mm ? : &init_mm; struct page *page = NULL; @@ -34,13 +35,14 @@ static inline struct page *pin_page(unsigned long addr, int write) * Do a quick atomic lookup first - this is the fastpath. */ retry: - page = follow_page(mm, addr, write); + page = follow_page_pfn(mm, addr, write, pfn); if (likely(page != NULL)) { if (!PageReserved(page)) get_page(page); return page; } - + if (*pfn) + return NULL; /* * No luck - bad address or need to fault in the page: */ @@ -95,11 +97,12 @@ static int rw_vm(unsigned long addr, void *buf, int len, int write) /* ignore errors, just check how much was sucessfully transfered */ while (len) { struct page *page = NULL; + unsigned long pfn = 0; int bytes, offset; void *maddr; - page = pin_page(addr, write); - if (!page) + page = pin_page(addr, write, &pfn); + if (!page && !pfn) break; bytes = len; @@ -107,7 +110,10 @@ static int rw_vm(unsigned long addr, void *buf, int len, int write) if (bytes > PAGE_SIZE-offset) bytes = PAGE_SIZE-offset; - maddr = kmap_atomic(page, KM_USER_COPY); + if (page) + maddr = kmap_atomic(page, KM_USER_COPY); + else + maddr = kmap_atomic_nocache_pfn(pfn, KM_USER_COPY); #define HANDLE_TYPE(type) \ case sizeof(type): *(type *)(maddr+offset) = *(type *)(buf); break; @@ -134,7 +140,8 @@ static int rw_vm(unsigned long addr, void *buf, int len, int write) #undef HANDLE_TYPE } kunmap_atomic(maddr, KM_USER_COPY); - unpin_page(page); + if (page) + unpin_page(page); len -= bytes; buf += bytes; addr += bytes; @@ -158,10 +165,11 @@ static int str_vm(unsigned long addr, void *buf0, int len, int copy) /* ignore errors, just check how much was sucessfully transfered */ while (len) { int bytes, offset, left, copied; + unsigned long pfn = 0; char *maddr; - page = pin_page(addr, copy == 2); - if (!page) { + page = pin_page(addr, copy == 2, &pfn); + if (!page && !pfn) { spin_unlock(&mm->page_table_lock); return -EFAULT; } @@ -170,7 +178,10 @@ static int str_vm(unsigned long addr, void *buf0, int len, int copy) if (bytes > PAGE_SIZE-offset) bytes = PAGE_SIZE-offset; - maddr = kmap_atomic(page, KM_USER_COPY); + if (page) + maddr = kmap_atomic(page, KM_USER_COPY); + else + maddr = kmap_atomic_nocache_pfn(pfn, KM_USER_COPY); if (copy == 2) { memset(maddr + offset, 0, bytes); copied = bytes; @@ -184,7 +195,8 @@ static int str_vm(unsigned long addr, void *buf0, int len, int copy) } BUG_ON(bytes < 0 || copied < 0); kunmap_atomic(maddr, KM_USER_COPY); - unpin_page(page); + if (page) + unpin_page(page); len -= copied; buf += copied; addr += copied; diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 16e6f88c2..27400b9ed 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -455,6 +455,28 @@ void *vmalloc(unsigned long size) EXPORT_SYMBOL(vmalloc); +/** + * vmalloc_exec - allocate virtually contiguous, executable memory + * + * @size: allocation size + * + * Kernel-internal function to allocate enough pages to cover @size + * the page level allocator and map them into contiguous and + * executable kernel virtual space. + * + * For tight cotrol over page level allocator and protection flags + * use __vmalloc() instead. + */ + +#ifndef PAGE_KERNEL_EXEC +# define PAGE_KERNEL_EXEC PAGE_KERNEL +#endif + +void *vmalloc_exec(unsigned long size) +{ + return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC); +} + /** * vmalloc_32 - allocate virtually contiguous memory (32bit addressable) * diff --git a/mm/vmscan.c b/mm/vmscan.c index 2a111c86b..da9e1853e 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -45,6 +45,11 @@ int vm_swappiness = 60; static long total_memory; + + +void try_to_clip_inodes(void); + + #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) #ifdef ARCH_HAS_PREFETCH @@ -1089,6 +1094,7 @@ int kswapd(void *p) prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&pgdat->kswapd_wait, &wait); + try_to_clip_inodes(); get_page_state(&ps); balance_pgdat(pgdat, 0, &ps); } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index db0931a9a..8b14637aa 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1066,8 +1066,8 @@ static int __init init_ipv4_mibs(void) { net_statistics[0] = alloc_percpu(struct linux_mib); net_statistics[1] = alloc_percpu(struct linux_mib); - ip_statistics[0] = alloc_percpu(struct ip_mib); - ip_statistics[1] = alloc_percpu(struct ip_mib); + ip_statistics[0] = alloc_percpu(struct ipstats_mib); + ip_statistics[1] = alloc_percpu(struct ipstats_mib); icmp_statistics[0] = alloc_percpu(struct icmp_mib); icmp_statistics[1] = alloc_percpu(struct icmp_mib); tcp_statistics[0] = alloc_percpu(struct tcp_mib); diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index f26d67ca6..be1e87c11 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -46,7 +46,7 @@ static inline int ip_forward_finish(struct sk_buff *skb) { struct ip_options * opt = &(IPCB(skb)->opt); - IP_INC_STATS_BH(IpForwDatagrams); + IP_INC_STATS_BH(OutForwDatagrams); if (unlikely(opt->optlen)) ip_forward_options(skb); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 375caffe0..1f007c67b 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -263,7 +263,7 @@ static void ip_evictor(void) spin_unlock(&qp->lock); ipq_put(qp); - IP_INC_STATS_BH(IpReasmFails); + IP_INC_STATS_BH(ReasmFails); } } @@ -281,8 +281,8 @@ static void ip_expire(unsigned long arg) ipq_kill(qp); - IP_INC_STATS_BH(IpReasmTimeout); - IP_INC_STATS_BH(IpReasmFails); + IP_INC_STATS_BH(ReasmTimeout); + IP_INC_STATS_BH(ReasmFails); if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) { struct sk_buff *head = qp->fragments; @@ -609,7 +609,7 @@ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev) iph = head->nh.iph; iph->frag_off = 0; iph->tot_len = htons(len); - IP_INC_STATS_BH(IpReasmOKs); + IP_INC_STATS_BH(ReasmOKs); qp->fragments = NULL; return head; @@ -625,7 +625,7 @@ out_oversize: "Oversized IP packet from %d.%d.%d.%d.\n", NIPQUAD(qp->saddr)); out_fail: - IP_INC_STATS_BH(IpReasmFails); + IP_INC_STATS_BH(ReasmFails); return NULL; } @@ -636,7 +636,7 @@ struct sk_buff *ip_defrag(struct sk_buff *skb) struct ipq *qp; struct net_device *dev; - IP_INC_STATS_BH(IpReasmReqds); + IP_INC_STATS_BH(ReasmReqds); /* Start by cleaning up the memory. */ if (atomic_read(&ip_frag_mem) > sysctl_ipfrag_high_thresh) @@ -661,7 +661,7 @@ struct sk_buff *ip_defrag(struct sk_buff *skb) return ret; } - IP_INC_STATS_BH(IpReasmFails); + IP_INC_STATS_BH(ReasmFails); kfree_skb(skb); return NULL; } diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 904f20aba..2f71ed5cf 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -150,7 +150,7 @@ * SNMP management statistics */ -DEFINE_SNMP_STAT(struct ip_mib, ip_statistics); +DEFINE_SNMP_STAT(struct ipstats_mib, ip_statistics); /* * Process Router Attention IP option @@ -249,16 +249,16 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) protocol = -ret; goto resubmit; } - IP_INC_STATS_BH(IpInDelivers); + IP_INC_STATS_BH(InDelivers); } else { if (!raw_sk) { if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { - IP_INC_STATS_BH(IpInUnknownProtos); + IP_INC_STATS_BH(InUnknownProtos); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); } } else - IP_INC_STATS_BH(IpInDelivers); + IP_INC_STATS_BH(InDelivers); kfree_skb(skb); } } @@ -324,7 +324,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb) */ if (skb_cow(skb, skb_headroom(skb))) { - IP_INC_STATS_BH(IpInDiscards); + IP_INC_STATS_BH(InDiscards); goto drop; } iph = skb->nh.iph; @@ -353,7 +353,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb) return dst_input(skb); inhdr_error: - IP_INC_STATS_BH(IpInHdrErrors); + IP_INC_STATS_BH(InHdrErrors); drop: kfree_skb(skb); return NET_RX_DROP; @@ -372,10 +372,10 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) if (skb->pkt_type == PACKET_OTHERHOST) goto drop; - IP_INC_STATS_BH(IpInReceives); + IP_INC_STATS_BH(InReceives); if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { - IP_INC_STATS_BH(IpInDiscards); + IP_INC_STATS_BH(InDiscards); goto out; } @@ -426,7 +426,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) ip_rcv_finish); inhdr_error: - IP_INC_STATS_BH(IpInHdrErrors); + IP_INC_STATS_BH(InHdrErrors); drop: kfree_skb(skb); out: diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 543dfba0b..84a3df368 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -232,7 +232,7 @@ int ip_mc_output(struct sk_buff *skb) /* * If the indicated interface is up and running, send the packet. */ - IP_INC_STATS(IpOutRequests); + IP_INC_STATS(OutRequests); skb->dev = dev; skb->protocol = htons(ETH_P_IP); @@ -255,7 +255,7 @@ int ip_mc_output(struct sk_buff *skb) && ((rt->rt_flags&RTCF_LOCAL) || !(IPCB(skb)->flags&IPSKB_FORWARDED)) #endif ) { - struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); + struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC); if (newskb) NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL, newskb->dev, @@ -271,7 +271,7 @@ int ip_mc_output(struct sk_buff *skb) } if (rt->rt_flags&RTCF_BROADCAST) { - struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); + struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC); if (newskb) NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL, newskb->dev, ip_dev_loopback_xmit); @@ -285,7 +285,7 @@ int ip_mc_output(struct sk_buff *skb) int ip_output(struct sk_buff *skb) { - IP_INC_STATS(IpOutRequests); + IP_INC_STATS(OutRequests); if ((skb->len > dst_pmtu(skb->dst) || skb_shinfo(skb)->frag_list) && !skb_shinfo(skb)->tso_size) @@ -390,7 +390,7 @@ packet_routed: dst_output); no_route: - IP_INC_STATS(IpOutNoRoutes); + IP_INC_STATS(OutNoRoutes); kfree_skb(skb); return -EHOSTUNREACH; } @@ -547,7 +547,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) } if (err == 0) { - IP_INC_STATS(IpFragOKs); + IP_INC_STATS(FragOKs); return 0; } @@ -556,7 +556,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) kfree_skb(frag); frag = skb; } - IP_INC_STATS(IpFragFails); + IP_INC_STATS(FragFails); return err; } @@ -662,7 +662,7 @@ slow_path: * Put this fragment into the sending queue. */ - IP_INC_STATS(IpFragCreates); + IP_INC_STATS(FragCreates); iph->tot_len = htons(len + hlen); @@ -673,12 +673,12 @@ slow_path: goto fail; } kfree_skb(skb); - IP_INC_STATS(IpFragOKs); + IP_INC_STATS(FragOKs); return err; fail: kfree_skb(skb); - IP_INC_STATS(IpFragFails); + IP_INC_STATS(FragFails); return err; } @@ -975,7 +975,7 @@ alloc_new_skb: error: inet->cork.length -= length; - IP_INC_STATS(IpOutDiscards); + IP_INC_STATS(OutDiscards); return err; } @@ -1088,7 +1088,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, error: inet->cork.length -= size; - IP_INC_STATS(IpOutDiscards); + IP_INC_STATS(OutDiscards); return err; } @@ -1198,7 +1198,7 @@ out: return err; error: - IP_INC_STATS(IpOutDiscards); + IP_INC_STATS(OutDiscards); goto out; } diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 2a5a7dfcf..57d84fa77 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -339,6 +339,7 @@ static void ipcomp_destroy(struct xfrm_state *x) struct ipcomp_data *ipcd = x->data; if (!ipcd) return; + xfrm_state_delete_tunnel(x); ipcomp_free_data(ipcd); kfree(ipcd); } diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 46f36a5c6..64ccce525 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1115,7 +1115,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) { struct ip_options * opt = &(IPCB(skb)->opt); - IP_INC_STATS_BH(IpForwDatagrams); + IP_INC_STATS_BH(OutForwDatagrams); if (unlikely(opt->optlen)) ip_forward_options(skb); @@ -1178,7 +1178,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) to blackhole. */ - IP_INC_STATS_BH(IpFragFails); + IP_INC_STATS_BH(FragFails); ip_rt_put(rt); goto out_free; } diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 416e2e552..be47cbec5 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -88,7 +88,7 @@ static struct file_operations sockstat_seq_fops = { }; static unsigned long -fold_field(void *mib[], int nr) +__fold_field(void *mib[], int offt) { unsigned long res = 0; int i; @@ -98,14 +98,41 @@ fold_field(void *mib[], int nr) continue; res += *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) + - sizeof (unsigned long) * nr)); + offt)); res += *((unsigned long *) (((void *) per_cpu_ptr(mib[1], i)) + - sizeof (unsigned long) * nr)); + offt)); } return res; } +#define fold_field(_mib, _nr) __fold_field(_mib, (sizeof(unsigned long) * (_nr))) + +/* snmp items */ +static struct snmp_item snmp4_ipstats_list[] = { +#define __SNMP_GEN(x,y) SNMP_ITEM(struct ipstats_mib, x, y) +#define SNMP_GEN(x) __SNMP_GEN(x, #x) + SNMP_GEN(InReceives), + SNMP_GEN(InHdrErrors), + SNMP_GEN(InAddrErrors), + __SNMP_GEN(OutForwDatagrams,"ForwDatagrams"), /* for backward compatibility */ + SNMP_GEN(InUnknownProtos), + SNMP_GEN(InDiscards), + SNMP_GEN(InDelivers), + SNMP_GEN(OutRequests), + SNMP_GEN(OutDiscards), + SNMP_GEN(OutNoRoutes), + SNMP_GEN(ReasmTimeout), + SNMP_GEN(ReasmReqds), + SNMP_GEN(ReasmOKs), + SNMP_GEN(ReasmFails), + SNMP_GEN(FragOKs), + SNMP_GEN(FragFails), + SNMP_GEN(FragCreates), + SNMP_ITEM_SENTINEL +#undef SNMP_GEN +}; + /* * Called from the PROCfs module. This outputs /proc/net/snmp. */ @@ -113,17 +140,18 @@ static int snmp_seq_show(struct seq_file *seq, void *v) { int i; - seq_printf(seq, "Ip: Forwarding DefaultTTL InReceives InHdrErrors " - "InAddrErrors ForwDatagrams InUnknownProtos " - "InDiscards InDelivers OutRequests OutDiscards " - "OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs " - "ReasmFails FragOKs FragFails FragCreates\nIp: %d %d", + seq_printf(seq, "Ip: Forwarding DefaultTTL"); + + for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) + seq_printf(seq, " %s", snmp4_ipstats_list[i].name); + + seq_printf(seq, "\nIp: %d %d", ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl); - for (i = 0; - i < offsetof(struct ip_mib, __pad) / sizeof(unsigned long); i++) + for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) seq_printf(seq, " %lu", - fold_field((void **) ip_statistics, i)); + __fold_field((void **) ip_statistics, + snmp4_ipstats_list[i].offset)); seq_printf(seq, "\nIcmp: InMsgs InErrors InDestUnreachs InTimeExcds " "InParmProbs InSrcQuenchs InRedirects InEchos " diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 755d53aae..8bae6ee8a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -319,7 +319,7 @@ error_fault: err = -EFAULT; kfree_skb(skb); error: - IP_INC_STATS(IpOutDiscards); + IP_INC_STATS(OutDiscards); return err; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 5bdc2809c..6e7cbd378 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1040,6 +1040,8 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, rt->u.dst.child = NULL; if (rt->u.dst.dev) dev_hold(rt->u.dst.dev); + if (rt->idev) + in_dev_hold(rt->idev); rt->u.dst.obsolete = 0; rt->u.dst.lastuse = jiffies; rt->u.dst.path = &rt->u.dst; @@ -1321,11 +1323,17 @@ static void ipv4_dst_destroy(struct dst_entry *dst) { struct rtable *rt = (struct rtable *) dst; struct inet_peer *peer = rt->peer; + struct in_device *idev = rt->idev; if (peer) { rt->peer = NULL; inet_putpeer(peer); } + + if (idev) { + rt->idev = NULL; + in_dev_put(idev); + } } static void ipv4_link_failure(struct sk_buff *skb) @@ -1486,6 +1494,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr, rth->fl.iif = dev->ifindex; rth->u.dst.dev = &loopback_dev; dev_hold(rth->u.dst.dev); + rth->idev = in_dev_get(rth->u.dst.dev); rth->fl.oif = 0; rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; @@ -1695,6 +1704,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, rth->fl.iif = dev->ifindex; rth->u.dst.dev = out_dev->dev; dev_hold(rth->u.dst.dev); + rth->idev = in_dev_get(rth->u.dst.dev); rth->fl.oif = 0; rth->rt_spec_dst= spec_dst; @@ -1774,6 +1784,7 @@ local_input: rth->fl.iif = dev->ifindex; rth->u.dst.dev = &loopback_dev; dev_hold(rth->u.dst.dev); + rth->idev = in_dev_get(rth->u.dst.dev); rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->u.dst.input= ip_local_deliver; @@ -2157,6 +2168,7 @@ make_route: rth->rt_iif = oldflp->oif ? : dev_out->ifindex; rth->u.dst.dev = dev_out; dev_hold(dev_out); + rth->idev = in_dev_get(dev_out); rth->rt_gateway = fl.fl4_dst; rth->rt_spec_dst= fl.fl4_src; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 87b73c85f..5eeae6dc0 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1290,12 +1290,12 @@ static struct dst_entry* tcp_v4_route_req(struct sock *sk, .dport = req->rmt_port } } }; if (ip_route_output_flow(&rt, &fl, sk, 0)) { - IP_INC_STATS_BH(IpOutNoRoutes); + IP_INC_STATS_BH(OutNoRoutes); return NULL; } if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway) { ip_rt_put(rt); - IP_INC_STATS_BH(IpOutNoRoutes); + IP_INC_STATS_BH(OutNoRoutes); return NULL; } return &rt->u.dst; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e91d4f51c..33e39d220 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -667,14 +667,14 @@ snmp6_mib_free(void *ptr[2]) static int __init init_ipv6_mibs(void) { - if (snmp6_mib_init((void **)ipv6_statistics, sizeof (struct ipv6_mib), - __alignof__(struct ipv6_mib)) < 0) + if (snmp6_mib_init((void **)ipv6_statistics, sizeof (struct ipstats_mib), + __alignof__(struct ipstats_mib)) < 0) goto err_ip_mib; if (snmp6_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib), - __alignof__(struct ipv6_mib)) < 0) + __alignof__(struct icmpv6_mib)) < 0) goto err_icmp_mib; if (snmp6_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib), - __alignof__(struct ipv6_mib)) < 0) + __alignof__(struct udp_mib)) < 0) goto err_udp_mib; return 0; diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 24286b940..a5fd7d644 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -159,7 +159,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp) if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); kfree_skb(skb); return -1; } @@ -172,7 +172,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp) return 1; } - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); return -1; } @@ -227,7 +227,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp) if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); kfree_skb(skb); return -1; } @@ -236,7 +236,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp) if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || skb->pkt_type != PACKET_HOST) { - IP6_INC_STATS_BH(Ip6InAddrErrors); + IP6_INC_STATS_BH(InAddrErrors); kfree_skb(skb); return -1; } @@ -252,13 +252,13 @@ looped_back: } if (hdr->type != IPV6_SRCRT_TYPE_0) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); return -1; } if (hdr->hdrlen & 0x01) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); return -1; } @@ -271,7 +271,7 @@ looped_back: n = hdr->hdrlen >> 1; if (hdr->segments_left > n) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw); return -1; } @@ -284,7 +284,7 @@ looped_back: kfree_skb(skb); /* the copy is a forwarded packet */ if (skb2 == NULL) { - IP6_INC_STATS_BH(Ip6OutDiscards); + IP6_INC_STATS_BH(OutDiscards); return -1; } *skbp = skb = skb2; @@ -302,7 +302,7 @@ looped_back: addr += i - 1; if (ipv6_addr_is_multicast(addr)) { - IP6_INC_STATS_BH(Ip6InAddrErrors); + IP6_INC_STATS_BH(InAddrErrors); kfree_skb(skb); return -1; } @@ -319,7 +319,7 @@ looped_back: } if (skb->dst->dev->flags&IFF_LOOPBACK) { if (skb->nh.ipv6h->hop_limit <= 1) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0, skb->dev); kfree_skb(skb); @@ -436,24 +436,24 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { LIMIT_NETDEBUG( printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1])); - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); goto drop; } pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2)); if (pkt_len <= IPV6_MAXPLEN) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); return 0; } if (skb->nh.ipv6h->payload_len) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); return 0; } if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { - IP6_INC_STATS_BH(Ip6InTruncatedPkts); + IP6_INC_STATS_BH(InTruncatedPkts); goto drop; } if (pkt_len + sizeof(struct ipv6hdr) < skb->len) { diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 24e3def47..cfecd15d9 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -174,7 +174,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type, */ dst = ip6_route_output(sk, fl); if (dst->error) { - IP6_INC_STATS(Ip6OutNoRoutes); + IP6_INC_STATS(OutNoRoutes); } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { res = 1; } else { diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index a274679a8..61695f33b 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -64,10 +64,10 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt if (skb->pkt_type == PACKET_OTHERHOST) goto drop; - IP6_INC_STATS_BH(Ip6InReceives); + IP6_INC_STATS_BH(InReceives); if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { - IP6_INC_STATS_BH(Ip6InDiscards); + IP6_INC_STATS_BH(InDiscards); goto out; } @@ -80,7 +80,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt goto err; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); goto drop; } @@ -97,7 +97,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt goto truncated; if (pkt_len + sizeof(struct ipv6hdr) < skb->len) { if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr))){ - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); goto drop; } hdr = skb->nh.ipv6h; @@ -109,7 +109,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt if (hdr->nexthdr == NEXTHDR_HOP) { skb->h.raw = (u8*)(hdr+1); if (ipv6_parse_hopopts(skb, offsetof(struct ipv6hdr, nexthdr)) < 0) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); return 0; } hdr = skb->nh.ipv6h; @@ -117,9 +117,9 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); truncated: - IP6_INC_STATS_BH(Ip6InTruncatedPkts); + IP6_INC_STATS_BH(InTruncatedPkts); err: - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); drop: kfree_skb(skb); out: @@ -194,15 +194,15 @@ resubmit: if (ret > 0) goto resubmit; else if (ret == 0) - IP6_INC_STATS_BH(Ip6InDelivers); + IP6_INC_STATS_BH(InDelivers); } else { if (!raw_sk) { if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { - IP6_INC_STATS_BH(Ip6InUnknownProtos); + IP6_INC_STATS_BH(InUnknownProtos); icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff); } } else { - IP6_INC_STATS_BH(Ip6InDelivers); + IP6_INC_STATS_BH(InDelivers); kfree_skb(skb); } } @@ -210,7 +210,7 @@ resubmit: return 0; discard: - IP6_INC_STATS_BH(Ip6InDiscards); + IP6_INC_STATS_BH(InDiscards); rcu_read_unlock(); kfree_skb(skb); return 0; @@ -227,7 +227,7 @@ int ip6_mc_input(struct sk_buff *skb) struct ipv6hdr *hdr; int deliver; - IP6_INC_STATS_BH(Ip6InMcastPkts); + IP6_INC_STATS_BH(InMcastPkts); hdr = skb->nh.ipv6h; deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d6f0db4aa..4f48168ab 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -87,7 +87,7 @@ static inline int ip6_output_finish(struct sk_buff *skb) } else if (dst->neighbour) return dst->neighbour->output(skb); - IP6_INC_STATS_BH(Ip6OutNoRoutes); + IP6_INC_STATS_BH(OutNoRoutes); kfree_skb(skb); return -EINVAL; @@ -121,7 +121,7 @@ int ip6_output2(struct sk_buff *skb) if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr, &skb->nh.ipv6h->saddr)) { - struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); + struct sk_buff *newskb = skb_copy(skb, GFP_ATOMIC); /* Do not check for IFF_ALLMULTI; multicast routing is not supported in any case. @@ -132,13 +132,13 @@ int ip6_output2(struct sk_buff *skb) ip6_dev_loopback_xmit); if (skb->nh.ipv6h->hop_limit == 0) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); kfree_skb(skb); return 0; } } - IP6_INC_STATS(Ip6OutMcastPkts); + IP6_INC_STATS(OutMcastPkts); } return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish); @@ -169,7 +169,7 @@ int ip6_route_me_harder(struct sk_buff *skb) dst = ip6_route_output(skb->sk, &fl); if (dst->error) { - IP6_INC_STATS(Ip6OutNoRoutes); + IP6_INC_STATS(OutNoRoutes); LIMIT_NETDEBUG( printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n")); dst_release(dst); @@ -228,7 +228,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, kfree_skb(skb); skb = skb2; if (skb == NULL) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); return -ENOBUFS; } if (sk) @@ -262,7 +262,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, mtu = dst_pmtu(dst); if ((skb->len <= mtu) || ipfragok) { - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute); } @@ -270,7 +270,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(FragFails); kfree_skb(skb); return -EMSGSIZE; } @@ -352,7 +352,7 @@ int ip6_forward(struct sk_buff *skb) goto error; if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { - IP6_INC_STATS(Ip6InDiscards); + IP6_INC_STATS(InDiscards); goto drop; } @@ -391,7 +391,7 @@ int ip6_forward(struct sk_buff *skb) } if (!xfrm6_route_forward(skb)) { - IP6_INC_STATS(Ip6InDiscards); + IP6_INC_STATS(InDiscards); goto drop; } @@ -429,14 +429,14 @@ int ip6_forward(struct sk_buff *skb) /* Again, force OUTPUT device used as source address */ skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_pmtu(dst), skb->dev); - IP6_INC_STATS_BH(Ip6InTooBigErrors); - IP6_INC_STATS_BH(Ip6FragFails); + IP6_INC_STATS_BH(InTooBigErrors); + IP6_INC_STATS_BH(FragFails); kfree_skb(skb); return -EMSGSIZE; } if (skb_cow(skb, dst->dev->hard_header_len)) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); goto drop; } @@ -446,11 +446,11 @@ int ip6_forward(struct sk_buff *skb) hdr->hop_limit--; - IP6_INC_STATS_BH(Ip6OutForwDatagrams); + IP6_INC_STATS_BH(OutForwDatagrams); return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish); error: - IP6_INC_STATS_BH(Ip6InAddrErrors); + IP6_INC_STATS_BH(InAddrErrors); drop: kfree_skb(skb); return -EINVAL; @@ -563,7 +563,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) tmp_hdr = kmalloc(hlen, GFP_ATOMIC); if (!tmp_hdr) { - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(FragFails); return -ENOMEM; } @@ -618,7 +618,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) kfree(tmp_hdr); if (err == 0) { - IP6_INC_STATS(Ip6FragOKs); + IP6_INC_STATS(FragOKs); return 0; } @@ -628,7 +628,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) frag = skb; } - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(FragFails); return err; } @@ -661,7 +661,7 @@ slow_path: if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n")); - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(FragFails); err = -ENOMEM; goto fail; } @@ -719,19 +719,19 @@ slow_path: * Put this fragment into the sending queue. */ - IP6_INC_STATS(Ip6FragCreates); + IP6_INC_STATS(FragCreates); err = output(frag); if (err) goto fail; } kfree_skb(skb); - IP6_INC_STATS(Ip6FragOKs); + IP6_INC_STATS(FragOKs); return err; fail: kfree_skb(skb); - IP6_INC_STATS(Ip6FragFails); + IP6_INC_STATS(FragFails); return err; } @@ -1016,7 +1016,7 @@ alloc_new_skb: return 0; error: inet->cork.length -= length; - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); return err; } @@ -1076,7 +1076,7 @@ int ip6_push_pending_frames(struct sock *sk) ipv6_addr_copy(&hdr->daddr, final_dst); skb->dst = dst_clone(&rt->u.dst); - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); if (err) { if (err > 0) @@ -1108,7 +1108,7 @@ void ip6_flush_pending_frames(struct sock *sk) struct sk_buff *skb; while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); kfree_skb(skb); } diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 420189ddc..73cc1dd09 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -55,7 +55,7 @@ #include -DEFINE_SNMP_STAT(struct ipv6_mib, ipv6_statistics); +DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); static struct packet_type ipv6_packet_type = { .type = __constant_htons(ETH_P_IPV6), diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 13be01672..b35114577 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1317,7 +1317,7 @@ static void mld_sendpack(struct sk_buff *skb) struct inet6_dev *idev = in6_dev_get(skb->dev); int err; - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h - sizeof(struct ipv6hdr); mldlen = skb->tail - skb->h.raw; @@ -1329,9 +1329,9 @@ static void mld_sendpack(struct sk_buff *skb) dev_queue_xmit); if (!err) { ICMP6_INC_STATS(idev,Icmp6OutMsgs); - IP6_INC_STATS(Ip6OutMcastPkts); + IP6_INC_STATS(OutMcastPkts); } else - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); if (likely(idev != NULL)) in6_dev_put(idev); @@ -1613,7 +1613,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) IPV6_TLV_ROUTERALERT, 2, 0, 0, IPV6_TLV_PADN, 0 }; - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); snd_addr = addr; if (type == ICMPV6_MGM_REDUCTION) { snd_addr = &all_routers; @@ -1627,7 +1627,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err); if (skb == NULL) { - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); return; } @@ -1672,16 +1672,16 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) else ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses); ICMP6_INC_STATS(idev, Icmp6OutMsgs); - IP6_INC_STATS(Ip6OutMcastPkts); + IP6_INC_STATS(OutMcastPkts); } else - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); if (likely(idev != NULL)) in6_dev_put(idev); return; out: - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); kfree_skb(skb); } diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 3de845af2..aa6b74d9b 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -452,7 +452,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, skb->dst = dst; idev = in6_dev_get(dst->dev); - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); if (!err) { ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements); @@ -536,7 +536,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, /* send it! */ skb->dst = dst; idev = in6_dev_get(dst->dev); - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); if (!err) { ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits); @@ -609,7 +609,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, /* send it! */ skb->dst = dst; idev = in6_dev_get(dst->dev); - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); if (!err) { ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits); @@ -1335,7 +1335,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, buff->dst = dst; idev = in6_dev_get(dst->dev); - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output); if (!err) { ICMP6_INC_STATS(idev, Icmp6OutRedirects); diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index e6e4621f5..fda6285ef 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -57,43 +57,36 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v) return 0; } -struct snmp6_item -{ - char *name; - int offset; -}; -#define SNMP6_SENTINEL { .name = NULL, .offset = 0 } - -static struct snmp6_item snmp6_ipv6_list[] = { +static struct snmp_item snmp6_ipstats_list[] = { /* ipv6 mib according to RFC 2465 */ -#define SNMP6_GEN(x) { .name = #x , .offset = offsetof(struct ipv6_mib, x) } - SNMP6_GEN(Ip6InReceives), - SNMP6_GEN(Ip6InHdrErrors), - SNMP6_GEN(Ip6InTooBigErrors), - SNMP6_GEN(Ip6InNoRoutes), - SNMP6_GEN(Ip6InAddrErrors), - SNMP6_GEN(Ip6InUnknownProtos), - SNMP6_GEN(Ip6InTruncatedPkts), - SNMP6_GEN(Ip6InDiscards), - SNMP6_GEN(Ip6InDelivers), - SNMP6_GEN(Ip6OutForwDatagrams), - SNMP6_GEN(Ip6OutRequests), - SNMP6_GEN(Ip6OutDiscards), - SNMP6_GEN(Ip6OutNoRoutes), - SNMP6_GEN(Ip6ReasmTimeout), - SNMP6_GEN(Ip6ReasmReqds), - SNMP6_GEN(Ip6ReasmOKs), - SNMP6_GEN(Ip6ReasmFails), - SNMP6_GEN(Ip6FragOKs), - SNMP6_GEN(Ip6FragFails), - SNMP6_GEN(Ip6FragCreates), - SNMP6_GEN(Ip6InMcastPkts), - SNMP6_GEN(Ip6OutMcastPkts), +#define SNMP6_GEN(x) SNMP_ITEM(struct ipstats_mib, x, "Ip6" #x) + SNMP6_GEN(InReceives), + SNMP6_GEN(InHdrErrors), + SNMP6_GEN(InTooBigErrors), + SNMP6_GEN(InNoRoutes), + SNMP6_GEN(InAddrErrors), + SNMP6_GEN(InUnknownProtos), + SNMP6_GEN(InTruncatedPkts), + SNMP6_GEN(InDiscards), + SNMP6_GEN(InDelivers), + SNMP6_GEN(OutForwDatagrams), + SNMP6_GEN(OutRequests), + SNMP6_GEN(OutDiscards), + SNMP6_GEN(OutNoRoutes), + SNMP6_GEN(ReasmTimeout), + SNMP6_GEN(ReasmReqds), + SNMP6_GEN(ReasmOKs), + SNMP6_GEN(ReasmFails), + SNMP6_GEN(FragOKs), + SNMP6_GEN(FragFails), + SNMP6_GEN(FragCreates), + SNMP6_GEN(InMcastPkts), + SNMP6_GEN(OutMcastPkts), #undef SNMP6_GEN - SNMP6_SENTINEL + SNMP_ITEM_SENTINEL }; -static struct snmp6_item snmp6_icmp6_list[] = { +static struct snmp_item snmp6_icmp6_list[] = { /* icmpv6 mib according to RFC 2466 Exceptions: {In|Out}AdminProhibs are removed, because I see @@ -104,7 +97,7 @@ static struct snmp6_item snmp6_icmp6_list[] = { OutRouterAdvertisements too. OutGroupMembQueries too. */ -#define SNMP6_GEN(x) { .name = #x , .offset = offsetof(struct icmpv6_mib, x) } +#define SNMP6_GEN(x) SNMP_ITEM(struct icmpv6_mib, x, #x) SNMP6_GEN(Icmp6InMsgs), SNMP6_GEN(Icmp6InErrors), SNMP6_GEN(Icmp6InDestUnreachs), @@ -134,17 +127,17 @@ static struct snmp6_item snmp6_icmp6_list[] = { SNMP6_GEN(Icmp6OutGroupMembResponses), SNMP6_GEN(Icmp6OutGroupMembReductions), #undef SNMP6_GEN - SNMP6_SENTINEL + SNMP_ITEM_SENTINEL }; -static struct snmp6_item snmp6_udp6_list[] = { -#define SNMP6_GEN(x) { .name = "Udp6" #x , .offset = offsetof(struct udp_mib, Udp##x) } +static struct snmp_item snmp6_udp6_list[] = { +#define SNMP6_GEN(x) SNMP_ITEM(struct udp_mib, Udp##x, "Udp6" #x) SNMP6_GEN(InDatagrams), SNMP6_GEN(NoPorts), SNMP6_GEN(InErrors), SNMP6_GEN(OutDatagrams), #undef SNMP6_GEN - SNMP6_SENTINEL + SNMP_ITEM_SENTINEL }; static unsigned long @@ -167,7 +160,7 @@ fold_field(void *mib[], int offt) } static inline void -snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp6_item *itemlist) +snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_item *itemlist) { int i; for (i=0; itemlist[i].name; i++) @@ -183,7 +176,7 @@ static int snmp6_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); } else { - snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipv6_list); + snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 0bc3b5f18..3d2961c48 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -535,7 +535,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, if (err) goto error_fault; - IP6_INC_STATS(Ip6OutRequests); + IP6_INC_STATS(OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); if (err > 0) @@ -549,7 +549,7 @@ error_fault: err = -EFAULT; kfree_skb(skb); error: - IP6_INC_STATS(Ip6OutDiscards); + IP6_INC_STATS(OutDiscards); return err; } static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 1ee91bff2..ccee9877c 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -284,7 +284,7 @@ static void ip6_evictor(void) spin_unlock(&fq->lock); fq_put(fq); - IP6_INC_STATS_BH(Ip6ReasmFails); + IP6_INC_STATS_BH(ReasmFails); } } @@ -299,8 +299,8 @@ static void ip6_frag_expire(unsigned long data) fq_kill(fq); - IP6_INC_STATS_BH(Ip6ReasmTimeout); - IP6_INC_STATS_BH(Ip6ReasmFails); + IP6_INC_STATS_BH(ReasmTimeout); + IP6_INC_STATS_BH(ReasmFails); /* Send error only if the first segment arrived. */ if (fq->last_in&FIRST_IN && fq->fragments) { @@ -386,7 +386,7 @@ ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr return ip6_frag_intern(hash, fq); oom: - IP6_INC_STATS_BH(Ip6ReasmFails); + IP6_INC_STATS_BH(ReasmFails); return NULL; } @@ -426,7 +426,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1))); if ((unsigned int)end > IPV6_MAXPLEN) { - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw); return; } @@ -453,7 +453,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, /* RFC2460 says always send parameter problem in * this case. -DaveM */ - IP6_INC_STATS_BH(Ip6InHdrErrors); + IP6_INC_STATS_BH(InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, offsetof(struct ipv6hdr, payload_len)); return; @@ -572,7 +572,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, return; err: - IP6_INC_STATS(Ip6ReasmFails); + IP6_INC_STATS(ReasmFails); kfree_skb(skb); } @@ -666,7 +666,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in, if (head->ip_summed == CHECKSUM_HW) head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum); - IP6_INC_STATS_BH(Ip6ReasmOKs); + IP6_INC_STATS_BH(ReasmOKs); fq->fragments = NULL; *nhoffp = nhoff; return 1; @@ -679,7 +679,7 @@ out_oom: if (net_ratelimit()) printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); out_fail: - IP6_INC_STATS_BH(Ip6ReasmFails); + IP6_INC_STATS_BH(ReasmFails); return -1; } @@ -693,16 +693,16 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp) hdr = skb->nh.ipv6h; - IP6_INC_STATS_BH(Ip6ReasmReqds); + IP6_INC_STATS_BH(ReasmReqds); /* Jumbo payload inhibits frag. header */ if (hdr->payload_len==0) { - IP6_INC_STATS(Ip6InHdrErrors); + IP6_INC_STATS(InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw); return -1; } if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) { - IP6_INC_STATS(Ip6InHdrErrors); + IP6_INC_STATS(InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw); return -1; } @@ -713,7 +713,7 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp) if (!(fhdr->frag_off & htons(0xFFF9))) { /* It is not a fragmented frame */ skb->h.raw += sizeof(struct frag_hdr); - IP6_INC_STATS_BH(Ip6ReasmOKs); + IP6_INC_STATS_BH(ReasmOKs); *nhoffp = (u8*)fhdr - skb->nh.raw; return 1; @@ -738,7 +738,7 @@ static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp) return ret; } - IP6_INC_STATS_BH(Ip6ReasmFails); + IP6_INC_STATS_BH(ReasmFails); kfree_skb(skb); return -1; } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 03863849e..18057ed15 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -83,6 +83,7 @@ static int ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static struct dst_entry *ip6_negative_advice(struct dst_entry *); +static void ip6_dst_destroy(struct dst_entry *); static int ip6_dst_gc(void); static int ip6_pkt_discard(struct sk_buff *skb); @@ -95,6 +96,7 @@ static struct dst_ops ip6_dst_ops = { .gc = ip6_dst_gc, .gc_thresh = 1024, .check = ip6_dst_check, + .destroy = ip6_dst_destroy, .negative_advice = ip6_negative_advice, .link_failure = ip6_link_failure, .update_pmtu = ip6_rt_update_pmtu, @@ -134,7 +136,15 @@ rwlock_t rt6_lock = RW_LOCK_UNLOCKED; /* allocate dst with ip6_dst_ops */ static __inline__ struct rt6_info *ip6_dst_alloc(void) { - return dst_alloc(&ip6_dst_ops); + return (struct rt6_info *)dst_alloc(&ip6_dst_ops); +} + +static void ip6_dst_destroy(struct dst_entry *dst) +{ + struct rt6_info *rt = (struct rt6_info *)dst; + if (rt->rt6i_idev != NULL) + in6_dev_put(rt->rt6i_idev); + } /* @@ -573,14 +583,14 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev, if (unlikely(rt == NULL)) goto out; - if (dev) - dev_hold(dev); + dev_hold(dev); if (neigh) neigh_hold(neigh); else neigh = ndisc_get_neigh(dev, addr); rt->rt6i_dev = dev; + rt->rt6i_idev = in6_dev_get(dev); rt->rt6i_nexthop = neigh; rt->rt6i_expires = 0; rt->rt6i_flags = RTF_LOCAL; @@ -714,6 +724,12 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr) if (rtmsg->rtmsg_src_len) return -EINVAL; #endif + if (rtmsg->rtmsg_ifindex) { + dev = dev_get_by_index(rtmsg->rtmsg_ifindex); + if (!dev) + return -ENODEV; + } + if (rtmsg->rtmsg_metric == 0) rtmsg->rtmsg_metric = IP6_RT_PRIO_USER; @@ -739,13 +755,6 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr) rt->u.dst.output = ip6_output; - if (rtmsg->rtmsg_ifindex) { - dev = dev_get_by_index(rtmsg->rtmsg_ifindex); - err = -ENODEV; - if (dev == NULL) - goto out; - } - ipv6_addr_prefix(&rt->rt6i_dst.addr, &rtmsg->rtmsg_dst, rtmsg->rtmsg_dst_len); rt->rt6i_dst.plen = rtmsg->rtmsg_dst_len; @@ -872,6 +881,7 @@ install_route: if (!rt->u.dst.metrics[RTAX_ADVMSS-1]) rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst)); rt->u.dst.dev = dev; + rt->rt6i_idev = in6_dev_get(dev); return rt6_ins(rt, nlh, _rtattr); out: @@ -1138,6 +1148,9 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) rt->u.dst.dev = ort->u.dst.dev; if (rt->u.dst.dev) dev_hold(rt->u.dst.dev); + rt->rt6i_idev = ort->rt6i_idev; + if (rt->rt6i_idev) + in6_dev_hold(rt->rt6i_idev); rt->u.dst.lastuse = jiffies; rt->rt6i_expires = 0; @@ -1259,7 +1272,7 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg) int ip6_pkt_discard(struct sk_buff *skb) { - IP6_INC_STATS(Ip6OutNoRoutes); + IP6_INC_STATS(OutNoRoutes); icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev); kfree_skb(skb); return 0; @@ -1282,6 +1295,7 @@ int ip6_rt_addr_add(struct in6_addr *addr, struct net_device *dev, int anycast) rt->u.dst.input = ip6_input; rt->u.dst.output = ip6_output; rt->rt6i_dev = &loopback_dev; + rt->rt6i_idev = in6_dev_get(&loopback_dev); rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst)); rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ipv6_get_hoplimit(rt->rt6i_dev); diff --git a/net/sctp/output.c b/net/sctp/output.c index 6d45e05c1..d54f915ae 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -496,7 +496,7 @@ out: return err; no_route: kfree_skb(nskb); - IP_INC_STATS_BH(IpOutNoRoutes); + IP_INC_STATS_BH(OutNoRoutes); /* FIXME: Returning the 'err' will effect all the associations * associated with a socket, although only one of the paths of the diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 86814653c..44cb5240f 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -231,7 +231,6 @@ static void __xfrm_state_delete(struct xfrm_state *x) void xfrm_state_delete(struct xfrm_state *x) { - xfrm_state_delete_tunnel(x); spin_lock_bh(&x->lock); __xfrm_state_delete(x); spin_unlock_bh(&x->lock); diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index be4d39864..8819822d8 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig @@ -1,6 +1,6 @@ config SECURITY_SELINUX bool "NSA SELinux Support" - depends on SECURITY + depends on SECURITY && NET default n help This selects NSA Security-Enhanced Linux (SELinux). diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 155dec41f..35d779a21 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -83,7 +83,7 @@ __setup("enforcing=", enforcing_setup); #endif #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM -int selinux_enabled = 0; +int selinux_enabled = 1; static int __init selinux_enabled_setup(char *str) { -- 2.47.0