From f1fddfb99c45201eb935879ef8322d166983c77b Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Thu, 14 Feb 2008 10:45:20 -0800 Subject: [PATCH] --- yaml --- r: 85675 b: refs/heads/master c: 08f01058fe8fcf0d4d69d96d667c51d52859b31d h: refs/heads/master i: 85673: 20f4bb1b0268c0b22feef2f660a8c017fc8fdc90 85671: 22ad79b252b38df3df9d70b293e46c14fec6491e v: v3 --- [refs] | 2 +- trunk/Documentation/00-INDEX | 2 - trunk/Documentation/cpuidle/core.txt | 23 - trunk/Documentation/cpuidle/driver.txt | 31 - trunk/Documentation/cpuidle/governor.txt | 29 - trunk/Documentation/cpuidle/sysfs.txt | 79 - trunk/MAINTAINERS | 9 +- trunk/Makefile | 4 +- trunk/arch/alpha/kernel/osf_sys.c | 4 +- trunk/arch/blackfin/kernel/traps.c | 12 +- trunk/arch/cris/arch-v10/lib/memset.c | 397 ++- trunk/arch/cris/arch-v32/lib/memset.c | 398 ++- trunk/arch/m68knommu/platform/5206/Makefile | 4 +- trunk/arch/m68knommu/platform/5206e/Makefile | 4 +- trunk/arch/m68knommu/platform/520x/Makefile | 4 +- trunk/arch/m68knommu/platform/523x/Makefile | 4 +- trunk/arch/m68knommu/platform/5249/Makefile | 4 +- trunk/arch/m68knommu/platform/5272/Makefile | 4 +- trunk/arch/m68knommu/platform/527x/Makefile | 4 +- trunk/arch/m68knommu/platform/528x/Makefile | 4 +- trunk/arch/m68knommu/platform/5307/Makefile | 4 +- trunk/arch/m68knommu/platform/532x/Makefile | 4 +- trunk/arch/m68knommu/platform/5407/Makefile | 4 +- .../arch/m68knommu/platform/coldfire/Makefile | 4 +- .../arch/m68knommu/platform/coldfire/entry.S | 9 +- .../arch/m68knommu/platform/coldfire/timers.c | 17 +- trunk/arch/mips/kernel/sysirix.c | 12 +- trunk/arch/parisc/hpux/sys_hpux.c | 4 +- trunk/arch/powerpc/Kconfig | 4 + trunk/arch/powerpc/boot/Makefile | 2 - trunk/arch/powerpc/boot/ps3-hvcall.S | 2 +- trunk/arch/powerpc/kernel/Makefile | 2 - trunk/arch/powerpc/kernel/process.c | 2 +- trunk/arch/powerpc/kernel/vdso.c | 12 +- .../powerpc/oprofile/cell/spu_task_sync.c | 15 +- trunk/arch/powerpc/platforms/512x/Kconfig | 1 + trunk/arch/powerpc/platforms/52xx/Kconfig | 2 + trunk/arch/powerpc/platforms/Kconfig | 2 + trunk/arch/powerpc/platforms/Kconfig.cputype | 4 + trunk/arch/powerpc/platforms/cell/ras.c | 11 +- .../arch/powerpc/platforms/cell/spufs/inode.c | 18 +- .../powerpc/platforms/cell/spufs/syscalls.c | 2 +- .../powerpc/platforms/embedded6xx/Kconfig | 4 + trunk/arch/powerpc/platforms/iseries/vio.c | 2 +- trunk/arch/sh/Kconfig | 19 - trunk/arch/sh/Kconfig.cpu | 4 +- trunk/arch/sh/Kconfig.debug | 3 +- trunk/arch/sh/Makefile | 1 - trunk/arch/sh/boards/renesas/migor/Makefile | 1 - trunk/arch/sh/boards/renesas/migor/setup.c | 61 - trunk/arch/sh/boards/renesas/r7780rp/setup.c | 47 +- .../arch/sh/boards/renesas/rts7751r2d/setup.c | 45 +- trunk/arch/sh/boards/renesas/sdk7780/Kconfig | 7 + trunk/arch/sh/cchips/hd6446x/hd64465/setup.c | 47 +- trunk/arch/sh/configs/migor_defconfig | 824 ----- trunk/arch/sh/configs/rts7751r2d1_defconfig | 340 +- .../arch/sh/configs/rts7751r2dplus_defconfig | 340 +- trunk/arch/sh/configs/se7705_defconfig | 1 + trunk/arch/sh/drivers/dma/dma-api.c | 2 +- trunk/arch/sh/drivers/pci/fixups-lboxre2.c | 4 +- trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c | 4 +- trunk/arch/sh/drivers/pci/ops-dreamcast.c | 44 +- trunk/arch/sh/drivers/pci/ops-rts7751r2d.c | 3 +- trunk/arch/sh/drivers/pci/pci-sh4.h | 4 +- trunk/arch/sh/drivers/pci/pci-sh7751.c | 16 +- trunk/arch/sh/drivers/pci/pci-sh7780.c | 2 +- trunk/arch/sh/kernel/Makefile_32 | 1 - trunk/arch/sh/kernel/Makefile_64 | 1 - trunk/arch/sh/kernel/cpu/irq/Makefile | 1 + trunk/arch/sh/kernel/cpu/irq/intc-sh5.c | 27 +- trunk/arch/sh/kernel/cpu/irq/maskreg.c | 93 + trunk/arch/sh/kernel/cpu/sh4/probe.c | 8 +- trunk/arch/sh/kernel/cpu/sh4a/Makefile | 2 - trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 10 +- trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 177 -- trunk/arch/sh/kernel/cpu/sh5/probe.c | 61 +- trunk/arch/sh/kernel/io.c | 8 +- trunk/arch/sh/kernel/io_generic.c | 24 +- trunk/arch/sh/kernel/io_trapped.c | 276 -- trunk/arch/sh/kernel/irq.c | 3 + trunk/arch/sh/kernel/process_64.c | 9 +- trunk/arch/sh/kernel/ptrace_32.c | 4 +- trunk/arch/sh/kernel/setup.c | 2 +- trunk/arch/sh/kernel/syscalls_32.S | 4 +- trunk/arch/sh/kernel/syscalls_64.S | 4 +- trunk/arch/sh/kernel/time_32.c | 19 +- trunk/arch/sh/kernel/time_64.c | 31 +- trunk/arch/sh/kernel/timers/timer-mtu2.c | 1 + trunk/arch/sh/kernel/traps_32.c | 164 +- trunk/arch/sh/kernel/traps_64.c | 4 +- trunk/arch/sh/kernel/vmlinux_64.lds.S | 2 +- trunk/arch/sh/mm/cache-sh5.c | 1019 +++--- trunk/arch/sh/mm/consistent.c | 32 +- trunk/arch/sh/mm/fault_32.c | 11 - trunk/arch/sh/mm/init.c | 2 - trunk/arch/sh/tools/mach-types | 2 - trunk/arch/sparc64/solaris/fs.c | 12 +- trunk/arch/um/drivers/mconsole_kern.c | 6 +- trunk/arch/x86/Kconfig | 4 +- trunk/arch/x86/kernel/acpi/cstate.c | 2 - trunk/arch/x86/kernel/efi.c | 4 +- trunk/arch/x86/kernel/pci-gart_64.c | 9 - trunk/arch/x86/kernel/test_rodata.c | 2 +- trunk/arch/x86/kernel/traps_64.c | 4 +- trunk/arch/x86/mm/fault.c | 2 +- trunk/arch/x86/mm/init_32.c | 1 - trunk/arch/x86/mm/init_64.c | 1 - trunk/arch/x86/mm/pageattr.c | 17 +- trunk/drivers/acpi/blacklist.c | 64 +- trunk/drivers/acpi/event.c | 2 +- trunk/drivers/acpi/hardware/hwsleep.c | 1 - trunk/drivers/acpi/osl.c | 6 +- trunk/drivers/acpi/processor_idle.c | 19 - trunk/drivers/ata/libata-scsi.c | 2 +- trunk/drivers/block/swim3.c | 4 + trunk/drivers/bluetooth/hci_ldisc.c | 1 - trunk/drivers/char/hvc_rtas.c | 2 +- trunk/drivers/cpuidle/cpuidle.c | 3 +- trunk/drivers/cpuidle/sysfs.c | 14 +- trunk/drivers/hid/hid-input-quirks.c | 17 +- trunk/drivers/hid/hid-input.c | 8 +- trunk/drivers/hid/usbhid/hid-quirks.c | 38 +- trunk/drivers/infiniband/core/cm.c | 26 +- trunk/drivers/infiniband/core/cma.c | 10 +- trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c | 17 - trunk/drivers/infiniband/hw/mlx4/mr.c | 2 +- trunk/drivers/infiniband/hw/mthca/mthca_cq.c | 2 +- .../infiniband/hw/mthca/mthca_memfree.c | 1 - trunk/drivers/infiniband/ulp/ipoib/ipoib.h | 1 + trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c | 1 - trunk/drivers/macintosh/mediabay.c | 2 + trunk/drivers/md/bitmap.c | 8 +- trunk/drivers/md/dm-table.c | 4 +- trunk/drivers/md/md.c | 3 +- trunk/drivers/misc/thinkpad_acpi.c | 4 +- trunk/drivers/mtd/mtdsuper.c | 14 +- trunk/drivers/net/8139too.c | 2 +- trunk/drivers/net/Kconfig | 18 - trunk/drivers/net/Makefile | 3 +- trunk/drivers/net/cxgb3/l2t.c | 2 +- trunk/drivers/net/cxgb3/sge.c | 35 +- trunk/drivers/net/dm9000.c | 654 ++-- trunk/drivers/net/e1000/e1000_main.c | 18 +- trunk/drivers/net/forcedeth.c | 132 +- trunk/drivers/net/mlx4/mr.c | 21 +- trunk/drivers/net/netconsole.c | 4 +- trunk/drivers/net/ni52.c | 1142 +++---- trunk/drivers/net/ni52.h | 158 +- trunk/drivers/net/pcnet32.c | 48 +- trunk/drivers/net/phy/fixed.c | 4 +- trunk/drivers/net/ps3_gelic_net.c | 1215 ++++---- trunk/drivers/net/ps3_gelic_net.h | 415 +-- trunk/drivers/net/ps3_gelic_wireless.c | 2753 ----------------- trunk/drivers/net/ps3_gelic_wireless.h | 329 -- trunk/drivers/net/r6040.c | 233 +- trunk/drivers/net/sis190.c | 3 +- trunk/drivers/oprofile/buffer_sync.c | 21 +- trunk/drivers/pnp/pnpacpi/core.c | 2 +- trunk/drivers/pnp/pnpbios/core.c | 2 + trunk/drivers/ps3/ps3-lpm.c | 22 +- trunk/drivers/ps3/ps3-sys-manager.c | 44 +- trunk/drivers/s390/net/claw.h | 19 +- trunk/drivers/s390/net/lcs.c | 2 +- trunk/drivers/s390/net/lcs.h | 16 +- trunk/drivers/s390/net/netiucv.c | 29 +- trunk/drivers/serial/sh-sci.c | 2 +- trunk/drivers/serial/sh-sci.h | 9 +- trunk/drivers/sh/maple/maple.c | 981 +++--- trunk/drivers/usb/gadget/file_storage.c | 8 +- trunk/fs/afs/mntpt.c | 23 +- trunk/fs/autofs4/root.c | 5 +- trunk/fs/binfmt_flat.c | 8 +- trunk/fs/block_dev.c | 6 +- trunk/fs/cifs/cifs_dfs_ref.c | 25 +- trunk/fs/coda/pioctl.c | 6 +- trunk/fs/compat.c | 11 +- trunk/fs/compat_ioctl.c | 2 +- trunk/fs/configfs/symlink.c | 8 +- trunk/fs/dcache.c | 103 +- trunk/fs/dcookies.c | 34 +- trunk/fs/dquot.c | 9 +- trunk/fs/ecryptfs/dentry.c | 12 +- trunk/fs/ecryptfs/inode.c | 24 +- trunk/fs/ecryptfs/main.c | 6 +- trunk/fs/exec.c | 8 +- trunk/fs/ext3/super.c | 8 +- trunk/fs/ext4/super.c | 8 +- trunk/fs/gfs2/ops_fstype.c | 7 +- trunk/fs/inotify_user.c | 12 +- trunk/fs/namei.c | 311 +- trunk/fs/namespace.c | 268 +- trunk/fs/nfs/callback.c | 18 +- trunk/fs/nfs/dir.c | 8 +- trunk/fs/nfs/namespace.c | 29 +- trunk/fs/nfs/nfs4proc.c | 8 +- trunk/fs/nfs/nfs4state.c | 4 +- trunk/fs/nfs/super.c | 4 - trunk/fs/nfsctl.c | 4 +- trunk/fs/nfsd/export.c | 122 +- trunk/fs/nfsd/nfs3proc.c | 2 +- trunk/fs/nfsd/nfs3xdr.c | 4 +- trunk/fs/nfsd/nfs4recover.c | 34 +- trunk/fs/nfsd/nfs4state.c | 4 +- trunk/fs/nfsd/nfs4xdr.c | 12 +- trunk/fs/nfsd/nfsfh.c | 26 +- trunk/fs/nfsd/nfsproc.c | 6 +- trunk/fs/nfsd/nfsxdr.c | 2 +- trunk/fs/nfsd/vfs.c | 13 +- trunk/fs/open.c | 61 +- trunk/fs/proc/base.c | 61 +- trunk/fs/proc/internal.h | 2 +- trunk/fs/proc/nommu.c | 2 +- trunk/fs/proc/proc_sysctl.c | 2 +- trunk/fs/proc/task_mmu.c | 8 +- trunk/fs/proc/task_nommu.c | 6 +- trunk/fs/reiserfs/super.c | 14 +- trunk/fs/seq_file.c | 6 +- trunk/fs/stat.c | 19 +- trunk/fs/utimes.c | 4 +- trunk/fs/xattr.c | 32 +- trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 8 +- trunk/include/acpi/processor.h | 9 +- trunk/include/asm-m68knommu/cacheflush.h | 14 +- trunk/include/asm-m68knommu/system.h | 2 +- trunk/include/asm-powerpc/systbl.h | 4 +- trunk/include/asm-powerpc/unistd.h | 6 +- trunk/include/asm-ppc/page.h | 2 - trunk/include/asm-sh/bugs.h | 2 +- trunk/include/asm-sh/cpu-sh4/freq.h | 4 +- trunk/include/asm-sh/cpu-sh5/cacheflush.h | 6 +- trunk/include/asm-sh/cpu-sh5/mmu_context.h | 6 + trunk/include/asm-sh/hp6xx.h | 28 +- trunk/include/asm-sh/io.h | 22 +- trunk/include/asm-sh/io_trapped.h | 58 - trunk/include/asm-sh/ioctls.h | 4 - trunk/include/asm-sh/irq.h | 4 - trunk/include/asm-sh/mmu_context_64.h | 3 - trunk/include/asm-sh/page.h | 7 +- trunk/include/asm-sh/pgtable_64.h | 13 - trunk/include/asm-sh/processor.h | 2 +- trunk/include/asm-sh/r7780rp.h | 3 + trunk/include/asm-sh/rts7751r2d.h | 3 + trunk/include/asm-sh/system.h | 5 - trunk/include/asm-sh/system_32.h | 3 - trunk/include/asm-sh/termbits.h | 5 +- trunk/include/asm-sh/termios.h | 6 +- trunk/include/asm-sh/tlb.h | 1 - trunk/include/asm-sh/uaccess.h | 29 - trunk/include/asm-sh/uaccess_32.h | 24 +- trunk/include/asm-sh/uaccess_64.h | 19 + trunk/include/asm-sh/unistd_32.h | 6 +- trunk/include/asm-sh/unistd_64.h | 6 +- trunk/include/asm-x86/cacheflush.h | 7 +- trunk/include/asm-x86/kdebug.h | 1 + trunk/include/linux/acpi.h | 1 - trunk/include/linux/audit.h | 5 +- trunk/include/linux/configfs.h | 1 - trunk/include/linux/cpuidle.h | 2 - trunk/include/linux/dcache.h | 5 +- trunk/include/linux/dcookies.h | 15 +- trunk/include/linux/dm9000.h | 2 - trunk/include/linux/fs.h | 6 +- trunk/include/linux/fs_struct.h | 10 +- trunk/include/linux/hid.h | 2 +- trunk/include/linux/ktime.h | 2 - trunk/include/linux/maple.h | 100 +- trunk/include/linux/module.h | 3 +- trunk/include/linux/namei.h | 11 +- trunk/include/linux/netdevice.h | 8 +- trunk/include/linux/nfsd/export.h | 8 +- trunk/include/linux/path.h | 15 - trunk/include/linux/proc_fs.h | 2 +- trunk/include/linux/seq_file.h | 5 +- trunk/include/linux/slub_def.h | 15 +- trunk/include/net/ax25.h | 2 - trunk/include/net/ndisc.h | 1 + trunk/include/net/xfrm.h | 5 +- trunk/init/do_mounts.c | 6 +- trunk/kernel/audit.c | 12 +- trunk/kernel/audit_tree.c | 28 +- trunk/kernel/auditfilter.c | 15 +- trunk/kernel/auditsc.c | 28 +- trunk/kernel/exit.c | 12 +- trunk/kernel/fork.c | 18 +- trunk/kernel/futex.c | 2 +- trunk/kernel/futex_compat.c | 2 +- trunk/kernel/hrtimer.c | 48 +- trunk/kernel/kmod.c | 5 +- trunk/kernel/posix-timers.c | 8 +- trunk/mm/memory.c | 9 +- trunk/mm/mempolicy.c | 2 +- trunk/mm/slab.c | 3 +- trunk/mm/slub.c | 94 +- trunk/mm/swapfile.c | 2 +- trunk/net/ax25/af_ax25.c | 12 +- trunk/net/ax25/ax25_dev.c | 2 +- trunk/net/ax25/ax25_ds_timer.c | 12 +- trunk/net/ax25/ax25_route.c | 28 +- trunk/net/ax25/ax25_timer.c | 60 +- trunk/net/core/dev.c | 4 +- trunk/net/core/neighbour.c | 12 +- trunk/net/core/rtnetlink.c | 36 +- trunk/net/core/skbuff.c | 3 +- trunk/net/ipv4/ah4.c | 2 +- trunk/net/ipv4/arp.c | 3 + trunk/net/ipv4/esp4.c | 5 +- trunk/net/ipv4/fib_trie.c | 99 +- trunk/net/ipv4/inet_hashtables.c | 3 + trunk/net/ipv4/ip_sockglue.c | 5 + trunk/net/ipv6/ah6.c | 2 +- trunk/net/ipv6/esp6.c | 5 +- trunk/net/ipv6/ip6_output.c | 6 +- trunk/net/ipv6/xfrm6_output.c | 2 +- trunk/net/key/af_key.c | 1 - trunk/net/netfilter/nf_conntrack_proto_tcp.c | 2 +- trunk/net/netfilter/xt_SECMARK.c | 2 +- trunk/net/netlabel/netlabel_domainhash.c | 6 +- trunk/net/netlabel/netlabel_unlabeled.c | 30 +- trunk/net/netlabel/netlabel_user.c | 3 +- trunk/net/netlink/genetlink.c | 6 +- trunk/net/socket.c | 3 - trunk/net/sunrpc/rpc_pipe.c | 7 +- trunk/net/unix/af_unix.c | 26 +- trunk/net/xfrm/Kconfig | 2 +- trunk/net/xfrm/xfrm_input.c | 4 +- trunk/net/xfrm/xfrm_output.c | 2 +- trunk/net/xfrm/xfrm_user.c | 1 - trunk/scripts/kernel-doc | 1 + trunk/security/selinux/avc.c | 15 +- trunk/security/selinux/hooks.c | 32 +- trunk/security/selinux/include/avc.h | 6 +- trunk/security/smack/smack_lsm.c | 2 +- trunk/sound/core/seq/seq_clientmgr.c | 4 +- trunk/sound/core/seq/seq_device.c | 3 + trunk/sound/core/sound.c | 4 + trunk/sound/core/timer.c | 2 + trunk/sound/ppc/daca.c | 5 +- trunk/sound/ppc/tumbler.c | 5 +- 338 files changed, 5405 insertions(+), 11005 deletions(-) delete mode 100644 trunk/Documentation/cpuidle/core.txt delete mode 100644 trunk/Documentation/cpuidle/driver.txt delete mode 100644 trunk/Documentation/cpuidle/governor.txt delete mode 100644 trunk/Documentation/cpuidle/sysfs.txt delete mode 100644 trunk/arch/sh/boards/renesas/migor/Makefile delete mode 100644 trunk/arch/sh/boards/renesas/migor/setup.c delete mode 100644 trunk/arch/sh/configs/migor_defconfig create mode 100644 trunk/arch/sh/kernel/cpu/irq/maskreg.c delete mode 100644 trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c delete mode 100644 trunk/arch/sh/kernel/io_trapped.c delete mode 100644 trunk/drivers/net/ps3_gelic_wireless.c delete mode 100644 trunk/drivers/net/ps3_gelic_wireless.h delete mode 100644 trunk/include/asm-sh/io_trapped.h delete mode 100644 trunk/include/linux/path.h diff --git a/[refs] b/[refs] index a8c22f1647c1..af68576261a8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 101142c37be8e5af9b847860219217e6b958c739 +refs/heads/master: 08f01058fe8fcf0d4d69d96d667c51d52859b31d diff --git a/trunk/Documentation/00-INDEX b/trunk/Documentation/00-INDEX index 30b327a116ea..8d556707bb68 100644 --- a/trunk/Documentation/00-INDEX +++ b/trunk/Documentation/00-INDEX @@ -109,8 +109,6 @@ cpu-hotplug.txt - document describing CPU hotplug support in the Linux kernel. cpu-load.txt - document describing how CPU load statistics are collected. -cpuidle/ - - info on CPU_IDLE, CPU idle state management subsystem. cpusets.txt - documents the cpusets feature; assign CPUs and Mem to a set of tasks. cputopology.txt diff --git a/trunk/Documentation/cpuidle/core.txt b/trunk/Documentation/cpuidle/core.txt deleted file mode 100644 index 63ecc5dc9d8a..000000000000 --- a/trunk/Documentation/cpuidle/core.txt +++ /dev/null @@ -1,23 +0,0 @@ - - Supporting multiple CPU idle levels in kernel - - cpuidle - -General Information: - -Various CPUs today support multiple idle levels that are differentiated -by varying exit latencies and power consumption during idle. -cpuidle is a generic in-kernel infrastructure that separates -idle policy (governor) from idle mechanism (driver) and provides a -standardized infrastructure to support independent development of -governors and drivers. - -cpuidle resides under drivers/cpuidle. - -Boot options: -"cpuidle_sysfs_switch" -enables current_governor interface in /sys/devices/system/cpu/cpuidle/, -which can be used to switch governors at run time. This boot option -is meant for developer testing only. In normal usage, kernel picks the -best governor based on governor ratings. -SEE ALSO: sysfs.txt in this directory. diff --git a/trunk/Documentation/cpuidle/driver.txt b/trunk/Documentation/cpuidle/driver.txt deleted file mode 100644 index 7a9e09ece931..000000000000 --- a/trunk/Documentation/cpuidle/driver.txt +++ /dev/null @@ -1,31 +0,0 @@ - - - Supporting multiple CPU idle levels in kernel - - cpuidle drivers - - - - -cpuidle driver hooks into the cpuidle infrastructure and handles the -architecture/platform dependent part of CPU idle states. Driver -provides the platform idle state detection capability and also -has mechanisms in place to support actual entry-exit into CPU idle states. - -cpuidle driver initializes the cpuidle_device structure for each CPU device -and registers with cpuidle using cpuidle_register_device. - -It can also support the dynamic changes (like battery <-> AC), by using -cpuidle_pause_and_lock, cpuidle_disable_device and cpuidle_enable_device, -cpuidle_resume_and_unlock. - -Interfaces: -extern int cpuidle_register_driver(struct cpuidle_driver *drv); -extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); -extern int cpuidle_register_device(struct cpuidle_device *dev); -extern void cpuidle_unregister_device(struct cpuidle_device *dev); - -extern void cpuidle_pause_and_lock(void); -extern void cpuidle_resume_and_unlock(void); -extern int cpuidle_enable_device(struct cpuidle_device *dev); -extern void cpuidle_disable_device(struct cpuidle_device *dev); diff --git a/trunk/Documentation/cpuidle/governor.txt b/trunk/Documentation/cpuidle/governor.txt deleted file mode 100644 index 12c6bd50c9f6..000000000000 --- a/trunk/Documentation/cpuidle/governor.txt +++ /dev/null @@ -1,29 +0,0 @@ - - - - Supporting multiple CPU idle levels in kernel - - cpuidle governors - - - - -cpuidle governor is policy routine that decides what idle state to enter at -any given time. cpuidle core uses different callbacks to the governor. - -* enable() to enable governor for a particular device -* disable() to disable governor for a particular device -* select() to select an idle state to enter -* reflect() called after returning from the idle state, which can be used - by the governor for some record keeping. - -More than one governor can be registered at the same time and -users can switch between drivers using /sysfs interface (when enabled). -More than one governor part is supported for developers to easily experiment -with different governors. By default, most optimal governor based on your -kernel configuration and platform will be selected by cpuidle. - -Interfaces: -extern int cpuidle_register_governor(struct cpuidle_governor *gov); -extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); -struct cpuidle_governor diff --git a/trunk/Documentation/cpuidle/sysfs.txt b/trunk/Documentation/cpuidle/sysfs.txt deleted file mode 100644 index 50d7b1642759..000000000000 --- a/trunk/Documentation/cpuidle/sysfs.txt +++ /dev/null @@ -1,79 +0,0 @@ - - - Supporting multiple CPU idle levels in kernel - - cpuidle sysfs - -System global cpuidle related information and tunables are under -/sys/devices/system/cpu/cpuidle - -The current interfaces in this directory has self-explanatory names: -* current_driver -* current_governor_ro - -With cpuidle_sysfs_switch boot option (meant for developer testing) -following objects are visible instead. -* current_driver -* available_governors -* current_governor -In this case users can switch the governor at run time by writing -to current_governor. - - -Per logical CPU specific cpuidle information are under -/sys/devices/system/cpu/cpuX/cpuidle -for each online cpu X - --------------------------------------------------------------------------------- -# ls -lR /sys/devices/system/cpu/cpu0/cpuidle/ -/sys/devices/system/cpu/cpu0/cpuidle/: -total 0 -drwxr-xr-x 2 root root 0 Feb 8 10:42 state0 -drwxr-xr-x 2 root root 0 Feb 8 10:42 state1 -drwxr-xr-x 2 root root 0 Feb 8 10:42 state2 -drwxr-xr-x 2 root root 0 Feb 8 10:42 state3 - -/sys/devices/system/cpu/cpu0/cpuidle/state0: -total 0 --r--r--r-- 1 root root 4096 Feb 8 10:42 desc --r--r--r-- 1 root root 4096 Feb 8 10:42 latency --r--r--r-- 1 root root 4096 Feb 8 10:42 name --r--r--r-- 1 root root 4096 Feb 8 10:42 power --r--r--r-- 1 root root 4096 Feb 8 10:42 time --r--r--r-- 1 root root 4096 Feb 8 10:42 usage - -/sys/devices/system/cpu/cpu0/cpuidle/state1: -total 0 --r--r--r-- 1 root root 4096 Feb 8 10:42 desc --r--r--r-- 1 root root 4096 Feb 8 10:42 latency --r--r--r-- 1 root root 4096 Feb 8 10:42 name --r--r--r-- 1 root root 4096 Feb 8 10:42 power --r--r--r-- 1 root root 4096 Feb 8 10:42 time --r--r--r-- 1 root root 4096 Feb 8 10:42 usage - -/sys/devices/system/cpu/cpu0/cpuidle/state2: -total 0 --r--r--r-- 1 root root 4096 Feb 8 10:42 desc --r--r--r-- 1 root root 4096 Feb 8 10:42 latency --r--r--r-- 1 root root 4096 Feb 8 10:42 name --r--r--r-- 1 root root 4096 Feb 8 10:42 power --r--r--r-- 1 root root 4096 Feb 8 10:42 time --r--r--r-- 1 root root 4096 Feb 8 10:42 usage - -/sys/devices/system/cpu/cpu0/cpuidle/state3: -total 0 --r--r--r-- 1 root root 4096 Feb 8 10:42 desc --r--r--r-- 1 root root 4096 Feb 8 10:42 latency --r--r--r-- 1 root root 4096 Feb 8 10:42 name --r--r--r-- 1 root root 4096 Feb 8 10:42 power --r--r--r-- 1 root root 4096 Feb 8 10:42 time --r--r--r-- 1 root root 4096 Feb 8 10:42 usage --------------------------------------------------------------------------------- - - -* desc : Small description about the idle state (string) -* latency : Latency to exit out of this idle state (in microseconds) -* name : Name of the idle state (string) -* power : Power consumed while in this idle state (in milliwatts) -* time : Total time spent in this idle state (in microseconds) -* usage : Number of times this state was entered (count) diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 1d2edb491b34..6680ec44779e 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1255,8 +1255,8 @@ W: http://linux-net.osdl.org/index.php/DCCP S: Maintained DECnet NETWORK LAYER -P: Christine Caulfield -M: christine.caulfield@googlemail.com +P: Patrick Caulfield +M: patrick@tykepenguin.com W: http://linux-decnet.sourceforge.net L: linux-decnet-user@lists.sourceforge.net S: Maintained @@ -1318,8 +1318,8 @@ L: linux-kernel@vger.kernel.org S: Maintained DISTRIBUTED LOCK MANAGER -P: Christine Caulfield -M: ccaulfie@redhat.com +P: Patrick Caulfield +M: pcaulfie@redhat.com P: David Teigland M: teigland@redhat.com L: cluster-devel@redhat.com @@ -1616,7 +1616,6 @@ S: Maintained FILESYSTEMS (VFS and infrastructure) P: Alexander Viro M: viro@zeniv.linux.org.uk -L: linux-fsdevel@vger.kernel.org S: Maintained FIREWIRE SUBSYSTEM (drivers/firewire, ) diff --git a/trunk/Makefile b/trunk/Makefile index 67cc45786177..c162370c7367 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,8 +1,8 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 25 -EXTRAVERSION = -rc2 -NAME = Funky Weasel is Jiggy wit it +EXTRAVERSION = -rc1 +NAME = Arr Matey! A Hairy Bilge Rat! # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index 8c71daf94a59..973c5c3705e3 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -259,8 +259,8 @@ osf_statfs(char __user *path, struct osf_statfs __user *buffer, unsigned long bu retval = user_path_walk(path, &nd); if (!retval) { - retval = do_osf_statfs(nd.path.dentry, buffer, bufsiz); - path_put(&nd.path); + retval = do_osf_statfs(nd.dentry, buffer, bufsiz); + path_release(&nd); } return retval; } diff --git a/trunk/arch/blackfin/kernel/traps.c b/trunk/arch/blackfin/kernel/traps.c index 56a67ab698c7..58717cb19707 100644 --- a/trunk/arch/blackfin/kernel/traps.c +++ b/trunk/arch/blackfin/kernel/traps.c @@ -126,13 +126,15 @@ static void decode_address(char *buf, unsigned long address) struct vm_area_struct *vma = vml->vma; if (address >= vma->vm_start && address < vma->vm_end) { - char _tmpbuf[256]; char *name = p->comm; struct file *file = vma->vm_file; - - if (file) - name = d_path(&file->f_path, _tmpbuf, - sizeof(_tmpbuf)); + if (file) { + char _tmpbuf[256]; + name = d_path(file->f_dentry, + file->f_vfsmnt, + _tmpbuf, + sizeof(_tmpbuf)); + } /* FLAT does not have its text aligned to the start of * the map while FDPIC ELF does ... diff --git a/trunk/arch/cris/arch-v10/lib/memset.c b/trunk/arch/cris/arch-v10/lib/memset.c index c94ea9b3ec29..42c1101043a3 100644 --- a/trunk/arch/cris/arch-v10/lib/memset.c +++ b/trunk/arch/cris/arch-v10/lib/memset.c @@ -1,259 +1,252 @@ -/* A memset for CRIS. - Copyright (C) 1999-2005 Axis Communications. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Neither the name of Axis Communications nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS - COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. */ - -/* FIXME: This file should really only be used for reference, as the - result is somewhat depending on gcc generating what we expect rather - than what we describe. An assembly file should be used instead. */ - -/* Note the multiple occurrence of the expression "12*4", including the - asm. It is hard to get it into the asm in a good way. Thus better to - expose the problem everywhere: no macro. */ - -/* Assuming one cycle per dword written or read (ok, not really true; the - world is not ideal), and one cycle per instruction, then 43+3*(n/48-1) - <= 24+24*(n/48-1) so n >= 45.7; n >= 0.9; we win on the first full - 48-byte block to set. */ - -#define MEMSET_BY_BLOCK_THRESHOLD (1 * 48) - -/* No name ambiguities in this file. */ -__asm__ (".syntax no_register_prefix"); - -void *memset(void *pdst, int c, unsigned int plen) +/*#************************************************************************#*/ +/*#-------------------------------------------------------------------------*/ +/*# */ +/*# FUNCTION NAME: memset() */ +/*# */ +/*# PARAMETERS: void* dst; Destination address. */ +/*# int c; Value of byte to write. */ +/*# int len; Number of bytes to write. */ +/*# */ +/*# RETURNS: dst. */ +/*# */ +/*# DESCRIPTION: Sets the memory dst of length len bytes to c, as standard. */ +/*# Framework taken from memcpy. This routine is */ +/*# very sensitive to compiler changes in register allocation. */ +/*# Should really be rewritten to avoid this problem. */ +/*# */ +/*#-------------------------------------------------------------------------*/ +/*# */ +/*# HISTORY */ +/*# */ +/*# DATE NAME CHANGES */ +/*# ---- ---- ------- */ +/*# 990713 HP Tired of watching this function (or */ +/*# really, the nonoptimized generic */ +/*# implementation) take up 90% of simulator */ +/*# output. Measurements needed. */ +/*# */ +/*#-------------------------------------------------------------------------*/ + +#include + +/* No, there's no macro saying 12*4, since it is "hard" to get it into + the asm in a good way. Thus better to expose the problem everywhere. + */ + +/* Assuming 1 cycle per dword written or read (ok, not really true), and + one per instruction, then 43+3*(n/48-1) <= 24+24*(n/48-1) + so n >= 45.7; n >= 0.9; we win on the first full 48-byte block to set. */ + +#define ZERO_BLOCK_SIZE (1*12*4) + +void *memset(void *pdst, + int c, + size_t plen) { - /* Now we want the parameters in special registers. Make sure the - compiler does something usable with this. */ + /* Ok. Now we want the parameters put in special registers. + Make sure the compiler is able to make something useful of this. */ register char *return_dst __asm__ ("r10") = pdst; register int n __asm__ ("r12") = plen; register int lc __asm__ ("r11") = c; - /* Most apps use memset sanely. Memsetting about 3..4 bytes or less get - penalized here compared to the generic implementation. */ + /* Most apps use memset sanely. Only those memsetting about 3..4 + bytes or less get penalized compared to the generic implementation + - and that's not really sane use. */ - /* This is fragile performancewise at best. Check with newer GCC - releases, if they compile cascaded "x |= x << 8" to sane code. */ - __asm__("movu.b %0,r13 \n\ - lslq 8,r13 \n\ - move.b %0,r13 \n\ - move.d r13,%0 \n\ - lslq 16,r13 \n\ - or.d r13,%0" - : "=r" (lc) /* Inputs. */ - : "0" (lc) /* Outputs. */ - : "r13"); /* Trash. */ + /* Ugh. This is fragile at best. Check with newer GCC releases, if + they compile cascaded "x |= x << 8" sanely! */ + __asm__("movu.b %0,$r13\n\t" + "lslq 8,$r13\n\t" + "move.b %0,$r13\n\t" + "move.d $r13,%0\n\t" + "lslq 16,$r13\n\t" + "or.d $r13,%0" + : "=r" (lc) : "0" (lc) : "r13"); { register char *dst __asm__ ("r13") = pdst; - if (((unsigned long) pdst & 3) != 0 - /* Oops! n = 0 must be a valid call, regardless of alignment. */ - && n >= 3) - { - if ((unsigned long) dst & 1) - { - *dst = (char) lc; - n--; - dst++; - } + /* This is NONPORTABLE, but since this whole routine is */ + /* grossly nonportable that doesn't matter. */ - if ((unsigned long) dst & 2) - { - *(short *) dst = lc; - n -= 2; - dst += 2; - } - } + if (((unsigned long) pdst & 3) != 0 + /* Oops! n=0 must be a legal call, regardless of alignment. */ + && n >= 3) + { + if ((unsigned long)dst & 1) + { + *dst = (char) lc; + n--; + dst++; + } + + if ((unsigned long)dst & 2) + { + *(short *)dst = lc; + n -= 2; + dst += 2; + } + } - /* Decide which setting method to use. */ - if (n >= MEMSET_BY_BLOCK_THRESHOLD) - { - /* It is not optimal to tell the compiler about clobbering any - registers; that will move the saving/restoring of those registers - to the function prologue/epilogue, and make non-block sizes - suboptimal. */ - __asm__ volatile - ("\ - ;; GCC does promise correct register allocations, but let's \n\ - ;; make sure it keeps its promises. \n\ - .ifnc %0-%1-%4,$r13-$r12-$r11 \n\ - .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\ - .endif \n\ - \n\ - ;; Save the registers we'll clobber in the movem process \n\ - ;; on the stack. Don't mention them to gcc, it will only be \n\ - ;; upset. \n\ - subq 11*4,sp \n\ - movem r10,[sp] \n\ + /* Now the fun part. For the threshold value of this, check the equation + above. */ + /* Decide which copying method to use. */ + if (n >= ZERO_BLOCK_SIZE) + { + /* For large copies we use 'movem' */ + + /* It is not optimal to tell the compiler about clobbering any + registers; that will move the saving/restoring of those registers + to the function prologue/epilogue, and make non-movem sizes + suboptimal. + + This method is not foolproof; it assumes that the "asm reg" + declarations at the beginning of the function really are used + here (beware: they may be moved to temporary registers). + This way, we do not have to save/move the registers around into + temporaries; we can safely use them straight away. + + If you want to check that the allocation was right; then + check the equalities in the first comment. It should say + "r13=r13, r12=r12, r11=r11" */ + __asm__ volatile ("\n\ + ;; Check that the following is true (same register names on \n\ + ;; both sides of equal sign, as in r8=r8): \n\ + ;; %0=r13, %1=r12, %4=r11 \n\ + ;; \n\ + ;; Save the registers we'll clobber in the movem process \n\ + ;; on the stack. Don't mention them to gcc, it will only be \n\ + ;; upset. \n\ + subq 11*4,$sp \n\ + movem $r10,[$sp] \n\ \n\ - move.d r11,r0 \n\ - move.d r11,r1 \n\ - move.d r11,r2 \n\ - move.d r11,r3 \n\ - move.d r11,r4 \n\ - move.d r11,r5 \n\ - move.d r11,r6 \n\ - move.d r11,r7 \n\ - move.d r11,r8 \n\ - move.d r11,r9 \n\ - move.d r11,r10 \n\ + move.d $r11,$r0 \n\ + move.d $r11,$r1 \n\ + move.d $r11,$r2 \n\ + move.d $r11,$r3 \n\ + move.d $r11,$r4 \n\ + move.d $r11,$r5 \n\ + move.d $r11,$r6 \n\ + move.d $r11,$r7 \n\ + move.d $r11,$r8 \n\ + move.d $r11,$r9 \n\ + move.d $r11,$r10 \n\ \n\ - ;; Now we've got this: \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ + ;; Now we've got this: \n\ + ;; r13 - dst \n\ + ;; r12 - n \n\ \n\ - ;; Update n for the first loop \n\ - subq 12*4,r12 \n\ + ;; Update n for the first loop \n\ + subq 12*4,$r12 \n\ 0: \n\ -" -#ifdef __arch_common_v10_v32 - /* Cater to branch offset difference between v32 and v10. We - assume the branch below has an 8-bit offset. */ -" setf\n" -#endif -" subq 12*4,r12 \n\ - bge 0b \n\ - movem r11,[r13+] \n\ + subq 12*4,$r12 \n\ + bge 0b \n\ + movem $r11,[$r13+] \n\ \n\ - ;; Compensate for last loop underflowing n. \n\ - addq 12*4,r12 \n\ + addq 12*4,$r12 ;; compensate for last loop underflowing n \n\ \n\ - ;; Restore registers from stack. \n\ - movem [sp+],r10" + ;; Restore registers from stack \n\ + movem [$sp+],$r10" - /* Outputs. */ - : "=r" (dst), "=r" (n) + /* Outputs */ : "=r" (dst), "=r" (n) + /* Inputs */ : "0" (dst), "1" (n), "r" (lc)); - /* Inputs. */ - : "0" (dst), "1" (n), "r" (lc)); - } - - /* An ad-hoc unroll, used for 4*12-1..16 bytes. */ - while (n >= 16) - { - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - n -= 16; - } + } + /* Either we directly starts copying, using dword copying + in a loop, or we copy as much as possible with 'movem' + and then the last block (<44 bytes) is copied here. + This will work since 'movem' will have updated src,dst,n. */ + + while ( n >= 16 ) + { + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + n -= 16; + } + + /* A switch() is definitely the fastest although it takes a LOT of code. + * Particularly if you inline code this. + */ switch (n) - { + { case 0: break; - case 1: - *dst = (char) lc; + *(char*)dst = (char) lc; break; - case 2: - *(short *) dst = (short) lc; + *(short*)dst = (short) lc; break; - case 3: - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 4: - *(long *) dst = lc; + *((long*)dst)++ = lc; break; - case 5: - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 6: - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 7: - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 8: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; break; - case 9: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 10: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 11: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 12: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; break; - case 13: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 14: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 15: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - } + } } - return return_dst; -} + return return_dst; /* destination pointer. */ +} /* memset() */ diff --git a/trunk/arch/cris/arch-v32/lib/memset.c b/trunk/arch/cris/arch-v32/lib/memset.c index c94ea9b3ec29..ffca1214674e 100644 --- a/trunk/arch/cris/arch-v32/lib/memset.c +++ b/trunk/arch/cris/arch-v32/lib/memset.c @@ -1,259 +1,253 @@ -/* A memset for CRIS. - Copyright (C) 1999-2005 Axis Communications. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Neither the name of Axis Communications nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS - COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. */ - -/* FIXME: This file should really only be used for reference, as the - result is somewhat depending on gcc generating what we expect rather - than what we describe. An assembly file should be used instead. */ - -/* Note the multiple occurrence of the expression "12*4", including the - asm. It is hard to get it into the asm in a good way. Thus better to - expose the problem everywhere: no macro. */ - -/* Assuming one cycle per dword written or read (ok, not really true; the - world is not ideal), and one cycle per instruction, then 43+3*(n/48-1) - <= 24+24*(n/48-1) so n >= 45.7; n >= 0.9; we win on the first full - 48-byte block to set. */ - -#define MEMSET_BY_BLOCK_THRESHOLD (1 * 48) - -/* No name ambiguities in this file. */ -__asm__ (".syntax no_register_prefix"); - -void *memset(void *pdst, int c, unsigned int plen) +/*#************************************************************************#*/ +/*#-------------------------------------------------------------------------*/ +/*# */ +/*# FUNCTION NAME: memset() */ +/*# */ +/*# PARAMETERS: void* dst; Destination address. */ +/*# int c; Value of byte to write. */ +/*# int len; Number of bytes to write. */ +/*# */ +/*# RETURNS: dst. */ +/*# */ +/*# DESCRIPTION: Sets the memory dst of length len bytes to c, as standard. */ +/*# Framework taken from memcpy. This routine is */ +/*# very sensitive to compiler changes in register allocation. */ +/*# Should really be rewritten to avoid this problem. */ +/*# */ +/*#-------------------------------------------------------------------------*/ +/*# */ +/*# HISTORY */ +/*# */ +/*# DATE NAME CHANGES */ +/*# ---- ---- ------- */ +/*# 990713 HP Tired of watching this function (or */ +/*# really, the nonoptimized generic */ +/*# implementation) take up 90% of simulator */ +/*# output. Measurements needed. */ +/*# */ +/*#-------------------------------------------------------------------------*/ + +#include + +/* No, there's no macro saying 12*4, since it is "hard" to get it into + the asm in a good way. Thus better to expose the problem everywhere. + */ + +/* Assuming 1 cycle per dword written or read (ok, not really true), and + one per instruction, then 43+3*(n/48-1) <= 24+24*(n/48-1) + so n >= 45.7; n >= 0.9; we win on the first full 48-byte block to set. */ + +#define ZERO_BLOCK_SIZE (1*12*4) + +void *memset(void *pdst, + int c, + size_t plen) { - /* Now we want the parameters in special registers. Make sure the - compiler does something usable with this. */ + /* Ok. Now we want the parameters put in special registers. + Make sure the compiler is able to make something useful of this. */ register char *return_dst __asm__ ("r10") = pdst; register int n __asm__ ("r12") = plen; register int lc __asm__ ("r11") = c; - /* Most apps use memset sanely. Memsetting about 3..4 bytes or less get - penalized here compared to the generic implementation. */ + /* Most apps use memset sanely. Only those memsetting about 3..4 + bytes or less get penalized compared to the generic implementation + - and that's not really sane use. */ - /* This is fragile performancewise at best. Check with newer GCC - releases, if they compile cascaded "x |= x << 8" to sane code. */ - __asm__("movu.b %0,r13 \n\ - lslq 8,r13 \n\ - move.b %0,r13 \n\ - move.d r13,%0 \n\ - lslq 16,r13 \n\ - or.d r13,%0" - : "=r" (lc) /* Inputs. */ - : "0" (lc) /* Outputs. */ - : "r13"); /* Trash. */ + /* Ugh. This is fragile at best. Check with newer GCC releases, if + they compile cascaded "x |= x << 8" sanely! */ + __asm__("movu.b %0,$r13 \n\ + lslq 8,$r13 \n\ + move.b %0,$r13 \n\ + move.d $r13,%0 \n\ + lslq 16,$r13 \n\ + or.d $r13,%0" + : "=r" (lc) : "0" (lc) : "r13"); { register char *dst __asm__ ("r13") = pdst; - if (((unsigned long) pdst & 3) != 0 - /* Oops! n = 0 must be a valid call, regardless of alignment. */ - && n >= 3) - { - if ((unsigned long) dst & 1) - { - *dst = (char) lc; - n--; - dst++; - } + /* This is NONPORTABLE, but since this whole routine is */ + /* grossly nonportable that doesn't matter. */ - if ((unsigned long) dst & 2) - { - *(short *) dst = lc; - n -= 2; - dst += 2; - } - } + if (((unsigned long) pdst & 3) != 0 + /* Oops! n=0 must be a legal call, regardless of alignment. */ + && n >= 3) + { + if ((unsigned long)dst & 1) + { + *dst = (char) lc; + n--; + dst++; + } + + if ((unsigned long)dst & 2) + { + *(short *)dst = lc; + n -= 2; + dst += 2; + } + } - /* Decide which setting method to use. */ - if (n >= MEMSET_BY_BLOCK_THRESHOLD) - { - /* It is not optimal to tell the compiler about clobbering any - registers; that will move the saving/restoring of those registers - to the function prologue/epilogue, and make non-block sizes - suboptimal. */ - __asm__ volatile - ("\ - ;; GCC does promise correct register allocations, but let's \n\ - ;; make sure it keeps its promises. \n\ - .ifnc %0-%1-%4,$r13-$r12-$r11 \n\ - .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\ - .endif \n\ + /* Now the fun part. For the threshold value of this, check the equation + above. */ + /* Decide which copying method to use. */ + if (n >= ZERO_BLOCK_SIZE) + { + /* For large copies we use 'movem' */ + + /* It is not optimal to tell the compiler about clobbering any + registers; that will move the saving/restoring of those registers + to the function prologue/epilogue, and make non-movem sizes + suboptimal. + + This method is not foolproof; it assumes that the "asm reg" + declarations at the beginning of the function really are used + here (beware: they may be moved to temporary registers). + This way, we do not have to save/move the registers around into + temporaries; we can safely use them straight away. + + If you want to check that the allocation was right; then + check the equalities in the first comment. It should say + "r13=r13, r12=r12, r11=r11" */ + __asm__ volatile (" \n\ + ;; Check that the register asm declaration got right. \n\ + ;; The GCC manual says it will work, but there *has* been bugs. \n\ + .ifnc %0-%1-%4,$r13-$r12-$r11 \n\ + .err \n\ + .endif \n\ \n\ - ;; Save the registers we'll clobber in the movem process \n\ - ;; on the stack. Don't mention them to gcc, it will only be \n\ - ;; upset. \n\ - subq 11*4,sp \n\ - movem r10,[sp] \n\ + ;; Save the registers we'll clobber in the movem process \n\ + ;; on the stack. Don't mention them to gcc, it will only be \n\ + ;; upset. \n\ + subq 11*4,$sp \n\ + movem $r10,[$sp] \n\ \n\ - move.d r11,r0 \n\ - move.d r11,r1 \n\ - move.d r11,r2 \n\ - move.d r11,r3 \n\ - move.d r11,r4 \n\ - move.d r11,r5 \n\ - move.d r11,r6 \n\ - move.d r11,r7 \n\ - move.d r11,r8 \n\ - move.d r11,r9 \n\ - move.d r11,r10 \n\ + move.d $r11,$r0 \n\ + move.d $r11,$r1 \n\ + move.d $r11,$r2 \n\ + move.d $r11,$r3 \n\ + move.d $r11,$r4 \n\ + move.d $r11,$r5 \n\ + move.d $r11,$r6 \n\ + move.d $r11,$r7 \n\ + move.d $r11,$r8 \n\ + move.d $r11,$r9 \n\ + move.d $r11,$r10 \n\ \n\ - ;; Now we've got this: \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ + ;; Now we've got this: \n\ + ;; r13 - dst \n\ + ;; r12 - n \n\ \n\ - ;; Update n for the first loop \n\ - subq 12*4,r12 \n\ + ;; Update n for the first loop \n\ + subq 12*4,$r12 \n\ 0: \n\ -" -#ifdef __arch_common_v10_v32 - /* Cater to branch offset difference between v32 and v10. We - assume the branch below has an 8-bit offset. */ -" setf\n" -#endif -" subq 12*4,r12 \n\ - bge 0b \n\ - movem r11,[r13+] \n\ + subq 12*4,$r12 \n\ + bge 0b \n\ + movem $r11,[$r13+] \n\ \n\ - ;; Compensate for last loop underflowing n. \n\ - addq 12*4,r12 \n\ + addq 12*4,$r12 ;; compensate for last loop underflowing n \n\ \n\ - ;; Restore registers from stack. \n\ - movem [sp+],r10" - - /* Outputs. */ - : "=r" (dst), "=r" (n) + ;; Restore registers from stack \n\ + movem [$sp+],$r10" - /* Inputs. */ - : "0" (dst), "1" (n), "r" (lc)); - } - - /* An ad-hoc unroll, used for 4*12-1..16 bytes. */ - while (n >= 16) - { - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - n -= 16; - } + /* Outputs */ : "=r" (dst), "=r" (n) + /* Inputs */ : "0" (dst), "1" (n), "r" (lc)); + } + /* Either we directly starts copying, using dword copying + in a loop, or we copy as much as possible with 'movem' + and then the last block (<44 bytes) is copied here. + This will work since 'movem' will have updated src,dst,n. */ + + while ( n >= 16 ) + { + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + n -= 16; + } + + /* A switch() is definitely the fastest although it takes a LOT of code. + * Particularly if you inline code this. + */ switch (n) - { + { case 0: break; - case 1: - *dst = (char) lc; + *(char*)dst = (char) lc; break; - case 2: - *(short *) dst = (short) lc; + *(short*)dst = (short) lc; break; - case 3: - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 4: - *(long *) dst = lc; + *((long*)dst)++ = lc; break; - case 5: - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 6: - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 7: - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 8: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; break; - case 9: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 10: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 11: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - case 12: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; break; - case 13: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(char*)dst = (char) lc; break; - case 14: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *(short*)dst = (short) lc; break; - case 15: - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(long *) dst = lc; dst += 4; - *(short *) dst = (short) lc; dst += 2; - *dst = (char) lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((long*)dst)++ = lc; + *((short*)dst)++ = (short) lc; + *(char*)dst = (char) lc; break; - } + } } - return return_dst; -} + return return_dst; /* destination pointer. */ +} /* memset() */ diff --git a/trunk/arch/m68knommu/platform/5206/Makefile b/trunk/arch/m68knommu/platform/5206/Makefile index a439d9ab3f27..c7bb0cef31a0 100644 --- a/trunk/arch/m68knommu/platform/5206/Makefile +++ b/trunk/arch/m68knommu/platform/5206/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5206e/Makefile b/trunk/arch/m68knommu/platform/5206e/Makefile index a439d9ab3f27..c7bb0cef31a0 100644 --- a/trunk/arch/m68knommu/platform/5206e/Makefile +++ b/trunk/arch/m68knommu/platform/5206e/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/520x/Makefile b/trunk/arch/m68knommu/platform/520x/Makefile index a50e76acc8fd..31b4eb51739d 100644 --- a/trunk/arch/m68knommu/platform/520x/Makefile +++ b/trunk/arch/m68knommu/platform/520x/Makefile @@ -12,6 +12,8 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/523x/Makefile b/trunk/arch/m68knommu/platform/523x/Makefile index 5694d593f029..ac9fbece8a4f 100644 --- a/trunk/arch/m68knommu/platform/523x/Makefile +++ b/trunk/arch/m68knommu/platform/523x/Makefile @@ -12,6 +12,8 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5249/Makefile b/trunk/arch/m68knommu/platform/5249/Makefile index a439d9ab3f27..c7bb0cef31a0 100644 --- a/trunk/arch/m68knommu/platform/5249/Makefile +++ b/trunk/arch/m68knommu/platform/5249/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5272/Makefile b/trunk/arch/m68knommu/platform/5272/Makefile index 26135d92b34d..7475c38c3b4e 100644 --- a/trunk/arch/m68knommu/platform/5272/Makefile +++ b/trunk/arch/m68knommu/platform/5272/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/527x/Makefile b/trunk/arch/m68knommu/platform/527x/Makefile index 26135d92b34d..7475c38c3b4e 100644 --- a/trunk/arch/m68knommu/platform/527x/Makefile +++ b/trunk/arch/m68knommu/platform/527x/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/528x/Makefile b/trunk/arch/m68knommu/platform/528x/Makefile index 26135d92b34d..7475c38c3b4e 100644 --- a/trunk/arch/m68knommu/platform/528x/Makefile +++ b/trunk/arch/m68knommu/platform/528x/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5307/Makefile b/trunk/arch/m68knommu/platform/5307/Makefile index cfd586860fd8..580fd6658d7c 100644 --- a/trunk/arch/m68knommu/platform/5307/Makefile +++ b/trunk/arch/m68knommu/platform/5307/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y += config.o diff --git a/trunk/arch/m68knommu/platform/532x/Makefile b/trunk/arch/m68knommu/platform/532x/Makefile index e431912f5628..475b92866a9b 100644 --- a/trunk/arch/m68knommu/platform/532x/Makefile +++ b/trunk/arch/m68knommu/platform/532x/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif #obj-y := config.o usb-mcf532x.o spi-mcf532x.o obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/5407/Makefile b/trunk/arch/m68knommu/platform/5407/Makefile index e6035e7a2d3f..68633b27df51 100644 --- a/trunk/arch/m68knommu/platform/5407/Makefile +++ b/trunk/arch/m68knommu/platform/5407/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-y := config.o diff --git a/trunk/arch/m68knommu/platform/coldfire/Makefile b/trunk/arch/m68knommu/platform/coldfire/Makefile index 40cf20be1b90..e5fff297ae01 100644 --- a/trunk/arch/m68knommu/platform/coldfire/Makefile +++ b/trunk/arch/m68knommu/platform/coldfire/Makefile @@ -12,7 +12,9 @@ # EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT # -asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 +ifdef CONFIG_FULLDEBUG +AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1 +endif obj-$(CONFIG_COLDFIRE) += dma.o entry.o vectors.o obj-$(CONFIG_M5206) += timers.o diff --git a/trunk/arch/m68knommu/platform/coldfire/entry.S b/trunk/arch/m68knommu/platform/coldfire/entry.S index 111b66dc737b..b333731b875a 100644 --- a/trunk/arch/m68knommu/platform/coldfire/entry.S +++ b/trunk/arch/m68knommu/platform/coldfire/entry.S @@ -197,13 +197,14 @@ ENTRY(fasthandler) RESTORE_LOCAL ENTRY(ret_from_interrupt) + jeq 2f +1: + RESTORE_ALL +2: moveb %sp@(PT_SR),%d0 andl #0x7,%d0 - jeq 1f + jhi 1b - RESTORE_ALL - -1: /* check if we need to do software interrupts */ movel irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0 jeq ret_from_exception diff --git a/trunk/arch/m68knommu/platform/coldfire/timers.c b/trunk/arch/m68knommu/platform/coldfire/timers.c index ba5a9f32ebd4..a60213e877ef 100644 --- a/trunk/arch/m68knommu/platform/coldfire/timers.c +++ b/trunk/arch/m68knommu/platform/coldfire/timers.c @@ -148,32 +148,25 @@ irqreturn_t coldfire_profile_tick(int irq, void *dummy) /* Reset ColdFire timer2 */ __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER)); if (current->pid) - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); return IRQ_HANDLED; } /***************************************************************************/ -static struct irqaction coldfire_profile_irq = { - .name = "profile timer", - .flags = IRQF_DISABLED | IRQF_TIMER, - .handler = coldfire_profile_tick, -}; - void coldfire_profile_init(void) { - printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", - PROFILEHZ); - - setup_irq(mcf_profilevector, &coldfire_profile_irq); + printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); /* Set up TIMER 2 as high speed profile clock */ __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); - __raw_writetrr(((MCF_BUSCLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); + __raw_writetrr(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); + request_irq(mcf_profilevector, coldfire_profile_tick, + (IRQF_DISABLED | IRQ_FLG_FAST), "profile timer", NULL); mcf_settimericr(2, 7); } diff --git a/trunk/arch/mips/kernel/sysirix.c b/trunk/arch/mips/kernel/sysirix.c index 672fba84b2cc..d70c4e0e85fb 100644 --- a/trunk/arch/mips/kernel/sysirix.c +++ b/trunk/arch/mips/kernel/sysirix.c @@ -694,7 +694,7 @@ asmlinkage int irix_statfs(const char __user *path, if (error) goto out; - error = vfs_statfs(nd.path.dentry, &kbuf); + error = vfs_statfs(nd.dentry, &kbuf); if (error) goto dput_and_out; @@ -711,7 +711,7 @@ asmlinkage int irix_statfs(const char __user *path, } dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -1360,7 +1360,7 @@ asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf) error = user_path_walk(fname, &nd); if (error) goto out; - error = vfs_statfs(nd.path.dentry, &kbuf); + error = vfs_statfs(nd.dentry, &kbuf); if (error) goto dput_and_out; @@ -1385,7 +1385,7 @@ asmlinkage int irix_statvfs(char __user *fname, struct irix_statvfs __user *buf) error |= __put_user(0, &buf->f_fstr[i]); dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -1611,7 +1611,7 @@ asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user * error = user_path_walk(fname, &nd); if (error) goto out; - error = vfs_statfs(nd.path.dentry, &kbuf); + error = vfs_statfs(nd.dentry, &kbuf); if (error) goto dput_and_out; @@ -1636,7 +1636,7 @@ asmlinkage int irix_statvfs64(char __user *fname, struct irix_statvfs64 __user * error |= __put_user(0, &buf->f_fstr[i]); dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } diff --git a/trunk/arch/parisc/hpux/sys_hpux.c b/trunk/arch/parisc/hpux/sys_hpux.c index 0c5b9dabb475..3e025df2dc86 100644 --- a/trunk/arch/parisc/hpux/sys_hpux.c +++ b/trunk/arch/parisc/hpux/sys_hpux.c @@ -219,10 +219,10 @@ asmlinkage long hpux_statfs(const char __user *path, error = user_path_walk(path, &nd); if (!error) { struct hpux_statfs tmp; - error = vfs_statfs_hpux(nd.path.dentry, &tmp); + error = vfs_statfs_hpux(nd.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&nd.path); + path_release(&nd); } return error; } diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 5b8d8382b762..485513c9f1af 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -442,6 +442,10 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. +config WANT_DEVICE_TREE + bool + default n + endmenu config ISA_DMA_API diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 63d07ccbb9db..49797a45416c 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -147,8 +147,6 @@ HOSTCFLAGS += -I$(src)/dtc-src/ -I$(src)/libfdt/ targets += dtc-src/dtc-parser.tab.c targets += dtc-src/dtc-lexer.lex.c -clean-files += dtc-src/dtc-parser.tab.h - ifdef DTC_GENPARSER BISON = bison FLEX = flex diff --git a/trunk/arch/powerpc/boot/ps3-hvcall.S b/trunk/arch/powerpc/boot/ps3-hvcall.S index d6068f1829ca..585965f7e6a8 100644 --- a/trunk/arch/powerpc/boot/ps3-hvcall.S +++ b/trunk/arch/powerpc/boot/ps3-hvcall.S @@ -145,7 +145,7 @@ .macro STORE_REGS_5_2 lwz r11, 16(r1) std r4, 0(r11) - lwz r11, 20(r1) + lwz r11, 24(r1) std r5, 0(r11) .endm diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index c1baf9d5903f..0662ae46f724 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -104,5 +104,3 @@ quiet_cmd_systbl_chk = CALL $< PHONY += systbl_chk systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i $(call cmd,systbl_chk) - -clean-files := vmlinux.lds diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 4846bf543a8c..b9d88374f14f 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -462,7 +462,7 @@ void show_regs(struct pt_regs * regs) current, task_pid_nr(current), current->comm, task_thread_info(current)); #ifdef CONFIG_SMP - printk(" CPU: %d", raw_smp_processor_id()); + printk(" CPU: %d", smp_processor_id()); #endif /* CONFIG_SMP */ for (i = 0; i < 32; i++) { diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index d3437c4c4a6f..3702df7dc567 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -336,9 +336,9 @@ static unsigned long __init find_function32(struct lib32_elfinfo *lib, return sym->st_value - VDSO32_LBASE; } -static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, - const char *orig, const char *fix) +static int vdso_do_func_patch32(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64, + const char *orig, const char *fix) { Elf32_Sym *sym32_gen, *sym32_fix; @@ -433,9 +433,9 @@ static unsigned long __init find_function64(struct lib64_elfinfo *lib, #endif } -static int __init vdso_do_func_patch64(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, - const char *orig, const char *fix) +static int vdso_do_func_patch64(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64, + const char *orig, const char *fix) { Elf64_Sym *sym64_gen, *sym64_fix; diff --git a/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c b/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c index 257b13cb18af..4a890cb42b98 100644 --- a/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/trunk/arch/powerpc/oprofile/cell/spu_task_sync.c @@ -198,13 +198,14 @@ static int release_cached_info(int spu_index) * dcookie user still being registered (namely, the reader * of the event buffer). */ -static inline unsigned long fast_get_dcookie(struct path *path) +static inline unsigned long fast_get_dcookie(struct dentry *dentry, + struct vfsmount *vfsmnt) { unsigned long cookie; - if (path->dentry->d_cookie) - return (unsigned long)path->dentry; - get_dcookie(path, &cookie); + if (dentry->d_cookie) + return (unsigned long)dentry; + get_dcookie(dentry, vfsmnt, &cookie); return cookie; } @@ -239,7 +240,8 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, continue; if (!(vma->vm_flags & VM_EXECUTABLE)) continue; - app_cookie = fast_get_dcookie(&vma->vm_file->f_path); + app_cookie = fast_get_dcookie(vma->vm_file->f_dentry, + vma->vm_file->f_vfsmnt); pr_debug("got dcookie for %s\n", vma->vm_file->f_dentry->d_name.name); app = vma->vm_file; @@ -260,7 +262,8 @@ get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, break; } - *spu_bin_dcookie = fast_get_dcookie(&vma->vm_file->f_path); + *spu_bin_dcookie = fast_get_dcookie(vma->vm_file->f_dentry, + vma->vm_file->f_vfsmnt); pr_debug("got dcookie for %s\n", vma->vm_file->f_dentry->d_name.name); up_read(&mm->mmap_sem); diff --git a/trunk/arch/powerpc/platforms/512x/Kconfig b/trunk/arch/powerpc/platforms/512x/Kconfig index 4c0da0c079e9..c6fa49e23dc0 100644 --- a/trunk/arch/powerpc/platforms/512x/Kconfig +++ b/trunk/arch/powerpc/platforms/512x/Kconfig @@ -13,6 +13,7 @@ config MPC5121_ADS bool "Freescale MPC5121E ADS" depends on PPC_MULTIPLATFORM && PPC32 select DEFAULT_UIMAGE + select WANT_DEVICE_TREE select PPC_MPC5121 help This option enables support for the MPC5121E ADS board. diff --git a/trunk/arch/powerpc/platforms/52xx/Kconfig b/trunk/arch/powerpc/platforms/52xx/Kconfig index cf945d55c276..515f244c90bb 100644 --- a/trunk/arch/powerpc/platforms/52xx/Kconfig +++ b/trunk/arch/powerpc/platforms/52xx/Kconfig @@ -8,6 +8,7 @@ config PPC_MPC5200_SIMPLE bool "Generic support for simple MPC5200 based boards" depends on PPC_MPC52xx select DEFAULT_UIMAGE + select WANT_DEVICE_TREE help This option enables support for a simple MPC52xx based boards which do not need a custom platform specific setup. Such boards are @@ -34,6 +35,7 @@ config PPC_LITE5200 bool "Freescale Lite5200 Eval Board" depends on PPC_MPC52xx select DEFAULT_UIMAGE + select WANT_DEVICE_TREE config PPC_MPC5200_BUGFIX bool "MPC5200 (L25R) bugfix support" diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig index 0afd22595546..fcedbec07f94 100644 --- a/trunk/arch/powerpc/platforms/Kconfig +++ b/trunk/arch/powerpc/platforms/Kconfig @@ -15,6 +15,7 @@ config PPC_MULTIPLATFORM config PPC_82xx bool "Freescale 82xx" depends on 6xx + select WANT_DEVICE_TREE config PPC_83xx bool "Freescale 83xx" @@ -22,6 +23,7 @@ config PPC_83xx select FSL_SOC select MPC83xx select IPIC + select WANT_DEVICE_TREE select FSL_EMB_PERFMON config PPC_86xx diff --git a/trunk/arch/powerpc/platforms/Kconfig.cputype b/trunk/arch/powerpc/platforms/Kconfig.cputype index 73d81ce14b67..69941ba70975 100644 --- a/trunk/arch/powerpc/platforms/Kconfig.cputype +++ b/trunk/arch/powerpc/platforms/Kconfig.cputype @@ -29,22 +29,26 @@ config PPC_85xx bool "Freescale 85xx" select E500 select FSL_SOC + select WANT_DEVICE_TREE select MPC85xx config PPC_8xx bool "Freescale 8xx" select FSL_SOC select 8xx + select WANT_DEVICE_TREE select PPC_LIB_RHEAP config 40x bool "AMCC 40x" select PPC_DCR_NATIVE + select WANT_DEVICE_TREE select PPC_UDBG_16550 config 44x bool "AMCC 44x" select PPC_DCR_NATIVE + select WANT_DEVICE_TREE select PPC_UDBG_16550 config E200 diff --git a/trunk/arch/powerpc/platforms/cell/ras.c b/trunk/arch/powerpc/platforms/cell/ras.c index e43024c0392e..b2494ebcdbe9 100644 --- a/trunk/arch/powerpc/platforms/cell/ras.c +++ b/trunk/arch/powerpc/platforms/cell/ras.c @@ -1,13 +1,4 @@ -/* - * Copyright 2006-2008, IBM Corporation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#undef DEBUG +#define DEBUG #include #include diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 6d1228c66c5e..e6e6559c55ed 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -1,4 +1,3 @@ - /* * SPU file system * @@ -593,7 +592,7 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, ret = -EINVAL; /* check if we are on spufs */ - if (nd->path.dentry->d_sb->s_type != &spufs_type) + if (nd->dentry->d_sb->s_type != &spufs_type) goto out; /* don't accept undefined flags */ @@ -601,9 +600,9 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, goto out; /* only threads can be underneath a gang */ - if (nd->path.dentry != nd->path.dentry->d_sb->s_root) { + if (nd->dentry != nd->dentry->d_sb->s_root) { if ((flags & SPU_CREATE_GANG) || - !SPUFS_I(nd->path.dentry->d_inode)->i_gang) + !SPUFS_I(nd->dentry->d_inode)->i_gang) goto out; } @@ -619,17 +618,16 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, mode &= ~current->fs->umask; if (flags & SPU_CREATE_GANG) - return spufs_create_gang(nd->path.dentry->d_inode, - dentry, nd->path.mnt, mode); + return spufs_create_gang(nd->dentry->d_inode, + dentry, nd->mnt, mode); else - return spufs_create_context(nd->path.dentry->d_inode, - dentry, nd->path.mnt, flags, mode, - filp); + return spufs_create_context(nd->dentry->d_inode, + dentry, nd->mnt, flags, mode, filp); out_dput: dput(dentry); out_dir: - mutex_unlock(&nd->path.dentry->d_inode->i_mutex); + mutex_unlock(&nd->dentry->d_inode->i_mutex); out: return ret; } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c index 49c87769b1f8..430404413178 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -73,7 +73,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags, LOOKUP_OPEN|LOOKUP_CREATE, &nd); if (!ret) { ret = spufs_create(&nd, flags, mode, neighbor); - path_put(&nd.path); + path_release(&nd); } putname(tmp); } diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig index 429088967813..6c8083757938 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig @@ -24,6 +24,7 @@ config STORCENTER select MPIC select FSL_SOC select PPC_UDBG_16550 if SERIAL_8250 + select WANT_DEVICE_TREE select MPC10X_OPENPIC select MPC10X_BRIDGE help @@ -36,6 +37,7 @@ config MPC7448HPC2 select TSI108_BRIDGE select DEFAULT_UIMAGE select PPC_UDBG_16550 + select WANT_DEVICE_TREE select TSI108_BRIDGE help Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) @@ -46,6 +48,7 @@ config PPC_HOLLY depends on EMBEDDED6xx select TSI108_BRIDGE select PPC_UDBG_16550 + select WANT_DEVICE_TREE select TSI108_BRIDGE help Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval @@ -56,6 +59,7 @@ config PPC_PRPMC2800 depends on EMBEDDED6xx select MV64X60 select NOT_COHERENT_CACHE + select WANT_DEVICE_TREE help This option enables support for the Motorola PrPMC2800 board diff --git a/trunk/arch/powerpc/platforms/iseries/vio.c b/trunk/arch/powerpc/platforms/iseries/vio.c index 657b72f68493..be06cfd9fa3d 100644 --- a/trunk/arch/powerpc/platforms/iseries/vio.c +++ b/trunk/arch/powerpc/platforms/iseries/vio.c @@ -75,7 +75,7 @@ static struct property *new_property(const char *name, int length, return np; } -static void free_property(struct property *np) +static void __init free_property(struct property *np) { kfree(np); } diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index b3400b5ad5c6..d87d4bf88803 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -93,9 +93,6 @@ config ARCH_NO_VIRT_TO_BUS config ARCH_SUPPORTS_AOUT def_bool y -config IO_TRAPPED - bool - source "init/Kconfig" menu "System type" @@ -315,13 +312,6 @@ config CPU_SUBTYPE_SH7722 select ARCH_SPARSEMEM_ENABLE select SYS_SUPPORTS_NUMA -config CPU_SUBTYPE_SH7366 - bool "Support SH7366 processor" - select CPU_SH4AL_DSP - select CPU_SHX2 - select ARCH_SPARSEMEM_ENABLE - select SYS_SUPPORTS_NUMA - # SH-5 Processor Support config CPU_SUBTYPE_SH5_101 @@ -466,7 +456,6 @@ config SH_RTS7751R2D bool "RTS7751R2D" depends on CPU_SUBTYPE_SH7751R select SYS_SUPPORTS_PCI - select IO_TRAPPED help Select RTS7751R2D if configuring for a Renesas Technology Sales SH-Graphics board. @@ -483,14 +472,6 @@ config SH_HIGHLANDER bool "Highlander" depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 select SYS_SUPPORTS_PCI - select IO_TRAPPED - -config SH_MIGOR - bool "Migo-R" - depends on CPU_SUBTYPE_SH7722 - help - Select Migo-R if configuring for the SH7722 Migo-R platform - by Renesas System Solutions Asia Pte. Ltd. config SH_EDOSK7705 bool "EDOSK7705" diff --git a/trunk/arch/sh/Kconfig.cpu b/trunk/arch/sh/Kconfig.cpu index 0e27fe3b182b..d850184d0694 100644 --- a/trunk/arch/sh/Kconfig.cpu +++ b/trunk/arch/sh/Kconfig.cpu @@ -12,7 +12,6 @@ config CPU_LITTLE_ENDIAN config CPU_BIG_ENDIAN bool "Big Endian" - depends on !CPU_SH5 endchoice @@ -88,6 +87,9 @@ config SH64_ID2815_WORKAROUND config CPU_HAS_INTEVT bool +config CPU_HAS_MASKREG_IRQ + bool + config CPU_HAS_IPR_IRQ bool diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug index 5dcb74b947a9..f7c716166ce8 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -29,8 +29,7 @@ config EARLY_SCIF_CONSOLE config EARLY_SCIF_CONSOLE_PORT hex depends on EARLY_SCIF_CONSOLE - default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 - default "0xffe00000" if CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 + default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 default "0xffea0000" if CPU_SUBTYPE_SH7785 default "0xfffe8000" if CPU_SUBTYPE_SH7203 default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263 diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index 81381e5773c8..17fc36186bf4 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -116,7 +116,6 @@ machdir-$(CONFIG_SH_RTS7751R2D) += renesas/rts7751r2d machdir-$(CONFIG_SH_7751_SYSTEMH) += renesas/systemh machdir-$(CONFIG_SH_EDOSK7705) += renesas/edosk7705 machdir-$(CONFIG_SH_HIGHLANDER) += renesas/r7780rp -machdir-$(CONFIG_SH_MIGOR) += renesas/migor machdir-$(CONFIG_SH_SDK7780) += renesas/sdk7780 machdir-$(CONFIG_SH_7710VOIPGW) += renesas/sh7710voipgw machdir-$(CONFIG_SH_X3PROTO) += renesas/x3proto diff --git a/trunk/arch/sh/boards/renesas/migor/Makefile b/trunk/arch/sh/boards/renesas/migor/Makefile deleted file mode 100644 index 77037567633b..000000000000 --- a/trunk/arch/sh/boards/renesas/migor/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y := setup.o diff --git a/trunk/arch/sh/boards/renesas/migor/setup.c b/trunk/arch/sh/boards/renesas/migor/setup.c deleted file mode 100644 index 21ab8c8fb590..000000000000 --- a/trunk/arch/sh/boards/renesas/migor/setup.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Renesas System Solutions Asia Pte. Ltd - Migo-R - * - * Copyright (C) 2008 Magnus Damm - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -/* Address IRQ Size Bus Description - * 0x00000000 64MB 16 NOR Flash (SP29PL256N) - * 0x0c000000 64MB 64 SDRAM (2xK4M563233G) - * 0x10000000 IRQ0 16 Ethernet (SMC91C111) - * 0x14000000 IRQ4 16 USB 2.0 Host Controller (M66596) - * 0x18000000 8GB 8 NAND Flash (K9K8G08U0A) - */ - -static struct resource smc91x_eth_resources[] = { - [0] = { - .name = "smc91x-regs" , - .start = P2SEGADDR(0x10000300), - .end = P2SEGADDR(0x1000030f), - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 32, /* IRQ0 */ - .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH, - }, -}; - -static struct platform_device smc91x_eth_device = { - .name = "smc91x", - .num_resources = ARRAY_SIZE(smc91x_eth_resources), - .resource = smc91x_eth_resources, -}; - -static struct platform_device *migor_devices[] __initdata = { - &smc91x_eth_device, -}; - -static int __init migor_devices_setup(void) -{ - return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); -} -__initcall(migor_devices_setup); - -static void __init migor_setup(char **cmdline_p) -{ - ctrl_outw(0x1000, 0xa4050110); /* Enable IRQ0 in PJCR */ -} - -static struct sh_machine_vector mv_migor __initmv = { - .mv_name = "Migo-R", - .mv_setup = migor_setup, -}; diff --git a/trunk/arch/sh/boards/renesas/r7780rp/setup.c b/trunk/arch/sh/boards/renesas/r7780rp/setup.c index 2f68bea7890c..f7a8d5c9d510 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/setup.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/setup.c @@ -23,7 +23,6 @@ #include #include #include -#include static struct resource r8a66597_usb_host_resources[] = { [0] = { @@ -182,27 +181,13 @@ static struct platform_device *r7780rp_devices[] __initdata = { &m66592_usb_peripheral_device, &heartbeat_device, #ifndef CONFIG_SH_R7780RP + &cf_ide_device, &ax88796_device, #endif }; -/* - * The CF is connected using a 16-bit bus where 8-bit operations are - * unsupported. The linux ata driver is however using 8-bit operations, so - * insert a trapped io filter to convert 8-bit operations into 16-bit. - */ -static struct trapped_io cf_trapped_io = { - .resource = cf_ide_resources, - .num_resources = 2, - .minimum_bus_width = 16, -}; - static int __init r7780rp_devices_setup(void) { -#ifndef CONFIG_SH_R7780RP - if (register_trapped_io(&cf_trapped_io) == 0) - platform_device_register(&cf_ide_device); -#endif return platform_add_devices(r7780rp_devices, ARRAY_SIZE(r7780rp_devices)); } @@ -241,6 +226,34 @@ static void r7780rp_power_off(void) ctrl_outw(0x0001, PA_POFF); } +static inline unsigned char is_ide_ioaddr(unsigned long addr) +{ + return ((cf_ide_resources[0].start <= addr && + addr <= cf_ide_resources[0].end) || + (cf_ide_resources[1].start <= addr && + addr <= cf_ide_resources[1].end)); +} + +void highlander_writeb(u8 b, void __iomem *addr) +{ + unsigned long tmp = (unsigned long __force)addr; + + if (is_ide_ioaddr(tmp)) + ctrl_outw((u16)b, tmp); + else + ctrl_outb(b, tmp); +} + +u8 highlander_readb(void __iomem *addr) +{ + unsigned long tmp = (unsigned long __force)addr; + + if (is_ide_ioaddr(tmp)) + return ctrl_inw(tmp) & 0xff; + else + return ctrl_inb(tmp); +} + /* * Initialize the board */ @@ -325,4 +338,6 @@ static struct sh_machine_vector mv_highlander __initmv = { .mv_setup = highlander_setup, .mv_init_irq = highlander_init_irq, .mv_irq_demux = highlander_irq_demux, + .mv_readb = highlander_readb, + .mv_writeb = highlander_writeb, }; diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c index f21ee49ef3a5..a0ef81b7de37 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -21,7 +21,6 @@ #include #include #include -#include #include static struct resource cf_ide_resources[] = { @@ -215,25 +214,13 @@ static struct platform_device *rts7751r2d_devices[] __initdata = { &uart_device, &sm501_device, #endif + &cf_ide_device, &heartbeat_device, &spi_sh_sci_device, }; -/* - * The CF is connected with a 16-bit bus where 8-bit operations are - * unsupported. The linux ata driver is however using 8-bit operations, so - * insert a trapped io filter to convert 8-bit operations into 16-bit. - */ -static struct trapped_io cf_trapped_io = { - .resource = cf_ide_resources, - .num_resources = 2, - .minimum_bus_width = 16, -}; - static int __init rts7751r2d_devices_setup(void) { - if (register_trapped_io(&cf_trapped_io) == 0) - platform_device_register(&cf_ide_device); spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); return platform_add_devices(rts7751r2d_devices, ARRAY_SIZE(rts7751r2d_devices)); @@ -245,6 +232,34 @@ static void rts7751r2d_power_off(void) ctrl_outw(0x0001, PA_POWOFF); } +static inline unsigned char is_ide_ioaddr(unsigned long addr) +{ + return ((cf_ide_resources[0].start <= addr && + addr <= cf_ide_resources[0].end) || + (cf_ide_resources[1].start <= addr && + addr <= cf_ide_resources[1].end)); +} + +void rts7751r2d_writeb(u8 b, void __iomem *addr) +{ + unsigned long tmp = (unsigned long __force)addr; + + if (is_ide_ioaddr(tmp)) + ctrl_outw((u16)b, tmp); + else + ctrl_outb(b, tmp); +} + +u8 rts7751r2d_readb(void __iomem *addr) +{ + unsigned long tmp = (unsigned long __force)addr; + + if (is_ide_ioaddr(tmp)) + return ctrl_inw(tmp) & 0xff; + else + return ctrl_inb(tmp); +} + /* * Initialize the board */ @@ -295,4 +310,6 @@ static struct sh_machine_vector mv_rts7751r2d __initmv = { .mv_setup = rts7751r2d_setup, .mv_init_irq = init_rts7751r2d_IRQ, .mv_irq_demux = rts7751r2d_irq_demux, + .mv_writeb = rts7751r2d_writeb, + .mv_readb = rts7751r2d_readb, }; diff --git a/trunk/arch/sh/boards/renesas/sdk7780/Kconfig b/trunk/arch/sh/boards/renesas/sdk7780/Kconfig index 065f1df09bf1..e4f5b6985be1 100644 --- a/trunk/arch/sh/boards/renesas/sdk7780/Kconfig +++ b/trunk/arch/sh/boards/renesas/sdk7780/Kconfig @@ -4,6 +4,13 @@ choice prompt "SDK7780 options" default SH_SDK7780_BASE +config SH_SDK7780_STANDALONE + bool "SDK7780 board support" + depends on CPU_SUBTYPE_SH7780 + help + Selecting this option will enable support for the + standalone version of the SDK7780. If in doubt, say Y. + config SH_SDK7780_BASE bool "SDK7780 with base-board support" depends on CPU_SUBTYPE_SH7780 diff --git a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c index 9b8820c36701..5cef0db4018b 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -17,8 +17,10 @@ #include #include #include + #include #include + #include static void disable_hd64465_irq(unsigned int irq) @@ -26,45 +28,51 @@ static void disable_hd64465_irq(unsigned int irq) unsigned short nimr; unsigned short mask = 1 << (irq - HD64465_IRQ_BASE); - pr_debug("disable_hd64465_irq(%d): mask=%x\n", irq, mask); + pr_debug("disable_hd64465_irq(%d): mask=%x\n", irq, mask); nimr = inw(HD64465_REG_NIMR); nimr |= mask; outw(nimr, HD64465_REG_NIMR); } + static void enable_hd64465_irq(unsigned int irq) { unsigned short nimr; unsigned short mask = 1 << (irq - HD64465_IRQ_BASE); - pr_debug("enable_hd64465_irq(%d): mask=%x\n", irq, mask); + pr_debug("enable_hd64465_irq(%d): mask=%x\n", irq, mask); nimr = inw(HD64465_REG_NIMR); nimr &= ~mask; outw(nimr, HD64465_REG_NIMR); } + static void mask_and_ack_hd64465(unsigned int irq) { disable_hd64465_irq(irq); } + static void end_hd64465_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_hd64465_irq(irq); } + static unsigned int startup_hd64465_irq(unsigned int irq) -{ +{ enable_hd64465_irq(irq); return 0; } + static void shutdown_hd64465_irq(unsigned int irq) { disable_hd64465_irq(irq); } + static struct hw_interrupt_type hd64465_irq_type = { .typename = "HD64465-IRQ", .startup = startup_hd64465_irq, @@ -75,6 +83,7 @@ static struct hw_interrupt_type hd64465_irq_type = { .end = end_hd64465_irq, }; + static irqreturn_t hd64465_interrupt(int irq, void *dev_id) { printk(KERN_INFO @@ -84,6 +93,9 @@ static irqreturn_t hd64465_interrupt(int irq, void *dev_id) return IRQ_NONE; } + +/*====================================================*/ + /* * Support for a secondary IRQ demux step. This is necessary * because the HD64465 presents a very thin interface to the @@ -91,7 +103,8 @@ static irqreturn_t hd64465_interrupt(int irq, void *dev_id) * normally done in hardware by other PCMCIA host bridges is * instead done in software. */ -static struct { +static struct +{ int (*func)(int, void *); void *dev; } hd64465_demux[HD64465_IRQ_NUM]; @@ -99,17 +112,19 @@ static struct { void hd64465_register_irq_demux(int irq, int (*demux)(int irq, void *dev), void *dev) { - hd64465_demux[irq - HD64465_IRQ_BASE].func = demux; - hd64465_demux[irq - HD64465_IRQ_BASE].dev = dev; + hd64465_demux[irq - HD64465_IRQ_BASE].func = demux; + hd64465_demux[irq - HD64465_IRQ_BASE].dev = dev; } EXPORT_SYMBOL(hd64465_register_irq_demux); void hd64465_unregister_irq_demux(int irq) { - hd64465_demux[irq - HD64465_IRQ_BASE].func = 0; + hd64465_demux[irq - HD64465_IRQ_BASE].func = 0; } EXPORT_SYMBOL(hd64465_unregister_irq_demux); + + int hd64465_irq_demux(int irq) { if (irq == CONFIG_HD64465_IRQ) { @@ -117,16 +132,16 @@ int hd64465_irq_demux(int irq) unsigned short nirr = inw(HD64465_REG_NIRR); unsigned short nimr = inw(HD64465_REG_NIMR); - pr_debug("hd64465_irq_demux, nirr=%04x, nimr=%04x\n", nirr, nimr); + pr_debug("hd64465_irq_demux, nirr=%04x, nimr=%04x\n", nirr, nimr); nirr &= ~nimr; for (bit = 1, i = 0 ; i < HD64465_IRQ_NUM ; bit <<= 1, i++) if (nirr & bit) - break; + break; - if (i < HD64465_IRQ_NUM) { + if (i < HD64465_IRQ_NUM) { irq = HD64465_IRQ_BASE + i; - if (hd64465_demux[i].func != 0) - irq = hd64465_demux[i].func(irq, hd64465_demux[i].dev); + if (hd64465_demux[i].func != 0) + irq = hd64465_demux[i].func(irq, hd64465_demux[i].dev); } } return irq; @@ -139,6 +154,7 @@ static struct irqaction irq0 = { .name = "HD64465", }; + static int __init setup_hd64465(void) { int i; @@ -160,8 +176,8 @@ static int __init setup_hd64465(void) rev = inw(HD64465_REG_SRR); printk(KERN_INFO "HD64465 hardware revision %d.%d\n", (rev >> 8) & 0xff, rev & 0xff); - - outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */ + + outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */ for (i = 0; i < HD64465_IRQ_NUM ; i++) { irq_desc[HD64465_IRQ_BASE + i].chip = &hd64465_irq_type; @@ -169,13 +185,16 @@ static int __init setup_hd64465(void) setup_irq(CONFIG_HD64465_IRQ, &irq0); +#ifdef CONFIG_SERIAL /* wake up the UART from STANDBY at this point */ smscr = inw(HD64465_REG_SMSCR); outw(smscr & (~HD64465_SMSCR_UARTST), HD64465_REG_SMSCR); /* remap IO ports for first ISA serial port to HD64465 UART */ hd64465_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1); +#endif return 0; } + module_init(setup_hd64465); diff --git a/trunk/arch/sh/configs/migor_defconfig b/trunk/arch/sh/configs/migor_defconfig deleted file mode 100644 index ee5900817f8f..000000000000 --- a/trunk/arch/sh/configs/migor_defconfig +++ /dev/null @@ -1,824 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.24 -# Wed Feb 6 21:52:20 2008 -# -CONFIG_SUPERH=y -CONFIG_SUPERH32=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_SYS_SUPPORTS_NUMA=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_NO_VIRT_TO_BUS=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -# CONFIG_MARKERS is not set -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y -# CONFIG_PREEMPT_RCU is not set - -# -# System type -# -CONFIG_CPU_SH4=y -CONFIG_CPU_SH4A=y -CONFIG_CPU_SH4AL_DSP=y -CONFIG_CPU_SHX2=y -# CONFIG_CPU_SUBTYPE_SH7619 is not set -# CONFIG_CPU_SUBTYPE_SH7203 is not set -# CONFIG_CPU_SUBTYPE_SH7206 is not set -# CONFIG_CPU_SUBTYPE_SH7263 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set -# CONFIG_CPU_SUBTYPE_SH7712 is not set -# CONFIG_CPU_SUBTYPE_SH7720 is not set -# CONFIG_CPU_SUBTYPE_SH7721 is not set -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set -# CONFIG_CPU_SUBTYPE_SH7763 is not set -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set -# CONFIG_CPU_SUBTYPE_SH7785 is not set -# CONFIG_CPU_SUBTYPE_SHX3 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set -CONFIG_CPU_SUBTYPE_SH7722=y -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set - -# -# Memory management options -# -CONFIG_QUICKLIST=y -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x04000000 -CONFIG_29BIT=y -# CONFIG_X2TLB is not set -CONFIG_VSYSCALL=y -CONFIG_NUMA=y -CONFIG_NODES_SHIFT=1 -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_MAX_ACTIVE_REGIONS=2 -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_SELECT_MEMORY_MODEL=y -# CONFIG_FLATMEM_MANUAL is not set -# CONFIG_DISCONTIGMEM_MANUAL is not set -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM=y -CONFIG_NEED_MULTIPLE_NODES=y -CONFIG_HAVE_MEMORY_PRESENT=y -CONFIG_SPARSEMEM_STATIC=y -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -# CONFIG_MEMORY_HOTPLUG is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_MIGRATION is not set -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -CONFIG_CACHE_WRITEBACK=y -# CONFIG_CACHE_WRITETHROUGH is not set -# CONFIG_CACHE_OFF is not set - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_BIG_ENDIAN is not set -# CONFIG_SH_FPU_EMU is not set -CONFIG_SH_DSP=y -# CONFIG_SH_STORE_QUEUES is not set -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_SR_RB=y -CONFIG_CPU_HAS_PTEA=y -CONFIG_CPU_HAS_DSP=y - -# -# Board support -# -# CONFIG_SH_7722_SOLUTION_ENGINE is not set -CONFIG_SH_MIGOR=y - -# -# Timer and clock configuration -# -CONFIG_SH_TMU=y -CONFIG_SH_TIMER_IRQ=16 -CONFIG_SH_PCLK_FREQ=33333333 -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# - -# -# Additional SuperH Device Drivers -# -# CONFIG_HEARTBEAT is not set -# CONFIG_PUSH_SWITCH is not set - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_RCU_TRACE=y -CONFIG_GUSA=y - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=serial ip=on" - -# -# Bus options -# -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE 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 -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC 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_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_EXT=y -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_PHYLIB is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_AX88796 is not set -# CONFIG_STNIC is not set -CONFIG_SMC91X=y -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=3 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_DEBUG_FS is not set -CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_AMD5536UDC is not set -# CONFIG_USB_GADGET_ATMEL_USBA is not set -# CONFIG_USB_GADGET_FSL_USB2 is not set -# CONFIG_USB_GADGET_NET2280 is not set -# CONFIG_USB_GADGET_PXA2XX is not set -CONFIG_USB_GADGET_M66592=y -CONFIG_USB_M66592=y -CONFIG_SUPERH_BUILT_IN_M66592=y -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_S3C2410 is not set -# CONFIG_USB_GADGET_AT91 is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -CONFIG_USB_GADGET_DUALSPEED=y -# CONFIG_USB_ZERO is not set -# CONFIG_USB_ETH is not set -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FILE_STORAGE is not set -CONFIG_USB_G_SERIAL=y -# CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_G_PRINTER is not set -# CONFIG_MMC is not set -# CONFIG_NEW_LEDS is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_SH=y - -# -# Userspace I/O -# -# CONFIG_UIO is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_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_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS 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_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -# CONFIG_NETWORK_FILESYSTEMS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set -# CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe00000 -CONFIG_EARLY_PRINTK=y -# CONFIG_SH_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_SEQIV is not set -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/trunk/arch/sh/configs/rts7751r2d1_defconfig b/trunk/arch/sh/configs/rts7751r2d1_defconfig index 3a915fd436d9..2dc754e5b733 100644 --- a/trunk/arch/sh/configs/rts7751r2d1_defconfig +++ b/trunk/arch/sh/configs/rts7751r2d1_defconfig @@ -1,10 +1,9 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24 -# Thu Feb 7 16:25:55 2008 +# Linux kernel version: 2.6.23-rc2 +# Tue Aug 14 18:04:44 2007 # CONFIG_SUPERH=y -CONFIG_SUPERH32=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -37,14 +36,9 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set # CONFIG_BLK_DEV_INITRD is not set @@ -59,7 +53,6 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y @@ -72,13 +65,6 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_PROFILING=y -# CONFIG_MARKERS is not set -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -105,17 +91,13 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y -# CONFIG_PREEMPT_RCU is not set # # System type # CONFIG_CPU_SH4=y # CONFIG_CPU_SUBTYPE_SH7619 is not set -# CONFIG_CPU_SUBTYPE_SH7203 is not set # CONFIG_CPU_SUBTYPE_SH7206 is not set -# CONFIG_CPU_SUBTYPE_SH7263 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set # CONFIG_CPU_SUBTYPE_SH7707 is not set @@ -123,8 +105,6 @@ CONFIG_CPU_SH4=y # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set # CONFIG_CPU_SUBTYPE_SH7712 is not set -# CONFIG_CPU_SUBTYPE_SH7720 is not set -# CONFIG_CPU_SUBTYPE_SH7721 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -133,15 +113,14 @@ CONFIG_CPU_SH4=y CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set -# CONFIG_CPU_SUBTYPE_SH7763 is not set +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set # CONFIG_CPU_SUBTYPE_SH7785 is not set # CONFIG_CPU_SUBTYPE_SHX3 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -151,7 +130,6 @@ CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 -CONFIG_29BIT=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -169,7 +147,6 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPARSEMEM_STATIC=y -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 @@ -191,22 +168,23 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SH_FPU=y # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC_IRQ=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y -CONFIG_CPU_HAS_FPU=y # # Board support # # CONFIG_SH_7751_SYSTEMH is not set # CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set CONFIG_SH_RTS7751R2D=y # CONFIG_SH_LANDISK is not set # CONFIG_SH_TITAN is not set # CONFIG_SH_LBOX_RE2 is not set # -# RTS7751R2D Board Revision +# RTS7751R2D options # # CONFIG_RTS7751R2D_PLUS is not set CONFIG_RTS7751R2D_1=y @@ -220,7 +198,6 @@ CONFIG_SH_PCLK_FREQ=60000000 # CONFIG_TICK_ONESHOT is not set # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # CPU Frequency scaling @@ -250,15 +227,11 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_RCU_TRACE=y -CONFIG_GUSA=y -# CONFIG_GUSA_RB is not set # # Boot options @@ -277,7 +250,10 @@ CONFIG_SH_PCIDMA_NONCOHERENT=y CONFIG_PCI_AUTO=y CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y + +# +# PCCARD (PCMCIA/CardBus) support +# # CONFIG_PCCARD is not set CONFIG_HOTPLUG_PCI=y # CONFIG_HOTPLUG_PCI_FAKE is not set @@ -305,7 +281,6 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -324,7 +299,6 @@ CONFIG_IP_FIB_HASH=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -350,6 +324,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set # @@ -357,7 +335,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -379,7 +356,6 @@ CONFIG_WIRELESS_EXT=y # # Generic Driver Options # -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m @@ -395,7 +371,6 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 @@ -445,7 +420,6 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set @@ -519,9 +493,7 @@ CONFIG_ATA=y # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set # CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set # CONFIG_PATA_PDC_OLD is not set @@ -536,7 +508,14 @@ CONFIG_ATA=y # CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y # CONFIG_MD is not set + +# +# Fusion MPT device support +# # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -551,31 +530,25 @@ CONFIG_NETDEVICES=y # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_VETH is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_AX88796 is not set # CONFIG_STNIC is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set -# CONFIG_ENC28J60 is not set # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set @@ -587,7 +560,6 @@ CONFIG_8139TOO=y # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -598,10 +570,6 @@ CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_E1000E_ENABLED is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -609,7 +577,6 @@ CONFIG_NETDEV_1000=y # CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set @@ -618,15 +585,11 @@ CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set -# CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set -# CONFIG_TEHUTI is not set -# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -634,21 +597,13 @@ CONFIG_NETDEV_10000=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -667,6 +622,7 @@ CONFIG_INPUT=y # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set @@ -694,7 +650,6 @@ CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set # # Serial drivers @@ -719,9 +674,11 @@ CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set +# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y @@ -730,30 +687,16 @@ CONFIG_DEVPORT=y # # SPI support # -CONFIG_SPI=y -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -CONFIG_SPI_BITBANG=y -CONFIG_SPI_SH_SCI=y - -# -# SPI Protocol Masters -# -# CONFIG_SPI_AT25 is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set @@ -765,13 +708,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set # # Multifunction device drivers @@ -784,12 +720,16 @@ CONFIG_MFD_SM501=y # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set # # Graphics support # -# CONFIG_DRM is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y @@ -798,7 +738,6 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set @@ -838,12 +777,6 @@ CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_PM3 is not set CONFIG_FB_SM501=y # CONFIG_FB_VIRTUAL is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set # # Console display driver support @@ -911,7 +844,6 @@ CONFIG_SND_AC97_CODEC=m # CONFIG_SND_BT87X is not set # CONFIG_SND_CA0106 is not set # CONFIG_SND_CMIPCI is not set -# CONFIG_SND_OXYGEN is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set # CONFIG_SND_DARLA20 is not set @@ -936,7 +868,6 @@ CONFIG_SND_AC97_CODEC=m # CONFIG_SND_HDA_INTEL is not set # CONFIG_SND_HDSP is not set # CONFIG_SND_HDSPM is not set -# CONFIG_SND_HIFIER is not set # CONFIG_SND_ICE1712 is not set # CONFIG_SND_ICE1724 is not set # CONFIG_SND_INTEL8X0 is not set @@ -954,26 +885,15 @@ CONFIG_SND_AC97_CODEC=m # CONFIG_SND_TRIDENT is not set # CONFIG_SND_VIA82XX is not set # CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VIRTUOSO is not set # CONFIG_SND_VX222 is not set CONFIG_SND_YMFPCI=m CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y # CONFIG_SND_AC97_POWER_SAVE is not set -# -# SPI devices -# - # # SUPERH devices # -# -# USB devices -# -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set - # # System on Chip audio support # @@ -983,10 +903,6 @@ CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y # SoC Audio support for SuperH # -# -# ALSA SoC audio for Freescale SOCs -# - # # Open Sound System # @@ -998,104 +914,19 @@ CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_USB is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # # -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -CONFIG_USB_LIBUSUAL=y - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_MON is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers +# USB Gadget Support # -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set # CONFIG_NEW_LEDS is not set @@ -1118,17 +949,13 @@ CONFIG_RTC_INTF_DEV=y # # SPI RTC drivers # -# CONFIG_RTC_DRV_MAX6902 is not set -CONFIG_RTC_DRV_R9701=y -# CONFIG_RTC_DRV_RS5C348 is not set # # Platform RTC drivers # -# CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set @@ -1136,7 +963,20 @@ CONFIG_RTC_DRV_R9701=y # # on-CPU RTC drivers # -# CONFIG_RTC_DRV_SH is not set +CONFIG_RTC_DRV_SH=y + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# # # Userspace I/O @@ -1194,6 +1034,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1212,7 +1053,10 @@ CONFIG_TMPFS=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y + +# +# Network File Systems +# # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set @@ -1226,6 +1070,10 @@ CONFIG_NETWORK_FILESYSTEMS=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1266,22 +1114,30 @@ CONFIG_NLS_CODEPAGE_932=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# # CONFIG_DLM is not set +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=y + # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set # CONFIG_SH_STANDARD_BIOS is not set CONFIG_EARLY_SCIF_CONSOLE=y CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 @@ -1293,53 +1149,7 @@ CONFIG_EARLY_PRINTK=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_SEQIV is not set -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_CRYPTO is not set # # Library routines diff --git a/trunk/arch/sh/configs/rts7751r2dplus_defconfig b/trunk/arch/sh/configs/rts7751r2dplus_defconfig index 0a6d3b9e648b..4ff5a752dcd9 100644 --- a/trunk/arch/sh/configs/rts7751r2dplus_defconfig +++ b/trunk/arch/sh/configs/rts7751r2dplus_defconfig @@ -1,10 +1,9 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24 -# Thu Feb 7 16:17:47 2008 +# Linux kernel version: 2.6.23-rc2 +# Tue Aug 14 16:33:08 2007 # CONFIG_SUPERH=y -CONFIG_SUPERH32=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -37,14 +36,9 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set # CONFIG_BLK_DEV_INITRD is not set @@ -59,7 +53,6 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y @@ -72,13 +65,6 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set -CONFIG_PROFILING=y -# CONFIG_MARKERS is not set -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -105,17 +91,13 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y -# CONFIG_PREEMPT_RCU is not set # # System type # CONFIG_CPU_SH4=y # CONFIG_CPU_SUBTYPE_SH7619 is not set -# CONFIG_CPU_SUBTYPE_SH7203 is not set # CONFIG_CPU_SUBTYPE_SH7206 is not set -# CONFIG_CPU_SUBTYPE_SH7263 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set # CONFIG_CPU_SUBTYPE_SH7707 is not set @@ -123,8 +105,6 @@ CONFIG_CPU_SH4=y # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set # CONFIG_CPU_SUBTYPE_SH7712 is not set -# CONFIG_CPU_SUBTYPE_SH7720 is not set -# CONFIG_CPU_SUBTYPE_SH7721 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -133,15 +113,14 @@ CONFIG_CPU_SH4=y CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set -# CONFIG_CPU_SUBTYPE_SH7763 is not set +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set # CONFIG_CPU_SUBTYPE_SH7785 is not set # CONFIG_CPU_SUBTYPE_SHX3 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -151,7 +130,6 @@ CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 -CONFIG_29BIT=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -169,7 +147,6 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPARSEMEM_STATIC=y -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 @@ -191,22 +168,23 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SH_FPU=y # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC_IRQ=y CONFIG_CPU_HAS_SR_RB=y CONFIG_CPU_HAS_PTEA=y -CONFIG_CPU_HAS_FPU=y # # Board support # # CONFIG_SH_7751_SYSTEMH is not set # CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set CONFIG_SH_RTS7751R2D=y # CONFIG_SH_LANDISK is not set # CONFIG_SH_TITAN is not set # CONFIG_SH_LBOX_RE2 is not set # -# RTS7751R2D Board Revision +# RTS7751R2D options # CONFIG_RTS7751R2D_PLUS=y # CONFIG_RTS7751R2D_1 is not set @@ -220,7 +198,6 @@ CONFIG_SH_PCLK_FREQ=60000000 # CONFIG_TICK_ONESHOT is not set # CONFIG_NO_HZ is not set # CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # CPU Frequency scaling @@ -250,15 +227,11 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_SCHED_HRTICK is not set # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_RCU_TRACE=y -CONFIG_GUSA=y -# CONFIG_GUSA_RB is not set # # Boot options @@ -277,7 +250,10 @@ CONFIG_SH_PCIDMA_NONCOHERENT=y CONFIG_PCI_AUTO=y CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_ARCH_SUPPORTS_MSI is not set -CONFIG_PCI_LEGACY=y + +# +# PCCARD (PCMCIA/CardBus) support +# # CONFIG_PCCARD is not set CONFIG_HOTPLUG_PCI=y # CONFIG_HOTPLUG_PCI_FAKE is not set @@ -305,7 +281,6 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -324,7 +299,6 @@ CONFIG_IP_FIB_HASH=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -350,6 +324,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set # @@ -357,7 +335,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -379,7 +356,6 @@ CONFIG_WIRELESS_EXT=y # # Generic Driver Options # -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m @@ -395,7 +371,6 @@ CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 @@ -445,7 +420,6 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set @@ -519,9 +493,7 @@ CONFIG_ATA=y # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set # CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_OPTIDMA is not set # CONFIG_PATA_PDC_OLD is not set @@ -536,7 +508,14 @@ CONFIG_ATA=y # CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y # CONFIG_MD is not set + +# +# Fusion MPT device support +# # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -551,31 +530,25 @@ CONFIG_NETDEVICES=y # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_VETH is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_AX88796 is not set # CONFIG_STNIC is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set -# CONFIG_ENC28J60 is not set # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set @@ -587,7 +560,6 @@ CONFIG_8139TOO=y # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -598,10 +570,6 @@ CONFIG_NETDEV_1000=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set # CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_E1000E_ENABLED is not set -# CONFIG_IP1000 is not set -# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -609,7 +577,6 @@ CONFIG_NETDEV_1000=y # CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set @@ -618,15 +585,11 @@ CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set -# CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set -# CONFIG_TEHUTI is not set -# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -634,21 +597,13 @@ CONFIG_NETDEV_10000=y # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -667,6 +622,7 @@ CONFIG_INPUT=y # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set @@ -694,7 +650,6 @@ CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set # # Serial drivers @@ -719,9 +674,11 @@ CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set +# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y @@ -730,30 +687,16 @@ CONFIG_DEVPORT=y # # SPI support # -CONFIG_SPI=y -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -CONFIG_SPI_BITBANG=y -CONFIG_SPI_SH_SCI=y - -# -# SPI Protocol Masters -# -# CONFIG_SPI_AT25 is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set @@ -765,13 +708,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set # # Multifunction device drivers @@ -784,12 +720,16 @@ CONFIG_MFD_SM501=y # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set CONFIG_DAB=y -# CONFIG_USB_DABUSB is not set # # Graphics support # -# CONFIG_DRM is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y @@ -798,7 +738,6 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set # CONFIG_FB_SYS_FILLRECT is not set # CONFIG_FB_SYS_COPYAREA is not set # CONFIG_FB_SYS_IMAGEBLIT is not set @@ -838,12 +777,6 @@ CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_PM3 is not set CONFIG_FB_SM501=y # CONFIG_FB_VIRTUAL is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set # # Console display driver support @@ -911,7 +844,6 @@ CONFIG_SND_AC97_CODEC=m # CONFIG_SND_BT87X is not set # CONFIG_SND_CA0106 is not set # CONFIG_SND_CMIPCI is not set -# CONFIG_SND_OXYGEN is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set # CONFIG_SND_DARLA20 is not set @@ -936,7 +868,6 @@ CONFIG_SND_AC97_CODEC=m # CONFIG_SND_HDA_INTEL is not set # CONFIG_SND_HDSP is not set # CONFIG_SND_HDSPM is not set -# CONFIG_SND_HIFIER is not set # CONFIG_SND_ICE1712 is not set # CONFIG_SND_ICE1724 is not set # CONFIG_SND_INTEL8X0 is not set @@ -954,26 +885,15 @@ CONFIG_SND_AC97_CODEC=m # CONFIG_SND_TRIDENT is not set # CONFIG_SND_VIA82XX is not set # CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VIRTUOSO is not set # CONFIG_SND_VX222 is not set CONFIG_SND_YMFPCI=m CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y # CONFIG_SND_AC97_POWER_SAVE is not set -# -# SPI devices -# - # # SUPERH devices # -# -# USB devices -# -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set - # # System on Chip audio support # @@ -983,10 +903,6 @@ CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL=y # SoC Audio support for SuperH # -# -# ALSA SoC audio for Freescale SOCs -# - # # Open Sound System # @@ -998,104 +914,19 @@ CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_USB is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # # -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -CONFIG_USB_LIBUSUAL=y - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_MON is not set - -# -# USB port drivers -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers +# USB Gadget Support # -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set # CONFIG_NEW_LEDS is not set @@ -1118,17 +949,13 @@ CONFIG_RTC_INTF_DEV=y # # SPI RTC drivers # -# CONFIG_RTC_DRV_MAX6902 is not set -CONFIG_RTC_DRV_R9701=y -# CONFIG_RTC_DRV_RS5C348 is not set # # Platform RTC drivers # -# CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set @@ -1136,7 +963,20 @@ CONFIG_RTC_DRV_R9701=y # # on-CPU RTC drivers # -# CONFIG_RTC_DRV_SH is not set +CONFIG_RTC_DRV_SH=y + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# # # Userspace I/O @@ -1194,6 +1034,7 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -1212,7 +1053,10 @@ CONFIG_TMPFS=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y + +# +# Network File Systems +# # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set @@ -1226,6 +1070,10 @@ CONFIG_NETWORK_FILESYSTEMS=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1266,22 +1114,30 @@ CONFIG_NLS_CODEPAGE_932=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# # CONFIG_DLM is not set +# +# Profiling support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=y + # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SAMPLES is not set # CONFIG_SH_STANDARD_BIOS is not set CONFIG_EARLY_SCIF_CONSOLE=y CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000 @@ -1293,53 +1149,7 @@ CONFIG_EARLY_PRINTK=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_SEQIV is not set -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_CRYPTO is not set # # Library routines diff --git a/trunk/arch/sh/configs/se7705_defconfig b/trunk/arch/sh/configs/se7705_defconfig index 84717d854867..87ae5c1f8629 100644 --- a/trunk/arch/sh/configs/se7705_defconfig +++ b/trunk/arch/sh/configs/se7705_defconfig @@ -231,6 +231,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_SH_DSP is not set # CONFIG_SH_ADC is not set CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_PINT_IRQ=y CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y diff --git a/trunk/arch/sh/drivers/dma/dma-api.c b/trunk/arch/sh/drivers/dma/dma-api.c index 727126e907e3..76ed816d9a24 100644 --- a/trunk/arch/sh/drivers/dma/dma-api.c +++ b/trunk/arch/sh/drivers/dma/dma-api.c @@ -350,7 +350,7 @@ int register_dmac(struct dma_info *info) BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); - info->pdev = platform_device_register_simple(info->name, -1, + info->pdev = platform_device_register_simple((char *)info->name, -1, NULL, 0); if (IS_ERR(info->pdev)) return PTR_ERR(info->pdev); diff --git a/trunk/arch/sh/drivers/pci/fixups-lboxre2.c b/trunk/arch/sh/drivers/pci/fixups-lboxre2.c index 1c1d41255ec0..40b19bdfb891 100644 --- a/trunk/arch/sh/drivers/pci/fixups-lboxre2.c +++ b/trunk/arch/sh/drivers/pci/fixups-lboxre2.c @@ -18,7 +18,7 @@ int pci_fixup_pcic(void) { unsigned long bcr1, mcr; - bcr1 = ctrl_inl(SH7751_BCR1); + bcr1 = inl(SH7751_BCR1); bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ pci_write_reg(bcr1, SH4_PCIBCR1); @@ -28,7 +28,7 @@ int pci_fixup_pcic(void) pci_write_reg(0xfb900047, SH7751_PCICONF1); pci_write_reg(0xab000001, SH7751_PCICONF4); - mcr = ctrl_inl(SH7751_MCR); + mcr = inl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; pci_write_reg(mcr, SH4_PCIMCR); diff --git a/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c b/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c index 904bce8768d3..e72ceb560d5b 100644 --- a/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -19,7 +19,7 @@ int pci_fixup_pcic(void) { unsigned long bcr1, mcr; - bcr1 = ctrl_inl(SH7751_BCR1); + bcr1 = inl(SH7751_BCR1); bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ pci_write_reg(bcr1, SH4_PCIBCR1); @@ -30,7 +30,7 @@ int pci_fixup_pcic(void) pci_write_reg(0xfb900047, SH7751_PCICONF1); pci_write_reg(0xab000001, SH7751_PCICONF4); - mcr = ctrl_inl(SH7751_MCR); + mcr = inl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; pci_write_reg(mcr, SH4_PCIMCR); diff --git a/trunk/arch/sh/drivers/pci/ops-dreamcast.c b/trunk/arch/sh/drivers/pci/ops-dreamcast.c index 0dac87b19624..e1284fc69361 100644 --- a/trunk/arch/sh/drivers/pci/ops-dreamcast.c +++ b/trunk/arch/sh/drivers/pci/ops-dreamcast.c @@ -83,9 +83,9 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: *val = ctrl_inb(GAPSPCI_BBA_CONFIG+where); break; - case 2: *val = ctrl_inw(GAPSPCI_BBA_CONFIG+where); break; - case 4: *val = ctrl_inl(GAPSPCI_BBA_CONFIG+where); break; + case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; + case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; + case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; @@ -97,9 +97,9 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: ctrl_outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; - case 2: ctrl_outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; - case 4: ctrl_outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; + case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; + case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; + case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; @@ -127,36 +127,36 @@ int __init gapspci_init(void) */ for (i=0; i<16; i++) - idbuf[i] = ctrl_inb(GAPSPCI_REGS+i); + idbuf[i] = inb(GAPSPCI_REGS+i); if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) return -ENODEV; - ctrl_outl(0x5a14a501, GAPSPCI_REGS+0x18); + outl(0x5a14a501, GAPSPCI_REGS+0x18); for (i=0; i<1000000; i++) ; - if (ctrl_inl(GAPSPCI_REGS+0x18) != 1) + if (inl(GAPSPCI_REGS+0x18) != 1) return -EINVAL; - ctrl_outl(0x01000000, GAPSPCI_REGS+0x20); - ctrl_outl(0x01000000, GAPSPCI_REGS+0x24); + outl(0x01000000, GAPSPCI_REGS+0x20); + outl(0x01000000, GAPSPCI_REGS+0x24); - ctrl_outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); - ctrl_outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); + outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); + outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); - ctrl_outl(1, GAPSPCI_REGS+0x14); - ctrl_outl(1, GAPSPCI_REGS+0x34); + outl(1, GAPSPCI_REGS+0x14); + outl(1, GAPSPCI_REGS+0x34); /* Setting Broadband Adapter */ - ctrl_outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); - ctrl_outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); - ctrl_outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); - ctrl_outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); - ctrl_outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); - ctrl_outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); - ctrl_outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); + outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); + outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); + outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); + outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); + outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); + outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); + outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); return 0; } diff --git a/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c b/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c index b3fa3e2ef184..ec8430c8d2d1 100644 --- a/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -33,7 +33,7 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) static struct resource sh7751_io_resource = { .name = "SH7751_IO", .start = 0x4000, - .end = SH7751_PCI_IO_SIZE - 1, + .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, .flags = IORESOURCE_IO }; @@ -68,7 +68,6 @@ static struct sh4_pci_address_map sh7751_pci_map = { int __init pcibios_init_platform(void) { - __set_io_port_base(SH7751_PCI_IO_BASE); return sh7751_pcic_init(&sh7751_pci_map); } diff --git a/trunk/arch/sh/drivers/pci/pci-sh4.h b/trunk/arch/sh/drivers/pci/pci-sh4.h index 07e29506080f..4925c79ea959 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh4.h +++ b/trunk/arch/sh/drivers/pci/pci-sh4.h @@ -172,11 +172,11 @@ struct sh4_pci_address_map { static inline void pci_write_reg(unsigned long val, unsigned long reg) { - ctrl_outl(val, PCI_REG(reg)); + outl(val, PCI_REG(reg)); } static inline unsigned long pci_read_reg(unsigned long reg) { - return ctrl_inl(PCI_REG(reg)); + return inl(PCI_REG(reg)); } #endif /* __PCI_SH4_H */ diff --git a/trunk/arch/sh/drivers/pci/pci-sh7751.c b/trunk/arch/sh/drivers/pci/pci-sh7751.c index 3065eb184f01..1aca7fe5783b 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7751.c +++ b/trunk/arch/sh/drivers/pci/pci-sh7751.c @@ -58,7 +58,7 @@ static int __init __area_sdram_check(unsigned int area) { u32 word; - word = ctrl_inl(SH7751_BCR1); + word = inl(SH7751_BCR1); /* check BCR for SDRAM in area */ if (((word >> area) & 1) == 0) { printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n", @@ -67,7 +67,7 @@ static int __init __area_sdram_check(unsigned int area) } pci_write_reg(word, SH4_PCIBCR1); - word = (u16)ctrl_inw(SH7751_BCR2); + word = (u16)inw(SH7751_BCR2); /* check BCR2 for 32bit SDRAM interface*/ if (((word >> (area << 1)) & 0x3) != 0x3) { printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n", @@ -85,9 +85,9 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) u32 word; /* Set the BCR's to enable PCI access */ - reg = ctrl_inl(SH7751_BCR1); + reg = inl(SH7751_BCR1); reg |= 0x80000; - ctrl_outl(reg, SH7751_BCR1); + outl(reg, SH7751_BCR1); /* Turn the clocks back on (not done in reset)*/ pci_write_reg(0, SH4_PCICLKR); @@ -179,13 +179,13 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) return 0; /* configure the wait control registers */ - word = ctrl_inl(SH7751_WCR1); + word = inl(SH7751_WCR1); pci_write_reg(word, SH4_PCIWCR1); - word = ctrl_inl(SH7751_WCR2); + word = inl(SH7751_WCR2); pci_write_reg(word, SH4_PCIWCR2); - word = ctrl_inl(SH7751_WCR3); + word = inl(SH7751_WCR3); pci_write_reg(word, SH4_PCIWCR3); - word = ctrl_inl(SH7751_MCR); + word = inl(SH7751_MCR); pci_write_reg(word, SH4_PCIMCR); /* NOTE: I'm ignoring the PCI error IRQs for now.. diff --git a/trunk/arch/sh/drivers/pci/pci-sh7780.c b/trunk/arch/sh/drivers/pci/pci-sh7780.c index b2a2bfa3c1bd..7d797f4de5e7 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7780.c +++ b/trunk/arch/sh/drivers/pci/pci-sh7780.c @@ -52,7 +52,7 @@ static int __init sh7780_pci_init(void) pr_debug("PCI: Starting intialization.\n"); - ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ + outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ /* check for SH7780/SH7780R hardware */ id = pci_read_reg(SH7780_PCIVID); diff --git a/trunk/arch/sh/kernel/Makefile_32 b/trunk/arch/sh/kernel/Makefile_32 index 62bf373266f7..c89289831053 100644 --- a/trunk/arch/sh/kernel/Makefile_32 +++ b/trunk/arch/sh/kernel/Makefile_32 @@ -22,6 +22,5 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_BINFMT_ELF) += dump_task.o -obj-$(CONFIG_IO_TRAPPED) += io_trapped.o EXTRA_CFLAGS += -Werror diff --git a/trunk/arch/sh/kernel/Makefile_64 b/trunk/arch/sh/kernel/Makefile_64 index e01283d49cbf..1ef21cc087f3 100644 --- a/trunk/arch/sh/kernel/Makefile_64 +++ b/trunk/arch/sh/kernel/Makefile_64 @@ -18,6 +18,5 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_BINFMT_ELF) += dump_task.o -obj-$(CONFIG_IO_TRAPPED) += io_trapped.o EXTRA_CFLAGS += -Werror diff --git a/trunk/arch/sh/kernel/cpu/irq/Makefile b/trunk/arch/sh/kernel/cpu/irq/Makefile index 462a8f6dfee2..cc1836e47a5d 100644 --- a/trunk/arch/sh/kernel/cpu/irq/Makefile +++ b/trunk/arch/sh/kernel/cpu/irq/Makefile @@ -6,3 +6,4 @@ obj-y += intc.o obj-$(CONFIG_SUPERH32) += imask.o obj-$(CONFIG_CPU_SH5) += intc-sh5.o obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o +obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o diff --git a/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c b/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c index d6e0e2bdaad5..43ee7a9a4f0b 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c @@ -75,6 +75,21 @@ int intc_evt_to_irq[(0xE20/0x20)+1] = { -1, -1 /* 0xE00 - 0xE20 */ }; +/* + * Opposite mapper. + */ +static int IRQ_to_vectorN[NR_INTC_IRQS] = { + 0x12, 0x15, 0x18, 0x1B, 0x40, 0x41, 0x42, 0x43, /* 0- 7 */ + -1, -1, -1, -1, 0x50, 0x51, 0x52, 0x53, /* 8-15 */ + 0x54, 0x55, 0x32, 0x33, 0x34, 0x35, 0x36, -1, /* 16-23 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 24-31 */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x38, /* 32-39 */ + 0x39, 0x3A, 0x3B, -1, -1, -1, -1, -1, /* 40-47 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 48-55 */ + -1, -1, -1, -1, -1, -1, -1, 0x2B, /* 56-63 */ + +}; + static unsigned long intc_virt; static unsigned int startup_intc_irq(unsigned int irq); @@ -161,18 +176,6 @@ void make_intc_irq(unsigned int irq) } #if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL) -static int IRQ_to_vectorN[NR_INTC_IRQS] = { - 0x12, 0x15, 0x18, 0x1B, 0x40, 0x41, 0x42, 0x43, /* 0- 7 */ - -1, -1, -1, -1, 0x50, 0x51, 0x52, 0x53, /* 8-15 */ - 0x54, 0x55, 0x32, 0x33, 0x34, 0x35, 0x36, -1, /* 16-23 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 24-31 */ - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x38, /* 32-39 */ - 0x39, 0x3A, 0x3B, -1, -1, -1, -1, -1, /* 40-47 */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 48-55 */ - -1, -1, -1, -1, -1, -1, -1, 0x2B, /* 56-63 */ - -}; - int intc_irq_describe(char* p, int irq) { if (irq < NR_INTC_IRQS) diff --git a/trunk/arch/sh/kernel/cpu/irq/maskreg.c b/trunk/arch/sh/kernel/cpu/irq/maskreg.c new file mode 100644 index 000000000000..978992e367a5 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/irq/maskreg.c @@ -0,0 +1,93 @@ +/* + * Interrupt handling for Simple external interrupt mask register + * + * Copyright (C) 2001 A&D Co., Ltd. + * + * This is for the machine which have single 16 bit register + * for masking external IRQ individually. + * Each bit of the register is for masking each interrupt. + * + * This file may be copied or modified under the terms of the GNU + * General Public License. See linux/COPYING for more information. + */ +#include +#include +#include +#include +#include + +/* address of external interrupt mask register */ +unsigned long irq_mask_register; + +/* forward declaration */ +static unsigned int startup_maskreg_irq(unsigned int irq); +static void shutdown_maskreg_irq(unsigned int irq); +static void enable_maskreg_irq(unsigned int irq); +static void disable_maskreg_irq(unsigned int irq); +static void mask_and_ack_maskreg(unsigned int); +static void end_maskreg_irq(unsigned int irq); + +/* hw_interrupt_type */ +static struct hw_interrupt_type maskreg_irq_type = { + .typename = "Mask Register", + .startup = startup_maskreg_irq, + .shutdown = shutdown_maskreg_irq, + .enable = enable_maskreg_irq, + .disable = disable_maskreg_irq, + .ack = mask_and_ack_maskreg, + .end = end_maskreg_irq +}; + +/* actual implementation */ +static unsigned int startup_maskreg_irq(unsigned int irq) +{ + enable_maskreg_irq(irq); + return 0; /* never anything pending */ +} + +static void shutdown_maskreg_irq(unsigned int irq) +{ + disable_maskreg_irq(irq); +} + +static void disable_maskreg_irq(unsigned int irq) +{ + unsigned short val, mask = 0x01 << irq; + + BUG_ON(!irq_mask_register); + + /* Set "irq"th bit */ + val = ctrl_inw(irq_mask_register); + val |= mask; + ctrl_outw(val, irq_mask_register); +} + +static void enable_maskreg_irq(unsigned int irq) +{ + unsigned short val, mask = ~(0x01 << irq); + + BUG_ON(!irq_mask_register); + + /* Clear "irq"th bit */ + val = ctrl_inw(irq_mask_register); + val &= mask; + ctrl_outw(val, irq_mask_register); +} + +static void mask_and_ack_maskreg(unsigned int irq) +{ + disable_maskreg_irq(irq); +} + +static void end_maskreg_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_maskreg_irq(irq); +} + +void make_maskreg_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &maskreg_irq_type; + disable_maskreg_irq(irq); +} diff --git a/trunk/arch/sh/kernel/cpu/sh4/probe.c b/trunk/arch/sh/kernel/cpu/sh4/probe.c index 9e89984c4f1d..f2b9238cda04 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh4/probe.c @@ -126,18 +126,12 @@ int __init detect_cpu_and_cache_system(void) CPU_HAS_LLSC; break; case 0x3008: - if (prr == 0xa0 || prr == 0xa1) { + if (prr == 0xa0) { boot_cpu_data.type = CPU_SH7722; boot_cpu_data.icache.ways = 4; boot_cpu_data.dcache.ways = 4; boot_cpu_data.flags |= CPU_HAS_LLSC; } - else if (prr == 0x70) { - boot_cpu_data.type = CPU_SH7366; - boot_cpu_data.icache.ways = 4; - boot_cpu_data.dcache.ways = 4; - boot_cpu_data.flags |= CPU_HAS_LLSC; - } break; case 0x4000: /* 1st cut */ case 0x4001: /* 2nd cut */ diff --git a/trunk/arch/sh/kernel/cpu/sh4a/Makefile b/trunk/arch/sh/kernel/cpu/sh4a/Makefile index 5d890ac8e793..08ac6387bf17 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh4a/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o -obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o # SMP setup @@ -22,7 +21,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o -clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o obj-y += $(clock-y) diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 299138ebe160..a0fd8bb21f7c 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -1,7 +1,7 @@ /* * arch/sh/kernel/cpu/sh4a/clock-sh7722.c * - * SH7722 & SH7366 support for the clock framework + * SH7722 support for the clock framework * * Copyright (c) 2006-2007 Nomad Global Solutions Inc * Based on code for sh7343 by Paul Mundt @@ -417,19 +417,15 @@ static int sh7722_siu_which(struct clk *clk) return 0; if (!strcmp(clk->name, "siu_b_clk")) return 1; -#if defined(CONFIG_CPU_SUBTYPE_SH7722) if (!strcmp(clk->name, "irda_clk")) return 2; -#endif return -EINVAL; } static unsigned long sh7722_siu_regs[] = { [0] = SCLKACR, [1] = SCLKBCR, -#if defined(CONFIG_CPU_SUBTYPE_SH7722) [2] = IrDACLKCR, -#endif }; static int sh7722_siu_start_stop(struct clk *clk, int enable) @@ -575,12 +571,10 @@ static struct clk sh7722_siu_b_clock = { .ops = &sh7722_siu_clk_ops, }; -#if defined(CONFIG_CPU_SUBTYPE_SH7722) static struct clk sh7722_irda_clock = { .name = "irda_clk", .ops = &sh7722_siu_clk_ops, }; -#endif static struct clk sh7722_video_clock = { .name = "video_clk", @@ -594,9 +588,7 @@ static struct clk *sh7722_clocks[] = { &sh7722_sdram_clock, &sh7722_siu_a_clock, &sh7722_siu_b_clock, -#if defined(CONFIG_CPU_SUBTYPE_SH7722) &sh7722_irda_clock, -#endif &sh7722_video_clock, }; diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c deleted file mode 100644 index 967e8b69a2f8..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * SH7366 Setup - * - * Copyright (C) 2008 Renesas Solutions - * - * Based on linux/arch/sh/kernel/cpu/sh4a/setup-sh7722.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7366_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7366_devices_setup(void) -{ - return platform_add_devices(sh7366_devices, - ARRAY_SIZE(sh7366_devices)); -} -__initcall(sh7366_devices_setup); - -enum { - UNUSED=0, - - /* interrupt sources */ - IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, - ICB, - DMAC0, DMAC1, DMAC2, DMAC3, - VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU, - MFI, VPU, USB, - MMC_MMC1I, MMC_MMC2I, MMC_MMC3I, - DMAC4, DMAC5, DMAC_DADERR, - SCIF, SCIFA1, SCIFA2, - DENC, MSIOF, - FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, - I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI, - SDHI0, SDHI1, SDHI2, SDHI3, - CMT, TSIF, SIU, - TMU0, TMU1, TMU2, - VEU2, LCDC, - - /* interrupt groups */ - - DMAC0123, VIOVOU, MMC, DMAC45, FLCTL, I2C, SDHI, -}; - -static struct intc_vect vectors[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), - INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0), - INTC_VECT(ICB, 0x700), - INTC_VECT(DMAC0, 0x800), INTC_VECT(DMAC1, 0x820), - INTC_VECT(DMAC2, 0x840), INTC_VECT(DMAC3, 0x860), - INTC_VECT(VIO_CEUI, 0x880), INTC_VECT(VIO_BEUI, 0x8a0), - INTC_VECT(VIO_VEUI, 0x8c0), INTC_VECT(VOU, 0x8e0), - INTC_VECT(MFI, 0x900), INTC_VECT(VPU, 0x980), INTC_VECT(USB, 0xa20), - INTC_VECT(MMC_MMC1I, 0xb00), INTC_VECT(MMC_MMC2I, 0xb20), - INTC_VECT(MMC_MMC3I, 0xb40), - INTC_VECT(DMAC4, 0xb80), INTC_VECT(DMAC5, 0xba0), - INTC_VECT(DMAC_DADERR, 0xbc0), - INTC_VECT(SCIF, 0xc00), INTC_VECT(SCIFA1, 0xc20), - INTC_VECT(SCIFA2, 0xc40), - INTC_VECT(DENC, 0xc60), INTC_VECT(MSIOF, 0xc80), - INTC_VECT(FLCTL_FLSTEI, 0xd80), INTC_VECT(FLCTL_FLENDI, 0xda0), - INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), - INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20), - INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60), - INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0), - INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0), - INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), - INTC_VECT(SIU, 0xf80), - INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), - INTC_VECT(TMU2, 0x440), - INTC_VECT(VEU2, 0x580), INTC_VECT(LCDC, 0x580), -}; - -static struct intc_group groups[] __initdata = { - INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3), - INTC_GROUP(VIOVOU, VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU), - INTC_GROUP(MMC, MMC_MMC1I, MMC_MMC2I, MMC_MMC3I), - INTC_GROUP(DMAC45, DMAC4, DMAC5, DMAC_DADERR), - INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI, - FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), - INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI), - INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), -}; - -static struct intc_mask_reg mask_registers[] __initdata = { - { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ - { } }, - { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ - { VOU, VIO_VEUI, VIO_BEUI, VIO_CEUI, DMAC3, DMAC2, DMAC1, DMAC0 } }, - { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ - { 0, 0, 0, VPU, 0, 0, 0, MFI } }, - { 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */ - { 0, 0, 0, ICB } }, - { 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */ - { 0, TMU2, TMU1, TMU0, VEU2, 0, 0, LCDC } }, - { 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */ - { 0, DMAC_DADERR, DMAC5, DMAC4, DENC, SCIFA2, SCIFA1, SCIF } }, - { 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */ - { 0, 0, 0, 0, 0, 0, 0, MSIOF } }, - { 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */ - { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, - FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, - { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ - { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, 0, SIU } }, - { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ - { 0, 0, 0, CMT, 0, USB, } }, - { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ - { 0, MMC_MMC3I, MMC_MMC2I, MMC_MMC1I } }, - { 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */ - { 0, 0, 0, 0, 0, 0, 0, TSIF } }, - { 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */ - { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, -}; - -static struct intc_prio_reg prio_registers[] __initdata = { - { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } }, - { 0xa4080004, 0, 16, 4, /* IPRB */ { VEU2, LCDC, ICB } }, - { 0xa4080008, 0, 16, 4, /* IPRC */ { } }, - { 0xa408000c, 0, 16, 4, /* IPRD */ { } }, - { 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, MFI, VPU } }, - { 0xa4080014, 0, 16, 4, /* IPRF */ { 0, DMAC45, USB, CMT } }, - { 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF, SCIFA1, SCIFA2, DENC } }, - { 0xa408001c, 0, 16, 4, /* IPRH */ { MSIOF, 0, FLCTL, I2C } }, - { 0xa4080020, 0, 16, 4, /* IPRI */ { 0, 0, TSIF, } }, - { 0xa4080024, 0, 16, 4, /* IPRJ */ { 0, 0, SIU } }, - { 0xa4080028, 0, 16, 4, /* IPRK */ { 0, MMC, 0, SDHI } }, - { 0xa408002c, 0, 16, 4, /* IPRL */ { } }, - { 0xa4140010, 0, 32, 4, /* INTPRI00 */ - { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, -}; - -static struct intc_sense_reg sense_registers[] __initdata = { - { 0xa414001c, 16, 2, /* ICR1 */ - { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, -}; - -static DECLARE_INTC_DESC(intc_desc, "sh7366", vectors, groups, - mask_registers, prio_registers, sense_registers); - -void __init plat_irq_setup(void) -{ - register_intc_controller(&intc_desc); -} - -void __init plat_mem_setup(void) -{ - /* TODO: Register Node 1 */ -} diff --git a/trunk/arch/sh/kernel/cpu/sh5/probe.c b/trunk/arch/sh/kernel/cpu/sh5/probe.c index 31f8cb0f6374..15d167fd0ae7 100644 --- a/trunk/arch/sh/kernel/cpu/sh5/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh5/probe.c @@ -20,18 +20,19 @@ int __init detect_cpu_and_cache_system(void) { unsigned long long cir; - /* - * Do peeks in real mode to avoid having to set up a mapping for - * the WPC registers. On SH5-101 cut2, such a mapping would be - * exposed to an address translation erratum which would make it - * hard to set up correctly. - */ + /* Do peeks in real mode to avoid having to set up a mapping for the + WPC registers. On SH5-101 cut2, such a mapping would be exposed to + an address translation erratum which would make it hard to set up + correctly. */ cir = peek_real_address_q(0x0d000008); - if ((cir & 0xffff) == 0x5103) + if ((cir & 0xffff) == 0x5103) { boot_cpu_data.type = CPU_SH5_103; - else if (((cir >> 32) & 0xffff) == 0x51e2) + } else if (((cir >> 32) & 0xffff) == 0x51e2) { /* CPU.VCR aliased at CIR address on SH5-101 */ boot_cpu_data.type = CPU_SH5_101; + } else { + boot_cpu_data.type = CPU_SH_NONE; + } /* * First, setup some sane values for the I-cache. @@ -39,33 +40,37 @@ int __init detect_cpu_and_cache_system(void) boot_cpu_data.icache.ways = 4; boot_cpu_data.icache.sets = 256; boot_cpu_data.icache.linesz = L1_CACHE_BYTES; - boot_cpu_data.icache.way_incr = (1 << 13); - boot_cpu_data.icache.entry_shift = 5; - boot_cpu_data.icache.way_size = boot_cpu_data.icache.sets * - boot_cpu_data.icache.linesz; - boot_cpu_data.icache.entry_mask = 0x1fe0; - boot_cpu_data.icache.flags = 0; +#if 0 /* - * Next, setup some sane values for the D-cache. - * - * On the SH5, these are pretty consistent with the I-cache settings, - * so we just copy over the existing definitions.. these can be fixed - * up later, especially if we add runtime CPU probing. - * - * Though in the meantime it saves us from having to duplicate all of - * the above definitions.. + * FIXME: This can probably be cleaned up a bit as well.. for example, + * do we really need the way shift _and_ the way_step_shift ?? Judging + * by the existing code, I would guess no.. is there any valid reason + * why we need to be tracking this around? */ - boot_cpu_data.dcache = boot_cpu_data.icache; + boot_cpu_data.icache.way_shift = 13; + boot_cpu_data.icache.entry_shift = 5; + boot_cpu_data.icache.set_shift = 4; + boot_cpu_data.icache.way_step_shift = 16; + boot_cpu_data.icache.asid_shift = 2; /* - * Setup any cache-related flags here + * way offset = cache size / associativity, so just don't factor in + * associativity in the first place.. */ -#if defined(CONFIG_CACHE_WRITETHROUGH) - set_bit(SH_CACHE_MODE_WT, &(boot_cpu_data.dcache.flags)); -#elif defined(CONFIG_CACHE_WRITEBACK) - set_bit(SH_CACHE_MODE_WB, &(boot_cpu_data.dcache.flags)); + boot_cpu_data.icache.way_ofs = boot_cpu_data.icache.sets * + boot_cpu_data.icache.linesz; + + boot_cpu_data.icache.asid_mask = 0x3fc; + boot_cpu_data.icache.idx_mask = 0x1fe0; + boot_cpu_data.icache.epn_mask = 0xffffe000; #endif + boot_cpu_data.icache.flags = 0; + + /* A trivial starting point.. */ + memcpy(&boot_cpu_data.dcache, + &boot_cpu_data.icache, sizeof(struct cache_info)); + return 0; } diff --git a/trunk/arch/sh/kernel/io.c b/trunk/arch/sh/kernel/io.c index 2b8991229900..71c9fde2fd90 100644 --- a/trunk/arch/sh/kernel/io.c +++ b/trunk/arch/sh/kernel/io.c @@ -63,13 +63,7 @@ EXPORT_SYMBOL(memset_io); void __iomem *ioport_map(unsigned long port, unsigned int nr) { - void __iomem *ret; - - ret = __ioport_map_trapped(port, nr); - if (ret) - return ret; - - return __ioport_map(port, nr); + return sh_mv.mv_ioport_map(port, nr); } EXPORT_SYMBOL(ioport_map); diff --git a/trunk/arch/sh/kernel/io_generic.c b/trunk/arch/sh/kernel/io_generic.c index db769449f5a7..771ea4230441 100644 --- a/trunk/arch/sh/kernel/io_generic.c +++ b/trunk/arch/sh/kernel/io_generic.c @@ -33,17 +33,17 @@ static inline void delay(void) u8 generic_inb(unsigned long port) { - return ctrl_inb((unsigned long __force)__ioport_map(port, 1)); + return ctrl_inb((unsigned long __force)ioport_map(port, 1)); } u16 generic_inw(unsigned long port) { - return ctrl_inw((unsigned long __force)__ioport_map(port, 2)); + return ctrl_inw((unsigned long __force)ioport_map(port, 2)); } u32 generic_inl(unsigned long port) { - return ctrl_inl((unsigned long __force)__ioport_map(port, 4)); + return ctrl_inl((unsigned long __force)ioport_map(port, 4)); } u8 generic_inb_p(unsigned long port) @@ -81,7 +81,7 @@ void generic_insb(unsigned long port, void *dst, unsigned long count) volatile u8 *port_addr; u8 *buf = dst; - port_addr = (volatile u8 *)__ioport_map(port, 1); + port_addr = (volatile u8 *)ioport_map(port, 1); while (count--) *buf++ = *port_addr; } @@ -91,7 +91,7 @@ void generic_insw(unsigned long port, void *dst, unsigned long count) volatile u16 *port_addr; u16 *buf = dst; - port_addr = (volatile u16 *)__ioport_map(port, 2); + port_addr = (volatile u16 *)ioport_map(port, 2); while (count--) *buf++ = *port_addr; @@ -103,7 +103,7 @@ void generic_insl(unsigned long port, void *dst, unsigned long count) volatile u32 *port_addr; u32 *buf = dst; - port_addr = (volatile u32 *)__ioport_map(port, 4); + port_addr = (volatile u32 *)ioport_map(port, 4); while (count--) *buf++ = *port_addr; @@ -112,17 +112,17 @@ void generic_insl(unsigned long port, void *dst, unsigned long count) void generic_outb(u8 b, unsigned long port) { - ctrl_outb(b, (unsigned long __force)__ioport_map(port, 1)); + ctrl_outb(b, (unsigned long __force)ioport_map(port, 1)); } void generic_outw(u16 b, unsigned long port) { - ctrl_outw(b, (unsigned long __force)__ioport_map(port, 2)); + ctrl_outw(b, (unsigned long __force)ioport_map(port, 2)); } void generic_outl(u32 b, unsigned long port) { - ctrl_outl(b, (unsigned long __force)__ioport_map(port, 4)); + ctrl_outl(b, (unsigned long __force)ioport_map(port, 4)); } void generic_outb_p(u8 b, unsigned long port) @@ -153,7 +153,7 @@ void generic_outsb(unsigned long port, const void *src, unsigned long count) volatile u8 *port_addr; const u8 *buf = src; - port_addr = (volatile u8 __force *)__ioport_map(port, 1); + port_addr = (volatile u8 __force *)ioport_map(port, 1); while (count--) *port_addr = *buf++; @@ -164,7 +164,7 @@ void generic_outsw(unsigned long port, const void *src, unsigned long count) volatile u16 *port_addr; const u16 *buf = src; - port_addr = (volatile u16 __force *)__ioport_map(port, 2); + port_addr = (volatile u16 __force *)ioport_map(port, 2); while (count--) *port_addr = *buf++; @@ -177,7 +177,7 @@ void generic_outsl(unsigned long port, const void *src, unsigned long count) volatile u32 *port_addr; const u32 *buf = src; - port_addr = (volatile u32 __force *)__ioport_map(port, 4); + port_addr = (volatile u32 __force *)ioport_map(port, 4); while (count--) *port_addr = *buf++; diff --git a/trunk/arch/sh/kernel/io_trapped.c b/trunk/arch/sh/kernel/io_trapped.c deleted file mode 100644 index 86a665d92201..000000000000 --- a/trunk/arch/sh/kernel/io_trapped.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Trapped io support - * - * Copyright (C) 2008 Magnus Damm - * - * Intercept io operations by trapping. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TRAPPED_PAGES_MAX 16 - -#ifdef CONFIG_HAS_IOPORT -LIST_HEAD(trapped_io); -EXPORT_SYMBOL_GPL(trapped_io); -#endif -#ifdef CONFIG_HAS_IOMEM -LIST_HEAD(trapped_mem); -EXPORT_SYMBOL_GPL(trapped_mem); -#endif -static DEFINE_SPINLOCK(trapped_lock); - -int __init register_trapped_io(struct trapped_io *tiop) -{ - struct resource *res; - unsigned long len = 0, flags = 0; - struct page *pages[TRAPPED_PAGES_MAX]; - int k, n; - - /* structure must be page aligned */ - if ((unsigned long)tiop & (PAGE_SIZE - 1)) - goto bad; - - for (k = 0; k < tiop->num_resources; k++) { - res = tiop->resource + k; - len += roundup((res->end - res->start) + 1, PAGE_SIZE); - flags |= res->flags; - } - - /* support IORESOURCE_IO _or_ MEM, not both */ - if (hweight_long(flags) != 1) - goto bad; - - n = len >> PAGE_SHIFT; - - if (n >= TRAPPED_PAGES_MAX) - goto bad; - - for (k = 0; k < n; k++) - pages[k] = virt_to_page(tiop); - - tiop->virt_base = vmap(pages, n, VM_MAP, PAGE_NONE); - if (!tiop->virt_base) - goto bad; - - len = 0; - for (k = 0; k < tiop->num_resources; k++) { - res = tiop->resource + k; - pr_info("trapped io 0x%08lx overrides %s 0x%08lx\n", - (unsigned long)(tiop->virt_base + len), - res->flags & IORESOURCE_IO ? "io" : "mmio", - (unsigned long)res->start); - len += roundup((res->end - res->start) + 1, PAGE_SIZE); - } - - tiop->magic = IO_TRAPPED_MAGIC; - INIT_LIST_HEAD(&tiop->list); - spin_lock_irq(&trapped_lock); - if (flags & IORESOURCE_IO) - list_add(&tiop->list, &trapped_io); - if (flags & IORESOURCE_MEM) - list_add(&tiop->list, &trapped_mem); - spin_unlock_irq(&trapped_lock); - - return 0; - bad: - pr_warning("unable to install trapped io filter\n"); - return -1; -} -EXPORT_SYMBOL_GPL(register_trapped_io); - -void __iomem *match_trapped_io_handler(struct list_head *list, - unsigned long offset, - unsigned long size) -{ - unsigned long voffs; - struct trapped_io *tiop; - struct resource *res; - int k, len; - - spin_lock_irq(&trapped_lock); - list_for_each_entry(tiop, list, list) { - voffs = 0; - for (k = 0; k < tiop->num_resources; k++) { - res = tiop->resource + k; - if (res->start == offset) { - spin_unlock_irq(&trapped_lock); - return tiop->virt_base + voffs; - } - - len = (res->end - res->start) + 1; - voffs += roundup(len, PAGE_SIZE); - } - } - spin_unlock_irq(&trapped_lock); - return NULL; -} -EXPORT_SYMBOL_GPL(match_trapped_io_handler); - -static struct trapped_io *lookup_tiop(unsigned long address) -{ - pgd_t *pgd_k; - pud_t *pud_k; - pmd_t *pmd_k; - pte_t *pte_k; - pte_t entry; - - pgd_k = swapper_pg_dir + pgd_index(address); - if (!pgd_present(*pgd_k)) - return NULL; - - pud_k = pud_offset(pgd_k, address); - if (!pud_present(*pud_k)) - return NULL; - - pmd_k = pmd_offset(pud_k, address); - if (!pmd_present(*pmd_k)) - return NULL; - - pte_k = pte_offset_kernel(pmd_k, address); - entry = *pte_k; - - return pfn_to_kaddr(pte_pfn(entry)); -} - -static unsigned long lookup_address(struct trapped_io *tiop, - unsigned long address) -{ - struct resource *res; - unsigned long vaddr = (unsigned long)tiop->virt_base; - unsigned long len; - int k; - - for (k = 0; k < tiop->num_resources; k++) { - res = tiop->resource + k; - len = roundup((res->end - res->start) + 1, PAGE_SIZE); - if (address < (vaddr + len)) - return res->start + (address - vaddr); - vaddr += len; - } - return 0; -} - -static unsigned long long copy_word(unsigned long src_addr, int src_len, - unsigned long dst_addr, int dst_len) -{ - unsigned long long tmp = 0; - - switch (src_len) { - case 1: - tmp = ctrl_inb(src_addr); - break; - case 2: - tmp = ctrl_inw(src_addr); - break; - case 4: - tmp = ctrl_inl(src_addr); - break; - case 8: - tmp = ctrl_inq(src_addr); - break; - } - - switch (dst_len) { - case 1: - ctrl_outb(tmp, dst_addr); - break; - case 2: - ctrl_outw(tmp, dst_addr); - break; - case 4: - ctrl_outl(tmp, dst_addr); - break; - case 8: - ctrl_outq(tmp, dst_addr); - break; - } - - return tmp; -} - -static unsigned long from_device(void *dst, const void *src, unsigned long cnt) -{ - struct trapped_io *tiop; - unsigned long src_addr = (unsigned long)src; - unsigned long long tmp; - - pr_debug("trapped io read 0x%08lx (%ld)\n", src_addr, cnt); - tiop = lookup_tiop(src_addr); - WARN_ON(!tiop || (tiop->magic != IO_TRAPPED_MAGIC)); - - src_addr = lookup_address(tiop, src_addr); - if (!src_addr) - return cnt; - - tmp = copy_word(src_addr, - max_t(unsigned long, cnt, - (tiop->minimum_bus_width / 8)), - (unsigned long)dst, cnt); - - pr_debug("trapped io read 0x%08lx -> 0x%08llx\n", src_addr, tmp); - return 0; -} - -static unsigned long to_device(void *dst, const void *src, unsigned long cnt) -{ - struct trapped_io *tiop; - unsigned long dst_addr = (unsigned long)dst; - unsigned long long tmp; - - pr_debug("trapped io write 0x%08lx (%ld)\n", dst_addr, cnt); - tiop = lookup_tiop(dst_addr); - WARN_ON(!tiop || (tiop->magic != IO_TRAPPED_MAGIC)); - - dst_addr = lookup_address(tiop, dst_addr); - if (!dst_addr) - return cnt; - - tmp = copy_word((unsigned long)src, cnt, - dst_addr, max_t(unsigned long, cnt, - (tiop->minimum_bus_width / 8))); - - pr_debug("trapped io write 0x%08lx -> 0x%08llx\n", dst_addr, tmp); - return 0; -} - -static struct mem_access trapped_io_access = { - from_device, - to_device, -}; - -int handle_trapped_io(struct pt_regs *regs, unsigned long address) -{ - mm_segment_t oldfs; - opcode_t instruction; - int tmp; - - if (!lookup_tiop(address)) - return 0; - - WARN_ON(user_mode(regs)); - - oldfs = get_fs(); - set_fs(KERNEL_DS); - if (copy_from_user(&instruction, (void *)(regs->pc), - sizeof(instruction))) { - set_fs(oldfs); - return 0; - } - - tmp = handle_unaligned_access(instruction, regs, &trapped_io_access); - set_fs(oldfs); - return tmp == 0; -} diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c index 9bf19b00696a..0586bc62ad96 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -248,6 +248,9 @@ asmlinkage void do_softirq(void) void __init init_IRQ(void) { +#ifdef CONFIG_CPU_HAS_PINT_IRQ + init_IRQ_pint(); +#endif plat_irq_setup(); /* Perform the machine specific initialisation */ diff --git a/trunk/arch/sh/kernel/process_64.c b/trunk/arch/sh/kernel/process_64.c index 046999b1d1af..cff3b7dc9c56 100644 --- a/trunk/arch/sh/kernel/process_64.c +++ b/trunk/arch/sh/kernel/process_64.c @@ -623,7 +623,6 @@ extern void interruptible_sleep_on(wait_queue_head_t *q); #define mid_sched ((unsigned long) interruptible_sleep_on) -#ifdef CONFIG_FRAME_POINTER static int in_sh64_switch_to(unsigned long pc) { extern char __sh64_switch_to_end; @@ -632,10 +631,12 @@ static int in_sh64_switch_to(unsigned long pc) return (pc >= (unsigned long) sh64_switch_to) && (pc < (unsigned long) &__sh64_switch_to_end); } -#endif unsigned long get_wchan(struct task_struct *p) { + unsigned long schedule_fp; + unsigned long sh64_switch_to_fp; + unsigned long schedule_caller_pc; unsigned long pc; if (!p || p == current || p->state == TASK_RUNNING) @@ -648,10 +649,6 @@ unsigned long get_wchan(struct task_struct *p) #ifdef CONFIG_FRAME_POINTER if (in_sh64_switch_to(pc)) { - unsigned long schedule_fp; - unsigned long sh64_switch_to_fp; - unsigned long schedule_caller_pc; - sh64_switch_to_fp = (long) p->thread.sp; /* r14 is saved at offset 4 in the sh64_switch_to frame */ schedule_fp = *(unsigned long *) (long)(sh64_switch_to_fp + 4); diff --git a/trunk/arch/sh/kernel/ptrace_32.c b/trunk/arch/sh/kernel/ptrace_32.c index fddb547f3c2b..ce0664a58b49 100644 --- a/trunk/arch/sh/kernel/ptrace_32.c +++ b/trunk/arch/sh/kernel/ptrace_32.c @@ -220,7 +220,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) dp = ((unsigned long) child) + THREAD_SIZE - sizeof(struct pt_dspregs); if (*((int *) (dp - 4)) == SR_FD) { - copy_to_user((void *)addr, (void *) dp, + copy_to_user(addr, (void *) dp, sizeof(struct pt_dspregs)); ret = 0; } @@ -234,7 +234,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) dp = ((unsigned long) child) + THREAD_SIZE - sizeof(struct pt_dspregs); if (*((int *) (dp - 4)) == SR_FD) { - copy_from_user((void *) dp, (void *)addr, + copy_from_user((void *) dp, addr, sizeof(struct pt_dspregs)); ret = 0; } diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index ff4f54a47c07..18a5baf2cbad 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -333,7 +333,7 @@ static const char *cpu_name[] = { [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3", [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103", - [CPU_SH7366] = "SH7366", [CPU_SH_NONE] = "Unknown" + [CPU_SH_NONE] = "Unknown" }; const char *get_cpu_subtype(struct sh_cpuinfo *c) diff --git a/trunk/arch/sh/kernel/syscalls_32.S b/trunk/arch/sh/kernel/syscalls_32.S index a46cc3a41148..719e127a7c05 100644 --- a/trunk/arch/sh/kernel/syscalls_32.S +++ b/trunk/arch/sh/kernel/syscalls_32.S @@ -338,8 +338,6 @@ ENTRY(sys_call_table) .long sys_epoll_pwait .long sys_utimensat /* 320 */ .long sys_signalfd - .long sys_timerfd_create + .long sys_ni_syscall .long sys_eventfd .long sys_fallocate - .long sys_timerfd_settime /* 325 */ - .long sys_timerfd_gettime diff --git a/trunk/arch/sh/kernel/syscalls_64.S b/trunk/arch/sh/kernel/syscalls_64.S index d5d7843aad94..12c7340356ae 100644 --- a/trunk/arch/sh/kernel/syscalls_64.S +++ b/trunk/arch/sh/kernel/syscalls_64.S @@ -376,8 +376,6 @@ sys_call_table: .long sys_epoll_pwait .long sys_utimensat .long sys_signalfd - .long sys_timerfd_create /* 350 */ + .long sys_ni_syscall /* 350 */ .long sys_eventfd .long sys_fallocate - .long sys_timerfd_settime - .long sys_timerfd_gettime diff --git a/trunk/arch/sh/kernel/time_32.c b/trunk/arch/sh/kernel/time_32.c index 7281342c044d..2bc04bfee738 100644 --- a/trunk/arch/sh/kernel/time_32.c +++ b/trunk/arch/sh/kernel/time_32.c @@ -120,6 +120,10 @@ static long last_rtc_update; */ void handle_timer_tick(void) { + do_timer(1); +#ifndef CONFIG_SMP + update_process_times(user_mode(get_irq_regs())); +#endif if (current->pid) profile_tick(CPU_PROFILING); @@ -128,16 +132,6 @@ void handle_timer_tick(void) sh_mv.mv_heartbeat(); #endif - /* - * Here we are in the timer irq handler. We just have irqs locally - * disabled but we don't know if the timer_bh is running on the other - * CPU. We need to avoid to SMP race with it. NOTE: we don' t need - * the irq version of write_lock because as just said we have irq - * locally disabled. -arca - */ - write_seqlock(&xtime_lock); - do_timer(1); - /* * If we have an externally synchronized Linux clock, then update * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be @@ -153,11 +147,6 @@ void handle_timer_tick(void) /* do it again in 60s */ last_rtc_update = xtime.tv_sec - 600; } - write_sequnlock(&xtime_lock); - -#ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); -#endif } #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ diff --git a/trunk/arch/sh/kernel/time_64.c b/trunk/arch/sh/kernel/time_64.c index 898977ee2030..f819ba38a6ce 100644 --- a/trunk/arch/sh/kernel/time_64.c +++ b/trunk/arch/sh/kernel/time_64.c @@ -229,22 +229,15 @@ static long last_rtc_update; static inline void do_timer_interrupt(void) { unsigned long long current_ctc; - - if (current->pid) - profile_tick(CPU_PROFILING); - - /* - * Here we are in the timer irq handler. We just have irqs locally - * disabled but we don't know if the timer_bh is running on the other - * CPU. We need to avoid to SMP race with it. NOTE: we don' t need - * the irq version of write_lock because as just said we have irq - * locally disabled. -arca - */ - write_lock(&xtime_lock); asm ("getcon cr62, %0" : "=r" (current_ctc)); ctc_last_interrupt = (unsigned long) current_ctc; do_timer(1); +#ifndef CONFIG_SMP + update_process_times(user_mode(get_irq_regs())); +#endif + if (current->pid) + profile_tick(CPU_PROFILING); #ifdef CONFIG_HEARTBEAT if (sh_mv.mv_heartbeat != NULL) @@ -266,11 +259,6 @@ static inline void do_timer_interrupt(void) /* do it again in 60 s */ last_rtc_update = xtime.tv_sec - 600; } - write_unlock(&xtime_lock); - -#ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); -#endif } /* @@ -287,7 +275,16 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) timer_status &= ~0x100; ctrl_outw(timer_status, TMU0_TCR); + /* + * Here we are in the timer irq handler. We just have irqs locally + * disabled but we don't know if the timer_bh is running on the other + * CPU. We need to avoid to SMP race with it. NOTE: we don' t need + * the irq version of write_lock because as just said we have irq + * locally disabled. -arca + */ + write_lock(&xtime_lock); do_timer_interrupt(); + write_unlock(&xtime_lock); return IRQ_HANDLED; } diff --git a/trunk/arch/sh/kernel/timers/timer-mtu2.c b/trunk/arch/sh/kernel/timers/timer-mtu2.c index ade9d6eb29f9..463cd08f9517 100644 --- a/trunk/arch/sh/kernel/timers/timer-mtu2.c +++ b/trunk/arch/sh/kernel/timers/timer-mtu2.c @@ -154,6 +154,7 @@ static int mtu2_timer_stop(void) static int mtu2_timer_init(void) { + u8 tmp; unsigned long interval; setup_irq(CONFIG_SH_TIMER_IRQ, &mtu2_irq); diff --git a/trunk/arch/sh/kernel/traps_32.c b/trunk/arch/sh/kernel/traps_32.c index baa4fa368dce..2e58f7a6b746 100644 --- a/trunk/arch/sh/kernel/traps_32.c +++ b/trunk/arch/sh/kernel/traps_32.c @@ -147,36 +147,6 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err) return -EFAULT; } -static inline void sign_extend(unsigned int count, unsigned char *dst) -{ -#ifdef __LITTLE_ENDIAN__ - if ((count == 1) && dst[0] & 0x80) { - dst[1] = 0xff; - dst[2] = 0xff; - dst[3] = 0xff; - } - if ((count == 2) && dst[1] & 0x80) { - dst[2] = 0xff; - dst[3] = 0xff; - } -#else - if ((count == 1) && dst[3] & 0x80) { - dst[2] = 0xff; - dst[1] = 0xff; - dst[0] = 0xff; - } - if ((count == 2) && dst[2] & 0x80) { - dst[1] = 0xff; - dst[0] = 0xff; - } -#endif -} - -static struct mem_access user_mem_access = { - copy_from_user, - copy_to_user, -}; - /* * handle an instruction that does an unaligned memory access by emulating the * desired behaviour @@ -184,8 +154,7 @@ static struct mem_access user_mem_access = { * (if that instruction is in a branch delay slot) * - return 0 if emulation okay, -EFAULT on existential error */ -static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, - struct mem_access *ma) +static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) { int ret, index, count; unsigned long *rm, *rn; @@ -209,13 +178,25 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, dst = (unsigned char*) rn; *(unsigned long*)dst = 0; -#if !defined(__LITTLE_ENDIAN__) +#ifdef __LITTLE_ENDIAN__ + if (copy_from_user(dst, src, count)) + goto fetch_fault; + + if ((count == 2) && dst[1] & 0x80) { + dst[2] = 0xff; + dst[3] = 0xff; + } +#else dst += 4-count; -#endif - if (ma->from(dst, src, count)) + + if (__copy_user(dst, src, count)) goto fetch_fault; - sign_extend(count, dst); + if ((count == 2) && dst[2] & 0x80) { + dst[0] = 0xff; + dst[1] = 0xff; + } +#endif } else { /* to memory */ src = (unsigned char*) rm; @@ -225,7 +206,7 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, dst = (unsigned char*) *rn; dst += regs->regs[0]; - if (ma->to(dst, src, count)) + if (copy_to_user(dst, src, count)) goto fetch_fault; } ret = 0; @@ -236,7 +217,7 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, dst = (unsigned char*) *rn; dst += (instruction&0x000F)<<2; - if (ma->to(dst, src, 4)) + if (copy_to_user(dst,src,4)) goto fetch_fault; ret = 0; break; @@ -249,7 +230,7 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, #if !defined(__LITTLE_ENDIAN__) src += 4-count; #endif - if (ma->to(dst, src, count)) + if (copy_to_user(dst, src, count)) goto fetch_fault; ret = 0; break; @@ -260,7 +241,7 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, dst = (unsigned char*) rn; *(unsigned long*)dst = 0; - if (ma->from(dst, src, 4)) + if (copy_from_user(dst,src,4)) goto fetch_fault; ret = 0; break; @@ -272,12 +253,25 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, dst = (unsigned char*) rn; *(unsigned long*)dst = 0; -#if !defined(__LITTLE_ENDIAN__) +#ifdef __LITTLE_ENDIAN__ + if (copy_from_user(dst, src, count)) + goto fetch_fault; + + if ((count == 2) && dst[1] & 0x80) { + dst[2] = 0xff; + dst[3] = 0xff; + } +#else dst += 4-count; -#endif - if (ma->from(dst, src, count)) + + if (copy_from_user(dst, src, count)) goto fetch_fault; - sign_extend(count, dst); + + if ((count == 2) && dst[2] & 0x80) { + dst[0] = 0xff; + dst[1] = 0xff; + } +#endif ret = 0; break; @@ -291,7 +285,7 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, dst = (unsigned char*) *rm; /* called Rn in the spec */ dst += (instruction&0x000F)<<1; - if (ma->to(dst, src, 2)) + if (copy_to_user(dst, src, 2)) goto fetch_fault; ret = 0; break; @@ -305,9 +299,21 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, #if !defined(__LITTLE_ENDIAN__) dst += 2; #endif - if (ma->from(dst, src, 2)) + + if (copy_from_user(dst, src, 2)) goto fetch_fault; - sign_extend(2, dst); + +#ifdef __LITTLE_ENDIAN__ + if (dst[1] & 0x80) { + dst[2] = 0xff; + dst[3] = 0xff; + } +#else + if (dst[2] & 0x80) { + dst[0] = 0xff; + dst[1] = 0xff; + } +#endif ret = 0; break; } @@ -326,14 +332,11 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs, * emulate the instruction in the delay slot * - fetches the instruction from PC+2 */ -static inline int handle_delayslot(struct pt_regs *regs, - opcode_t old_instruction, - struct mem_access *ma) +static inline int handle_unaligned_delayslot(struct pt_regs *regs) { - opcode_t instruction; - void *addr = (void *)(regs->pc + instruction_size(old_instruction)); + u16 instruction; - if (copy_from_user(&instruction, addr, sizeof(instruction))) { + if (copy_from_user(&instruction, (u16 *)(regs->pc+2), 2)) { /* the instruction-fetch faulted */ if (user_mode(regs)) return -EFAULT; @@ -343,7 +346,7 @@ static inline int handle_delayslot(struct pt_regs *regs, regs, 0); } - return handle_unaligned_ins(instruction, regs, ma); + return handle_unaligned_ins(instruction,regs); } /* @@ -366,11 +369,10 @@ static inline int handle_delayslot(struct pt_regs *regs, * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit * opcodes.. */ - +#ifndef CONFIG_CPU_SH2A static int handle_unaligned_notify_count = 10; -int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, - struct mem_access *ma) +static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) { u_int rm; int ret, index; @@ -385,7 +387,7 @@ int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, printk(KERN_NOTICE "Fixing up unaligned userspace access " "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", current->comm, task_pid_nr(current), - (void *)regs->pc, instruction); + (u16 *)regs->pc, instruction); } ret = -EFAULT; @@ -393,19 +395,19 @@ int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, case 0x0000: if (instruction==0x000B) { /* rts */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) regs->pc = regs->pr; } else if ((instruction&0x00FF)==0x0023) { /* braf @Rm */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) regs->pc += rm + 4; } else if ((instruction&0x00FF)==0x0003) { /* bsrf @Rm */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) { regs->pr = regs->pc + 4; regs->pc += rm + 4; @@ -426,13 +428,13 @@ int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, case 0x4000: if ((instruction&0x00FF)==0x002B) { /* jmp @Rm */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) regs->pc = rm; } else if ((instruction&0x00FF)==0x000B) { /* jsr @Rm */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) { regs->pr = regs->pc + 4; regs->pc = rm; @@ -459,7 +461,7 @@ int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, case 0x0B00: /* bf lab - no delayslot*/ break; case 0x0F00: /* bf/s lab */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) { #if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) if ((regs->sr & 0x00000001) != 0) @@ -472,7 +474,7 @@ int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, case 0x0900: /* bt lab - no delayslot */ break; case 0x0D00: /* bt/s lab */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) { #if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) if ((regs->sr & 0x00000001) == 0) @@ -486,13 +488,13 @@ int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, break; case 0xA000: /* bra label */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) regs->pc += SH_PC_12BIT_OFFSET(instruction); break; case 0xB000: /* bsr label */ - ret = handle_delayslot(regs, instruction, ma); + ret = handle_unaligned_delayslot(regs); if (ret==0) { regs->pr = regs->pc + 4; regs->pc += SH_PC_12BIT_OFFSET(instruction); @@ -503,11 +505,12 @@ int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, /* handle non-delay-slot instruction */ simple: - ret = handle_unaligned_ins(instruction, regs, ma); + ret = handle_unaligned_ins(instruction,regs); if (ret==0) regs->pc += instruction_size(instruction); return ret; } +#endif /* CONFIG_CPU_SH2A */ #ifdef CONFIG_CPU_HAS_SR_RB #define lookup_exception_vector(x) \ @@ -535,8 +538,10 @@ asmlinkage void do_address_error(struct pt_regs *regs, unsigned long error_code = 0; mm_segment_t oldfs; siginfo_t info; - opcode_t instruction; +#ifndef CONFIG_CPU_SH2A + u16 instruction; int tmp; +#endif /* Intentional ifdef */ #ifdef CONFIG_CPU_HAS_SR_RB @@ -556,9 +561,9 @@ asmlinkage void do_address_error(struct pt_regs *regs, goto uspace_segv; } +#ifndef CONFIG_CPU_SH2A set_fs(USER_DS); - if (copy_from_user(&instruction, (void *)(regs->pc), - sizeof(instruction))) { + if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) { /* Argh. Fault on the instruction itself. This should never happen non-SMP */ @@ -566,12 +571,13 @@ asmlinkage void do_address_error(struct pt_regs *regs, goto uspace_segv; } - tmp = handle_unaligned_access(instruction, regs, - &user_mem_access); + tmp = handle_unaligned_access(instruction, regs); set_fs(oldfs); if (tmp==0) return; /* sorted */ +#endif + uspace_segv: printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned " "access (PC %lx PR %lx)\n", current->comm, regs->pc, @@ -586,9 +592,9 @@ asmlinkage void do_address_error(struct pt_regs *regs, if (regs->pc & 1) die("unaligned program counter", regs, error_code); +#ifndef CONFIG_CPU_SH2A set_fs(KERNEL_DS); - if (copy_from_user(&instruction, (void *)(regs->pc), - sizeof(instruction))) { + if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) { /* Argh. Fault on the instruction itself. This should never happen non-SMP */ @@ -596,8 +602,14 @@ asmlinkage void do_address_error(struct pt_regs *regs, die("insn faulting in do_address_error", regs, 0); } - handle_unaligned_access(instruction, regs, &user_mem_access); + handle_unaligned_access(instruction, regs); set_fs(oldfs); +#else + printk(KERN_NOTICE "Killing process \"%s\" due to unaligned " + "access\n", current->comm); + + force_sig(SIGSEGV, current); +#endif } } diff --git a/trunk/arch/sh/kernel/traps_64.c b/trunk/arch/sh/kernel/traps_64.c index a55ac81d795b..c0b3c6f6edb5 100644 --- a/trunk/arch/sh/kernel/traps_64.c +++ b/trunk/arch/sh/kernel/traps_64.c @@ -630,7 +630,7 @@ static int misaligned_fpu_load(struct pt_regs *regs, current->thread.fpu.hard.fp_regs[destreg] = buflo; current->thread.fpu.hard.fp_regs[destreg+1] = bufhi; } else { -#if defined(CONFIG_CPU_LITTLE_ENDIAN) +#if defined(CONFIG_LITTLE_ENDIAN) current->thread.fpu.hard.fp_regs[destreg] = bufhi; current->thread.fpu.hard.fp_regs[destreg+1] = buflo; #else @@ -700,7 +700,7 @@ static int misaligned_fpu_store(struct pt_regs *regs, buflo = current->thread.fpu.hard.fp_regs[srcreg]; bufhi = current->thread.fpu.hard.fp_regs[srcreg+1]; } else { -#if defined(CONFIG_CPU_LITTLE_ENDIAN) +#if defined(CONFIG_LITTLE_ENDIAN) bufhi = current->thread.fpu.hard.fp_regs[srcreg]; buflo = current->thread.fpu.hard.fp_regs[srcreg+1]; #else diff --git a/trunk/arch/sh/kernel/vmlinux_64.lds.S b/trunk/arch/sh/kernel/vmlinux_64.lds.S index d1e177009a41..3f1bd6392bb3 100644 --- a/trunk/arch/sh/kernel/vmlinux_64.lds.S +++ b/trunk/arch/sh/kernel/vmlinux_64.lds.S @@ -51,7 +51,7 @@ SECTIONS KPROBES_TEXT *(.fixup) *(.gnu.warning) -#ifdef CONFIG_CPU_LITTLE_ENDIAN +#ifdef CONFIG_LITTLE_ENDIAN } = 0x6ff0fff0 #else } = 0xf0fff06f diff --git a/trunk/arch/sh/mm/cache-sh5.c b/trunk/arch/sh/mm/cache-sh5.c index 3877321fcede..4617e3aeee73 100644 --- a/trunk/arch/sh/mm/cache-sh5.c +++ b/trunk/arch/sh/mm/cache-sh5.c @@ -1,10 +1,10 @@ /* * arch/sh/mm/cache-sh5.c * - * Copyright (C) 2000, 2001 Paolo Alberelli - * Copyright (C) 2002 Benedict Gaster - * Copyright (C) 2003 Richard Curnow - * Copyright (C) 2003 - 2008 Paul Mundt + * Original version Copyright (C) 2000, 2001 Paolo Alberelli + * Second version Copyright (C) benedict.gaster@superh.com 2002 + * Third version Copyright Richard.Curnow@superh.com 2003 + * Hacks to third version Copyright (C) 2003 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -13,20 +13,101 @@ #include #include #include -#include +#include +#include +#include #include #include -#include +#include +#include #include #include +#include /* for flush_itlb_range */ + +#include + +/* This function is in entry.S */ +extern unsigned long switch_and_save_asid(unsigned long new_asid); /* Wired TLB entry for the D-cache */ static unsigned long long dtlb_cache_slot; -void __init p3_cache_init(void) +/** + * sh64_cache_init() + * + * This is pretty much just a straightforward clone of the SH + * detect_cpu_and_cache_system(). + * + * This function is responsible for setting up all of the cache + * info dynamically as well as taking care of CPU probing and + * setting up the relevant subtype data. + * + * FIXME: For the time being, we only really support the SH5-101 + * out of the box, and don't support dynamic probing for things + * like the SH5-103 or even cut2 of the SH5-101. Implement this + * later! + */ +int __init sh64_cache_init(void) { - /* Reserve a slot for dcache colouring in the DTLB */ - dtlb_cache_slot = sh64_get_wired_dtlb_entry(); + /* + * First, setup some sane values for the I-cache. + */ + cpu_data->icache.ways = 4; + cpu_data->icache.sets = 256; + cpu_data->icache.linesz = L1_CACHE_BYTES; + + /* + * FIXME: This can probably be cleaned up a bit as well.. for example, + * do we really need the way shift _and_ the way_step_shift ?? Judging + * by the existing code, I would guess no.. is there any valid reason + * why we need to be tracking this around? + */ + cpu_data->icache.way_shift = 13; + cpu_data->icache.entry_shift = 5; + cpu_data->icache.set_shift = 4; + cpu_data->icache.way_step_shift = 16; + cpu_data->icache.asid_shift = 2; + + /* + * way offset = cache size / associativity, so just don't factor in + * associativity in the first place.. + */ + cpu_data->icache.way_ofs = cpu_data->icache.sets * + cpu_data->icache.linesz; + + cpu_data->icache.asid_mask = 0x3fc; + cpu_data->icache.idx_mask = 0x1fe0; + cpu_data->icache.epn_mask = 0xffffe000; + cpu_data->icache.flags = 0; + + /* + * Next, setup some sane values for the D-cache. + * + * On the SH5, these are pretty consistent with the I-cache settings, + * so we just copy over the existing definitions.. these can be fixed + * up later, especially if we add runtime CPU probing. + * + * Though in the meantime it saves us from having to duplicate all of + * the above definitions.. + */ + cpu_data->dcache = cpu_data->icache; + + /* + * Setup any cache-related flags here + */ +#if defined(CONFIG_DCACHE_WRITE_THROUGH) + set_bit(SH_CACHE_MODE_WT, &(cpu_data->dcache.flags)); +#elif defined(CONFIG_DCACHE_WRITE_BACK) + set_bit(SH_CACHE_MODE_WB, &(cpu_data->dcache.flags)); +#endif + + /* + * We also need to reserve a slot for the D-cache in the DTLB, so we + * do this now .. + */ + dtlb_cache_slot = sh64_get_wired_dtlb_entry(); + + return 0; } #ifdef CONFIG_DCACHE_DISABLED @@ -35,48 +116,73 @@ void __init p3_cache_init(void) #define sh64_dcache_purge_user_range(mm, start, end) do { } while (0) #define sh64_dcache_purge_phy_page(paddr) do { } while (0) #define sh64_dcache_purge_virt_page(mm, eaddr) do { } while (0) +#define sh64_dcache_purge_kernel_range(start, end) do { } while (0) +#define sh64_dcache_wback_current_user_range(start, end) do { } while (0) #endif -/* - * The following group of functions deal with mapping and unmapping a - * temporary page into a DTLB slot that has been set aside for exclusive - * use. - */ -static inline void -sh64_setup_dtlb_cache_slot(unsigned long eaddr, unsigned long asid, - unsigned long paddr) +/*##########################################################################*/ + +/* From here onwards, a rewrite of the implementation, + by Richard.Curnow@superh.com. + + The major changes in this compared to the old version are; + 1. use more selective purging through OCBP instead of using ALLOCO to purge + by natural replacement. This avoids purging out unrelated cache lines + that happen to be in the same set. + 2. exploit the APIs copy_user_page and clear_user_page better + 3. be more selective about I-cache purging, in particular use invalidate_all + more sparingly. + + */ + +/*########################################################################## + SUPPORT FUNCTIONS + ##########################################################################*/ + +/****************************************************************************/ +/* The following group of functions deal with mapping and unmapping a temporary + page into the DTLB slot that have been set aside for our exclusive use. */ +/* In order to accomplish this, we use the generic interface for adding and + removing a wired slot entry as defined in arch/sh/mm/tlb-sh5.c */ +/****************************************************************************/ + +static unsigned long slot_own_flags; + +static inline void sh64_setup_dtlb_cache_slot(unsigned long eaddr, unsigned long asid, unsigned long paddr) { - local_irq_disable(); + local_irq_save(slot_own_flags); sh64_setup_tlb_slot(dtlb_cache_slot, eaddr, asid, paddr); } static inline void sh64_teardown_dtlb_cache_slot(void) { sh64_teardown_tlb_slot(dtlb_cache_slot); - local_irq_enable(); + local_irq_restore(slot_own_flags); } +/****************************************************************************/ + #ifndef CONFIG_ICACHE_DISABLED -static inline void sh64_icache_inv_all(void) + +static void __inline__ sh64_icache_inv_all(void) { unsigned long long addr, flag, data; unsigned int flags; - addr = ICCR0; - flag = ICCR0_ICI; - data = 0; + addr=ICCR0; + flag=ICCR0_ICI; + data=0; /* Make this a critical section for safety (probably not strictly necessary.) */ local_irq_save(flags); /* Without %1 it gets unexplicably wrong */ - __asm__ __volatile__ ( - "getcfg %3, 0, %0\n\t" - "or %0, %2, %0\n\t" - "putcfg %3, 0, %0\n\t" - "synci" - : "=&r" (data) - : "0" (data), "r" (flag), "r" (addr)); + asm volatile("getcfg %3, 0, %0\n\t" + "or %0, %2, %0\n\t" + "putcfg %3, 0, %0\n\t" + "synci" + : "=&r" (data) + : "0" (data), "r" (flag), "r" (addr)); local_irq_restore(flags); } @@ -87,12 +193,20 @@ static void sh64_icache_inv_kernel_range(unsigned long start, unsigned long end) * the addresses lie in the kernel superpage. */ unsigned long long ullend, addr, aligned_start; +#if (NEFF == 32) aligned_start = (unsigned long long)(signed long long)(signed long) start; - addr = L1_CACHE_ALIGN(aligned_start); +#else +#error "NEFF != 32" +#endif + aligned_start &= L1_CACHE_ALIGN_MASK; + addr = aligned_start; +#if (NEFF == 32) ullend = (unsigned long long) (signed long long) (signed long) end; - +#else +#error "NEFF != 32" +#endif while (addr <= ullend) { - __asm__ __volatile__ ("icbi %0, 0" : : "r" (addr)); + asm __volatile__ ("icbi %0, 0" : : "r" (addr)); addr += L1_CACHE_BYTES; } } @@ -101,7 +215,7 @@ static void sh64_icache_inv_user_page(struct vm_area_struct *vma, unsigned long { /* If we get called, we know that vma->vm_flags contains VM_EXEC. Also, eaddr is page-aligned. */ - unsigned int cpu = smp_processor_id(); + unsigned long long addr, end_addr; unsigned long flags = 0; unsigned long running_asid, vma_asid; @@ -123,17 +237,17 @@ static void sh64_icache_inv_user_page(struct vm_area_struct *vma, unsigned long */ running_asid = get_asid(); - vma_asid = cpu_asid(cpu, vma->vm_mm); + vma_asid = (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK); if (running_asid != vma_asid) { local_irq_save(flags); switch_and_save_asid(vma_asid); } while (addr < end_addr) { /* Worth unrolling a little */ - __asm__ __volatile__("icbi %0, 0" : : "r" (addr)); - __asm__ __volatile__("icbi %0, 32" : : "r" (addr)); - __asm__ __volatile__("icbi %0, 64" : : "r" (addr)); - __asm__ __volatile__("icbi %0, 96" : : "r" (addr)); + asm __volatile__("icbi %0, 0" : : "r" (addr)); + asm __volatile__("icbi %0, 32" : : "r" (addr)); + asm __volatile__("icbi %0, 64" : : "r" (addr)); + asm __volatile__("icbi %0, 96" : : "r" (addr)); addr += 128; } if (running_asid != vma_asid) { @@ -142,6 +256,8 @@ static void sh64_icache_inv_user_page(struct vm_area_struct *vma, unsigned long } } +/****************************************************************************/ + static void sh64_icache_inv_user_page_range(struct mm_struct *mm, unsigned long start, unsigned long end) { @@ -159,10 +275,10 @@ static void sh64_icache_inv_user_page_range(struct mm_struct *mm, possible with the D-cache. Just assume 64 for now as a working figure. */ + int n_pages; - if (!mm) - return; + if (!mm) return; n_pages = ((end - start) >> PAGE_SHIFT); if (n_pages >= 64) { @@ -174,7 +290,7 @@ static void sh64_icache_inv_user_page_range(struct mm_struct *mm, unsigned long mm_asid, current_asid; unsigned long long flags = 0ULL; - mm_asid = cpu_asid(smp_processor_id(), mm); + mm_asid = mm->context & MMU_CONTEXT_ASID_MASK; current_asid = get_asid(); if (mm_asid != current_asid) { @@ -206,7 +322,6 @@ static void sh64_icache_inv_user_page_range(struct mm_struct *mm, } aligned_start = vma->vm_end; /* Skip to start of next region */ } - if (mm_asid != current_asid) { switch_and_save_asid(current_asid); local_irq_restore(flags); @@ -214,46 +329,47 @@ static void sh64_icache_inv_user_page_range(struct mm_struct *mm, } } -/* - * Invalidate a small range of user context I-cache, not necessarily page - * (or even cache-line) aligned. - * - * Since this is used inside ptrace, the ASID in the mm context typically - * won't match current_asid. We'll have to switch ASID to do this. For - * safety, and given that the range will be small, do all this under cli. - * - * Note, there is a hazard that the ASID in mm->context is no longer - * actually associated with mm, i.e. if the mm->context has started a new - * cycle since mm was last active. However, this is just a performance - * issue: all that happens is that we invalidate lines belonging to - * another mm, so the owning process has to refill them when that mm goes - * live again. mm itself can't have any cache entries because there will - * have been a flush_cache_all when the new mm->context cycle started. - */ static void sh64_icache_inv_user_small_range(struct mm_struct *mm, unsigned long start, int len) { + + /* Invalidate a small range of user context I-cache, not necessarily + page (or even cache-line) aligned. */ + unsigned long long eaddr = start; unsigned long long eaddr_end = start + len; unsigned long current_asid, mm_asid; unsigned long long flags; unsigned long long epage_start; - /* - * Align to start of cache line. Otherwise, suppose len==8 and - * start was at 32N+28 : the last 4 bytes wouldn't get invalidated. - */ - eaddr = L1_CACHE_ALIGN(start); + /* Since this is used inside ptrace, the ASID in the mm context + typically won't match current_asid. We'll have to switch ASID to do + this. For safety, and given that the range will be small, do all + this under cli. + + Note, there is a hazard that the ASID in mm->context is no longer + actually associated with mm, i.e. if the mm->context has started a + new cycle since mm was last active. However, this is just a + performance issue: all that happens is that we invalidate lines + belonging to another mm, so the owning process has to refill them + when that mm goes live again. mm itself can't have any cache + entries because there will have been a flush_cache_all when the new + mm->context cycle started. */ + + /* Align to start of cache line. Otherwise, suppose len==8 and start + was at 32N+28 : the last 4 bytes wouldn't get invalidated. */ + eaddr = start & L1_CACHE_ALIGN_MASK; eaddr_end = start + len; - mm_asid = cpu_asid(smp_processor_id(), mm); local_irq_save(flags); + mm_asid = mm->context & MMU_CONTEXT_ASID_MASK; current_asid = switch_and_save_asid(mm_asid); epage_start = eaddr & PAGE_MASK; - while (eaddr < eaddr_end) { - __asm__ __volatile__("icbi %0, 0" : : "r" (eaddr)); + while (eaddr < eaddr_end) + { + asm __volatile__("icbi %0, 0" : : "r" (eaddr)); eaddr += L1_CACHE_BYTES; } switch_and_save_asid(current_asid); @@ -278,24 +394,30 @@ static void sh64_icache_inv_current_user_range(unsigned long start, unsigned lon been recycled since we were last active in which case we might just invalidate another processes I-cache entries : no worries, just a performance drop for him. */ - aligned_start = L1_CACHE_ALIGN(start); + aligned_start = start & L1_CACHE_ALIGN_MASK; addr = aligned_start; while (addr < ull_end) { - __asm__ __volatile__ ("icbi %0, 0" : : "r" (addr)); - __asm__ __volatile__ ("nop"); - __asm__ __volatile__ ("nop"); + asm __volatile__ ("icbi %0, 0" : : "r" (addr)); + asm __volatile__ ("nop"); + asm __volatile__ ("nop"); addr += L1_CACHE_BYTES; } } + #endif /* !CONFIG_ICACHE_DISABLED */ +/****************************************************************************/ + #ifndef CONFIG_DCACHE_DISABLED + /* Buffer used as the target of alloco instructions to purge data from cache sets by natural eviction. -- RPC */ -#define DUMMY_ALLOCO_AREA_SIZE ((L1_CACHE_BYTES << 10) + (1024 * 4)) +#define DUMMY_ALLOCO_AREA_SIZE L1_CACHE_SIZE_BYTES + (1024 * 4) static unsigned char dummy_alloco_area[DUMMY_ALLOCO_AREA_SIZE] __cacheline_aligned = { 0, }; -static void inline sh64_dcache_purge_sets(int sets_to_purge_base, int n_sets) +/****************************************************************************/ + +static void __inline__ sh64_dcache_purge_sets(int sets_to_purge_base, int n_sets) { /* Purge all ways in a particular block of sets, specified by the base set number and number of sets. Can handle wrap-around, if that's @@ -306,86 +428,102 @@ static void inline sh64_dcache_purge_sets(int sets_to_purge_base, int n_sets) int j; int set_offset; - dummy_buffer_base_set = ((int)&dummy_alloco_area & - cpu_data->dcache.entry_mask) >> - cpu_data->dcache.entry_shift; + dummy_buffer_base_set = ((int)&dummy_alloco_area & cpu_data->dcache.idx_mask) >> cpu_data->dcache.entry_shift; set_offset = sets_to_purge_base - dummy_buffer_base_set; - for (j = 0; j < n_sets; j++, set_offset++) { + for (j=0; jdcache.sets - 1); - eaddr0 = (unsigned long long)dummy_alloco_area + - (set_offset << cpu_data->dcache.entry_shift); - - /* - * Do one alloco which hits the required set per cache - * way. For write-back mode, this will purge the #ways - * resident lines. There's little point unrolling this - * loop because the allocos stall more if they're too - * close together. - */ - eaddr1 = eaddr0 + cpu_data->dcache.way_size * - cpu_data->dcache.ways; - - for (eaddr = eaddr0; eaddr < eaddr1; - eaddr += cpu_data->dcache.way_size) { - __asm__ __volatile__ ("alloco %0, 0" : : "r" (eaddr)); - __asm__ __volatile__ ("synco"); /* TAKum03020 */ + eaddr0 = (unsigned long long)dummy_alloco_area + (set_offset << cpu_data->dcache.entry_shift); + + /* Do one alloco which hits the required set per cache way. For + write-back mode, this will purge the #ways resident lines. There's + little point unrolling this loop because the allocos stall more if + they're too close together. */ + eaddr1 = eaddr0 + cpu_data->dcache.way_ofs * cpu_data->dcache.ways; + for (eaddr=eaddr0; eaddrdcache.way_ofs) { + asm __volatile__ ("alloco %0, 0" : : "r" (eaddr)); + asm __volatile__ ("synco"); /* TAKum03020 */ } - eaddr1 = eaddr0 + cpu_data->dcache.way_size * - cpu_data->dcache.ways; - - for (eaddr = eaddr0; eaddr < eaddr1; - eaddr += cpu_data->dcache.way_size) { - /* - * Load from each address. Required because - * alloco is a NOP if the cache is write-through. - */ + eaddr1 = eaddr0 + cpu_data->dcache.way_ofs * cpu_data->dcache.ways; + for (eaddr=eaddr0; eaddrdcache.way_ofs) { + /* Load from each address. Required because alloco is a NOP if + the cache is write-through. Write-through is a config option. */ if (test_bit(SH_CACHE_MODE_WT, &(cpu_data->dcache.flags))) - ctrl_inb(eaddr); + *(volatile unsigned char *)(int)eaddr; } } - /* - * Don't use OCBI to invalidate the lines. That costs cycles - * directly. If the dummy block is just left resident, it will - * naturally get evicted as required. - */ + /* Don't use OCBI to invalidate the lines. That costs cycles directly. + If the dummy block is just left resident, it will naturally get + evicted as required. */ + + return; } -/* - * Purge the entire contents of the dcache. The most efficient way to - * achieve this is to use alloco instructions on a region of unused - * memory equal in size to the cache, thereby causing the current - * contents to be discarded by natural eviction. The alternative, namely - * reading every tag, setting up a mapping for the corresponding page and - * doing an OCBP for the line, would be much more expensive. - */ +/****************************************************************************/ + static void sh64_dcache_purge_all(void) { + /* Purge the entire contents of the dcache. The most efficient way to + achieve this is to use alloco instructions on a region of unused + memory equal in size to the cache, thereby causing the current + contents to be discarded by natural eviction. The alternative, + namely reading every tag, setting up a mapping for the corresponding + page and doing an OCBP for the line, would be much more expensive. + */ sh64_dcache_purge_sets(0, cpu_data->dcache.sets); + + return; + } +/****************************************************************************/ + +static void sh64_dcache_purge_kernel_range(unsigned long start, unsigned long end) +{ + /* Purge the range of addresses [start,end] from the D-cache. The + addresses lie in the superpage mapping. There's no harm if we + overpurge at either end - just a small performance loss. */ + unsigned long long ullend, addr, aligned_start; +#if (NEFF == 32) + aligned_start = (unsigned long long)(signed long long)(signed long) start; +#else +#error "NEFF != 32" +#endif + aligned_start &= L1_CACHE_ALIGN_MASK; + addr = aligned_start; +#if (NEFF == 32) + ullend = (unsigned long long) (signed long long) (signed long) end; +#else +#error "NEFF != 32" +#endif + while (addr <= ullend) { + asm __volatile__ ("ocbp %0, 0" : : "r" (addr)); + addr += L1_CACHE_BYTES; + } + return; +} /* Assumes this address (+ (2**n_synbits) pages up from it) aren't used for anything else in the kernel */ #define MAGIC_PAGE0_START 0xffffffffec000000ULL -/* Purge the physical page 'paddr' from the cache. It's known that any - * cache lines requiring attention have the same page colour as the the - * address 'eaddr'. - * - * This relies on the fact that the D-cache matches on physical tags when - * no virtual tag matches. So we create an alias for the original page - * and purge through that. (Alternatively, we could have done this by - * switching ASID to match the original mapping and purged through that, - * but that involves ASID switching cost + probably a TLBMISS + refill - * anyway.) - */ -static void sh64_dcache_purge_coloured_phy_page(unsigned long paddr, - unsigned long eaddr) +static void sh64_dcache_purge_coloured_phy_page(unsigned long paddr, unsigned long eaddr) { + /* Purge the physical page 'paddr' from the cache. It's known that any + cache lines requiring attention have the same page colour as the the + address 'eaddr'. + + This relies on the fact that the D-cache matches on physical tags + when no virtual tag matches. So we create an alias for the original + page and purge through that. (Alternatively, we could have done + this by switching ASID to match the original mapping and purged + through that, but that involves ASID switching cost + probably a + TLBMISS + refill anyway.) + */ + unsigned long long magic_page_start; unsigned long long magic_eaddr, magic_eaddr_end; @@ -393,45 +531,47 @@ static void sh64_dcache_purge_coloured_phy_page(unsigned long paddr, /* As long as the kernel is not pre-emptible, this doesn't need to be under cli/sti. */ + sh64_setup_dtlb_cache_slot(magic_page_start, get_asid(), paddr); magic_eaddr = magic_page_start; magic_eaddr_end = magic_eaddr + PAGE_SIZE; - while (magic_eaddr < magic_eaddr_end) { /* Little point in unrolling this loop - the OCBPs are blocking and won't go any quicker (i.e. the loop overhead is parallel to part of the OCBP execution.) */ - __asm__ __volatile__ ("ocbp %0, 0" : : "r" (magic_eaddr)); + asm __volatile__ ("ocbp %0, 0" : : "r" (magic_eaddr)); magic_eaddr += L1_CACHE_BYTES; } sh64_teardown_dtlb_cache_slot(); } -/* - * Purge a page given its physical start address, by creating a temporary - * 1 page mapping and purging across that. Even if we know the virtual - * address (& vma or mm) of the page, the method here is more elegant - * because it avoids issues of coping with page faults on the purge - * instructions (i.e. no special-case code required in the critical path - * in the TLB miss handling). - */ +/****************************************************************************/ + static void sh64_dcache_purge_phy_page(unsigned long paddr) { + /* Pure a page given its physical start address, by creating a + temporary 1 page mapping and purging across that. Even if we know + the virtual address (& vma or mm) of the page, the method here is + more elegant because it avoids issues of coping with page faults on + the purge instructions (i.e. no special-case code required in the + critical path in the TLB miss handling). */ + unsigned long long eaddr_start, eaddr, eaddr_end; int i; /* As long as the kernel is not pre-emptible, this doesn't need to be under cli/sti. */ + eaddr_start = MAGIC_PAGE0_START; - for (i = 0; i < (1 << CACHE_OC_N_SYNBITS); i++) { + for (i=0; i < (1 << CACHE_OC_N_SYNBITS); i++) { sh64_setup_dtlb_cache_slot(eaddr_start, get_asid(), paddr); eaddr = eaddr_start; eaddr_end = eaddr + PAGE_SIZE; while (eaddr < eaddr_end) { - __asm__ __volatile__ ("ocbp %0, 0" : : "r" (eaddr)); + asm __volatile__ ("ocbp %0, 0" : : "r" (eaddr)); eaddr += L1_CACHE_BYTES; } @@ -444,7 +584,6 @@ static void sh64_dcache_purge_user_pages(struct mm_struct *mm, unsigned long addr, unsigned long end) { pgd_t *pgd; - pud_t *pud; pmd_t *pmd; pte_t *pte; pte_t entry; @@ -458,11 +597,7 @@ static void sh64_dcache_purge_user_pages(struct mm_struct *mm, if (pgd_bad(*pgd)) return; - pud = pud_offset(pgd, addr); - if (pud_none(*pud) || pud_bad(*pud)) - return; - - pmd = pmd_offset(pud, addr); + pmd = pmd_offset(pgd, addr); if (pmd_none(*pmd) || pmd_bad(*pmd)) return; @@ -476,357 +611,419 @@ static void sh64_dcache_purge_user_pages(struct mm_struct *mm, } while (pte++, addr += PAGE_SIZE, addr != end); pte_unmap_unlock(pte - 1, ptl); } +/****************************************************************************/ -/* - * There are at least 5 choices for the implementation of this, with - * pros (+), cons(-), comments(*): - * - * 1. ocbp each line in the range through the original user's ASID - * + no lines spuriously evicted - * - tlbmiss handling (must either handle faults on demand => extra - * special-case code in tlbmiss critical path), or map the page in - * advance (=> flush_tlb_range in advance to avoid multiple hits) - * - ASID switching - * - expensive for large ranges - * - * 2. temporarily map each page in the range to a special effective - * address and ocbp through the temporary mapping; relies on the - * fact that SH-5 OCB* always do TLB lookup and match on ptags (they - * never look at the etags) - * + no spurious evictions - * - expensive for large ranges - * * surely cheaper than (1) - * - * 3. walk all the lines in the cache, check the tags, if a match - * occurs create a page mapping to ocbp the line through - * + no spurious evictions - * - tag inspection overhead - * - (especially for small ranges) - * - potential cost of setting up/tearing down page mapping for - * every line that matches the range - * * cost partly independent of range size - * - * 4. walk all the lines in the cache, check the tags, if a match - * occurs use 4 * alloco to purge the line (+3 other probably - * innocent victims) by natural eviction - * + no tlb mapping overheads - * - spurious evictions - * - tag inspection overhead - * - * 5. implement like flush_cache_all - * + no tag inspection overhead - * - spurious evictions - * - bad for small ranges - * - * (1) can be ruled out as more expensive than (2). (2) appears best - * for small ranges. The choice between (3), (4) and (5) for large - * ranges and the range size for the large/small boundary need - * benchmarking to determine. - * - * For now use approach (2) for small ranges and (5) for large ones. - */ static void sh64_dcache_purge_user_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - int n_pages = ((end - start) >> PAGE_SHIFT); + /* There are at least 5 choices for the implementation of this, with + pros (+), cons(-), comments(*): + + 1. ocbp each line in the range through the original user's ASID + + no lines spuriously evicted + - tlbmiss handling (must either handle faults on demand => extra + special-case code in tlbmiss critical path), or map the page in + advance (=> flush_tlb_range in advance to avoid multiple hits) + - ASID switching + - expensive for large ranges + + 2. temporarily map each page in the range to a special effective + address and ocbp through the temporary mapping; relies on the + fact that SH-5 OCB* always do TLB lookup and match on ptags (they + never look at the etags) + + no spurious evictions + - expensive for large ranges + * surely cheaper than (1) + + 3. walk all the lines in the cache, check the tags, if a match + occurs create a page mapping to ocbp the line through + + no spurious evictions + - tag inspection overhead + - (especially for small ranges) + - potential cost of setting up/tearing down page mapping for + every line that matches the range + * cost partly independent of range size + + 4. walk all the lines in the cache, check the tags, if a match + occurs use 4 * alloco to purge the line (+3 other probably + innocent victims) by natural eviction + + no tlb mapping overheads + - spurious evictions + - tag inspection overhead + + 5. implement like flush_cache_all + + no tag inspection overhead + - spurious evictions + - bad for small ranges + + (1) can be ruled out as more expensive than (2). (2) appears best + for small ranges. The choice between (3), (4) and (5) for large + ranges and the range size for the large/small boundary need + benchmarking to determine. + + For now use approach (2) for small ranges and (5) for large ones. + + */ + + int n_pages; + n_pages = ((end - start) >> PAGE_SHIFT); if (n_pages >= 64 || ((start ^ (end - 1)) & PMD_MASK)) { +#if 1 sh64_dcache_purge_all(); +#else + unsigned long long set, way; + unsigned long mm_asid = mm->context & MMU_CONTEXT_ASID_MASK; + for (set = 0; set < cpu_data->dcache.sets; set++) { + unsigned long long set_base_config_addr = CACHE_OC_ADDRESS_ARRAY + (set << cpu_data->dcache.set_shift); + for (way = 0; way < cpu_data->dcache.ways; way++) { + unsigned long long config_addr = set_base_config_addr + (way << cpu_data->dcache.way_step_shift); + unsigned long long tag0; + unsigned long line_valid; + + asm __volatile__("getcfg %1, 0, %0" : "=r" (tag0) : "r" (config_addr)); + line_valid = tag0 & SH_CACHE_VALID; + if (line_valid) { + unsigned long cache_asid; + unsigned long epn; + + cache_asid = (tag0 & cpu_data->dcache.asid_mask) >> cpu_data->dcache.asid_shift; + /* The next line needs some + explanation. The virtual tags + encode bits [31:13] of the virtual + address, bit [12] of the 'tag' being + implied by the cache set index. */ + epn = (tag0 & cpu_data->dcache.epn_mask) | ((set & 0x80) << cpu_data->dcache.entry_shift); + + if ((cache_asid == mm_asid) && (start <= epn) && (epn < end)) { + /* TODO : could optimise this + call by batching multiple + adjacent sets together. */ + sh64_dcache_purge_sets(set, 1); + break; /* Don't waste time inspecting other ways for this set */ + } + } + } + } +#endif } else { /* Small range, covered by a single page table page */ start &= PAGE_MASK; /* should already be so */ end = PAGE_ALIGN(end); /* should already be so */ sh64_dcache_purge_user_pages(mm, start, end); } + return; } -/* - * Purge the range of addresses from the D-cache. - * - * The addresses lie in the superpage mapping. There's no harm if we - * overpurge at either end - just a small performance loss. - */ -void __flush_purge_region(void *start, int size) +static void sh64_dcache_wback_current_user_range(unsigned long start, unsigned long end) { - unsigned long long ullend, addr, aligned_start; + unsigned long long aligned_start; + unsigned long long ull_end; + unsigned long long addr; - aligned_start = (unsigned long long)(signed long long)(signed long) start; - addr = L1_CACHE_ALIGN(aligned_start); - ullend = (unsigned long long) (signed long long) (signed long) start + size; + ull_end = end; - while (addr <= ullend) { - __asm__ __volatile__ ("ocbp %0, 0" : : "r" (addr)); + /* Just wback over the range using the natural addresses. TLB miss + handling will be OK (TBC) : the range has just been written to by + the signal frame setup code, so the PTEs must exist. + + Note, if we have CONFIG_PREEMPT and get preempted inside this loop, + it doesn't matter, even if the pid->ASID mapping changes whilst + we're away. In that case the cache will have been flushed when the + mapping was renewed. So the writebacks below will be nugatory (and + we'll doubtless have to fault the TLB entry/ies in again with the + new ASID), but it's a rare case. + */ + aligned_start = start & L1_CACHE_ALIGN_MASK; + addr = aligned_start; + while (addr < ull_end) { + asm __volatile__ ("ocbwb %0, 0" : : "r" (addr)); addr += L1_CACHE_BYTES; } } -void __flush_wback_region(void *start, int size) +/****************************************************************************/ + +/* These *MUST* lie in an area of virtual address space that's otherwise unused. */ +#define UNIQUE_EADDR_START 0xe0000000UL +#define UNIQUE_EADDR_END 0xe8000000UL + +static unsigned long sh64_make_unique_eaddr(unsigned long user_eaddr, unsigned long paddr) { - unsigned long long ullend, addr, aligned_start; + /* Given a physical address paddr, and a user virtual address + user_eaddr which will eventually be mapped to it, create a one-off + kernel-private eaddr mapped to the same paddr. This is used for + creating special destination pages for copy_user_page and + clear_user_page */ - aligned_start = (unsigned long long)(signed long long)(signed long) start; - addr = L1_CACHE_ALIGN(aligned_start); - ullend = (unsigned long long) (signed long long) (signed long) start + size; + static unsigned long current_pointer = UNIQUE_EADDR_START; + unsigned long coloured_pointer; - while (addr < ullend) { - __asm__ __volatile__ ("ocbwb %0, 0" : : "r" (addr)); - addr += L1_CACHE_BYTES; + if (current_pointer == UNIQUE_EADDR_END) { + sh64_dcache_purge_all(); + current_pointer = UNIQUE_EADDR_START; } + + coloured_pointer = (current_pointer & ~CACHE_OC_SYN_MASK) | (user_eaddr & CACHE_OC_SYN_MASK); + sh64_setup_dtlb_cache_slot(coloured_pointer, get_asid(), paddr); + + current_pointer += (PAGE_SIZE << CACHE_OC_N_SYNBITS); + + return coloured_pointer; } -void __flush_invalidate_region(void *start, int size) +/****************************************************************************/ + +static void sh64_copy_user_page_coloured(void *to, void *from, unsigned long address) { - unsigned long long ullend, addr, aligned_start; + void *coloured_to; - aligned_start = (unsigned long long)(signed long long)(signed long) start; - addr = L1_CACHE_ALIGN(aligned_start); - ullend = (unsigned long long) (signed long long) (signed long) start + size; + /* Discard any existing cache entries of the wrong colour. These are + present quite often, if the kernel has recently used the page + internally, then given it up, then it's been allocated to the user. + */ + sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long) to); - while (addr < ullend) { - __asm__ __volatile__ ("ocbi %0, 0" : : "r" (addr)); - addr += L1_CACHE_BYTES; - } + coloured_to = (void *) sh64_make_unique_eaddr(address, __pa(to)); + sh64_page_copy(from, coloured_to); + + sh64_teardown_dtlb_cache_slot(); +} + +static void sh64_clear_user_page_coloured(void *to, unsigned long address) +{ + void *coloured_to; + + /* Discard any existing kernel-originated lines of the wrong colour (as + above) */ + sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long) to); + + coloured_to = (void *) sh64_make_unique_eaddr(address, __pa(to)); + sh64_page_clear(coloured_to); + + sh64_teardown_dtlb_cache_slot(); } + #endif /* !CONFIG_DCACHE_DISABLED */ -/* - * Invalidate the entire contents of both caches, after writing back to - * memory any dirty data from the D-cache. - */ +/****************************************************************************/ + +/*########################################################################## + EXTERNALLY CALLABLE API. + ##########################################################################*/ + +/* These functions are described in Documentation/cachetlb.txt. + Each one of these functions varies in behaviour depending on whether the + I-cache and/or D-cache are configured out. + + Note that the Linux term 'flush' corresponds to what is termed 'purge' in + the sh/sh64 jargon for the D-cache, i.e. write back dirty data then + invalidate the cache lines, and 'invalidate' for the I-cache. + */ + +#undef FLUSH_TRACE + void flush_cache_all(void) { + /* Invalidate the entire contents of both caches, after writing back to + memory any dirty data from the D-cache. */ sh64_dcache_purge_all(); sh64_icache_inv_all(); } -/* - * Invalidate an entire user-address space from both caches, after - * writing back dirty data (e.g. for shared mmap etc). - * - * This could be coded selectively by inspecting all the tags then - * doing 4*alloco on any set containing a match (as for - * flush_cache_range), but fork/exit/execve (where this is called from) - * are expensive anyway. - * - * Have to do a purge here, despite the comments re I-cache below. - * There could be odd-coloured dirty data associated with the mm still - * in the cache - if this gets written out through natural eviction - * after the kernel has reused the page there will be chaos. - * - * The mm being torn down won't ever be active again, so any Icache - * lines tagged with its ASID won't be visible for the rest of the - * lifetime of this ASID cycle. Before the ASID gets reused, there - * will be a flush_cache_all. Hence we don't need to touch the - * I-cache. This is similar to the lack of action needed in - * flush_tlb_mm - see fault.c. - */ +/****************************************************************************/ + void flush_cache_mm(struct mm_struct *mm) { + /* Invalidate an entire user-address space from both caches, after + writing back dirty data (e.g. for shared mmap etc). */ + + /* This could be coded selectively by inspecting all the tags then + doing 4*alloco on any set containing a match (as for + flush_cache_range), but fork/exit/execve (where this is called from) + are expensive anyway. */ + + /* Have to do a purge here, despite the comments re I-cache below. + There could be odd-coloured dirty data associated with the mm still + in the cache - if this gets written out through natural eviction + after the kernel has reused the page there will be chaos. + */ + sh64_dcache_purge_all(); + + /* The mm being torn down won't ever be active again, so any Icache + lines tagged with its ASID won't be visible for the rest of the + lifetime of this ASID cycle. Before the ASID gets reused, there + will be a flush_cache_all. Hence we don't need to touch the + I-cache. This is similar to the lack of action needed in + flush_tlb_mm - see fault.c. */ } -/* - * Invalidate (from both caches) the range [start,end) of virtual - * addresses from the user address space specified by mm, after writing - * back any dirty data. - * - * Note, 'end' is 1 byte beyond the end of the range to flush. - */ +/****************************************************************************/ + void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { struct mm_struct *mm = vma->vm_mm; + /* Invalidate (from both caches) the range [start,end) of virtual + addresses from the user address space specified by mm, after writing + back any dirty data. + + Note, 'end' is 1 byte beyond the end of the range to flush. */ + sh64_dcache_purge_user_range(mm, start, end); sh64_icache_inv_user_page_range(mm, start, end); } -/* - * Invalidate any entries in either cache for the vma within the user - * address space vma->vm_mm for the page starting at virtual address - * 'eaddr'. This seems to be used primarily in breaking COW. Note, - * the I-cache must be searched too in case the page in question is - * both writable and being executed from (e.g. stack trampolines.) - * - * Note, this is called with pte lock held. - */ -void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr, - unsigned long pfn) +/****************************************************************************/ + +void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr, unsigned long pfn) { + /* Invalidate any entries in either cache for the vma within the user + address space vma->vm_mm for the page starting at virtual address + 'eaddr'. This seems to be used primarily in breaking COW. Note, + the I-cache must be searched too in case the page in question is + both writable and being executed from (e.g. stack trampolines.) + + Note, this is called with pte lock held. + */ + sh64_dcache_purge_phy_page(pfn << PAGE_SHIFT); - if (vma->vm_flags & VM_EXEC) + if (vma->vm_flags & VM_EXEC) { sh64_icache_inv_user_page(vma, eaddr); + } } -void flush_dcache_page(struct page *page) -{ - sh64_dcache_purge_phy_page(page_to_phys(page)); - wmb(); -} +/****************************************************************************/ -/* - * Flush the range [start,end] of kernel virtual adddress space from - * the I-cache. The corresponding range must be purged from the - * D-cache also because the SH-5 doesn't have cache snooping between - * the caches. The addresses will be visible through the superpage - * mapping, therefore it's guaranteed that there no cache entries for - * the range in cache sets of the wrong colour. - */ -void flush_icache_range(unsigned long start, unsigned long end) -{ - __flush_purge_region((void *)start, end); - wmb(); - sh64_icache_inv_kernel_range(start, end); -} +#ifndef CONFIG_DCACHE_DISABLED -/* - * Flush the range of user (defined by vma->vm_mm) address space starting - * at 'addr' for 'len' bytes from the cache. The range does not straddle - * a page boundary, the unique physical page containing the range is - * 'page'. This seems to be used mainly for invalidating an address - * range following a poke into the program text through the ptrace() call - * from another process (e.g. for BRK instruction insertion). - */ -void flush_icache_user_range(struct vm_area_struct *vma, - struct page *page, unsigned long addr, int len) +void copy_user_page(void *to, void *from, unsigned long address, struct page *page) { + /* 'from' and 'to' are kernel virtual addresses (within the superpage + mapping of the physical RAM). 'address' is the user virtual address + where the copy 'to' will be mapped after. This allows a custom + mapping to be used to ensure that the new copy is placed in the + right cache sets for the user to see it without having to bounce it + out via memory. Note however : the call to flush_page_to_ram in + (generic)/mm/memory.c:(break_cow) undoes all this good work in that one + very important case! + + TBD : can we guarantee that on every call, any cache entries for + 'from' are in the same colour sets as 'address' also? i.e. is this + always used just to deal with COW? (I suspect not). */ + + /* There are two possibilities here for when the page 'from' was last accessed: + * by the kernel : this is OK, no purge required. + * by the/a user (e.g. for break_COW) : need to purge. + + If the potential user mapping at 'address' is the same colour as + 'from' there is no need to purge any cache lines from the 'from' + page mapped into cache sets of colour 'address'. (The copy will be + accessing the page through 'from'). + */ - sh64_dcache_purge_coloured_phy_page(page_to_phys(page), addr); - mb(); - - if (vma->vm_flags & VM_EXEC) - sh64_icache_inv_user_small_range(vma->vm_mm, addr, len); -} + if (((address ^ (unsigned long) from) & CACHE_OC_SYN_MASK) != 0) { + sh64_dcache_purge_coloured_phy_page(__pa(from), address); + } -/* - * For the address range [start,end), write back the data from the - * D-cache and invalidate the corresponding region of the I-cache for the - * current process. Used to flush signal trampolines on the stack to - * make them executable. - */ -void flush_cache_sigtramp(unsigned long vaddr) -{ - unsigned long end = vaddr + L1_CACHE_BYTES; + if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0) { + /* No synonym problem on destination */ + sh64_page_copy(from, to); + } else { + sh64_copy_user_page_coloured(to, from, address); + } - __flush_wback_region((void *)vaddr, L1_CACHE_BYTES); - wmb(); - sh64_icache_inv_current_user_range(vaddr, end); + /* Note, don't need to flush 'from' page from the cache again - it's + done anyway by the generic code */ } -/* - * These *MUST* lie in an area of virtual address space that's otherwise - * unused. - */ -#define UNIQUE_EADDR_START 0xe0000000UL -#define UNIQUE_EADDR_END 0xe8000000UL - -/* - * Given a physical address paddr, and a user virtual address user_eaddr - * which will eventually be mapped to it, create a one-off kernel-private - * eaddr mapped to the same paddr. This is used for creating special - * destination pages for copy_user_page and clear_user_page. - */ -static unsigned long sh64_make_unique_eaddr(unsigned long user_eaddr, - unsigned long paddr) +void clear_user_page(void *to, unsigned long address, struct page *page) { - static unsigned long current_pointer = UNIQUE_EADDR_START; - unsigned long coloured_pointer; + /* 'to' is a kernel virtual address (within the superpage + mapping of the physical RAM). 'address' is the user virtual address + where the 'to' page will be mapped after. This allows a custom + mapping to be used to ensure that the new copy is placed in the + right cache sets for the user to see it without having to bounce it + out via memory. + */ - if (current_pointer == UNIQUE_EADDR_END) { - sh64_dcache_purge_all(); - current_pointer = UNIQUE_EADDR_START; + if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0) { + /* No synonym problem on destination */ + sh64_page_clear(to); + } else { + sh64_clear_user_page_coloured(to, address); } +} - coloured_pointer = (current_pointer & ~CACHE_OC_SYN_MASK) | - (user_eaddr & CACHE_OC_SYN_MASK); - sh64_setup_dtlb_cache_slot(coloured_pointer, get_asid(), paddr); +#endif /* !CONFIG_DCACHE_DISABLED */ - current_pointer += (PAGE_SIZE << CACHE_OC_N_SYNBITS); +/****************************************************************************/ - return coloured_pointer; +void flush_dcache_page(struct page *page) +{ + sh64_dcache_purge_phy_page(page_to_phys(page)); + wmb(); } -static void sh64_copy_user_page_coloured(void *to, void *from, - unsigned long address) +/****************************************************************************/ + +void flush_icache_range(unsigned long start, unsigned long end) { - void *coloured_to; + /* Flush the range [start,end] of kernel virtual adddress space from + the I-cache. The corresponding range must be purged from the + D-cache also because the SH-5 doesn't have cache snooping between + the caches. The addresses will be visible through the superpage + mapping, therefore it's guaranteed that there no cache entries for + the range in cache sets of the wrong colour. - /* - * Discard any existing cache entries of the wrong colour. These are - * present quite often, if the kernel has recently used the page - * internally, then given it up, then it's been allocated to the user. - */ - sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long)to); + Primarily used for cohering the I-cache after a module has + been loaded. */ - coloured_to = (void *)sh64_make_unique_eaddr(address, __pa(to)); - copy_page(from, coloured_to); + /* We also make sure to purge the same range from the D-cache since + flush_page_to_ram() won't be doing this for us! */ - sh64_teardown_dtlb_cache_slot(); + sh64_dcache_purge_kernel_range(start, end); + wmb(); + sh64_icache_inv_kernel_range(start, end); } -static void sh64_clear_user_page_coloured(void *to, unsigned long address) -{ - void *coloured_to; +/****************************************************************************/ - /* - * Discard any existing kernel-originated lines of the wrong - * colour (as above) - */ - sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long)to); +void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, int len) +{ + /* Flush the range of user (defined by vma->vm_mm) address space + starting at 'addr' for 'len' bytes from the cache. The range does + not straddle a page boundary, the unique physical page containing + the range is 'page'. This seems to be used mainly for invalidating + an address range following a poke into the program text through the + ptrace() call from another process (e.g. for BRK instruction + insertion). */ - coloured_to = (void *)sh64_make_unique_eaddr(address, __pa(to)); - clear_page(coloured_to); + sh64_dcache_purge_coloured_phy_page(page_to_phys(page), addr); + mb(); - sh64_teardown_dtlb_cache_slot(); + if (vma->vm_flags & VM_EXEC) { + sh64_icache_inv_user_small_range(vma->vm_mm, addr, len); + } } -/* - * 'from' and 'to' are kernel virtual addresses (within the superpage - * mapping of the physical RAM). 'address' is the user virtual address - * where the copy 'to' will be mapped after. This allows a custom - * mapping to be used to ensure that the new copy is placed in the - * right cache sets for the user to see it without having to bounce it - * out via memory. Note however : the call to flush_page_to_ram in - * (generic)/mm/memory.c:(break_cow) undoes all this good work in that one - * very important case! - * - * TBD : can we guarantee that on every call, any cache entries for - * 'from' are in the same colour sets as 'address' also? i.e. is this - * always used just to deal with COW? (I suspect not). - * - * There are two possibilities here for when the page 'from' was last accessed: - * - by the kernel : this is OK, no purge required. - * - by the/a user (e.g. for break_COW) : need to purge. - * - * If the potential user mapping at 'address' is the same colour as - * 'from' there is no need to purge any cache lines from the 'from' - * page mapped into cache sets of colour 'address'. (The copy will be - * accessing the page through 'from'). - */ -void copy_user_page(void *to, void *from, unsigned long address, - struct page *page) +/*########################################################################## + ARCH/SH64 PRIVATE CALLABLE API. + ##########################################################################*/ + +void flush_cache_sigtramp(unsigned long start, unsigned long end) { - if (((address ^ (unsigned long) from) & CACHE_OC_SYN_MASK) != 0) - sh64_dcache_purge_coloured_phy_page(__pa(from), address); + /* For the address range [start,end), write back the data from the + D-cache and invalidate the corresponding region of the I-cache for + the current process. Used to flush signal trampolines on the stack + to make them executable. */ - if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0) - copy_page(to, from); - else - sh64_copy_user_page_coloured(to, from, address); + sh64_dcache_wback_current_user_range(start, end); + wmb(); + sh64_icache_inv_current_user_range(start, end); } -/* - * 'to' is a kernel virtual address (within the superpage mapping of the - * physical RAM). 'address' is the user virtual address where the 'to' - * page will be mapped after. This allows a custom mapping to be used to - * ensure that the new copy is placed in the right cache sets for the - * user to see it without having to bounce it out via memory. - */ -void clear_user_page(void *to, unsigned long address, struct page *page) -{ - if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0) - clear_page(to); - else - sh64_clear_user_page_coloured(to, address); -} diff --git a/trunk/arch/sh/mm/consistent.c b/trunk/arch/sh/mm/consistent.c index d3c33fc5b1c2..7b2131c9eeda 100644 --- a/trunk/arch/sh/mm/consistent.c +++ b/trunk/arch/sh/mm/consistent.c @@ -26,7 +26,7 @@ struct dma_coherent_mem { void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) { - void *ret, *ret_nocache; + void *ret; struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; int order = get_order(size); @@ -44,24 +44,17 @@ void *dma_alloc_coherent(struct device *dev, size_t size, } ret = (void *)__get_free_pages(gfp, order); - if (!ret) - return NULL; - - memset(ret, 0, size); - /* - * Pages from the page allocator may have data present in - * cache. So flush the cache before using uncached memory. - */ - dma_cache_sync(dev, ret, size, DMA_BIDIRECTIONAL); - - ret_nocache = ioremap_nocache(virt_to_phys(ret), size); - if (!ret_nocache) { - free_pages((unsigned long)ret, order); - return NULL; - } - *dma_handle = virt_to_phys(ret); - return ret_nocache; + if (ret != NULL) { + memset(ret, 0, size); + /* + * Pages from the page allocator may have data present in + * cache. So flush the cache before using uncached memory. + */ + dma_cache_sync(NULL, ret, size, DMA_BIDIRECTIONAL); + *dma_handle = virt_to_phys(ret); + } + return ret; } EXPORT_SYMBOL(dma_alloc_coherent); @@ -78,8 +71,7 @@ void dma_free_coherent(struct device *dev, size_t size, } else { WARN_ON(irqs_disabled()); /* for portability */ BUG_ON(mem && mem->flags & DMA_MEMORY_EXCLUSIVE); - free_pages((unsigned long)phys_to_virt(dma_handle), order); - iounmap(vaddr); + free_pages((unsigned long)vaddr, order); } } EXPORT_SYMBOL(dma_free_coherent); diff --git a/trunk/arch/sh/mm/fault_32.c b/trunk/arch/sh/mm/fault_32.c index d1fa27594c6e..33b43d20e9f6 100644 --- a/trunk/arch/sh/mm/fault_32.c +++ b/trunk/arch/sh/mm/fault_32.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -164,8 +163,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, if (fixup_exception(regs)) return; - if (handle_trapped_io(regs, address)) - return; /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. @@ -299,14 +296,6 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, entry = pte_mkdirty(entry); entry = pte_mkyoung(entry); -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SMP) - /* - * ITLB is not affected by "ldtlb" instruction. - * So, we need to flush the entry by ourselves. - */ - local_flush_tlb_one(get_asid(), address & PAGE_MASK); -#endif - set_pte(pte, entry); update_mmu_cache(NULL, address, entry); diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index e2ed6dd252b9..2918c6b14659 100644 --- a/trunk/arch/sh/mm/init.c +++ b/trunk/arch/sh/mm/init.c @@ -203,7 +203,6 @@ void __init paging_init(void) free_area_init_nodes(max_zone_pfns); -#ifdef CONFIG_SUPERH32 /* Set up the uncached fixmap */ set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start)); @@ -215,7 +214,6 @@ void __init paging_init(void) */ cached_to_uncached = P2SEG - P1SEG; #endif -#endif } static struct kcore_list kcore_mem, kcore_vmalloc; diff --git a/trunk/arch/sh/tools/mach-types b/trunk/arch/sh/tools/mach-types index 67997af25c0c..25810670a0fa 100644 --- a/trunk/arch/sh/tools/mach-types +++ b/trunk/arch/sh/tools/mach-types @@ -45,5 +45,3 @@ MAGICPANELR2 SH_MAGIC_PANEL_R2 R2D_PLUS RTS7751R2D_PLUS R2D_1 RTS7751R2D_1 CAYMAN SH_CAYMAN -SDK7780 SH_SDK7780 -MIGOR SH_MIGOR diff --git a/trunk/arch/sparc64/solaris/fs.c b/trunk/arch/sparc64/solaris/fs.c index 7d035f0d3ae1..9311bfe4f2f7 100644 --- a/trunk/arch/sparc64/solaris/fs.c +++ b/trunk/arch/sparc64/solaris/fs.c @@ -434,9 +434,9 @@ asmlinkage int solaris_statvfs(u32 path, u32 buf) error = user_path_walk(A(path),&nd); if (!error) { - struct inode *inode = nd.path.dentry->d_inode; - error = report_statvfs(nd.path.mnt, inode, buf); - path_put(&nd.path); + struct inode * inode = nd.dentry->d_inode; + error = report_statvfs(nd.mnt, inode, buf); + path_release(&nd); } return error; } @@ -464,9 +464,9 @@ asmlinkage int solaris_statvfs64(u32 path, u32 buf) lock_kernel(); error = user_path_walk(A(path), &nd); if (!error) { - struct inode *inode = nd.path.dentry->d_inode; - error = report_statvfs64(nd.path.mnt, inode, buf); - path_put(&nd.path); + struct inode * inode = nd.dentry->d_inode; + error = report_statvfs64(nd.mnt, inode, buf); + path_release(&nd); } unlock_kernel(); return error; diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 19d579d74d27..ebb265c07e4d 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -145,8 +145,8 @@ void mconsole_proc(struct mc_request *req) } up_write(&super->s_umount); - nd.path.dentry = super->s_root; - nd.path.mnt = NULL; + nd.dentry = super->s_root; + nd.mnt = NULL; nd.flags = O_RDONLY + 1; nd.last_type = LAST_ROOT; @@ -159,7 +159,7 @@ void mconsole_proc(struct mc_request *req) goto out_kill; } - file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY); + file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); if (IS_ERR(file)) { mconsole_reply(req, "Failed to open file", 1, 0); goto out_kill; diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 3be2305709b7..aaed1a3b92d6 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -21,8 +21,6 @@ config X86 select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES - select HAVE_KVM - config GENERIC_LOCKBREAK def_bool n @@ -121,6 +119,8 @@ config ARCH_HAS_CPU_RELAX config HAVE_SETUP_PER_CPU_AREA def_bool X86_64 +select HAVE_KVM + config ARCH_HIBERNATION_POSSIBLE def_bool y depends on !SMP || !X86_VOYAGER diff --git a/trunk/arch/x86/kernel/acpi/cstate.c b/trunk/arch/x86/kernel/acpi/cstate.c index 8ca3557a6d59..10b67170b133 100644 --- a/trunk/arch/x86/kernel/acpi/cstate.c +++ b/trunk/arch/x86/kernel/acpi/cstate.c @@ -126,8 +126,6 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d " "state\n", cx->type); } - snprintf(cx->desc, ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x", - cx->address); out: set_cpus_allowed(current, saved_mask); diff --git a/trunk/arch/x86/kernel/efi.c b/trunk/arch/x86/kernel/efi.c index 0c0eeb163d90..cbdf9bacc575 100644 --- a/trunk/arch/x86/kernel/efi.c +++ b/trunk/arch/x86/kernel/efi.c @@ -391,7 +391,7 @@ static void __init runtime_code_page_mkexec(void) if (md->type != EFI_RUNTIME_SERVICES_CODE) continue; - set_memory_x(md->virt_addr, md->num_pages); + set_memory_x(md->virt_addr, md->num_pages << EFI_PAGE_SHIFT); } } @@ -434,7 +434,7 @@ void __init efi_enter_virtual_mode(void) } if (!(md->attribute & EFI_MEMORY_WB)) - set_memory_uc(md->virt_addr, md->num_pages); + set_memory_uc(md->virt_addr, size); systab = (u64) (unsigned long) efi_phys.systab; if (md->phys_addr <= systab && systab < end) { diff --git a/trunk/arch/x86/kernel/pci-gart_64.c b/trunk/arch/x86/kernel/pci-gart_64.c index faf3229f8fb3..65f6acb025c8 100644 --- a/trunk/arch/x86/kernel/pci-gart_64.c +++ b/trunk/arch/x86/kernel/pci-gart_64.c @@ -749,15 +749,6 @@ void __init gart_iommu_init(void) */ set_memory_np((unsigned long)__va(iommu_bus_base), iommu_size >> PAGE_SHIFT); - /* - * Tricky. The GART table remaps the physical memory range, - * so the CPU wont notice potential aliases and if the memory - * is remapped to UC later on, we might surprise the PCI devices - * with a stray writeout of a cacheline. So play it sure and - * do an explicit, full-scale wbinvd() _after_ having marked all - * the pages as Not-Present: - */ - wbinvd(); /* * Try to workaround a bug (thanks to BenH) diff --git a/trunk/arch/x86/kernel/test_rodata.c b/trunk/arch/x86/kernel/test_rodata.c index c29e235792af..4c163772000e 100644 --- a/trunk/arch/x86/kernel/test_rodata.c +++ b/trunk/arch/x86/kernel/test_rodata.c @@ -10,8 +10,8 @@ * of the License. */ #include -#include #include +extern int rodata_test_data; int rodata_test(void) { diff --git a/trunk/arch/x86/kernel/traps_64.c b/trunk/arch/x86/kernel/traps_64.c index 045466681911..efc66df728b6 100644 --- a/trunk/arch/x86/kernel/traps_64.c +++ b/trunk/arch/x86/kernel/traps_64.c @@ -84,7 +84,7 @@ static inline void conditional_sti(struct pt_regs *regs) static inline void preempt_conditional_sti(struct pt_regs *regs) { - inc_preempt_count(); + preempt_disable(); if (regs->flags & X86_EFLAGS_IF) local_irq_enable(); } @@ -95,7 +95,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) local_irq_disable(); /* Make sure to not schedule here because we could be running on an exception stack. */ - dec_preempt_count(); + preempt_enable_no_resched(); } int kstack_depth_to_print = 12; diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index fdc667422df9..621afb6343dc 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -186,7 +186,7 @@ static int bad_address(void *p) } #endif -static void dump_pagetable(unsigned long address) +void dump_pagetable(unsigned long address) { #ifdef CONFIG_X86_32 __typeof__(pte_val(__pte(0))) page; diff --git a/trunk/arch/x86/mm/init_32.c b/trunk/arch/x86/mm/init_32.c index ee1091a46964..8106bba41ecb 100644 --- a/trunk/arch/x86/mm/init_32.c +++ b/trunk/arch/x86/mm/init_32.c @@ -47,7 +47,6 @@ #include #include #include -#include unsigned int __VMALLOC_RESERVE = 128 << 20; diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index a4a9cccdd4f2..b59fc238151f 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -45,7 +45,6 @@ #include #include #include -#include const struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index 4119379f80ff..bd61ed13f9cf 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -688,15 +688,6 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages, if (!pgprot_val(mask_set) && !pgprot_val(mask_clr)) return 0; - /* Ensure we are PAGE_SIZE aligned */ - if (addr & ~PAGE_MASK) { - addr &= PAGE_MASK; - /* - * People should not be passing in unaligned addresses: - */ - WARN_ON_ONCE(1); - } - cpa.vaddr = addr; cpa.numpages = numpages; cpa.mask_set = mask_set; @@ -870,12 +861,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable) return; /* - * The return value is ignored as the calls cannot fail. - * Large pages are kept enabled at boot time, and are - * split up quickly with DEBUG_PAGEALLOC. If a splitup - * fails here (due to temporary memory shortage) no damage - * is done because we just keep the largepage intact up - * to the next attempt when it will likely be split up: + * The return value is ignored - the calls cannot fail, + * large pages are disabled at boot time: */ if (enable) __set_pages_p(page, numpages); diff --git a/trunk/drivers/acpi/blacklist.c b/trunk/drivers/acpi/blacklist.c index ea92bac42c53..9ce983ed60f0 100644 --- a/trunk/drivers/acpi/blacklist.c +++ b/trunk/drivers/acpi/blacklist.c @@ -186,12 +186,6 @@ static int __init dmi_unknown_osi_linux(const struct dmi_system_id *d) acpi_dmi_osi_linux(-1, d); /* unknown */ return 0; } -static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) -{ - printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); - acpi_osi_setup("!Windows 2006"); - return 0; -} /* * Most BIOS that invoke OSI(Linux) do nothing with it. @@ -234,10 +228,10 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"), * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"), * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"), + * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"), * * _OSI(Linux) is a NOP: * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), - * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"), */ { .callback = dmi_disable_osi_linux, @@ -333,20 +327,12 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, { /* OSI(Linux) effect unknown */ .callback = dmi_unknown_osi_linux, - .ident = "Dell OptiPlex GX620", + .ident = "Dell OP GX620", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"), }, }, - { /* OSI(Linux) causes some USB initialization to not run */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell OptiPlex 755", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 755"), - }, - }, { /* OSI(Linux) effect unknown */ .callback = dmi_unknown_osi_linux, .ident = "Dell PE 1900", @@ -356,14 +342,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, { /* OSI(Linux) is a NOP */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell PE 1950", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), - }, - }, - { /* OSI(Linux) is a NOP */ .callback = dmi_disable_osi_linux, .ident = "Dell PE R200", .matches = { @@ -379,22 +357,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"), }, }, - { /* OSI(Linux) touches USB */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell PR 390", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 690"), - }, - }, - { /* OSI(Linux) unknown - ASL looks benign, but may effect dock/SMM */ - .callback = dmi_unknown_osi_linux, - .ident = "Dell PR M4300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision M4300"), - }, - }, { /* OSI(Linux) is a NOP */ .callback = dmi_disable_osi_linux, .ident = "Dell Vostro 1000", @@ -428,10 +390,10 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1536"), * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1556"), * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 1546"), - * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), * _OSI(Linux) unknown effect: * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo M1425"), * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo Si 1520"), + * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), */ { .callback = dmi_disable_osi_linux, @@ -440,14 +402,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), }, }, - { - .callback = dmi_disable_osi_vista, - .ident = "Fujitsu Siemens", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), - }, - }, /* * Disable OSI(Linux) warnings on all "Hewlett-Packard" * @@ -489,11 +443,10 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { * _OSI(Linux) helps sound * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), - * _OSI(Linux) has Linux specific hooks - * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), * _OSI(Linux) is a NOP: * DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), - * DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"), + * _OSI(Linux) effect unknown + * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), */ { .callback = dmi_enable_osi_linux, @@ -512,7 +465,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, { - .callback = dmi_enable_osi_linux, + .callback = dmi_unknown_osi_linux, .ident = "Lenovo ThinkPad X61", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), @@ -520,7 +473,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, { - .callback = dmi_disable_osi_linux, + .callback = dmi_unknown_osi_linux, .ident = "Lenovo 3000 V100", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), @@ -590,9 +543,8 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { * Disable OSI(Linux) warnings on all "Sony Corporation" * * _OSI(Linux) is a NOP: - * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NR11S_S"), - * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"), * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"), + * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"), * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-TZ21MN_N"), * _OSI(Linux) unknown effect: * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"), diff --git a/trunk/drivers/acpi/event.c b/trunk/drivers/acpi/event.c index abec1ca94cf4..5479dc0eeeec 100644 --- a/trunk/drivers/acpi/event.c +++ b/trunk/drivers/acpi/event.c @@ -110,7 +110,7 @@ static const struct file_operations acpi_system_event_ops = { #endif /* CONFIG_ACPI_PROC_EVENT */ /* ACPI notifier chain */ -static BLOCKING_NOTIFIER_HEAD(acpi_chain_head); +BLOCKING_NOTIFIER_HEAD(acpi_chain_head); int acpi_notifier_call_chain(struct acpi_device *dev, u32 type, u32 data) { diff --git a/trunk/drivers/acpi/hardware/hwsleep.c b/trunk/drivers/acpi/hardware/hwsleep.c index 4290e0193097..058d0be5cbe2 100644 --- a/trunk/drivers/acpi/hardware/hwsleep.c +++ b/trunk/drivers/acpi/hardware/hwsleep.c @@ -616,7 +616,6 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) return_ACPI_STATUS(status); } - arg.integer.value = sleep_state; status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 8edba7b678eb..15e602377655 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -325,7 +325,7 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val, } #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD -static struct acpi_table_header *acpi_find_dsdt_initrd(void) +struct acpi_table_header *acpi_find_dsdt_initrd(void) { struct file *firmware_file; mm_segment_t oldfs; @@ -419,7 +419,7 @@ acpi_os_table_override(struct acpi_table_header * existing_table, } #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD -static int __init acpi_no_initrd_override_setup(char *s) +int __init acpi_no_initrd_override_setup(char *s) { acpi_no_initrd_override = 1; return 1; @@ -1109,7 +1109,7 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) * string starting with '!' disables that string * otherwise string is added to list, augmenting built-in strings */ -int __init acpi_osi_setup(char *str) +static int __init acpi_osi_setup(char *str) { if (str == NULL || *str == '\0') { printk(KERN_INFO PREFIX "_OSI method disabled\n"); diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 980e1c33e6c5..32003fdc91e8 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -945,16 +945,11 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) * Otherwise, ignore this info and continue. */ cx.entry_method = ACPI_CSTATE_HALT; - snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT"); } else { continue; } - } else { - snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", - cx.address); } - obj = &(element->package.elements[2]); if (obj->type != ACPI_TYPE_INTEGER) continue; @@ -1425,14 +1420,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, return 0; local_irq_disable(); - - /* Do not access any ACPI IO ports in suspend path */ - if (acpi_idle_suspend) { - acpi_safe_halt(); - local_irq_enable(); - return 0; - } - if (pr->flags.bm_check) acpi_idle_update_bm_rld(pr, cx); @@ -1656,11 +1643,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) return -EINVAL; } - for (i = 0; i < CPUIDLE_STATE_MAX; i++) { - dev->states[i].name[0] = '\0'; - dev->states[i].desc[0] = '\0'; - } - for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { cx = &pr->power.states[i]; state = &dev->states[count]; @@ -1677,7 +1659,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) cpuidle_set_statedata(state, cx); snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); - strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); state->exit_latency = cx->latency; state->target_residency = cx->latency * latency_factor; state->power_usage = cx->power; diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index c02c490122dc..1cea18f62abc 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -1862,7 +1862,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, * spin_lock_irqsave(host lock) */ -unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf, +static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen) { u8 pbuf[60]; diff --git a/trunk/drivers/block/swim3.c b/trunk/drivers/block/swim3.c index 730ccea78e45..b4e462f154ea 100644 --- a/trunk/drivers/block/swim3.c +++ b/trunk/drivers/block/swim3.c @@ -251,6 +251,10 @@ static int floppy_release(struct inode *inode, struct file *filp); static int floppy_check_change(struct gendisk *disk); static int floppy_revalidate(struct gendisk *disk); +#ifndef CONFIG_PMAC_MEDIABAY +#define check_media_bay(which, what) 1 +#endif + static void swim3_select(struct floppy_state *fs, int sel) { struct swim3 __iomem *sw = fs->swim3; diff --git a/trunk/drivers/bluetooth/hci_ldisc.c b/trunk/drivers/bluetooth/hci_ldisc.c index 7e31d5f1bc8a..e68821d074b0 100644 --- a/trunk/drivers/bluetooth/hci_ldisc.c +++ b/trunk/drivers/bluetooth/hci_ldisc.c @@ -208,7 +208,6 @@ static int hci_uart_close(struct hci_dev *hdev) return 0; hci_uart_flush(hdev); - hdev->flush = NULL; return 0; } diff --git a/trunk/drivers/char/hvc_rtas.c b/trunk/drivers/char/hvc_rtas.c index 88590d040046..bb09413d5a21 100644 --- a/trunk/drivers/char/hvc_rtas.c +++ b/trunk/drivers/char/hvc_rtas.c @@ -76,7 +76,7 @@ static struct hv_ops hvc_rtas_get_put_ops = { .put_chars = hvc_rtas_write_console, }; -static int __init hvc_rtas_init(void) +static int hvc_rtas_init(void) { struct hvc_struct *hp; diff --git a/trunk/drivers/cpuidle/cpuidle.c b/trunk/drivers/cpuidle/cpuidle.c index d73663a52324..60f71e6345e3 100644 --- a/trunk/drivers/cpuidle/cpuidle.c +++ b/trunk/drivers/cpuidle/cpuidle.c @@ -219,8 +219,7 @@ static void poll_idle_init(struct cpuidle_device *dev) cpuidle_set_statedata(state, NULL); - snprintf(state->name, CPUIDLE_NAME_LEN, "C0"); - snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); + snprintf(state->name, CPUIDLE_NAME_LEN, "C0 (poll idle)"); state->exit_latency = 0; state->target_residency = 0; state->power_usage = -1; diff --git a/trunk/drivers/cpuidle/sysfs.c b/trunk/drivers/cpuidle/sysfs.c index 69102ca05685..088ea74edd34 100644 --- a/trunk/drivers/cpuidle/sysfs.c +++ b/trunk/drivers/cpuidle/sysfs.c @@ -218,23 +218,16 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ return sprintf(buf, "%u\n", state->_name);\ } -#define define_show_state_str_function(_name) \ -static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ -{ \ - if (state->_name[0] == '\0')\ - return sprintf(buf, "\n");\ - return sprintf(buf, "%s\n", state->_name);\ +static ssize_t show_state_name(struct cpuidle_state *state, char *buf) +{ + return sprintf(buf, "%s\n", state->name); } define_show_state_function(exit_latency) define_show_state_function(power_usage) define_show_state_function(usage) define_show_state_function(time) -define_show_state_str_function(name) -define_show_state_str_function(desc) - define_one_state_ro(name, show_state_name); -define_one_state_ro(desc, show_state_desc); define_one_state_ro(latency, show_state_exit_latency); define_one_state_ro(power, show_state_power_usage); define_one_state_ro(usage, show_state_usage); @@ -242,7 +235,6 @@ define_one_state_ro(time, show_state_time); static struct attribute *cpuidle_state_default_attrs[] = { &attr_name.attr, - &attr_desc.attr, &attr_latency.attr, &attr_power.attr, &attr_usage.attr, diff --git a/trunk/drivers/hid/hid-input-quirks.c b/trunk/drivers/hid/hid-input-quirks.c index dceadd0c1419..a870ba58faa3 100644 --- a/trunk/drivers/hid/hid-input-quirks.c +++ b/trunk/drivers/hid/hid-input-quirks.c @@ -352,7 +352,7 @@ int hidinput_mapping_quirks(struct hid_usage *usage, return 0; } -int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) +void hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { struct input_dev *input; @@ -362,34 +362,34 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; - return 1; + return; } if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && (usage->type == EV_REL) && (usage->code == REL_WHEEL)) { hid->delayed_value = value; - return 1; + return; } if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && (usage->hid == 0x000100b8)) { input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value); - return 1; + return; } if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { input_event(input, usage->type, usage->code, -value); - return 1; + return; } if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { input_event(input, usage->type, REL_HWHEEL, value); - return 1; + return; } if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value)) - return 1; + return; /* Handling MS keyboards special buttons */ if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS && @@ -416,9 +416,8 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT && usage->type == EV_REL && usage->code == REL_HWHEEL) { input_event(input, usage->type, REL_WHEEL, -value); - return 1; + return; } - return 0; } diff --git a/trunk/drivers/hid/hid-input.c b/trunk/drivers/hid/hid-input.c index 5a38fb27d69f..5325d98b4328 100644 --- a/trunk/drivers/hid/hid-input.c +++ b/trunk/drivers/hid/hid-input.c @@ -97,7 +97,6 @@ struct hidinput_key_translation { #define APPLE_FLAG_FKEY 0x01 static struct hidinput_key_translation apple_fn_keys[] = { - { KEY_BACKSPACE, KEY_DELETE }, { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, { KEY_F3, KEY_CYCLEWINDOWS, APPLE_FLAG_FKEY }, /* Exposé */ @@ -110,10 +109,6 @@ static struct hidinput_key_translation apple_fn_keys[] = { { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, - { KEY_UP, KEY_PAGEUP }, - { KEY_DOWN, KEY_PAGEDOWN }, - { KEY_LEFT, KEY_HOME }, - { KEY_RIGHT, KEY_END }, { } }; @@ -859,8 +854,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; /* handle input events for quirky devices */ - if (hidinput_event_quirks(hid, field, usage, value)) - return; + hidinput_event_quirks(hid, field, usage, value); if (usage->hat_min < usage->hat_max || usage->hat_dir) { int hat_dir = usage->hat_dir; diff --git a/trunk/drivers/hid/usbhid/hid-quirks.c b/trunk/drivers/hid/usbhid/hid-quirks.c index e6d05f6b1c1c..b77b61e0cd7b 100644 --- a/trunk/drivers/hid/usbhid/hid-quirks.c +++ b/trunk/drivers/hid/usbhid/hid-quirks.c @@ -66,12 +66,6 @@ #define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 #define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 #define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 -#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 -#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a -#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b -#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c -#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d -#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 @@ -199,17 +193,6 @@ #define USB_DEVICE_ID_GTCO_502 0x0502 #define USB_DEVICE_ID_GTCO_503 0x0503 #define USB_DEVICE_ID_GTCO_504 0x0504 -#define USB_DEVICE_ID_GTCO_600 0x0600 -#define USB_DEVICE_ID_GTCO_601 0x0601 -#define USB_DEVICE_ID_GTCO_602 0x0602 -#define USB_DEVICE_ID_GTCO_603 0x0603 -#define USB_DEVICE_ID_GTCO_604 0x0604 -#define USB_DEVICE_ID_GTCO_605 0x0605 -#define USB_DEVICE_ID_GTCO_606 0x0606 -#define USB_DEVICE_ID_GTCO_607 0x0607 -#define USB_DEVICE_ID_GTCO_608 0x0608 -#define USB_DEVICE_ID_GTCO_609 0x0609 -#define USB_DEVICE_ID_GTCO_609 0x0609 #define USB_DEVICE_ID_GTCO_1000 0x1000 #define USB_DEVICE_ID_GTCO_1001 0x1001 #define USB_DEVICE_ID_GTCO_1002 0x1002 @@ -217,7 +200,7 @@ #define USB_DEVICE_ID_GTCO_1004 0x1004 #define USB_DEVICE_ID_GTCO_1005 0x1005 #define USB_DEVICE_ID_GTCO_1006 0x1006 -#define USB_DEVICE_ID_GTCO_1007 0x1007 + #define USB_VENDOR_ID_HAPP 0x078b #define USB_DEVICE_ID_UGCI_DRIVING 0x0010 #define USB_DEVICE_ID_UGCI_FLYING 0x0020 @@ -385,7 +368,6 @@ #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 -#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 #define USB_VENDOR_ID_WACOM 0x056a @@ -514,16 +496,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_600, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_601, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_602, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_603, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_604, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_605, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_606, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_607, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_608, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_609, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002, HID_QUIRK_IGNORE }, @@ -531,7 +503,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, @@ -570,7 +541,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT, HID_QUIRK_IGNORE }, @@ -623,12 +593,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_HAS_FN }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, - { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_HAS_FN }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index b10ade92efed..638b727d42e0 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -3587,6 +3587,8 @@ static void cm_release_port_obj(struct kobject *obj) { struct cm_port *cm_port; + printk(KERN_ERR "free cm port\n"); + cm_port = container_of(obj, struct cm_port, port_obj); kfree(cm_port); } @@ -3599,6 +3601,8 @@ static void cm_release_dev_obj(struct kobject *obj) { struct cm_device *cm_dev; + printk(KERN_ERR "free cm dev\n"); + cm_dev = container_of(obj, struct cm_device, dev_obj); kfree(cm_dev); } @@ -3612,12 +3616,18 @@ struct class cm_class = { }; EXPORT_SYMBOL(cm_class); +static void cm_remove_fs_obj(struct kobject *obj) +{ + kobject_put(obj->parent); + kobject_put(obj); +} + static int cm_create_port_fs(struct cm_port *port) { int i, ret; ret = kobject_init_and_add(&port->port_obj, &cm_port_obj_type, - &port->cm_dev->dev_obj, + kobject_get(&port->cm_dev->dev_obj), "%d", port->port_num); if (ret) { kfree(port); @@ -3627,7 +3637,7 @@ static int cm_create_port_fs(struct cm_port *port) for (i = 0; i < CM_COUNTER_GROUPS; i++) { ret = kobject_init_and_add(&port->counter_group[i].obj, &cm_counter_obj_type, - &port->port_obj, + kobject_get(&port->port_obj), "%s", counter_group_names[i]); if (ret) goto error; @@ -3637,8 +3647,8 @@ static int cm_create_port_fs(struct cm_port *port) error: while (i--) - kobject_put(&port->counter_group[i].obj); - kobject_put(&port->port_obj); + cm_remove_fs_obj(&port->counter_group[i].obj); + cm_remove_fs_obj(&port->port_obj); return ret; } @@ -3648,9 +3658,9 @@ static void cm_remove_port_fs(struct cm_port *port) int i; for (i = 0; i < CM_COUNTER_GROUPS; i++) - kobject_put(&port->counter_group[i].obj); + cm_remove_fs_obj(&port->counter_group[i].obj); - kobject_put(&port->port_obj); + cm_remove_fs_obj(&port->port_obj); } static void cm_add_one(struct ib_device *device) @@ -3734,7 +3744,7 @@ static void cm_add_one(struct ib_device *device) ib_unregister_mad_agent(port->mad_agent); cm_remove_port_fs(port); } - kobject_put(&cm_dev->dev_obj); + cm_remove_fs_obj(&cm_dev->dev_obj); } static void cm_remove_one(struct ib_device *device) @@ -3761,7 +3771,7 @@ static void cm_remove_one(struct ib_device *device) ib_unregister_mad_agent(port->mad_agent); cm_remove_port_fs(port); } - kobject_put(&cm_dev->dev_obj); + cm_remove_fs_obj(&cm_dev->dev_obj); } static int __init ib_cm_init(void) diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index 34507daaf9b6..1eff1b2c0e08 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -1107,6 +1107,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) event.param.ud.private_data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE - offset; } else { + ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); conn_id = cma_new_conn_id(&listen_id->id, ib_event); cma_set_req_event_data(&event, &ib_event->param.req_rcvd, ib_event->private_data, offset); @@ -1129,15 +1130,6 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) ret = conn_id->id.event_handler(&conn_id->id, &event); if (!ret) { - /* - * Acquire mutex to prevent user executing rdma_destroy_id() - * while we're accessing the cm_id. - */ - mutex_lock(&lock); - if (cma_comp(conn_id, CMA_CONNECT) && - !cma_is_ud_ps(conn_id->id.ps)) - ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); - mutex_unlock(&lock); cma_enable_remove(conn_id); goto out; } diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c index 320f2b6ddee6..e9a08fa3dffe 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -1785,17 +1784,6 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) return err; } -static int is_loopback_dst(struct iw_cm_id *cm_id) -{ - struct net_device *dev; - - dev = ip_dev_find(&init_net, cm_id->remote_addr.sin_addr.s_addr); - if (!dev) - return 0; - dev_put(dev); - return 1; -} - int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) { int err = 0; @@ -1803,11 +1791,6 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) struct iwch_ep *ep; struct rtable *rt; - if (is_loopback_dst(cm_id)) { - err = -ENOSYS; - goto out; - } - ep = alloc_ep(sizeof(*ep), GFP_KERNEL); if (!ep) { printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __FUNCTION__); diff --git a/trunk/drivers/infiniband/hw/mlx4/mr.c b/trunk/drivers/infiniband/hw/mlx4/mr.c index fe2c2e94a5f8..7dc91a3e712d 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mr.c +++ b/trunk/drivers/infiniband/hw/mlx4/mr.c @@ -199,7 +199,7 @@ struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc, if (err) goto err_free; - err = mlx4_fmr_enable(to_mdev(pd->device)->dev, &fmr->mfmr); + err = mlx4_mr_enable(to_mdev(pd->device)->dev, &fmr->mfmr.mr); if (err) goto err_mr; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index 1e1e336d3ef9..6bd9f1393349 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -473,7 +473,7 @@ static void handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, if (!(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd)) return; - be16_add_cpu(&cqe->db_cnt, -dbd); + cqe->db_cnt = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd); cqe->wqe = new_wqe; cqe->syndrome = SYNDROME_WR_FLUSH_ERR; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c index 252db0822f6c..1f4d27d7c16d 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -542,7 +542,6 @@ struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) for (i = 0; i < npages; ++i) { db_tab->page[i].refcount = 0; db_tab->page[i].uvirt = 0; - sg_init_table(&db_tab->page[i].mem, 1); } return db_tab; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h index 054fab8e27a0..f9b7caa54143 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h @@ -209,6 +209,7 @@ struct ipoib_cm_tx { unsigned tx_tail; unsigned long flags; u32 mtu; + struct ib_wc ibwc[IPOIB_NUM_WC]; }; struct ipoib_cm_rx_buf { diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 08c4396cf418..9d3e778dc56d 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -780,7 +780,6 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event) if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); ipoib_ib_dev_down(dev, 0); - ipoib_ib_dev_stop(dev, 0); ipoib_pkey_dev_delay_open(dev); return; } diff --git a/trunk/drivers/macintosh/mediabay.c b/trunk/drivers/macintosh/mediabay.c index 51a112815f46..936788272a5f 100644 --- a/trunk/drivers/macintosh/mediabay.c +++ b/trunk/drivers/macintosh/mediabay.c @@ -416,6 +416,7 @@ static void poll_media_bay(struct media_bay_info* bay) } } +#ifdef CONFIG_MAC_FLOPPY int check_media_bay(struct device_node *which_bay, int what) { int i; @@ -430,6 +431,7 @@ int check_media_bay(struct device_node *which_bay, int what) return -ENODEV; } EXPORT_SYMBOL(check_media_bay); +#endif /* CONFIG_MAC_FLOPPY */ #ifdef CONFIG_BLK_DEV_IDE_PMAC int check_media_bay_by_base(unsigned long base, int what) diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 7aeceedcf7d4..a0585fb6da94 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -206,10 +206,16 @@ static void bitmap_checkfree(struct bitmap *bitmap, unsigned long page) /* copy the pathname of a file to a buffer */ char *file_path(struct file *file, char *buf, int count) { + struct dentry *d; + struct vfsmount *v; + if (!buf) return NULL; - buf = d_path(&file->f_path, buf, count); + d = file->f_path.dentry; + v = file->f_path.mnt; + + buf = d_path(d, v, buf, count); return IS_ERR(buf) ? NULL : buf; } diff --git a/trunk/drivers/md/dm-table.c b/trunk/drivers/md/dm-table.c index e75b1437b58b..f16062982383 100644 --- a/trunk/drivers/md/dm-table.c +++ b/trunk/drivers/md/dm-table.c @@ -361,7 +361,7 @@ static int lookup_device(const char *path, dev_t *dev) if ((r = path_lookup(path, LOOKUP_FOLLOW, &nd))) return r; - inode = nd.path.dentry->d_inode; + inode = nd.dentry->d_inode; if (!inode) { r = -ENOENT; goto out; @@ -375,7 +375,7 @@ static int lookup_device(const char *path, dev_t *dev) *dev = inode->i_rdev; out: - path_put(&nd.path); + path_release(&nd); return r; } diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 7da6ec244e15..5fc326d3970e 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -5197,7 +5197,8 @@ static int md_seq_show(struct seq_file *seq, void *v) chunk_kb ? "KB" : "B"); if (bitmap->file) { seq_printf(seq, ", file: "); - seq_path(seq, &bitmap->file->f_path, " \t\n"); + seq_path(seq, bitmap->file->f_path.mnt, + bitmap->file->f_path.dentry," \t\n"); } seq_printf(seq, "\n"); diff --git a/trunk/drivers/misc/thinkpad_acpi.c b/trunk/drivers/misc/thinkpad_acpi.c index e2c7edd206a6..7ba1acad5402 100644 --- a/trunk/drivers/misc/thinkpad_acpi.c +++ b/trunk/drivers/misc/thinkpad_acpi.c @@ -1689,7 +1689,7 @@ static ssize_t hotkey_wakeup_reason_show(struct device *dev, static struct device_attribute dev_attr_hotkey_wakeup_reason = __ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL); -static void hotkey_wakeup_reason_notify_change(void) +void hotkey_wakeup_reason_notify_change(void) { if (tp_features.hotkey_mask) sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, @@ -1708,7 +1708,7 @@ static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete = __ATTR(wakeup_hotunplug_complete, S_IRUGO, hotkey_wakeup_hotunplug_complete_show, NULL); -static void hotkey_wakeup_hotunplug_complete_notify_change(void) +void hotkey_wakeup_hotunplug_complete_notify_change(void) { if (tp_features.hotkey_mask) sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, diff --git a/trunk/drivers/mtd/mtdsuper.c b/trunk/drivers/mtd/mtdsuper.c index 28cc6787a800..9b430f20b640 100644 --- a/trunk/drivers/mtd/mtdsuper.c +++ b/trunk/drivers/mtd/mtdsuper.c @@ -184,26 +184,26 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags, ret = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); DEBUG(1, "MTDSB: path_lookup() returned %d, inode %p\n", - ret, nd.path.dentry ? nd.path.dentry->d_inode : NULL); + ret, nd.dentry ? nd.dentry->d_inode : NULL); if (ret) return ret; ret = -EINVAL; - if (!S_ISBLK(nd.path.dentry->d_inode->i_mode)) + if (!S_ISBLK(nd.dentry->d_inode->i_mode)) goto out; - if (nd.path.mnt->mnt_flags & MNT_NODEV) { + if (nd.mnt->mnt_flags & MNT_NODEV) { ret = -EACCES; goto out; } - if (imajor(nd.path.dentry->d_inode) != MTD_BLOCK_MAJOR) + if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) goto not_an_MTD_device; - mtdnr = iminor(nd.path.dentry->d_inode); - path_put(&nd.path); + mtdnr = iminor(nd.dentry->d_inode); + path_release(&nd); return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super, mnt); @@ -214,7 +214,7 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags, "MTD: Attempt to mount non-MTD device \"%s\"\n", dev_name); out: - path_put(&nd.path); + path_release(&nd); return ret; } diff --git a/trunk/drivers/net/8139too.c b/trunk/drivers/net/8139too.c index be6e918456d9..eef6fecfff2a 100644 --- a/trunk/drivers/net/8139too.c +++ b/trunk/drivers/net/8139too.c @@ -168,7 +168,7 @@ static int debug = -1; * Warning: 64K ring has hardware issues and may lock up. */ #if defined(CONFIG_SH_DREAMCAST) -#define RX_BUF_IDX 0 /* 8K ring */ +#define RX_BUF_IDX 1 /* 16K ring */ #else #define RX_BUF_IDX 2 /* 32K ring */ #endif diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index f337800076c0..50c2b60e1fee 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -931,14 +931,6 @@ config ENC28J60_WRITEVERIFY Enable the verify after the buffer write useful for debugging purpose. If unsure, say N. -config DM9000_DEBUGLEVEL - int "DM9000 maximum debug level" - depends on DM9000 - default 4 - help - The maximum level of debugging code compiled into the DM9000 - driver. - config SMC911X tristate "SMSC LAN911[5678] support" select CRC32 @@ -2360,16 +2352,6 @@ config GELIC_NET To compile this driver as a module, choose M here: the module will be called ps3_gelic. -config GELIC_WIRELESS - bool "PS3 Wireless support" - depends on GELIC_NET - help - This option adds the support for the wireless feature of PS3. - If you have the wireless-less model of PS3 or have no plan to - use wireless feature, disabling this option saves memory. As - the driver automatically distinguishes the models, you can - safely enable this option even if you have a wireless-less model. - config GIANFAR tristate "Gianfar Ethernet" depends on FSL_SOC diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 3b1ea321dc05..9fc7794e88ea 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -70,8 +70,7 @@ obj-$(CONFIG_BNX2X) += bnx2x.o spidernet-y += spider_net.o spider_net_ethtool.o obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o obj-$(CONFIG_GELIC_NET) += ps3_gelic.o -gelic_wireless-$(CONFIG_GELIC_WIRELESS) += ps3_gelic_wireless.o -ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y) +ps3_gelic-objs += ps3_gelic_net.o obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_SKGE) += skge.o obj-$(CONFIG_SKY2) += sky2.o diff --git a/trunk/drivers/net/cxgb3/l2t.c b/trunk/drivers/net/cxgb3/l2t.c index 865faee53e17..17ed4c3527b7 100644 --- a/trunk/drivers/net/cxgb3/l2t.c +++ b/trunk/drivers/net/cxgb3/l2t.c @@ -404,7 +404,7 @@ void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh) if (neigh->nud_state & NUD_FAILED) { arpq = e->arpq_head; e->arpq_head = e->arpq_tail = NULL; - } else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE)) + } else if (neigh_is_connected(neigh)) setup_l2e_send_pending(dev, NULL, e); } else { e->state = neigh_is_connected(neigh) ? diff --git a/trunk/drivers/net/cxgb3/sge.c b/trunk/drivers/net/cxgb3/sge.c index 979f3fc5e765..9ca8c66abd16 100644 --- a/trunk/drivers/net/cxgb3/sge.c +++ b/trunk/drivers/net/cxgb3/sge.c @@ -1059,14 +1059,6 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb, htonl(V_WR_TID(q->token))); } -static inline void t3_stop_queue(struct net_device *dev, struct sge_qset *qs, - struct sge_txq *q) -{ - netif_stop_queue(dev); - set_bit(TXQ_ETH, &qs->txq_stopped); - q->stops++; -} - /** * eth_xmit - add a packet to the Ethernet Tx queue * @skb: the packet @@ -1098,18 +1090,31 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) ndesc = calc_tx_descs(skb); if (unlikely(credits < ndesc)) { - t3_stop_queue(dev, qs, q); - dev_err(&adap->pdev->dev, - "%s: Tx ring %u full while queue awake!\n", - dev->name, q->cntxt_id & 7); + if (!netif_queue_stopped(dev)) { + netif_stop_queue(dev); + set_bit(TXQ_ETH, &qs->txq_stopped); + q->stops++; + dev_err(&adap->pdev->dev, + "%s: Tx ring %u full while queue awake!\n", + dev->name, q->cntxt_id & 7); + } spin_unlock(&q->lock); return NETDEV_TX_BUSY; } q->in_use += ndesc; - if (unlikely(credits - ndesc < q->stop_thres)) - if (USE_GTS || !should_restart_tx(q)) - t3_stop_queue(dev, qs, q); + if (unlikely(credits - ndesc < q->stop_thres)) { + q->stops++; + netif_stop_queue(dev); + set_bit(TXQ_ETH, &qs->txq_stopped); +#if !USE_GTS + if (should_restart_tx(q) && + test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) { + q->restarts++; + netif_wake_queue(dev); + } +#endif + } gen = q->gen; q->unacked += ndesc; diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index 1fe305ca2cf0..6a20a5491a96 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -1,5 +1,7 @@ /* - * Davicom DM9000 Fast Ethernet driver for Linux. + * dm9000.c: Version 1.2 03/18/2003 + * + * A Davicom DM9000 ISA NIC fast Ethernet driver for Linux. * Copyright (C) 1997 Sten Wang * * This program is free software; you can redistribute it and/or @@ -12,11 +14,44 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * (C) Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. + * (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. + * + * V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match + * 06/22/2001 Support DM9801 progrmming + * E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000 + * E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200 + * R17 = (R17 & 0xfff0) | NF + 3 + * E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200 + * R17 = (R17 & 0xfff0) | NF + * + * v1.00 modify by simon 2001.9.5 + * change for kernel 2.4.x + * + * v1.1 11/09/2001 fix force mode bug + * + * v1.2 03/18/2003 Weilun Huang : + * Fixed phy reset. + * Added tx/rx 32 bit mode. + * Cleaned up for kernel merge. + * + * 03/03/2004 Sascha Hauer + * Port to 2.6 kernel + * + * 24-Sep-2004 Ben Dooks + * Cleanup of code to remove ifdefs + * Allowed platform device data to influence access width + * Reformatting areas of code + * + * 17-Mar-2005 Sascha Hauer + * * removed 2.4 style module parameters + * * removed removed unused stat counter and fixed + * net_device_stats + * * introduced tx_timeout function + * * reworked locking * - * Additional updates, Copyright: - * Ben Dooks - * Sascha Hauer + * 01-Jul-2005 Ben Dooks + * * fixed spinlock call without pointer + * * ensure spinlock is initialised */ #include @@ -28,7 +63,6 @@ #include #include #include -#include #include #include #include @@ -46,7 +80,30 @@ #define CARDNAME "dm9000" #define PFX CARDNAME ": " -#define DRV_VERSION "1.30" + +#define DM9000_TIMER_WUT jiffies+(HZ*2) /* timer wakeup time : 2 second */ + +#define DM9000_DEBUG 0 + +#if DM9000_DEBUG > 2 +#define PRINTK3(args...) printk(CARDNAME ": " args) +#else +#define PRINTK3(args...) do { } while(0) +#endif + +#if DM9000_DEBUG > 1 +#define PRINTK2(args...) printk(CARDNAME ": " args) +#else +#define PRINTK2(args...) do { } while(0) +#endif + +#if DM9000_DEBUG > 0 +#define PRINTK1(args...) printk(CARDNAME ": " args) +#define PRINTK(args...) printk(CARDNAME ": " args) +#else +#define PRINTK1(args...) do { } while(0) +#define PRINTK(args...) printk(KERN_DEBUG args) +#endif #ifdef CONFIG_BLACKFIN #define readsb insb @@ -55,9 +112,9 @@ #define writesb outsb #define writesw outsw #define writesl outsl -#define DEFAULT_TRIGGER IRQF_TRIGGER_HIGH +#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH) #else -#define DEFAULT_TRIGGER (0) +#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQT_RISING) #endif /* @@ -67,24 +124,6 @@ static int watchdog = 5000; module_param(watchdog, int, 0400); MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds"); -/* DM9000 register address locking. - * - * The DM9000 uses an address register to control where data written - * to the data register goes. This means that the address register - * must be preserved over interrupts or similar calls. - * - * During interrupt and other critical calls, a spinlock is used to - * protect the system, but the calls themselves save the address - * in the address register in case they are interrupting another - * access to the device. - * - * For general accesses a lock is provided so that calls which are - * allowed to sleep are serialised so that the address register does - * not need to be saved. This lock also serves to serialise access - * to the EEPROM and PHY access registers which are shared between - * these two devices. - */ - /* Structure/enum declaration ------------------------------- */ typedef struct board_info { @@ -98,52 +137,33 @@ typedef struct board_info { u16 dbug_cnt; u8 io_mode; /* 0:word, 2:byte */ u8 phy_addr; - unsigned int flags; - unsigned int in_suspend :1; - - int debug_level; void (*inblk)(void __iomem *port, void *data, int length); void (*outblk)(void __iomem *port, void *data, int length); void (*dumpblk)(void __iomem *port, int length); - struct device *dev; /* parent device */ - struct resource *addr_res; /* resources found */ struct resource *data_res; struct resource *addr_req; /* resources requested */ struct resource *data_req; struct resource *irq_res; - struct mutex addr_lock; /* phy and eeprom access lock */ - + struct timer_list timer; + unsigned char srom[128]; spinlock_t lock; struct mii_if_info mii; u32 msg_enable; } board_info_t; -/* debug code */ - -#define dm9000_dbg(db, lev, msg...) do { \ - if ((lev) < CONFIG_DM9000_DEBUGLEVEL && \ - (lev) < db->debug_level) { \ - dev_dbg(db->dev, msg); \ - } \ -} while (0) - -static inline board_info_t *to_dm9000_board(struct net_device *dev) -{ - return dev->priv; -} - /* function declaration ------------------------------------- */ static int dm9000_probe(struct platform_device *); static int dm9000_open(struct net_device *); static int dm9000_start_xmit(struct sk_buff *, struct net_device *); static int dm9000_stop(struct net_device *); -static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd); + +static void dm9000_timer(unsigned long); static void dm9000_init_dm9000(struct net_device *); static irqreturn_t dm9000_interrupt(int, void *); @@ -151,19 +171,20 @@ static irqreturn_t dm9000_interrupt(int, void *); static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg); static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value); - -static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to); -static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp); +static u16 read_srom_word(board_info_t *, int); static void dm9000_rx(struct net_device *); static void dm9000_hash_table(struct net_device *); +//#define DM9000_PROGRAM_EEPROM +#ifdef DM9000_PROGRAM_EEPROM +static void program_eeprom(board_info_t * db); +#endif /* DM9000 network board routine ---------------------------- */ static void dm9000_reset(board_info_t * db) { - dev_dbg(db->dev, "resetting device\n"); - + PRINTK1("dm9000x: resetting\n"); /* RESET device */ writeb(DM9000_NCR, db->io_addr); udelay(200); @@ -279,10 +300,14 @@ static void dm9000_set_io(struct board_info *db, int byte_width) db->inblk = dm9000_inblk_8bit; break; + case 2: + db->dumpblk = dm9000_dumpblk_16bit; + db->outblk = dm9000_outblk_16bit; + db->inblk = dm9000_inblk_16bit; + break; case 3: - dev_dbg(db->dev, ": 3 byte IO, falling back to 16bit\n"); - case 2: + printk(KERN_ERR PFX ": 3 byte IO, falling back to 16bit\n"); db->dumpblk = dm9000_dumpblk_16bit; db->outblk = dm9000_outblk_16bit; db->inblk = dm9000_inblk_16bit; @@ -333,139 +358,6 @@ static void dm9000_poll_controller(struct net_device *dev) } #endif -static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd) -{ - board_info_t *dm = to_dm9000_board(dev); - - if (!netif_running(dev)) - return -EINVAL; - - return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL); -} - -/* ethtool ops */ - -static void dm9000_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - board_info_t *dm = to_dm9000_board(dev); - - strcpy(info->driver, CARDNAME); - strcpy(info->version, DRV_VERSION); - strcpy(info->bus_info, to_platform_device(dm->dev)->name); -} - -static u32 dm9000_get_msglevel(struct net_device *dev) -{ - board_info_t *dm = to_dm9000_board(dev); - - return dm->msg_enable; -} - -static void dm9000_set_msglevel(struct net_device *dev, u32 value) -{ - board_info_t *dm = to_dm9000_board(dev); - - dm->msg_enable = value; -} - -static int dm9000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - board_info_t *dm = to_dm9000_board(dev); - - mii_ethtool_gset(&dm->mii, cmd); - return 0; -} - -static int dm9000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - board_info_t *dm = to_dm9000_board(dev); - - return mii_ethtool_sset(&dm->mii, cmd); -} - -static int dm9000_nway_reset(struct net_device *dev) -{ - board_info_t *dm = to_dm9000_board(dev); - return mii_nway_restart(&dm->mii); -} - -static u32 dm9000_get_link(struct net_device *dev) -{ - board_info_t *dm = to_dm9000_board(dev); - return mii_link_ok(&dm->mii); -} - -#define DM_EEPROM_MAGIC (0x444D394B) - -static int dm9000_get_eeprom_len(struct net_device *dev) -{ - return 128; -} - -static int dm9000_get_eeprom(struct net_device *dev, - struct ethtool_eeprom *ee, u8 *data) -{ - board_info_t *dm = to_dm9000_board(dev); - int offset = ee->offset; - int len = ee->len; - int i; - - /* EEPROM access is aligned to two bytes */ - - if ((len & 1) != 0 || (offset & 1) != 0) - return -EINVAL; - - if (dm->flags & DM9000_PLATF_NO_EEPROM) - return -ENOENT; - - ee->magic = DM_EEPROM_MAGIC; - - for (i = 0; i < len; i += 2) - dm9000_read_eeprom(dm, (offset + i) / 2, data + i); - - return 0; -} - -static int dm9000_set_eeprom(struct net_device *dev, - struct ethtool_eeprom *ee, u8 *data) -{ - board_info_t *dm = to_dm9000_board(dev); - int offset = ee->offset; - int len = ee->len; - int i; - - /* EEPROM access is aligned to two bytes */ - - if ((len & 1) != 0 || (offset & 1) != 0) - return -EINVAL; - - if (dm->flags & DM9000_PLATF_NO_EEPROM) - return -ENOENT; - - if (ee->magic != DM_EEPROM_MAGIC) - return -EINVAL; - - for (i = 0; i < len; i += 2) - dm9000_write_eeprom(dm, (offset + i) / 2, data + i); - - return 0; -} - -static const struct ethtool_ops dm9000_ethtool_ops = { - .get_drvinfo = dm9000_get_drvinfo, - .get_settings = dm9000_get_settings, - .set_settings = dm9000_set_settings, - .get_msglevel = dm9000_get_msglevel, - .set_msglevel = dm9000_set_msglevel, - .nway_reset = dm9000_nway_reset, - .get_link = dm9000_get_link, - .get_eeprom_len = dm9000_get_eeprom_len, - .get_eeprom = dm9000_get_eeprom, - .set_eeprom = dm9000_set_eeprom, -}; - - /* dm9000_release_board * * release a board, and any mapped resources @@ -509,7 +401,6 @@ dm9000_probe(struct platform_device *pdev) struct dm9000_plat_data *pdata = pdev->dev.platform_data; struct board_info *db; /* Point a board information structure */ struct net_device *ndev; - const unsigned char *mac_src; unsigned long base; int ret = 0; int iosize; @@ -519,22 +410,19 @@ dm9000_probe(struct platform_device *pdev) /* Init network device */ ndev = alloc_etherdev(sizeof (struct board_info)); if (!ndev) { - dev_err(&pdev->dev, "could not allocate device.\n"); + printk("%s: could not allocate device.\n", CARDNAME); return -ENOMEM; } SET_NETDEV_DEV(ndev, &pdev->dev); - dev_dbg(&pdev->dev, "dm9000_probe()"); + PRINTK2("dm9000_probe()"); /* setup board info structure */ db = (struct board_info *) ndev->priv; memset(db, 0, sizeof (*db)); - db->dev = &pdev->dev; - spin_lock_init(&db->lock); - mutex_init(&db->addr_lock); if (pdev->num_resources < 2) { ret = -ENODEV; @@ -562,7 +450,7 @@ dm9000_probe(struct platform_device *pdev) if (db->addr_res == NULL || db->data_res == NULL || db->irq_res == NULL) { - dev_err(db->dev, "insufficient resources\n"); + printk(KERN_ERR PFX "insufficient resources\n"); ret = -ENOENT; goto out; } @@ -572,7 +460,7 @@ dm9000_probe(struct platform_device *pdev) pdev->name); if (db->addr_req == NULL) { - dev_err(db->dev, "cannot claim address reg area\n"); + printk(KERN_ERR PFX "cannot claim address reg area\n"); ret = -EIO; goto out; } @@ -580,7 +468,7 @@ dm9000_probe(struct platform_device *pdev) db->io_addr = ioremap(db->addr_res->start, i); if (db->io_addr == NULL) { - dev_err(db->dev, "failed to ioremap address reg\n"); + printk(KERN_ERR "failed to ioremap address reg\n"); ret = -EINVAL; goto out; } @@ -590,7 +478,7 @@ dm9000_probe(struct platform_device *pdev) pdev->name); if (db->data_req == NULL) { - dev_err(db->dev, "cannot claim data reg area\n"); + printk(KERN_ERR PFX "cannot claim data reg area\n"); ret = -EIO; goto out; } @@ -598,7 +486,7 @@ dm9000_probe(struct platform_device *pdev) db->io_data = ioremap(db->data_res->start, iosize); if (db->io_data == NULL) { - dev_err(db->dev,"failed to ioremap data reg\n"); + printk(KERN_ERR "failed to ioremap data reg\n"); ret = -EINVAL; goto out; } @@ -637,14 +525,12 @@ dm9000_probe(struct platform_device *pdev) if (pdata->dumpblk != NULL) db->dumpblk = pdata->dumpblk; - - db->flags = pdata->flags; } dm9000_reset(db); /* try two times, DM9000 sometimes gets the first read wrong */ - for (i = 0; i < 8; i++) { + for (i = 0; i < 2; i++) { id_val = ior(db, DM9000_VIDL); id_val |= (u32)ior(db, DM9000_VIDH) << 8; id_val |= (u32)ior(db, DM9000_PIDL) << 16; @@ -652,11 +538,11 @@ dm9000_probe(struct platform_device *pdev) if (id_val == DM9000_ID) break; - dev_err(db->dev, "read wrong id 0x%08x\n", id_val); + printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val); } if (id_val != DM9000_ID) { - dev_err(db->dev, "wrong id: 0x%08x\n", id_val); + printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val); ret = -ENODEV; goto out; } @@ -672,13 +558,13 @@ dm9000_probe(struct platform_device *pdev) ndev->watchdog_timeo = msecs_to_jiffies(watchdog); ndev->stop = &dm9000_stop; ndev->set_multicast_list = &dm9000_hash_table; - ndev->ethtool_ops = &dm9000_ethtool_ops; - ndev->do_ioctl = &dm9000_ioctl; - #ifdef CONFIG_NET_POLL_CONTROLLER ndev->poll_controller = &dm9000_poll_controller; #endif +#ifdef DM9000_PROGRAM_EEPROM + program_eeprom(db); +#endif db->msg_enable = NETIF_MSG_LINK; db->mii.phy_id_mask = 0x1f; db->mii.reg_num_mask = 0x1f; @@ -688,37 +574,38 @@ dm9000_probe(struct platform_device *pdev) db->mii.mdio_read = dm9000_phy_read; db->mii.mdio_write = dm9000_phy_write; - mac_src = "eeprom"; + /* Read SROM content */ + for (i = 0; i < 64; i++) + ((u16 *) db->srom)[i] = read_srom_word(db, i); - /* try reading the node address from the attached EEPROM */ - for (i = 0; i < 6; i += 2) - dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i); + /* Set Node Address */ + for (i = 0; i < 6; i++) + ndev->dev_addr[i] = db->srom[i]; if (!is_valid_ether_addr(ndev->dev_addr)) { /* try reading from mac */ - - mac_src = "chip"; + for (i = 0; i < 6; i++) ndev->dev_addr[i] = ior(db, i+DM9000_PAR); } if (!is_valid_ether_addr(ndev->dev_addr)) - dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please " - "set using ifconfig\n", ndev->name); + printk("%s: Invalid ethernet MAC address. Please " + "set using ifconfig\n", ndev->name); platform_set_drvdata(pdev, ndev); ret = register_netdev(ndev); if (ret == 0) { DECLARE_MAC_BUF(mac); - printk("%s: dm9000 at %p,%p IRQ %d MAC: %s (%s)\n", + printk("%s: dm9000 at %p,%p IRQ %d MAC: %s\n", ndev->name, db->io_addr, db->io_data, ndev->irq, - print_mac(mac, ndev->dev_addr), mac_src); + print_mac(mac, ndev->dev_addr)); } return 0; out: - dev_err(db->dev, "not found (%d).\n", ret); + printk("%s: not found (%d).\n", CARDNAME, ret); dm9000_release_board(pdev, db); free_netdev(ndev); @@ -734,22 +621,10 @@ static int dm9000_open(struct net_device *dev) { board_info_t *db = (board_info_t *) dev->priv; - unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK; - if (netif_msg_ifup(db)) - dev_dbg(db->dev, "enabling %s\n", dev->name); + PRINTK2("entering dm9000_open\n"); - /* If there is no IRQ type specified, default to something that - * may work, and tell the user that this is a problem */ - - if (irqflags == IRQF_TRIGGER_NONE) { - dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n"); - irqflags = DEFAULT_TRIGGER; - } - - irqflags |= IRQF_SHARED; - - if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev)) + if (request_irq(dev->irq, &dm9000_interrupt, DM9000_IRQ_FLAGS, dev->name, dev)) return -EAGAIN; /* Initialize DM9000 board */ @@ -759,6 +634,13 @@ dm9000_open(struct net_device *dev) /* Init driver variable */ db->dbug_cnt = 0; + /* set and active a timer process */ + init_timer(&db->timer); + db->timer.expires = DM9000_TIMER_WUT; + db->timer.data = (unsigned long) dev; + db->timer.function = &dm9000_timer; + add_timer(&db->timer); + mii_check_media(&db->mii, netif_msg_link(db), 1); netif_start_queue(dev); @@ -773,7 +655,7 @@ dm9000_init_dm9000(struct net_device *dev) { board_info_t *db = (board_info_t *) dev->priv; - dm9000_dbg(db, 1, "entering %s\n", __func__); + PRINTK1("entering %s\n",__FUNCTION__); /* I/O mode */ db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */ @@ -783,9 +665,6 @@ dm9000_init_dm9000(struct net_device *dev) iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ iow(db, DM9000_GPR, 0); /* Enable PHY */ - if (db->flags & DM9000_PLATF_EXT_PHY) - iow(db, DM9000_NCR, NCR_EXT_PHY); - /* Program operating register */ iow(db, DM9000_TCR, 0); /* TX Polling clear */ iow(db, DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */ @@ -819,7 +698,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; board_info_t *db = (board_info_t *) dev->priv; - dm9000_dbg(db, 3, "%s:\n", __func__); + PRINTK3("dm9000_start_xmit\n"); if (db->tx_pkt_cnt > 1) return 1; @@ -836,8 +715,8 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) /* TX control: First packet immediately send, second packet queue */ if (db->tx_pkt_cnt == 1) { /* Set TX length to DM9000 */ - iow(db, DM9000_TXPLL, skb->len); - iow(db, DM9000_TXPLH, skb->len >> 8); + iow(db, DM9000_TXPLL, skb->len & 0xff); + iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff); /* Issue TX polling command */ iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ @@ -878,8 +757,10 @@ dm9000_stop(struct net_device *ndev) { board_info_t *db = (board_info_t *) ndev->priv; - if (netif_msg_ifdown(db)) - dev_dbg(db->dev, "shutting down %s\n", ndev->name); + PRINTK1("entering %s\n",__FUNCTION__); + + /* deleted timer */ + del_timer(&db->timer); netif_stop_queue(ndev); netif_carrier_off(ndev); @@ -907,13 +788,10 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db) db->tx_pkt_cnt--; dev->stats.tx_packets++; - if (netif_msg_tx_done(db)) - dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status); - /* Queue packet check & send */ if (db->tx_pkt_cnt > 0) { - iow(db, DM9000_TXPLL, db->queue_pkt_len); - iow(db, DM9000_TXPLH, db->queue_pkt_len >> 8); + iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff); + iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff); iow(db, DM9000_TCR, TCR_TXREQ); dev->trans_start = jiffies; } @@ -925,14 +803,19 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; - board_info_t *db = (board_info_t *) dev->priv; + board_info_t *db; int int_status; u8 reg_save; - dm9000_dbg(db, 3, "entering %s\n", __func__); + PRINTK3("entering %s\n",__FUNCTION__); - /* A real interrupt coming */ + if (!dev) { + PRINTK1("dm9000_interrupt() without DEVICE arg\n"); + return IRQ_HANDLED; + } + /* A real interrupt coming */ + db = (board_info_t *) dev->priv; spin_lock(&db->lock); /* Save previous register address */ @@ -945,9 +828,6 @@ dm9000_interrupt(int irq, void *dev_id) int_status = ior(db, DM9000_ISR); /* Got ISR */ iow(db, DM9000_ISR, int_status); /* Clear ISR status */ - if (netif_msg_intr(db)) - dev_dbg(db->dev, "interrupt status %02x\n", int_status); - /* Received the coming packet */ if (int_status & ISR_PRS) dm9000_rx(dev); @@ -967,9 +847,27 @@ dm9000_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +/* + * A periodic timer routine + * Dynamic media sense, allocated Rx buffer... + */ +static void +dm9000_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *) data; + board_info_t *db = (board_info_t *) dev->priv; + + PRINTK3("dm9000_timer()\n"); + + mii_check_media(&db->mii, netif_msg_link(db), 0); + + /* Set timer again */ + db->timer.expires = DM9000_TIMER_WUT; + add_timer(&db->timer); +} + struct dm9000_rxhdr { - u8 RxPktReady; - u8 RxStatus; + u16 RxStatus; u16 RxLen; } __attribute__((__packed__)); @@ -995,7 +893,7 @@ dm9000_rx(struct net_device *dev) /* Status check: this byte must be 0 or 1 */ if (rxbyte > DM9000_PKT_RDY) { - dev_warn(db->dev, "status check fail: %d\n", rxbyte); + printk("status check failed: %d\n", rxbyte); iow(db, DM9000_RCR, 0x00); /* Stop Device */ iow(db, DM9000_ISR, IMR_PAR); /* Stop INT request */ return; @@ -1010,38 +908,30 @@ dm9000_rx(struct net_device *dev) (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr)); - RxLen = le16_to_cpu(rxhdr.RxLen); - - if (netif_msg_rx_status(db)) - dev_dbg(db->dev, "RX: status %02x, length %04x\n", - rxhdr.RxStatus, RxLen); + RxLen = rxhdr.RxLen; /* Packet Status check */ if (RxLen < 0x40) { GoodPacket = false; - if (netif_msg_rx_err(db)) - dev_dbg(db->dev, "RX: Bad Packet (runt)\n"); + PRINTK1("Bad Packet received (runt)\n"); } if (RxLen > DM9000_PKT_MAX) { - dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen); + PRINTK1("RST: RX Len:%x\n", RxLen); } - if (rxhdr.RxStatus & 0xbf) { + if (rxhdr.RxStatus & 0xbf00) { GoodPacket = false; - if (rxhdr.RxStatus & 0x01) { - if (netif_msg_rx_err(db)) - dev_dbg(db->dev, "fifo error\n"); + if (rxhdr.RxStatus & 0x100) { + PRINTK1("fifo error\n"); dev->stats.rx_fifo_errors++; } - if (rxhdr.RxStatus & 0x02) { - if (netif_msg_rx_err(db)) - dev_dbg(db->dev, "crc error\n"); + if (rxhdr.RxStatus & 0x200) { + PRINTK1("crc error\n"); dev->stats.rx_crc_errors++; } - if (rxhdr.RxStatus & 0x80) { - if (netif_msg_rx_err(db)) - dev_dbg(db->dev, "length error\n"); + if (rxhdr.RxStatus & 0x8000) { + PRINTK1("length error\n"); dev->stats.rx_length_errors++; } } @@ -1070,119 +960,72 @@ dm9000_rx(struct net_device *dev) } while (rxbyte == DM9000_PKT_RDY); } -static unsigned int -dm9000_read_locked(board_info_t *db, int reg) -{ - unsigned long flags; - unsigned int ret; - - spin_lock_irqsave(&db->lock, flags); - ret = ior(db, reg); - spin_unlock_irqrestore(&db->lock, flags); - - return ret; -} - -static int dm9000_wait_eeprom(board_info_t *db) -{ - unsigned int status; - int timeout = 8; /* wait max 8msec */ - - /* The DM9000 data sheets say we should be able to - * poll the ERRE bit in EPCR to wait for the EEPROM - * operation. From testing several chips, this bit - * does not seem to work. - * - * We attempt to use the bit, but fall back to the - * timeout (which is why we do not return an error - * on expiry) to say that the EEPROM operation has - * completed. - */ - - while (1) { - status = dm9000_read_locked(db, DM9000_EPCR); - - if ((status & EPCR_ERRE) == 0) - break; - - if (timeout-- < 0) { - dev_dbg(db->dev, "timeout waiting EEPROM\n"); - break; - } - } - - return 0; -} - /* - * Read a word data from EEPROM + * Read a word data from SROM */ -static void -dm9000_read_eeprom(board_info_t *db, int offset, u8 *to) +static u16 +read_srom_word(board_info_t * db, int offset) { - unsigned long flags; - - if (db->flags & DM9000_PLATF_NO_EEPROM) { - to[0] = 0xff; - to[1] = 0xff; - return; - } - - mutex_lock(&db->addr_lock); - - spin_lock_irqsave(&db->lock, flags); - iow(db, DM9000_EPAR, offset); iow(db, DM9000_EPCR, EPCR_ERPRR); - - spin_unlock_irqrestore(&db->lock, flags); - - dm9000_wait_eeprom(db); - - /* delay for at-least 150uS */ - msleep(1); - - spin_lock_irqsave(&db->lock, flags); - + mdelay(8); /* according to the datasheet 200us should be enough, + but it doesn't work */ iow(db, DM9000_EPCR, 0x0); - - to[0] = ior(db, DM9000_EPDRL); - to[1] = ior(db, DM9000_EPDRH); - - spin_unlock_irqrestore(&db->lock, flags); - - mutex_unlock(&db->addr_lock); + return (ior(db, DM9000_EPDRL) + (ior(db, DM9000_EPDRH) << 8)); } +#ifdef DM9000_PROGRAM_EEPROM /* * Write a word data to SROM */ static void -dm9000_write_eeprom(board_info_t *db, int offset, u8 *data) +write_srom_word(board_info_t * db, int offset, u16 val) { - unsigned long flags; + iow(db, DM9000_EPAR, offset); + iow(db, DM9000_EPDRH, ((val >> 8) & 0xff)); + iow(db, DM9000_EPDRL, (val & 0xff)); + iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); + mdelay(8); /* same shit */ + iow(db, DM9000_EPCR, 0); +} - if (db->flags & DM9000_PLATF_NO_EEPROM) - return; +/* + * Only for development: + * Here we write static data to the eeprom in case + * we don't have valid content on a new board + */ +static void +program_eeprom(board_info_t * db) +{ + u16 eeprom[] = { 0x0c00, 0x007f, 0x1300, /* MAC Address */ + 0x0000, /* Autoload: accept nothing */ + 0x0a46, 0x9000, /* Vendor / Product ID */ + 0x0000, /* pin control */ + 0x0000, + }; /* Wake-up mode control */ + int i; + for (i = 0; i < 8; i++) + write_srom_word(db, i, eeprom[i]); +} +#endif - mutex_lock(&db->addr_lock); - spin_lock_irqsave(&db->lock, flags); - iow(db, DM9000_EPAR, offset); - iow(db, DM9000_EPDRH, data[1]); - iow(db, DM9000_EPDRL, data[0]); - iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW); - spin_unlock_irqrestore(&db->lock, flags); +/* + * Calculate the CRC valude of the Rx packet + * flag = 1 : return the reverse CRC (for the received packet CRC) + * 0 : return the normal CRC (for Hash Table index) + */ - dm9000_wait_eeprom(db); +static unsigned long +cal_CRC(unsigned char *Data, unsigned int Len, u8 flag) +{ - mdelay(1); /* wait at least 150uS to clear */ + u32 crc = ether_crc_le(Len, Data); - spin_lock_irqsave(&db->lock, flags); - iow(db, DM9000_EPCR, 0); - spin_unlock_irqrestore(&db->lock, flags); + if (flag) + return ~crc; - mutex_unlock(&db->addr_lock); + return crc; } /* @@ -1194,16 +1037,15 @@ dm9000_hash_table(struct net_device *dev) board_info_t *db = (board_info_t *) dev->priv; struct dev_mc_list *mcptr = dev->mc_list; int mc_cnt = dev->mc_count; - int i, oft; u32 hash_val; - u16 hash_table[4]; + u16 i, oft, hash_table[4]; unsigned long flags; - dm9000_dbg(db, 1, "entering %s\n", __func__); + PRINTK2("dm9000_hash_table()\n"); - spin_lock_irqsave(&db->lock, flags); + spin_lock_irqsave(&db->lock,flags); - for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) + for (i = 0, oft = 0x10; i < 6; i++, oft++) iow(db, oft, dev->dev_addr[i]); /* Clear Hash Table */ @@ -1215,32 +1057,20 @@ dm9000_hash_table(struct net_device *dev) /* the multicast address in Hash Table : 64 bits */ for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { - hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f; + hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f; hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16); } /* Write the hash table to MAC MD table */ - for (i = 0, oft = DM9000_MAR; i < 4; i++) { - iow(db, oft++, hash_table[i]); - iow(db, oft++, hash_table[i] >> 8); + for (i = 0, oft = 0x16; i < 4; i++) { + iow(db, oft++, hash_table[i] & 0xff); + iow(db, oft++, (hash_table[i] >> 8) & 0xff); } - spin_unlock_irqrestore(&db->lock, flags); + spin_unlock_irqrestore(&db->lock,flags); } -/* - * Sleep, either by using msleep() or if we are suspending, then - * use mdelay() to sleep. - */ -static void dm9000_msleep(board_info_t *db, unsigned int ms) -{ - if (db->in_suspend) - mdelay(ms); - else - msleep(ms); -} - /* * Read a word from phyxcer */ @@ -1252,8 +1082,6 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) unsigned int reg_save; int ret; - mutex_lock(&db->addr_lock); - spin_lock_irqsave(&db->lock,flags); /* Save previous register address */ @@ -1263,15 +1091,7 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) iow(db, DM9000_EPAR, DM9000_PHY | reg); iow(db, DM9000_EPCR, 0xc); /* Issue phyxcer read command */ - - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock,flags); - - dm9000_msleep(db, 1); /* Wait read complete */ - - spin_lock_irqsave(&db->lock,flags); - reg_save = readb(db->io_addr); - + udelay(100); /* Wait read complete */ iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ /* The read data keeps on REG_0D & REG_0E */ @@ -1279,9 +1099,9 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) /* restore the previous address */ writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock,flags); - mutex_unlock(&db->addr_lock); return ret; } @@ -1295,8 +1115,6 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) unsigned long flags; unsigned long reg_save; - mutex_lock(&db->addr_lock); - spin_lock_irqsave(&db->lock,flags); /* Save previous register address */ @@ -1306,38 +1124,25 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) iow(db, DM9000_EPAR, DM9000_PHY | reg); /* Fill the written data into REG_0D & REG_0E */ - iow(db, DM9000_EPDRL, value); - iow(db, DM9000_EPDRH, value >> 8); + iow(db, DM9000_EPDRL, (value & 0xff)); + iow(db, DM9000_EPDRH, ((value >> 8) & 0xff)); iow(db, DM9000_EPCR, 0xa); /* Issue phyxcer write command */ - - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - - dm9000_msleep(db, 1); /* Wait write complete */ - - spin_lock_irqsave(&db->lock,flags); - reg_save = readb(db->io_addr); - + udelay(500); /* Wait write complete */ iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ /* restore the previous address */ writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - mutex_unlock(&db->addr_lock); + spin_unlock_irqrestore(&db->lock,flags); } static int dm9000_drv_suspend(struct platform_device *dev, pm_message_t state) { struct net_device *ndev = platform_get_drvdata(dev); - board_info_t *db; if (ndev) { - db = (board_info_t *) ndev->priv; - db->in_suspend = 1; - if (netif_running(ndev)) { netif_device_detach(ndev); dm9000_shutdown(ndev); @@ -1360,8 +1165,6 @@ dm9000_drv_resume(struct platform_device *dev) netif_device_attach(ndev); } - - db->in_suspend = 0; } return 0; } @@ -1377,7 +1180,8 @@ dm9000_drv_remove(struct platform_device *pdev) dm9000_release_board(pdev, (board_info_t *) ndev->priv); free_netdev(ndev); /* free device structure */ - dev_dbg(&pdev->dev, "released and freed device\n"); + PRINTK1("clean_module() exit\n"); + return 0; } @@ -1395,7 +1199,7 @@ static struct platform_driver dm9000_driver = { static int __init dm9000_init(void) { - printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION); + printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME); return platform_driver_register(&dm9000_driver); /* search board and register */ } diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index d4ee8ec34b56..7c5b05a82f0e 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -926,6 +926,8 @@ e1000_probe(struct pci_dev *pdev, { struct net_device *netdev; struct e1000_adapter *adapter; + unsigned long mmio_start, mmio_len; + unsigned long flash_start, flash_len; static int cards_found = 0; static int global_quad_port_a = 0; /* global ksp3 port a indication */ @@ -968,9 +970,11 @@ e1000_probe(struct pci_dev *pdev, adapter->hw.back = adapter; adapter->msg_enable = (1 << debug) - 1; + mmio_start = pci_resource_start(pdev, BAR_0); + mmio_len = pci_resource_len(pdev, BAR_0); + err = -EIO; - adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0), - pci_resource_len(pdev, BAR_0)); + adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); if (!adapter->hw.hw_addr) goto err_ioremap; @@ -1005,6 +1009,10 @@ e1000_probe(struct pci_dev *pdev, #endif strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); + netdev->mem_start = mmio_start; + netdev->mem_end = mmio_start + mmio_len; + netdev->base_addr = adapter->hw.io_base; + adapter->bd_number = cards_found; /* setup the private structure */ @@ -1017,9 +1025,9 @@ e1000_probe(struct pci_dev *pdev, * because it depends on mac_type */ if ((adapter->hw.mac_type == e1000_ich8lan) && (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { - adapter->hw.flash_address = - ioremap(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1)); + flash_start = pci_resource_start(pdev, 1); + flash_len = pci_resource_len(pdev, 1); + adapter->hw.flash_address = ioremap(flash_start, flash_len); if (!adapter->hw.flash_address) goto err_flashmap; } diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 801b4d9cd972..d4843d014bc9 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -166,24 +166,21 @@ * Hardware access: */ -#define DEV_NEED_TIMERIRQ 0x00001 /* set the timer irq flag in the irq mask */ -#define DEV_NEED_LINKTIMER 0x00002 /* poll link settings. Relies on the timer irq */ -#define DEV_HAS_LARGEDESC 0x00004 /* device supports jumbo frames and needs packet format 2 */ -#define DEV_HAS_HIGH_DMA 0x00008 /* device supports 64bit dma */ -#define DEV_HAS_CHECKSUM 0x00010 /* device supports tx and rx checksum offloads */ -#define DEV_HAS_VLAN 0x00020 /* device supports vlan tagging and striping */ -#define DEV_HAS_MSI 0x00040 /* device supports MSI */ -#define DEV_HAS_MSI_X 0x00080 /* device supports MSI-X */ -#define DEV_HAS_POWER_CNTRL 0x00100 /* device supports power savings */ -#define DEV_HAS_STATISTICS_V1 0x00200 /* device supports hw statistics version 1 */ -#define DEV_HAS_STATISTICS_V2 0x00400 /* device supports hw statistics version 2 */ -#define DEV_HAS_TEST_EXTENDED 0x00800 /* device supports extended diagnostic test */ -#define DEV_HAS_MGMT_UNIT 0x01000 /* device supports management unit */ -#define DEV_HAS_CORRECT_MACADDR 0x02000 /* device supports correct mac address order */ -#define DEV_HAS_COLLISION_FIX 0x04000 /* device supports tx collision fix */ -#define DEV_HAS_PAUSEFRAME_TX_V1 0x08000 /* device supports tx pause frames version 1 */ -#define DEV_HAS_PAUSEFRAME_TX_V2 0x10000 /* device supports tx pause frames version 2 */ -#define DEV_HAS_PAUSEFRAME_TX_V3 0x20000 /* device supports tx pause frames version 3 */ +#define DEV_NEED_TIMERIRQ 0x0001 /* set the timer irq flag in the irq mask */ +#define DEV_NEED_LINKTIMER 0x0002 /* poll link settings. Relies on the timer irq */ +#define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */ +#define DEV_HAS_HIGH_DMA 0x0008 /* device supports 64bit dma */ +#define DEV_HAS_CHECKSUM 0x0010 /* device supports tx and rx checksum offloads */ +#define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */ +#define DEV_HAS_MSI 0x0040 /* device supports MSI */ +#define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ +#define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ +#define DEV_HAS_PAUSEFRAME_TX 0x0200 /* device supports tx pause frames */ +#define DEV_HAS_STATISTICS_V1 0x0400 /* device supports hw statistics version 1 */ +#define DEV_HAS_STATISTICS_V2 0x0800 /* device supports hw statistics version 2 */ +#define DEV_HAS_TEST_EXTENDED 0x1000 /* device supports extended diagnostic test */ +#define DEV_HAS_MGMT_UNIT 0x2000 /* device supports management unit */ +#define DEV_HAS_CORRECT_MACADDR 0x4000 /* device supports correct mac address order */ enum { NvRegIrqStatus = 0x000, @@ -269,12 +266,9 @@ enum { #define NVREG_RNDSEED_FORCE3 0x7400 NvRegTxDeferral = 0xA0, -#define NVREG_TX_DEFERRAL_DEFAULT 0x15050f -#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f -#define NVREG_TX_DEFERRAL_RGMII_1000 0x14050f -#define NVREG_TX_DEFERRAL_RGMII_STRETCH_10 0x16190f -#define NVREG_TX_DEFERRAL_RGMII_STRETCH_100 0x16300f -#define NVREG_TX_DEFERRAL_MII_STRETCH 0x152000 +#define NVREG_TX_DEFERRAL_DEFAULT 0x15050f +#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f +#define NVREG_TX_DEFERRAL_RGMII_1000 0x14050f NvRegRxDeferral = 0xA4, #define NVREG_RX_DEFERRAL_DEFAULT 0x16 NvRegMacAddrA = 0xA8, @@ -324,10 +318,8 @@ enum { NvRegTxRingPhysAddrHigh = 0x148, NvRegRxRingPhysAddrHigh = 0x14C, NvRegTxPauseFrame = 0x170, -#define NVREG_TX_PAUSEFRAME_DISABLE 0x0fff0080 -#define NVREG_TX_PAUSEFRAME_ENABLE_V1 0x01800010 -#define NVREG_TX_PAUSEFRAME_ENABLE_V2 0x056003f0 -#define NVREG_TX_PAUSEFRAME_ENABLE_V3 0x09f00880 +#define NVREG_TX_PAUSEFRAME_DISABLE 0x01ff0080 +#define NVREG_TX_PAUSEFRAME_ENABLE 0x01800010 NvRegMIIStatus = 0x180, #define NVREG_MIISTAT_ERROR 0x0001 #define NVREG_MIISTAT_LINKCHANGE 0x0008 @@ -2759,12 +2751,7 @@ static void nv_update_pause(struct net_device *dev, u32 pause_flags) if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) { u32 regmisc = readl(base + NvRegMisc1) & ~NVREG_MISC1_PAUSE_TX; if (pause_flags & NV_PAUSEFRAME_TX_ENABLE) { - u32 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V1; - if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) - pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V2; - if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3) - pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V3; - writel(pause_enable, base + NvRegTxPauseFrame); + writel(NVREG_TX_PAUSEFRAME_ENABLE, base + NvRegTxPauseFrame); writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1); np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE; } else { @@ -2798,7 +2785,6 @@ static int nv_update_linkspeed(struct net_device *dev) int retval = 0; u32 control_1000, status_1000, phyreg, pause_flags, txreg; u32 txrxFlags = 0; - u32 phy_exp; /* BMSR_LSTATUS is latched, read it twice: * we want the current value. @@ -2926,25 +2912,13 @@ static int nv_update_linkspeed(struct net_device *dev) phyreg |= PHY_1000; writel(phyreg, base + NvRegPhyInterface); - phy_exp = mii_rw(dev, np->phyaddr, MII_EXPANSION, MII_READ) & EXPANSION_NWAY; /* autoneg capable */ if (phyreg & PHY_RGMII) { - if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_1000) { + if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_1000) txreg = NVREG_TX_DEFERRAL_RGMII_1000; - } else { - if (!phy_exp && !np->duplex && (np->driver_data & DEV_HAS_COLLISION_FIX)) { - if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_10) - txreg = NVREG_TX_DEFERRAL_RGMII_STRETCH_10; - else - txreg = NVREG_TX_DEFERRAL_RGMII_STRETCH_100; - } else { - txreg = NVREG_TX_DEFERRAL_RGMII_10_100; - } - } - } else { - if (!phy_exp && !np->duplex && (np->driver_data & DEV_HAS_COLLISION_FIX)) - txreg = NVREG_TX_DEFERRAL_MII_STRETCH; else - txreg = NVREG_TX_DEFERRAL_DEFAULT; + txreg = NVREG_TX_DEFERRAL_RGMII_10_100; + } else { + txreg = NVREG_TX_DEFERRAL_DEFAULT; } writel(txreg, base + NvRegTxDeferral); @@ -5181,9 +5155,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i } np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG; - if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) || - (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) || - (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V3)) { + if (id->driver_data & DEV_HAS_PAUSEFRAME_TX) { np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ; } @@ -5587,107 +5559,107 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP73 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, }, {0,}, }; diff --git a/trunk/drivers/net/mlx4/mr.c b/trunk/drivers/net/mlx4/mr.c index 79b317b88c86..679dfdb6807f 100644 --- a/trunk/drivers/net/mlx4/mr.c +++ b/trunk/drivers/net/mlx4/mr.c @@ -578,6 +578,13 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, goto err_free; } + fmr->mpt = mlx4_table_find(&priv->mr_table.dmpt_table, + key_to_hw_index(fmr->mr.key), NULL); + if (!fmr->mpt) { + err = -ENOMEM; + goto err_free; + } + return 0; err_free: @@ -588,19 +595,7 @@ EXPORT_SYMBOL_GPL(mlx4_fmr_alloc); int mlx4_fmr_enable(struct mlx4_dev *dev, struct mlx4_fmr *fmr) { - struct mlx4_priv *priv = mlx4_priv(dev); - int err; - - err = mlx4_mr_enable(dev, &fmr->mr); - if (err) - return err; - - fmr->mpt = mlx4_table_find(&priv->mr_table.dmpt_table, - key_to_hw_index(fmr->mr.key), NULL); - if (!fmr->mpt) - return -ENOMEM; - - return 0; + return mlx4_mr_enable(dev, &fmr->mr); } EXPORT_SYMBOL_GPL(mlx4_fmr_enable); diff --git a/trunk/drivers/net/netconsole.c b/trunk/drivers/net/netconsole.c index 501e451be911..31e047dd7bb3 100644 --- a/trunk/drivers/net/netconsole.c +++ b/trunk/drivers/net/netconsole.c @@ -309,8 +309,8 @@ static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) struct net_device *dev = nt->np.dev; DECLARE_MAC_BUF(mac); - return snprintf(buf, PAGE_SIZE, "%s\n", dev ? - print_mac(mac, dev->dev_addr) : "ff:ff:ff:ff:ff:ff"); + return snprintf(buf, PAGE_SIZE, "%s\n", + print_mac(mac, dev->dev_addr)); } static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) diff --git a/trunk/drivers/net/ni52.c b/trunk/drivers/net/ni52.c index 26aa8fe1fb2d..6b3384a24f07 100644 --- a/trunk/drivers/net/ni52.c +++ b/trunk/drivers/net/ni52.c @@ -33,20 +33,20 @@ * I have also done a look in the following sources: (mail me if you need them) * crynwr-packet-driver by Russ Nelson * Garret A. Wollman's (fourth) i82586-driver for BSD - * (before getting an i82596 (yes 596 not 586) manual, the existing drivers - * helped me a lot to understand this tricky chip.) + * (before getting an i82596 (yes 596 not 586) manual, the existing drivers helped + * me a lot to understand this tricky chip.) * * Known Problems: * The internal sysbus seems to be slow. So we often lose packets because of * overruns while receiving from a fast remote host. - * This can slow down TCP connections. Maybe the newer ni5210 cards are - * better. My experience is, that if a machine sends with more than about - * 500-600K/s the fifo/sysbus overflows. + * This can slow down TCP connections. Maybe the newer ni5210 cards are better. + * my experience is, that if a machine sends with more than about 500-600K/s + * the fifo/sysbus overflows. * * IMPORTANT NOTE: * On fast networks, it's a (very) good idea to have 16K shared memory. With - * 8K, we can store only 4 receive frames, so it can (easily) happen that a - * remote machine 'overruns' our system. + * 8K, we can store only 4 receive frames, so it can (easily) happen that a remote + * machine 'overruns' our system. * * Known i82586/card problems (I'm sure, there are many more!): * Running the NOP-mode, the i82586 sometimes seems to forget to report @@ -60,8 +60,7 @@ * * results from ftp performance tests with Linux 1.2.5 * send and receive about 350-400 KByte/s (peak up to 460 kbytes/s) - * sending in NOP-mode: peak performance up to 530K/s (but better don't - * run this mode) + * sending in NOP-mode: peak performance up to 530K/s (but better don't run this mode) */ /* @@ -95,8 +94,7 @@ * * 26.March.94: patches for Linux 1.0 and iomem-auto-probe (MH) * - * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, - * too (MH) + * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, too (MH) * * < 30.Sep.93: first versions */ @@ -104,7 +102,7 @@ static int debuglevel; /* debug-printk 0: off 1: a few 2: more */ static int automatic_resume; /* experimental .. better should be zero */ static int rfdadd; /* rfdadd=1 may be better for 8K MEM cards */ -static int fifo = 0x8; /* don't change */ +static int fifo=0x8; /* don't change */ #include #include @@ -129,15 +127,14 @@ static int fifo = 0x8; /* don't change */ #define DEBUG /* debug on */ #define SYSBUSVAL 1 /* 8 Bit */ -#define ni_attn586() { outb(0, dev->base_addr + NI52_ATTENTION); } -#define ni_reset586() { outb(0, dev->base_addr + NI52_RESET); } -#define ni_disint() { outb(0, dev->base_addr + NI52_INTDIS); } -#define ni_enaint() { outb(0, dev->base_addr + NI52_INTENA); } +#define ni_attn586() {outb(0,dev->base_addr+NI52_ATTENTION);} +#define ni_reset586() {outb(0,dev->base_addr+NI52_RESET);} +#define ni_disint() {outb(0,dev->base_addr+NI52_INTDIS);} +#define ni_enaint() {outb(0,dev->base_addr+NI52_INTENA);} -#define make32(ptr16) (p->memtop + (short) (ptr16)) -#define make24(ptr32) ((unsigned long)(ptr32)) - p->base -#define make16(ptr32) ((unsigned short) ((unsigned long)(ptr32)\ - - (unsigned long) p->memtop)) +#define make32(ptr16) (p->memtop + (short) (ptr16) ) +#define make24(ptr32) ( ((char *) (ptr32)) - p->base) +#define make16(ptr32) ((unsigned short) ((unsigned long)(ptr32) - (unsigned long) p->memtop )) /******************* how to calculate the buffers ***************************** @@ -162,112 +159,96 @@ sizeof(nop_cmd) = 8; /**************************************************************************/ +/* different DELAYs */ +#define DELAY(x) mdelay(32 * x); +#define DELAY_16(); { udelay(16); } +#define DELAY_18(); { udelay(4); } + +/* wait for command with timeout: */ +#define WAIT_4_SCB_CMD() \ +{ int i; \ + for(i=0;i<16384;i++) { \ + if(!p->scb->cmd_cuc) break; \ + DELAY_18(); \ + if(i == 16383) { \ + printk("%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_cuc,p->scb->cus); \ + if(!p->reseted) { p->reseted = 1; ni_reset586(); } } } } + +#define WAIT_4_SCB_CMD_RUC() { int i; \ + for(i=0;i<16384;i++) { \ + if(!p->scb->cmd_ruc) break; \ + DELAY_18(); \ + if(i == 16383) { \ + printk("%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_ruc,p->scb->rus); \ + if(!p->reseted) { p->reseted = 1; ni_reset586(); } } } } + +#define WAIT_4_STAT_COMPL(addr) { int i; \ + for(i=0;i<32767;i++) { \ + if((addr)->cmd_status & STAT_COMPL) break; \ + DELAY_16(); DELAY_16(); } } #define NI52_TOTAL_SIZE 16 #define NI52_ADDR0 0x02 #define NI52_ADDR1 0x07 #define NI52_ADDR2 0x01 -static int ni52_probe1(struct net_device *dev, int ioaddr); -static irqreturn_t ni52_interrupt(int irq, void *dev_id); +static int ni52_probe1(struct net_device *dev,int ioaddr); +static irqreturn_t ni52_interrupt(int irq,void *dev_id); static int ni52_open(struct net_device *dev); static int ni52_close(struct net_device *dev); -static int ni52_send_packet(struct sk_buff *, struct net_device *); +static int ni52_send_packet(struct sk_buff *,struct net_device *); static struct net_device_stats *ni52_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void ni52_timeout(struct net_device *dev); +#if 0 +static void ni52_dump(struct net_device *,void *); +#endif /* helper-functions */ static int init586(struct net_device *dev); -static int check586(struct net_device *dev, char *where, unsigned size); +static int check586(struct net_device *dev,char *where,unsigned size); static void alloc586(struct net_device *dev); static void startrecv586(struct net_device *dev); -static void *alloc_rfa(struct net_device *dev, void *ptr); +static void *alloc_rfa(struct net_device *dev,void *ptr); static void ni52_rcv_int(struct net_device *dev); static void ni52_xmt_int(struct net_device *dev); static void ni52_rnr_int(struct net_device *dev); -struct priv { +struct priv +{ struct net_device_stats stats; unsigned long base; char *memtop; - spinlock_t spinlock; - int reset; - struct rfd_struct *rfd_last, *rfd_top, *rfd_first; - struct scp_struct *scp; - struct iscp_struct *iscp; - struct scb_struct *scb; - struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS]; + long int lock; + int reseted; + volatile struct rfd_struct *rfd_last,*rfd_top,*rfd_first; + volatile struct scp_struct *scp; /* volatile is important */ + volatile struct iscp_struct *iscp; /* volatile is important */ + volatile struct scb_struct *scb; /* volatile is important */ + volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS]; #if (NUM_XMIT_BUFFS == 1) - struct transmit_cmd_struct *xmit_cmds[2]; - struct nop_cmd_struct *nop_cmds[2]; + volatile struct transmit_cmd_struct *xmit_cmds[2]; + volatile struct nop_cmd_struct *nop_cmds[2]; #else - struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS]; - struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS]; + volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS]; + volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS]; #endif - int nop_point, num_recv_buffs; - char *xmit_cbuffs[NUM_XMIT_BUFFS]; - int xmit_count, xmit_last; + volatile int nop_point,num_recv_buffs; + volatile char *xmit_cbuffs[NUM_XMIT_BUFFS]; + volatile int xmit_count,xmit_last; }; -/* wait for command with timeout: */ -static void wait_for_scb_cmd(struct net_device *dev) -{ - struct priv *p = dev->priv; - int i; - for (i = 0; i < 16384; i++) { - if (readb(&p->scb->cmd_cuc) == 0) - break; - udelay(4); - if (i == 16383) { - printk(KERN_ERR "%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n", - dev->name, readb(&p->scb->cmd_cuc), readb(&p->scb->cus)); - if (!p->reset) { - p->reset = 1; - ni_reset586(); - } - } - } -} - -static void wait_for_scb_cmd_ruc(struct net_device *dev) -{ - struct priv *p = dev->priv; - int i; - for (i = 0; i < 16384; i++) { - if (readb(&p->scb->cmd_ruc) == 0) - break; - udelay(4); - if (i == 16383) { - printk(KERN_ERR "%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n", - dev->name, p->scb->cmd_ruc, p->scb->rus); - if (!p->reset) { - p->reset = 1; - ni_reset586(); - } - } - } -} - -static void wait_for_stat_compl(void *p) -{ - struct nop_cmd_struct *addr = p; - int i; - for (i = 0; i < 32767; i++) { - if (readw(&((addr)->cmd_status)) & STAT_COMPL) - break; - udelay(32); - } -} - /********************************************** * close device */ static int ni52_close(struct net_device *dev) { free_irq(dev->irq, dev); + ni_reset586(); /* the hard way to stop the receiver */ + netif_stop_queue(dev); + return 0; } @@ -284,53 +265,55 @@ static int ni52_open(struct net_device *dev) startrecv586(dev); ni_enaint(); - ret = request_irq(dev->irq, &ni52_interrupt, 0, dev->name, dev); - if (ret) { + ret = request_irq(dev->irq, &ni52_interrupt,0,dev->name,dev); + if (ret) + { ni_reset586(); return ret; } + netif_start_queue(dev); + return 0; /* most done by init */ } /********************************************** * Check to see if there's an 82586 out there. */ -static int check586(struct net_device *dev, char *where, unsigned size) +static int check586(struct net_device *dev,char *where,unsigned size) { struct priv pb; struct priv *p = /* (struct priv *) dev->priv*/ &pb; char *iscp_addrs[2]; int i; - p->base = (unsigned long) isa_bus_to_virt((unsigned long)where) - + size - 0x01000000; + p->base = (unsigned long) isa_bus_to_virt((unsigned long)where) + size - 0x01000000; p->memtop = isa_bus_to_virt((unsigned long)where) + size; p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS); - memset_io((char *)p->scp, 0, sizeof(struct scp_struct)); - for (i = 0; i < sizeof(struct scp_struct); i++) - /* memory was writeable? */ - if (readb((char *)p->scp + i)) + memset((char *)p->scp,0, sizeof(struct scp_struct)); + for(i=0;iscp)[i]) return 0; - writeb(SYSBUSVAL, &p->scp->sysbus); /* 1 = 8Bit-Bus, 0 = 16 Bit */ - if (readb(&p->scp->sysbus) != SYSBUSVAL) + p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */ + if(p->scp->sysbus != SYSBUSVAL) return 0; iscp_addrs[0] = isa_bus_to_virt((unsigned long)where); - iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct); + iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct); - for (i = 0; i < 2; i++) { + for(i=0;i<2;i++) + { p->iscp = (struct iscp_struct *) iscp_addrs[i]; - memset_io((char *)p->iscp, 0, sizeof(struct iscp_struct)); + memset((char *)p->iscp,0, sizeof(struct iscp_struct)); - writel(make24(p->iscp), &p->scp->iscp); - writeb(1, &p->iscp->busy); + p->scp->iscp = make24(p->iscp); + p->iscp->busy = 1; ni_reset586(); ni_attn586(); - mdelay(32); /* wait a while... */ - /* i82586 clears 'busy' after successful init */ - if (readb(&p->iscp->busy)) + DELAY(1); /* wait a while... */ + + if(p->iscp->busy) /* i82586 clears 'busy' after successful init */ return 0; } return 1; @@ -344,39 +327,36 @@ static void alloc586(struct net_device *dev) struct priv *p = (struct priv *) dev->priv; ni_reset586(); - mdelay(32); - - spin_lock_init(&p->spinlock); + DELAY(1); p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS); p->scb = (struct scb_struct *) isa_bus_to_virt(dev->mem_start); - p->iscp = (struct iscp_struct *) - ((char *)p->scp - sizeof(struct iscp_struct)); + p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct)); - memset_io(p->iscp, 0, sizeof(struct iscp_struct)); - memset_io(p->scp , 0, sizeof(struct scp_struct)); + memset((char *) p->iscp,0,sizeof(struct iscp_struct)); + memset((char *) p->scp ,0,sizeof(struct scp_struct)); - writel(make24(p->iscp), &p->scp->iscp); - writeb(SYSBUSVAL, &p->scp->sysbus); - writew(make16(p->scb), &p->iscp->scb_offset); + p->scp->iscp = make24(p->iscp); + p->scp->sysbus = SYSBUSVAL; + p->iscp->scb_offset = make16(p->scb); - writeb(1, &p->iscp->busy); + p->iscp->busy = 1; ni_reset586(); ni_attn586(); - mdelay(32); + DELAY(1); - if (readb(&p->iscp->busy)) - printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name); + if(p->iscp->busy) + printk("%s: Init-Problems (alloc).\n",dev->name); - p->reset = 0; + p->reseted = 0; - memset_io((char *)p->scb, 0, sizeof(struct scb_struct)); + memset((char *)p->scb,0,sizeof(struct scb_struct)); } /* set: io,irq,memstart,memend or set it when calling insmod */ -static int irq = 9; -static int io = 0x300; +static int irq=9; +static int io=0x300; static long memstart; /* e.g 0xd0000 */ static long memend; /* e.g 0xd4000 */ @@ -433,7 +413,7 @@ struct net_device * __init ni52_probe(int unit) return ERR_PTR(err); } -static int __init ni52_probe1(struct net_device *dev, int ioaddr) +static int __init ni52_probe1(struct net_device *dev,int ioaddr) { int i, size, retval; @@ -445,96 +425,90 @@ static int __init ni52_probe1(struct net_device *dev, int ioaddr) if (!request_region(ioaddr, NI52_TOTAL_SIZE, DRV_NAME)) return -EBUSY; - if (!(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || + if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2)) { retval = -ENODEV; goto out; } - for (i = 0; i < ETH_ALEN; i++) + for(i=0;idev_addr[i] = inb(dev->base_addr+i); - if (dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1 + if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1 || dev->dev_addr[2] != NI52_ADDR2) { retval = -ENODEV; goto out; } - printk(KERN_INFO "%s: NI5210 found at %#3lx, ", - dev->name, dev->base_addr); + printk(KERN_INFO "%s: NI5210 found at %#3lx, ",dev->name,dev->base_addr); /* * check (or search) IO-Memory, 8K and 16K */ #ifdef MODULE size = dev->mem_end - dev->mem_start; - if (size != 0x2000 && size != 0x4000) { - printk("\n"); - printk(KERN_ERR "%s: Invalid memory size %d. Allowed is 0x2000 or 0x4000 bytes.\n", dev->name, size); + if(size != 0x2000 && size != 0x4000) { + printk("\n%s: Illegal memory size %d. Allowed is 0x2000 or 0x4000 bytes.\n",dev->name,size); retval = -ENODEV; goto out; } - if (!check586(dev, (char *)dev->mem_start, size)) { - printk(KERN_ERR "?memcheck, Can't find memory at 0x%lx with size %d!\n", dev->mem_start, size); + if(!check586(dev,(char *) dev->mem_start,size)) { + printk("?memcheck, Can't find memory at 0x%lx with size %d!\n",dev->mem_start,size); retval = -ENODEV; goto out; } #else - if (dev->mem_start != 0) { - /* no auto-mem-probe */ + if(dev->mem_start != 0) /* no auto-mem-probe */ + { size = 0x4000; /* check for 16K mem */ - if (!check586(dev, (char *) dev->mem_start, size)) { + if(!check586(dev,(char *) dev->mem_start,size)) { size = 0x2000; /* check for 8K mem */ - if (!check586(dev, (char *)dev->mem_start, size)) { - printk(KERN_ERR "?memprobe, Can't find memory at 0x%lx!\n", dev->mem_start); + if(!check586(dev,(char *) dev->mem_start,size)) { + printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start); retval = -ENODEV; goto out; } } - } else { - static const unsigned long memaddrs[] = { - 0xc8000, 0xca000, 0xcc000, 0xce000, 0xd0000, 0xd2000, - 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0 - }; - for (i = 0;; i++) { - if (!memaddrs[i]) { - printk(KERN_ERR "?memprobe, Can't find io-memory!\n"); + } + else + { + static long memaddrs[] = { 0xc8000,0xca000,0xcc000,0xce000,0xd0000,0xd2000, + 0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 }; + for(i=0;;i++) + { + if(!memaddrs[i]) { + printk("?memprobe, Can't find io-memory!\n"); retval = -ENODEV; goto out; } dev->mem_start = memaddrs[i]; size = 0x2000; /* check for 8K mem */ - if (check586(dev, (char *)dev->mem_start, size)) - /* 8K-check */ + if(check586(dev,(char *)dev->mem_start,size)) /* 8K-check */ break; size = 0x4000; /* check for 16K mem */ - if (check586(dev, (char *)dev->mem_start, size)) - /* 16K-check */ + if(check586(dev,(char *)dev->mem_start,size)) /* 16K-check */ break; } } - /* set mem_end showed by 'ifconfig' */ - dev->mem_end = dev->mem_start + size; + dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */ #endif - memset((char *)dev->priv, 0, sizeof(struct priv)); + memset((char *) dev->priv,0,sizeof(struct priv)); - ((struct priv *)(dev->priv))->memtop = - isa_bus_to_virt(dev->mem_start) + size; - ((struct priv *)(dev->priv))->base = (unsigned long) - isa_bus_to_virt(dev->mem_start) + size - 0x01000000; + ((struct priv *) (dev->priv))->memtop = isa_bus_to_virt(dev->mem_start) + size; + ((struct priv *) (dev->priv))->base = (unsigned long) isa_bus_to_virt(dev->mem_start) + size - 0x01000000; alloc586(dev); /* set number of receive-buffs according to memsize */ - if (size == 0x2000) + if(size == 0x2000) ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8; else ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16; - printk(KERN_DEBUG "Memaddr: 0x%lx, Memsize: %d, ", - dev->mem_start, size); + printk("Memaddr: 0x%lx, Memsize: %d, ",dev->mem_start,size); - if (dev->irq < 2) { + if(dev->irq < 2) + { unsigned long irq_mask; irq_mask = probe_irq_on(); @@ -543,16 +517,18 @@ static int __init ni52_probe1(struct net_device *dev, int ioaddr) mdelay(20); dev->irq = probe_irq_off(irq_mask); - if (!dev->irq) { + if(!dev->irq) + { printk("?autoirq, Failed to detect IRQ line!\n"); retval = -EAGAIN; goto out; } - printk("IRQ %d (autodetected).\n", dev->irq); - } else { - if (dev->irq == 2) + printk("IRQ %d (autodetected).\n",dev->irq); + } + else { + if(dev->irq == 2) dev->irq = 9; - printk("IRQ %d (assigned and not checked!).\n", dev->irq); + printk("IRQ %d (assigned and not checked!).\n",dev->irq); } dev->open = ni52_open; @@ -579,58 +555,56 @@ static int __init ni52_probe1(struct net_device *dev, int ioaddr) static int init586(struct net_device *dev) { void *ptr; - int i, result = 0; - struct priv *p = (struct priv *)dev->priv; - struct configure_cmd_struct *cfg_cmd; - struct iasetup_cmd_struct *ias_cmd; - struct tdr_cmd_struct *tdr_cmd; - struct mcsetup_cmd_struct *mc_cmd; - struct dev_mc_list *dmi = dev->mc_list; - int num_addrs = dev->mc_count; + int i,result=0; + struct priv *p = (struct priv *) dev->priv; + volatile struct configure_cmd_struct *cfg_cmd; + volatile struct iasetup_cmd_struct *ias_cmd; + volatile struct tdr_cmd_struct *tdr_cmd; + volatile struct mcsetup_cmd_struct *mc_cmd; + struct dev_mc_list *dmi=dev->mc_list; + int num_addrs=dev->mc_count; ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct)); cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */ - writew(0, &cfg_cmd->cmd_status); - writew(CMD_CONFIGURE | CMD_LAST, &cfg_cmd->cmd_cmd); - writew(0xFFFF, &cfg_cmd->cmd_link); - - /* number of cfg bytes */ - writeb(0x0a, &cfg_cmd->byte_cnt); - /* fifo-limit (8=tx:32/rx:64) */ - writeb(fifo, &cfg_cmd->fifo); - /* hold or discard bad recv frames (bit 7) */ - writeb(0x40, &cfg_cmd->sav_bf); - /* addr_len |!src_insert |pre-len |loopback */ - writeb(0x2e, &cfg_cmd->adr_len); - writeb(0x00, &cfg_cmd->priority); - writeb(0x60, &cfg_cmd->ifs);; - writeb(0x00, &cfg_cmd->time_low); - writeb(0xf2, &cfg_cmd->time_high); - writeb(0x00, &cfg_cmd->promisc);; - if (dev->flags & IFF_ALLMULTI) { + cfg_cmd->cmd_status = 0; + cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST; + cfg_cmd->cmd_link = 0xffff; + + cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */ + cfg_cmd->fifo = fifo; /* fifo-limit (8=tx:32/rx:64) */ + cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */ + cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */ + cfg_cmd->priority = 0x00; + cfg_cmd->ifs = 0x60; + cfg_cmd->time_low = 0x00; + cfg_cmd->time_high = 0xf2; + cfg_cmd->promisc = 0; + if(dev->flags & IFF_ALLMULTI) { int len = ((char *) p->iscp - (char *) ptr - 8) / 6; - if (num_addrs > len) { - printk(KERN_ERR "%s: switching to promisc. mode\n", - dev->name); - dev->flags |= IFF_PROMISC; + if(num_addrs > len) { + printk("%s: switching to promisc. mode\n",dev->name); + dev->flags|=IFF_PROMISC; } } - if (dev->flags & IFF_PROMISC) - writeb(0x01, &cfg_cmd->promisc); - writeb(0x00, &cfg_cmd->carr_coll); - writew(make16(cfg_cmd), &p->scb->cbl_offset); - writew(0, &p->scb->cmd_ruc); + if(dev->flags&IFF_PROMISC) + { + cfg_cmd->promisc=1; + dev->flags|=IFF_PROMISC; + } + cfg_cmd->carr_coll = 0x00; - writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */ + p->scb->cbl_offset = make16(cfg_cmd); + p->scb->cmd_ruc = 0; + + p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */ ni_attn586(); - wait_for_stat_compl(cfg_cmd); + WAIT_4_STAT_COMPL(cfg_cmd); - if ((readw(&cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != - (STAT_COMPL|STAT_OK)) { - printk(KERN_ERR "%s: configure command failed: %x\n", - dev->name, readw(&cfg_cmd->cmd_status)); + if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK)) + { + printk("%s: configure command failed: %x\n",dev->name,cfg_cmd->cmd_status); return 1; } @@ -640,22 +614,21 @@ static int init586(struct net_device *dev) ias_cmd = (struct iasetup_cmd_struct *)ptr; - writew(0, &ias_cmd->cmd_status); - writew(CMD_IASETUP | CMD_LAST, &ias_cmd->cmd_cmd); - writew(0xffff, &ias_cmd->cmd_link); + ias_cmd->cmd_status = 0; + ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST; + ias_cmd->cmd_link = 0xffff; - memcpy_toio((char *)&ias_cmd->iaddr, (char *)dev->dev_addr, ETH_ALEN); + memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN); - writew(make16(ias_cmd), &p->scb->cbl_offset); + p->scb->cbl_offset = make16(ias_cmd); - writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */ + p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */ ni_attn586(); - wait_for_stat_compl(ias_cmd); + WAIT_4_STAT_COMPL(ias_cmd); - if ((readw(&ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) != - (STAT_OK|STAT_COMPL)) { - printk(KERN_ERR "%s (ni52): individual address setup command failed: %04x\n", dev->name, readw(&ias_cmd->cmd_status)); + if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) { + printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status); return 1; } @@ -665,119 +638,117 @@ static int init586(struct net_device *dev) tdr_cmd = (struct tdr_cmd_struct *)ptr; - writew(0, &tdr_cmd->cmd_status); - writew(CMD_TDR | CMD_LAST, &tdr_cmd->cmd_cmd); - writew(0xffff, &tdr_cmd->cmd_link); - writew(0, &tdr_cmd->status); + tdr_cmd->cmd_status = 0; + tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST; + tdr_cmd->cmd_link = 0xffff; + tdr_cmd->status = 0; - writew(make16(tdr_cmd), &p->scb->cbl_offset); - writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */ + p->scb->cbl_offset = make16(tdr_cmd); + p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */ ni_attn586(); - wait_for_stat_compl(tdr_cmd); + WAIT_4_STAT_COMPL(tdr_cmd); + + if(!(tdr_cmd->cmd_status & STAT_COMPL)) + { + printk("%s: Problems while running the TDR.\n",dev->name); + } + else + { + DELAY_16(); /* wait for result */ + result = tdr_cmd->status; - if (!(readw(&tdr_cmd->cmd_status) & STAT_COMPL)) - printk(KERN_ERR "%s: Problems while running the TDR.\n", - dev->name); - else { - udelay(16); - result = readw(&tdr_cmd->status); - writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc); + p->scb->cmd_cuc = p->scb->cus & STAT_MASK; ni_attn586(); /* ack the interrupts */ - if (result & TDR_LNK_OK) + if(result & TDR_LNK_OK) ; - else if (result & TDR_XCVR_PRB) - printk(KERN_ERR "%s: TDR: Transceiver problem. Check the cable(s)!\n", - dev->name); - else if (result & TDR_ET_OPN) - printk(KERN_ERR "%s: TDR: No correct termination %d clocks away.\n", - dev->name, result & TDR_TIMEMASK); - else if (result & TDR_ET_SRT) { - /* time == 0 -> strange :-) */ - if (result & TDR_TIMEMASK) - printk(KERN_ERR "%s: TDR: Detected a short circuit %d clocks away.\n", - dev->name, result & TDR_TIMEMASK); - } else - printk(KERN_ERR "%s: TDR: Unknown status %04x\n", - dev->name, result); + else if(result & TDR_XCVR_PRB) + printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name); + else if(result & TDR_ET_OPN) + printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK); + else if(result & TDR_ET_SRT) + { + if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */ + printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK); + } + else + printk("%s: TDR: Unknown status %04x\n",dev->name,result); } /* * Multicast setup */ - if (num_addrs && !(dev->flags & IFF_PROMISC)) { + if(num_addrs && !(dev->flags & IFF_PROMISC) ) + { mc_cmd = (struct mcsetup_cmd_struct *) ptr; - writew(0, &mc_cmd->cmd_status); - writew(CMD_MCSETUP | CMD_LAST, &mc_cmd->cmd_cmd); - writew(0xffff, &mc_cmd->cmd_link); - writew(num_addrs * 6, &mc_cmd->mc_cnt); + mc_cmd->cmd_status = 0; + mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST; + mc_cmd->cmd_link = 0xffff; + mc_cmd->mc_cnt = num_addrs * 6; - for (i = 0; i < num_addrs; i++, dmi = dmi->next) - memcpy_toio((char *) mc_cmd->mc_list[i], - dmi->dmi_addr, 6); + for(i=0;inext) + memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6); - writew(make16(mc_cmd), &p->scb->cbl_offset); - writeb(CUC_START, &p->scb->cmd_cuc); + p->scb->cbl_offset = make16(mc_cmd); + p->scb->cmd_cuc = CUC_START; ni_attn586(); - wait_for_stat_compl(mc_cmd); + WAIT_4_STAT_COMPL(mc_cmd); - if ((readw(&mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK)) - != (STAT_COMPL|STAT_OK)) - printk(KERN_ERR "%s: Can't apply multicast-address-list.\n", dev->name); + if( (mc_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) ) + printk("%s: Can't apply multicast-address-list.\n",dev->name); } /* * alloc nop/xmit-cmds */ #if (NUM_XMIT_BUFFS == 1) - for (i = 0; i < 2; i++) { - p->nop_cmds[i] = (struct nop_cmd_struct *)ptr; - writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd); - writew(0, &p->nop_cmds[i]->cmd_status); - writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link); + for(i=0;i<2;i++) + { + p->nop_cmds[i] = (struct nop_cmd_struct *)ptr; + p->nop_cmds[i]->cmd_cmd = CMD_NOP; + p->nop_cmds[i]->cmd_status = 0; + p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); ptr = (char *) ptr + sizeof(struct nop_cmd_struct); } #else - for (i = 0; i < NUM_XMIT_BUFFS; i++) { - p->nop_cmds[i] = (struct nop_cmd_struct *)ptr; - writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd); - writew(0, &p->nop_cmds[i]->cmd_status); - writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link); + for(i=0;inop_cmds[i] = (struct nop_cmd_struct *)ptr; + p->nop_cmds[i]->cmd_cmd = CMD_NOP; + p->nop_cmds[i]->cmd_status = 0; + p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i])); ptr = (char *) ptr + sizeof(struct nop_cmd_struct); } #endif - ptr = alloc_rfa(dev, (void *)ptr); /* init receive-frame-area */ + ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ /* * alloc xmit-buffs / init xmit_cmds */ - for (i = 0; i < NUM_XMIT_BUFFS; i++) { - /* Transmit cmd/buff 0 */ - p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; + for(i=0;ixmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/ ptr = (char *) ptr + sizeof(struct transmit_cmd_struct); p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */ ptr = (char *) ptr + XMIT_BUFF_SIZE; p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */ ptr = (char *) ptr + sizeof(struct tbd_struct); - if ((void *)ptr > (void *)p->iscp) { - printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n", - dev->name); + if((void *)ptr > (void *)p->iscp) + { + printk("%s: not enough shared-mem for your configuration!\n",dev->name); return 1; } - memset_io((char *)(p->xmit_cmds[i]), 0, - sizeof(struct transmit_cmd_struct)); - memset_io((char *)(p->xmit_buffs[i]), 0, - sizeof(struct tbd_struct)); - writew(make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]), - &p->xmit_cmds[i]->cmd_link); - writew(STAT_COMPL, &p->xmit_cmds[i]->cmd_status); - writew(CMD_XMIT|CMD_INT, &p->xmit_cmds[i]->cmd_cmd); - writew(make16(p->xmit_buffs[i]), &p->xmit_cmds[i]->tbd_offset); - writew(0xffff, &p->xmit_buffs[i]->next); - writel(make24(p->xmit_cbuffs[i]), &p->xmit_buffs[i]->buffer); + memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct)); + memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct)); + p->xmit_cmds[i]->cmd_link = make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]); + p->xmit_cmds[i]->cmd_status = STAT_COMPL; + p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT; + p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i])); + p->xmit_buffs[i]->next = 0xffff; + p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i])); } p->xmit_count = 0; @@ -790,21 +761,21 @@ static int init586(struct net_device *dev) * 'start transmitter' */ #ifndef NO_NOPCOMMANDS - writew(make16(p->nop_cmds[0]), &p->scb->cbl_offset); - writeb(CUC_START, &p->scb->cmd_cuc); + p->scb->cbl_offset = make16(p->nop_cmds[0]); + p->scb->cmd_cuc = CUC_START; ni_attn586(); - wait_for_scb_cmd(dev); + WAIT_4_SCB_CMD(); #else - writew(make16(p->xmit_cmds[0]), &p->xmit_cmds[0]->cmd_link); - writew(CMD_XMIT | CMD_SUSPEND | CMD_INT, &p->xmit_cmds[0]->cmd_cmd); + p->xmit_cmds[0]->cmd_link = make16(p->xmit_cmds[0]); + p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_SUSPEND | CMD_INT; #endif /* * ack. interrupts */ - writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc); + p->scb->cmd_cuc = p->scb->cus & STAT_MASK; ni_attn586(); - udelay(16); + DELAY_16(); ni_enaint(); @@ -816,45 +787,43 @@ static int init586(struct net_device *dev) * It sets up the Receive Frame Area (RFA). */ -static void *alloc_rfa(struct net_device *dev, void *ptr) +static void *alloc_rfa(struct net_device *dev,void *ptr) { - struct rfd_struct *rfd = (struct rfd_struct *)ptr; - struct rbd_struct *rbd; + volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr; + volatile struct rbd_struct *rbd; int i; struct priv *p = (struct priv *) dev->priv; - memset_io((char *) rfd, 0, - sizeof(struct rfd_struct) * (p->num_recv_buffs + rfdadd)); + memset((char *) rfd,0,sizeof(struct rfd_struct)*(p->num_recv_buffs+rfdadd)); p->rfd_first = rfd; - for (i = 0; i < (p->num_recv_buffs + rfdadd); i++) { - writew(make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd)), - &rfd[i].next); - writew(0xffff, &rfd[i].rbd_offset); + for(i = 0; i < (p->num_recv_buffs+rfdadd); i++) { + rfd[i].next = make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd) ); + rfd[i].rbd_offset = 0xffff; } - /* RU suspend */ - writeb(RFD_SUSP, &rfd[p->num_recv_buffs-1+rfdadd].last); + rfd[p->num_recv_buffs-1+rfdadd].last = RFD_SUSP; /* RU suspend */ - ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd)); + ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd) ); rbd = (struct rbd_struct *) ptr; ptr = (void *) (rbd + p->num_recv_buffs); /* clr descriptors */ - memset_io((char *)rbd, 0, - sizeof(struct rbd_struct) * (p->num_recv_buffs)); + memset((char *) rbd,0,sizeof(struct rbd_struct)*(p->num_recv_buffs)); - for (i = 0; i < p->num_recv_buffs; i++) { - writew(make16(rbd + (i+1) % p->num_recv_buffs), &rbd[i].next); - writew(RECV_BUFF_SIZE, &rbd[i].size); - writel(make24(ptr), &rbd[i].buffer); + for(i=0;inum_recv_buffs;i++) + { + rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs)); + rbd[i].size = RECV_BUFF_SIZE; + rbd[i].buffer = make24(ptr); ptr = (char *) ptr + RECV_BUFF_SIZE; } + p->rfd_top = p->rfd_first; p->rfd_last = p->rfd_first + (p->num_recv_buffs - 1 + rfdadd); - writew(make16(p->rfd_first), &p->scb->rfa_offset); - writew(make16(rbd), &p->rfd_first->rbd_offset); + p->scb->rfa_offset = make16(p->rfd_first); + p->rfd_first->rbd_offset = make16(rbd); return ptr; } @@ -864,71 +833,73 @@ static void *alloc_rfa(struct net_device *dev, void *ptr) * Interrupt Handler ... */ -static irqreturn_t ni52_interrupt(int irq, void *dev_id) +static irqreturn_t ni52_interrupt(int irq,void *dev_id) { struct net_device *dev = dev_id; - unsigned int stat; - int cnt = 0; + unsigned short stat; + int cnt=0; struct priv *p; + if (!dev) { + printk ("ni5210-interrupt: irq %d for unknown device.\n",irq); + return IRQ_NONE; + } p = (struct priv *) dev->priv; - if (debuglevel > 1) + if(debuglevel > 1) printk("I"); - spin_lock(&p->spinlock); - - wait_for_scb_cmd(dev); /* wait for last command */ + WAIT_4_SCB_CMD(); /* wait for last command */ - while ((stat = readb(&p->scb->cus) & STAT_MASK)) { - writeb(stat, &p->scb->cmd_cuc); + while((stat=p->scb->cus & STAT_MASK)) + { + p->scb->cmd_cuc = stat; ni_attn586(); - if (stat & STAT_FR) /* received a frame */ + if(stat & STAT_FR) /* received a frame */ ni52_rcv_int(dev); - if (stat & STAT_RNR) { /* RU went 'not ready' */ + if(stat & STAT_RNR) /* RU went 'not ready' */ + { printk("(R)"); - if (readb(&p->scb->rus) & RU_SUSPEND) { - /* special case: RU_SUSPEND */ - wait_for_scb_cmd(dev); + if(p->scb->rus & RU_SUSPEND) /* special case: RU_SUSPEND */ + { + WAIT_4_SCB_CMD(); p->scb->cmd_ruc = RUC_RESUME; ni_attn586(); - wait_for_scb_cmd_ruc(dev); - } else { - printk(KERN_ERR "%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n", - dev->name, stat, readb(&p->scb->rus)); + WAIT_4_SCB_CMD_RUC(); + } + else + { + printk("%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->rus); ni52_rnr_int(dev); } } - /* Command with I-bit set complete */ - if (stat & STAT_CX) + if(stat & STAT_CX) /* command with I-bit set complete */ ni52_xmt_int(dev); #ifndef NO_NOPCOMMANDS - if (stat & STAT_CNA) { /* CU went 'not ready' */ - if (netif_running(dev)) - printk(KERN_ERR "%s: oops! CU has left active state. stat: %04x/%02x.\n", - dev->name, stat, readb(&p->scb->cus)); + if(stat & STAT_CNA) /* CU went 'not ready' */ + { + if(netif_running(dev)) + printk("%s: oops! CU has left active state. stat: %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->cus); } #endif - if (debuglevel > 1) - printk("%d", cnt++); + if(debuglevel > 1) + printk("%d",cnt++); - /* Wait for ack. (ni52_xmt_int can be faster than ack!!) */ - wait_for_scb_cmd(dev); - if (p->scb->cmd_cuc) { /* timed out? */ - printk(KERN_ERR "%s: Acknowledge timed out.\n", - dev->name); + WAIT_4_SCB_CMD(); /* wait for ack. (ni52_xmt_int can be faster than ack!!) */ + if(p->scb->cmd_cuc) /* timed out? */ + { + printk("%s: Acknowledge timed out.\n",dev->name); ni_disint(); break; } } - spin_unlock(&p->spinlock); - if (debuglevel > 1) + if(debuglevel > 1) printk("i"); return IRQ_HANDLED; } @@ -939,91 +910,121 @@ static irqreturn_t ni52_interrupt(int irq, void *dev_id) static void ni52_rcv_int(struct net_device *dev) { - int status, cnt = 0; + int status,cnt=0; unsigned short totlen; struct sk_buff *skb; struct rbd_struct *rbd; - struct priv *p = (struct priv *)dev->priv; + struct priv *p = (struct priv *) dev->priv; - if (debuglevel > 0) + if(debuglevel > 0) printk("R"); - for (; (status = readb(&p->rfd_top->stat_high)) & RFD_COMPL;) { - rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset); - if (status & RFD_OK) { /* frame received without error? */ - totlen = readw(&rbd->status); - if (totlen & RBD_LAST) { - /* the first and the last buffer? */ - totlen &= RBD_MASK; /* length of this frame */ - writew(0x00, &rbd->status); - skb = (struct sk_buff *)dev_alloc_skb(totlen+2); - if (skb != NULL) { - skb_reserve(skb, 2); - skb_put(skb, totlen); - skb_copy_to_linear_data(skb, (char *)p->base + (unsigned long) rbd->buffer, totlen); - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - dev->last_rx = jiffies; - p->stats.rx_packets++; - p->stats.rx_bytes += totlen; - } else - p->stats.rx_dropped++; - } else { - int rstat; - /* free all RBD's until RBD_LAST is set */ - totlen = 0; - while (!((rstat = readw(&rbd->status)) & RBD_LAST)) { - totlen += rstat & RBD_MASK; - if (!rstat) { - printk(KERN_ERR "%s: Whoops .. no end mark in RBD list\n", dev->name); - break; + for(;(status = p->rfd_top->stat_high) & RFD_COMPL;) + { + rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset); + + if(status & RFD_OK) /* frame received without error? */ + { + if( (totlen = rbd->status) & RBD_LAST) /* the first and the last buffer? */ + { + totlen &= RBD_MASK; /* length of this frame */ + rbd->status = 0; + skb = (struct sk_buff *) dev_alloc_skb(totlen+2); + if(skb != NULL) + { + skb_reserve(skb,2); + skb_put(skb,totlen); + skb_copy_to_linear_data(skb,(char *) p->base+(unsigned long) rbd->buffer,totlen); + skb->protocol=eth_type_trans(skb,dev); + netif_rx(skb); + dev->last_rx = jiffies; + p->stats.rx_packets++; + p->stats.rx_bytes += totlen; } - writew(0, &rbd->status); - rbd = (struct rbd_struct *) make32(readl(&rbd->next)); + else + p->stats.rx_dropped++; } - totlen += rstat & RBD_MASK; - writew(0, &rbd->status); - printk(KERN_ERR "%s: received oversized frame! length: %d\n", - dev->name, totlen); - p->stats.rx_dropped++; + else + { + int rstat; + /* free all RBD's until RBD_LAST is set */ + totlen = 0; + while(!((rstat=rbd->status) & RBD_LAST)) + { + totlen += rstat & RBD_MASK; + if(!rstat) + { + printk("%s: Whoops .. no end mark in RBD list\n",dev->name); + break; + } + rbd->status = 0; + rbd = (struct rbd_struct *) make32(rbd->next); + } + totlen += rstat & RBD_MASK; + rbd->status = 0; + printk("%s: received oversized frame! length: %d\n",dev->name,totlen); + p->stats.rx_dropped++; } - } else {/* frame !(ok), only with 'save-bad-frames' */ - printk(KERN_ERR "%s: oops! rfd-error-status: %04x\n", - dev->name, status); + } + else /* frame !(ok), only with 'save-bad-frames' */ + { + printk("%s: oops! rfd-error-status: %04x\n",dev->name,status); p->stats.rx_errors++; } - writeb(0, &p->rfd_top->stat_high); - writeb(RFD_SUSP, &p->rfd_top->last); /* maybe exchange by RFD_LAST */ - writew(0xffff, &p->rfd_top->rbd_offset); - writeb(0, &p->rfd_last->last); /* delete RFD_SUSP */ + p->rfd_top->stat_high = 0; + p->rfd_top->last = RFD_SUSP; /* maybe exchange by RFD_LAST */ + p->rfd_top->rbd_offset = 0xffff; + p->rfd_last->last = 0; /* delete RFD_SUSP */ p->rfd_last = p->rfd_top; p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */ - writew(make16(p->rfd_top), &p->scb->rfa_offset); + p->scb->rfa_offset = make16(p->rfd_top); - if (debuglevel > 0) - printk("%d", cnt++); + if(debuglevel > 0) + printk("%d",cnt++); } - if (automatic_resume) { - wait_for_scb_cmd(dev); - writeb(RUC_RESUME, &p->scb->cmd_ruc); + if(automatic_resume) + { + WAIT_4_SCB_CMD(); + p->scb->cmd_ruc = RUC_RESUME; ni_attn586(); - wait_for_scb_cmd_ruc(dev); + WAIT_4_SCB_CMD_RUC(); } #ifdef WAIT_4_BUSY { int i; - for (i = 0; i < 1024; i++) { - if (p->rfd_top->status) + for(i=0;i<1024;i++) + { + if(p->rfd_top->status) break; - udelay(16); - if (i == 1023) - printk(KERN_ERR "%s: RU hasn't fetched next RFD (not busy/complete)\n", dev->name); + DELAY_16(); + if(i == 1023) + printk("%s: RU hasn't fetched next RFD (not busy/complete)\n",dev->name); } } #endif - if (debuglevel > 0) + +#if 0 + if(!at_least_one) + { + int i; + volatile struct rfd_struct *rfds=p->rfd_top; + volatile struct rbd_struct *rbds; + printk("%s: received a FC intr. without having a frame: %04x %d\n",dev->name,status,old_at_least); + for(i=0;i< (p->num_recv_buffs+4);i++) + { + rbds = (struct rbd_struct *) make32(rfds->rbd_offset); + printk("%04x:%04x ",rfds->status,rbds->status); + rfds = (struct rfd_struct *) make32(rfds->next); + } + printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status); + printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus); + } + old_at_least = at_least_one; +#endif + + if(debuglevel > 0) printk("r"); } @@ -1037,16 +1038,16 @@ static void ni52_rnr_int(struct net_device *dev) p->stats.rx_errors++; - wait_for_scb_cmd(dev); /* wait for the last cmd, WAIT_4_FULLSTAT?? */ - writeb(RUC_ABORT, &p->scb->cmd_ruc); /* usually the RU is in the 'no resource'-state .. abort it now. */ + WAIT_4_SCB_CMD(); /* wait for the last cmd, WAIT_4_FULLSTAT?? */ + p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */ ni_attn586(); - wait_for_scb_cmd_ruc(dev); /* wait for accept cmd. */ + WAIT_4_SCB_CMD_RUC(); /* wait for accept cmd. */ - alloc_rfa(dev, (char *)p->rfd_first); - /* maybe add a check here, before restarting the RU */ + alloc_rfa(dev,(char *)p->rfd_first); +/* maybe add a check here, before restarting the RU */ startrecv586(dev); /* restart RU */ - printk(KERN_ERR "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->rus); + printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->rus); } @@ -1059,41 +1060,43 @@ static void ni52_xmt_int(struct net_device *dev) int status; struct priv *p = (struct priv *) dev->priv; - if (debuglevel > 0) + if(debuglevel > 0) printk("X"); - status = readw(&p->xmit_cmds[p->xmit_last]->cmd_status); - if (!(status & STAT_COMPL)) - printk(KERN_ERR "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name); + status = p->xmit_cmds[p->xmit_last]->cmd_status; + if(!(status & STAT_COMPL)) + printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name); - if (status & STAT_OK) { + if(status & STAT_OK) + { p->stats.tx_packets++; p->stats.collisions += (status & TCMD_MAXCOLLMASK); - } else { + } + else + { p->stats.tx_errors++; - if (status & TCMD_LATECOLL) { - printk(KERN_ERR "%s: late collision detected.\n", - dev->name); + if(status & TCMD_LATECOLL) { + printk("%s: late collision detected.\n",dev->name); p->stats.collisions++; - } else if (status & TCMD_NOCARRIER) { + } + else if(status & TCMD_NOCARRIER) { p->stats.tx_carrier_errors++; - printk(KERN_ERR "%s: no carrier detected.\n", - dev->name); - } else if (status & TCMD_LOSTCTS) - printk(KERN_ERR "%s: loss of CTS detected.\n", - dev->name); - else if (status & TCMD_UNDERRUN) { + printk("%s: no carrier detected.\n",dev->name); + } + else if(status & TCMD_LOSTCTS) + printk("%s: loss of CTS detected.\n",dev->name); + else if(status & TCMD_UNDERRUN) { p->stats.tx_fifo_errors++; - printk(KERN_ERR "%s: DMA underrun detected.\n", - dev->name); - } else if (status & TCMD_MAXCOLL) { - printk(KERN_ERR "%s: Max. collisions exceeded.\n", - dev->name); + printk("%s: DMA underrun detected.\n",dev->name); + } + else if(status & TCMD_MAXCOLL) { + printk("%s: Max. collisions exceeded.\n",dev->name); p->stats.collisions += 16; } } + #if (NUM_XMIT_BUFFS > 1) - if ((++p->xmit_last) == NUM_XMIT_BUFFS) + if( (++p->xmit_last) == NUM_XMIT_BUFFS) p->xmit_last = 0; #endif netif_wake_queue(dev); @@ -1107,51 +1110,41 @@ static void startrecv586(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; - wait_for_scb_cmd(dev); - wait_for_scb_cmd_ruc(dev); - writew(make16(p->rfd_first), &p->scb->rfa_offset); - writeb(RUC_START, &p->scb->cmd_ruc); + WAIT_4_SCB_CMD(); + WAIT_4_SCB_CMD_RUC(); + p->scb->rfa_offset = make16(p->rfd_first); + p->scb->cmd_ruc = RUC_START; ni_attn586(); /* start cmd. */ - wait_for_scb_cmd_ruc(dev); - /* wait for accept cmd. (no timeout!!) */ + WAIT_4_SCB_CMD_RUC(); /* wait for accept cmd. (no timeout!!) */ } static void ni52_timeout(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; #ifndef NO_NOPCOMMANDS - if (readb(&p->scb->cus) & CU_ACTIVE) { /* COMMAND-UNIT active? */ + if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */ + { netif_wake_queue(dev); #ifdef DEBUG - printk(KERN_ERR "%s: strange ... timeout with CU active?!?\n", - dev->name); - printk(KERN_ERR "%s: X0: %04x N0: %04x N1: %04x %d\n", - dev->name, (int)p->xmit_cmds[0]->cmd_status, - readw(&p->nop_cmds[0]->cmd_status), - readw(&p->nop_cmds[1]->cmd_status), - p->nop_point); + printk("%s: strange ... timeout with CU active?!?\n",dev->name); + printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point); #endif - writeb(CUC_ABORT, &p->scb->cmd_cuc); + p->scb->cmd_cuc = CUC_ABORT; ni_attn586(); - wait_for_scb_cmd(dev); - writew(make16(p->nop_cmds[p->nop_point]), &p->scb->cbl_offset); - writeb(CUC_START, &p->scb->cmd_cuc); + WAIT_4_SCB_CMD(); + p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]); + p->scb->cmd_cuc = CUC_START; ni_attn586(); - wait_for_scb_cmd(dev); + WAIT_4_SCB_CMD(); dev->trans_start = jiffies; return 0; } #endif { #ifdef DEBUG - printk(KERN_ERR "%s: xmitter timed out, try to restart! stat: %02x\n", - dev->name, readb(&p->scb->cus)); - printk(KERN_ERR "%s: command-stats: %04x %04x\n", - dev->name, - readw(&p->xmit_cmds[0]->cmd_status), - readw(&p->xmit_cmds[1]->cmd_status)); - printk(KERN_ERR "%s: check, whether you set the right interrupt number!\n", - dev->name); + printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus); + printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status); + printk("%s: check, whether you set the right interrupt number!\n",dev->name); #endif ni52_close(dev); ni52_open(dev); @@ -1165,99 +1158,110 @@ static void ni52_timeout(struct net_device *dev) static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev) { - int len, i; + int len,i; #ifndef NO_NOPCOMMANDS int next_nop; #endif struct priv *p = (struct priv *) dev->priv; - if (skb->len > XMIT_BUFF_SIZE) { - printk(KERN_ERR "%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n", dev->name, XMIT_BUFF_SIZE, skb->len); + if(skb->len > XMIT_BUFF_SIZE) + { + printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len); return 0; } netif_stop_queue(dev); - skb_copy_from_linear_data(skb, (char *)p->xmit_cbuffs[p->xmit_count], - skb->len); - len = skb->len; - if (len < ETH_ZLEN) { - len = ETH_ZLEN; - memset((char *)p->xmit_cbuffs[p->xmit_count]+skb->len, 0, - len - skb->len); +#if(NUM_XMIT_BUFFS > 1) + if(test_and_set_bit(0,(void *) &p->lock)) { + printk("%s: Queue was locked\n",dev->name); + return 1; } + else +#endif + { + skb_copy_from_linear_data(skb, (char *) p->xmit_cbuffs[p->xmit_count], skb->len); + len = skb->len; + if (len < ETH_ZLEN) { + len = ETH_ZLEN; + memset((char *)p->xmit_cbuffs[p->xmit_count]+skb->len, 0, len - skb->len); + } #if (NUM_XMIT_BUFFS == 1) # ifdef NO_NOPCOMMANDS #ifdef DEBUG - if (p->scb->cus & CU_ACTIVE) { - printk(KERN_ERR "%s: Hmmm .. CU is still running and we wanna send a new packet.\n", dev->name); - printk(KERN_ERR "%s: stat: %04x %04x\n", - dev->name, readb(&p->scb->cus), - readw(&p->xmit_cmds[0]->cmd_status)); - } + if(p->scb->cus & CU_ACTIVE) + { + printk("%s: Hmmm .. CU is still running and we wanna send a new packet.\n",dev->name); + printk("%s: stat: %04x %04x\n",dev->name,p->scb->cus,p->xmit_cmds[0]->cmd_status); + } #endif - writew(TBD_LAST | len, &p->xmit_buffs[0]->size);; - for (i = 0; i < 16; i++) { - writew(0, &p->xmit_cmds[0]->cmd_status); - wait_for_scb_cmd(dev); - if ((readb(&p->scb->cus) & CU_STATUS) == CU_SUSPEND) - writeb(CUC_RESUME, &p->scb->cmd_cuc); - else { - writew(make16(p->xmit_cmds[0]), &p->scb->cbl_offset); - writeb(CUC_START, &p->scb->cmd_cuc); + + p->xmit_buffs[0]->size = TBD_LAST | len; + for(i=0;i<16;i++) + { + p->xmit_cmds[0]->cmd_status = 0; + WAIT_4_SCB_CMD(); + if( (p->scb->cus & CU_STATUS) == CU_SUSPEND) + p->scb->cmd_cuc = CUC_RESUME; + else + { + p->scb->cbl_offset = make16(p->xmit_cmds[0]); + p->scb->cmd_cuc = CUC_START; + } + + ni_attn586(); + dev->trans_start = jiffies; + if(!i) + dev_kfree_skb(skb); + WAIT_4_SCB_CMD(); + if( (p->scb->cus & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */ + break; + if(p->xmit_cmds[0]->cmd_status) + break; + if(i==15) + printk("%s: Can't start transmit-command.\n",dev->name); } - ni_attn586(); - dev->trans_start = jiffies; - if (!i) - dev_kfree_skb(skb); - wait_for_scb_cmd(dev); - /* test it, because CU sometimes doesn't start immediately */ - if (readb(&p->scb->cus) & CU_ACTIVE) - break; - if (readw(&p->xmit_cmds[0]->cmd_status)) - break; - if (i == 15) - printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name); - } # else - next_nop = (p->nop_point + 1) & 0x1; - writew(TBD_LAST | len, &p->xmit_buffs[0]->size); - writew(make16(p->nop_cmds[next_nop]), &p->xmit_cmds[0]->cmd_link); - writew(make16(p->nop_cmds[next_nop]), - &p->nop_cmds[next_nop]->cmd_link); - writew(0, &p->xmit_cmds[0]->cmd_status); - writew(0, &p->nop_cmds[next_nop]->cmd_status); - - writew(make16(p->xmit_cmds[0]), &p->nop_cmds[p->nop_point]->cmd_link); - dev->trans_start = jiffies; - p->nop_point = next_nop; - dev_kfree_skb(skb); + next_nop = (p->nop_point + 1) & 0x1; + p->xmit_buffs[0]->size = TBD_LAST | len; + + p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link + = make16((p->nop_cmds[next_nop])); + p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0; + + p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0])); + dev->trans_start = jiffies; + p->nop_point = next_nop; + dev_kfree_skb(skb); # endif #else - writew(TBD_LAST | len, &p->xmit_buffs[p->xmit_count]->size); - next_nop = p->xmit_count + 1 - if (next_nop == NUM_XMIT_BUFFS) - next_nop = 0; - writew(0, &p->xmit_cmds[p->xmit_count]->cmd_status); - /* linkpointer of xmit-command already points to next nop cmd */ - writew(make16(p->nop_cmds[next_nop]), - &p->nop_cmds[next_nop]->cmd_link); - writew(0, &p->nop_cmds[next_nop]->cmd_status); - writew(make16(p->xmit_cmds[p->xmit_count]), - &p->nop_cmds[p->xmit_count]->cmd_link); - dev->trans_start = jiffies; - p->xmit_count = next_nop; - { - unsigned long flags; - spin_lock_irqsave(&p->spinlock); - if (p->xmit_count != p->xmit_last) - netif_wake_queue(dev); - spin_unlock_irqrestore(&p->spinlock); - } - dev_kfree_skb(skb); + p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len; + if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS ) + next_nop = 0; + + p->xmit_cmds[p->xmit_count]->cmd_status = 0; + /* linkpointer of xmit-command already points to next nop cmd */ + p->nop_cmds[next_nop]->cmd_link = make16((p->nop_cmds[next_nop])); + p->nop_cmds[next_nop]->cmd_status = 0; + + p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count])); + dev->trans_start = jiffies; + p->xmit_count = next_nop; + + { + unsigned long flags; + save_flags(flags); + cli(); + if(p->xmit_count != p->xmit_last) + netif_wake_queue(dev); + p->lock = 0; + restore_flags(flags); + } + dev_kfree_skb(skb); #endif + } return 0; } @@ -1268,17 +1272,16 @@ static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev) static struct net_device_stats *ni52_get_stats(struct net_device *dev) { struct priv *p = (struct priv *) dev->priv; - unsigned short crc, aln, rsc, ovrn; - - /* Get error-statistics from the ni82586 */ - crc = readw(&p->scb->crc_errs); - writew(0, &p->scb->crc_errs); - aln = readw(&p->scb->aln_errs); - writew(0, &p->scb->aln_errs); - rsc = readw(&p->scb->rsc_errs); - writew(0, &p->scb->rsc_errs); - ovrn = readw(&p->scb->ovrn_errs); - writew(0, &p->scb->ovrn_errs); + unsigned short crc,aln,rsc,ovrn; + + crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */ + p->scb->crc_errs = 0; + aln = p->scb->aln_errs; + p->scb->aln_errs = 0; + rsc = p->scb->rsc_errs; + p->scb->rsc_errs = 0; + ovrn = p->scb->ovrn_errs; + p->scb->ovrn_errs = 0; p->stats.rx_crc_errors += crc; p->stats.rx_fifo_errors += ovrn; @@ -1317,9 +1320,8 @@ MODULE_PARM_DESC(memend, "NI5210 memory end address,required"); int __init init_module(void) { - if (io <= 0x0 || !memend || !memstart || irq < 2) { - printk(KERN_ERR "ni52: Autoprobing not allowed for modules.\n"); - printk(KERN_ERR "ni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n"); + if(io <= 0x0 || !memend || !memstart || irq < 2) { + printk("ni52: Autoprobing not allowed for modules.\nni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n"); return -ENODEV; } dev_ni52 = ni52_probe(-1); @@ -1336,6 +1338,42 @@ void __exit cleanup_module(void) } #endif /* MODULE */ +#if 0 +/* + * DUMP .. we expect a not running CMD unit and enough space + */ +void ni52_dump(struct net_device *dev,void *ptr) +{ + struct priv *p = (struct priv *) dev->priv; + struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr; + int i; + + p->scb->cmd_cuc = CUC_ABORT; + ni_attn586(); + WAIT_4_SCB_CMD(); + WAIT_4_SCB_CMD_RUC(); + + dump_cmd->cmd_status = 0; + dump_cmd->cmd_cmd = CMD_DUMP | CMD_LAST; + dump_cmd->dump_offset = make16((dump_cmd + 1)); + dump_cmd->cmd_link = 0xffff; + + p->scb->cbl_offset = make16(dump_cmd); + p->scb->cmd_cuc = CUC_START; + ni_attn586(); + WAIT_4_STAT_COMPL(dump_cmd); + + if( (dump_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) ) + printk("%s: Can't get dump information.\n",dev->name); + + for(i=0;i<170;i++) { + printk("%02x ",(int) ((unsigned char *) (dump_cmd + 1))[i]); + if(i % 24 == 23) + printk("\n"); + } + printk("\n"); +} +#endif MODULE_LICENSE("GPL"); /* diff --git a/trunk/drivers/net/ni52.h b/trunk/drivers/net/ni52.h index 1f28a4d1a319..a33ea0884aaf 100644 --- a/trunk/drivers/net/ni52.h +++ b/trunk/drivers/net/ni52.h @@ -36,12 +36,12 @@ struct scp_struct { - u16 zero_dum0; /* has to be zero */ - u8 sysbus; /* 0=16Bit,1=8Bit */ - u8 zero_dum1; /* has to be zero for 586 */ - u8 zero_dum2; - u8 zero_dum3; - u32 iscp; /* pointer to the iscp-block */ + unsigned short zero_dum0; /* has to be zero */ + unsigned char sysbus; /* 0=16Bit,1=8Bit */ + unsigned char zero_dum1; /* has to be zero for 586 */ + unsigned short zero_dum2; + unsigned short zero_dum3; + char *iscp; /* pointer to the iscp-block */ }; @@ -50,10 +50,10 @@ struct scp_struct */ struct iscp_struct { - u8 busy; /* 586 clears after successful init */ - u8 zero_dummy; /* has to be zero */ - u16 scb_offset; /* pointeroffset to the scb_base */ - u32 scb_base; /* base-address of all 16-bit offsets */ + unsigned char busy; /* 586 clears after successful init */ + unsigned char zero_dummy; /* has to be zero */ + unsigned short scb_offset; /* pointeroffset to the scb_base */ + char *scb_base; /* base-address of all 16-bit offsets */ }; /* @@ -61,16 +61,16 @@ struct iscp_struct */ struct scb_struct { - u8 rus; - u8 cus; - u8 cmd_ruc; /* command word: RU part */ - u8 cmd_cuc; /* command word: CU part & ACK */ - u16 cbl_offset; /* pointeroffset, command block list */ - u16 rfa_offset; /* pointeroffset, receive frame area */ - u16 crc_errs; /* CRC-Error counter */ - u16 aln_errs; /* alignmenterror counter */ - u16 rsc_errs; /* Resourceerror counter */ - u16 ovrn_errs; /* OVerrunerror counter */ + unsigned char rus; + unsigned char cus; + unsigned char cmd_ruc; /* command word: RU part */ + unsigned char cmd_cuc; /* command word: CU part & ACK */ + unsigned short cbl_offset; /* pointeroffset, command block list */ + unsigned short rfa_offset; /* pointeroffset, receive frame area */ + unsigned short crc_errs; /* CRC-Error counter */ + unsigned short aln_errs; /* alignmenterror counter */ + unsigned short rsc_errs; /* Resourceerror counter */ + unsigned short ovrn_errs; /* OVerrunerror counter */ }; /* @@ -119,16 +119,16 @@ struct scb_struct */ struct rfd_struct { - u8 stat_low; /* status word */ - u8 stat_high; /* status word */ - u8 rfd_sf; /* 82596 mode only */ - u8 last; /* Bit15,Last Frame on List / Bit14,suspend */ - u16 next; /* linkoffset to next RFD */ - u16 rbd_offset; /* pointeroffset to RBD-buffer */ - u8 dest[6]; /* ethernet-address, destination */ - u8 source[6]; /* ethernet-address, source */ - u16 length; /* 802.3 frame-length */ - u16 zero_dummy; /* dummy */ + unsigned char stat_low; /* status word */ + unsigned char stat_high; /* status word */ + unsigned char rfd_sf; /* 82596 mode only */ + unsigned char last; /* Bit15,Last Frame on List / Bit14,suspend */ + unsigned short next; /* linkoffset to next RFD */ + unsigned short rbd_offset; /* pointeroffset to RBD-buffer */ + unsigned char dest[6]; /* ethernet-address, destination */ + unsigned char source[6]; /* ethernet-address, source */ + unsigned short length; /* 802.3 frame-length */ + unsigned short zero_dummy; /* dummy */ }; #define RFD_LAST 0x80 /* last: last rfd in the list */ @@ -153,11 +153,11 @@ struct rfd_struct */ struct rbd_struct { - u16 status; /* status word,number of used bytes in buff */ - u16 next; /* pointeroffset to next RBD */ - u32 buffer; /* receive buffer address pointer */ - u16 size; /* size of this buffer */ - u16 zero_dummy; /* dummy */ + unsigned short status; /* status word,number of used bytes in buff */ + unsigned short next; /* pointeroffset to next RBD */ + char *buffer; /* receive buffer address pointer */ + unsigned short size; /* size of this buffer */ + unsigned short zero_dummy; /* dummy */ }; #define RBD_LAST 0x8000 /* last buffer */ @@ -195,9 +195,9 @@ struct rbd_struct */ struct nop_cmd_struct { - u16 cmd_status; /* status of this command */ - u16 cmd_cmd; /* the command itself (+bits) */ - u16 cmd_link; /* offsetpointer to next command */ + unsigned short cmd_status; /* status of this command */ + unsigned short cmd_cmd; /* the command itself (+bits) */ + unsigned short cmd_link; /* offsetpointer to next command */ }; /* @@ -205,10 +205,10 @@ struct nop_cmd_struct */ struct iasetup_cmd_struct { - u16 cmd_status; - u16 cmd_cmd; - u16 cmd_link; - u8 iaddr[6]; + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned char iaddr[6]; }; /* @@ -216,21 +216,21 @@ struct iasetup_cmd_struct */ struct configure_cmd_struct { - u16 cmd_status; - u16 cmd_cmd; - u16 cmd_link; - u8 byte_cnt; /* size of the config-cmd */ - u8 fifo; /* fifo/recv monitor */ - u8 sav_bf; /* save bad frames (bit7=1)*/ - u8 adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/ - u8 priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */ - u8 ifs; /* inter frame spacing */ - u8 time_low; /* slot time low */ - u8 time_high; /* slot time high(0-2) and max. retries(4-7) */ - u8 promisc; /* promisc-mode(0) , et al (1-7) */ - u8 carr_coll; /* carrier(0-3)/collision(4-7) stuff */ - u8 fram_len; /* minimal frame len */ - u8 dummy; /* dummy */ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned char byte_cnt; /* size of the config-cmd */ + unsigned char fifo; /* fifo/recv monitor */ + unsigned char sav_bf; /* save bad frames (bit7=1)*/ + unsigned char adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/ + unsigned char priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */ + unsigned char ifs; /* inter frame spacing */ + unsigned char time_low; /* slot time low */ + unsigned char time_high; /* slot time high(0-2) and max. retries(4-7) */ + unsigned char promisc; /* promisc-mode(0) , et al (1-7) */ + unsigned char carr_coll; /* carrier(0-3)/collision(4-7) stuff */ + unsigned char fram_len; /* minimal frame len */ + unsigned char dummy; /* dummy */ }; /* @@ -238,11 +238,11 @@ struct configure_cmd_struct */ struct mcsetup_cmd_struct { - u16 cmd_status; - u16 cmd_cmd; - u16 cmd_link; - u16 mc_cnt; /* number of bytes in the MC-List */ - u8 mc_list[0][6]; /* pointer to 6 bytes entries */ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned short mc_cnt; /* number of bytes in the MC-List */ + unsigned char mc_list[0][6]; /* pointer to 6 bytes entries */ }; /* @@ -250,10 +250,10 @@ struct mcsetup_cmd_struct */ struct dump_cmd_struct { - u16 cmd_status; - u16 cmd_cmd; - u16 cmd_link; - u16 dump_offset; /* pointeroffset to DUMP space */ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned short dump_offset; /* pointeroffset to DUMP space */ }; /* @@ -261,12 +261,12 @@ struct dump_cmd_struct */ struct transmit_cmd_struct { - u16 cmd_status; - u16 cmd_cmd; - u16 cmd_link; - u16 tbd_offset; /* pointeroffset to TBD */ - u8 dest[6]; /* destination address of the frame */ - u16 length; /* user defined: 802.3 length / Ether type */ + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned short tbd_offset; /* pointeroffset to TBD */ + unsigned char dest[6]; /* destination address of the frame */ + unsigned short length; /* user defined: 802.3 length / Ether type */ }; #define TCMD_ERRMASK 0x0fa0 @@ -281,10 +281,10 @@ struct transmit_cmd_struct struct tdr_cmd_struct { - u16 cmd_status; - u16 cmd_cmd; - u16 cmd_link; - u16 status; + unsigned short cmd_status; + unsigned short cmd_cmd; + unsigned short cmd_link; + unsigned short status; }; #define TDR_LNK_OK 0x8000 /* No link problem identified */ @@ -298,9 +298,9 @@ struct tdr_cmd_struct */ struct tbd_struct { - u16 size; /* size + EOF-Flag(15) */ - u16 next; /* pointeroffset to next TBD */ - u32 buffer; /* pointer to buffer */ + unsigned short size; /* size + EOF-Flag(15) */ + unsigned short next; /* pointeroffset to next TBD */ + char *buffer; /* pointer to buffer */ }; #define TBD_LAST 0x8000 /* EOF-Flag, indicates last buffer in list */ diff --git a/trunk/drivers/net/pcnet32.c b/trunk/drivers/net/pcnet32.c index 4eb322e5273d..c4b74e9fed20 100644 --- a/trunk/drivers/net/pcnet32.c +++ b/trunk/drivers/net/pcnet32.c @@ -174,11 +174,7 @@ static int homepna[MAX_UNITS]; #define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS)) #define RX_MAX_RING_SIZE (1 << (PCNET32_LOG_MAX_RX_BUFFERS)) -#define PKT_BUF_SKB 1544 -/* actual buffer length after being aligned */ -#define PKT_BUF_SIZE (PKT_BUF_SKB - NET_IP_ALIGN) -/* chip wants twos complement of the (aligned) buffer length */ -#define NEG_BUF_SIZE (NET_IP_ALIGN - PKT_BUF_SKB) +#define PKT_BUF_SZ 1544 /* Offsets from base I/O address. */ #define PCNET32_WIO_RDP 0x10 @@ -608,7 +604,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, /* now allocate any new buffers needed */ for (; new < size; new++ ) { struct sk_buff *rx_skbuff; - new_skb_list[new] = dev_alloc_skb(PKT_BUF_SKB); + new_skb_list[new] = dev_alloc_skb(PKT_BUF_SZ); if (!(rx_skbuff = new_skb_list[new])) { /* keep the original lists and buffers */ if (netif_msg_drv(lp)) @@ -617,20 +613,20 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, dev->name); goto free_all_new; } - skb_reserve(rx_skbuff, NET_IP_ALIGN); + skb_reserve(rx_skbuff, 2); new_dma_addr_list[new] = pci_map_single(lp->pci_dev, rx_skbuff->data, - PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); new_rx_ring[new].base = cpu_to_le32(new_dma_addr_list[new]); - new_rx_ring[new].buf_length = cpu_to_le16(NEG_BUF_SIZE); + new_rx_ring[new].buf_length = cpu_to_le16(2 - PKT_BUF_SZ); new_rx_ring[new].status = cpu_to_le16(0x8000); } /* and free any unneeded buffers */ for (; new < lp->rx_ring_size; new++) { if (lp->rx_skbuff[new]) { pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[new], - PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); dev_kfree_skb(lp->rx_skbuff[new]); } } @@ -655,7 +651,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, for (; --new >= lp->rx_ring_size; ) { if (new_skb_list[new]) { pci_unmap_single(lp->pci_dev, new_dma_addr_list[new], - PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); dev_kfree_skb(new_skb_list[new]); } } @@ -682,7 +678,7 @@ static void pcnet32_purge_rx_ring(struct net_device *dev) wmb(); /* Make sure adapter sees owner change */ if (lp->rx_skbuff[i]) { pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], - PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); dev_kfree_skb_any(lp->rx_skbuff[i]); } lp->rx_skbuff[i] = NULL; @@ -1205,7 +1201,7 @@ static void pcnet32_rx_entry(struct net_device *dev, pkt_len = (le32_to_cpu(rxp->msg_length) & 0xfff) - 4; /* Discard oversize frames. */ - if (unlikely(pkt_len > PKT_BUF_SIZE)) { + if (unlikely(pkt_len > PKT_BUF_SZ - 2)) { if (netif_msg_drv(lp)) printk(KERN_ERR "%s: Impossible packet size %d!\n", dev->name, pkt_len); @@ -1222,26 +1218,26 @@ static void pcnet32_rx_entry(struct net_device *dev, if (pkt_len > rx_copybreak) { struct sk_buff *newskb; - if ((newskb = dev_alloc_skb(PKT_BUF_SKB))) { - skb_reserve(newskb, NET_IP_ALIGN); + if ((newskb = dev_alloc_skb(PKT_BUF_SZ))) { + skb_reserve(newskb, 2); skb = lp->rx_skbuff[entry]; pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[entry], - PKT_BUF_SIZE, + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); skb_put(skb, pkt_len); lp->rx_skbuff[entry] = newskb; lp->rx_dma_addr[entry] = pci_map_single(lp->pci_dev, newskb->data, - PKT_BUF_SIZE, + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); rxp->base = cpu_to_le32(lp->rx_dma_addr[entry]); rx_in_place = 1; } else skb = NULL; } else { - skb = dev_alloc_skb(pkt_len + NET_IP_ALIGN); + skb = dev_alloc_skb(pkt_len + 2); } if (skb == NULL) { @@ -1254,7 +1250,7 @@ static void pcnet32_rx_entry(struct net_device *dev, } skb->dev = dev; if (!rx_in_place) { - skb_reserve(skb, NET_IP_ALIGN); + skb_reserve(skb, 2); /* 16 byte align */ skb_put(skb, pkt_len); /* Make room */ pci_dma_sync_single_for_cpu(lp->pci_dev, lp->rx_dma_addr[entry], @@ -1295,7 +1291,7 @@ static int pcnet32_rx(struct net_device *dev, int budget) * The docs say that the buffer length isn't touched, but Andrew * Boyd of QNX reports that some revs of the 79C965 clear it. */ - rxp->buf_length = cpu_to_le16(NEG_BUF_SIZE); + rxp->buf_length = cpu_to_le16(2 - PKT_BUF_SZ); wmb(); /* Make sure owner changes after others are visible */ rxp->status = cpu_to_le16(0x8000); entry = (++lp->cur_rx) & lp->rx_mod_mask; @@ -1778,8 +1774,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) memset(dev->dev_addr, 0, sizeof(dev->dev_addr)); if (pcnet32_debug & NETIF_MSG_PROBE) { - DECLARE_MAC_BUF(mac); - printk(" %s", print_mac(mac, dev->dev_addr)); + for (i = 0; i < 6; i++) + printk(" %2.2x", dev->dev_addr[i]); /* Version 0x2623 and 0x2624 */ if (((chip_version + 1) & 0xfffe) == 0x2624) { @@ -2400,7 +2396,7 @@ static int pcnet32_init_ring(struct net_device *dev) if (rx_skbuff == NULL) { if (! (rx_skbuff = lp->rx_skbuff[i] = - dev_alloc_skb(PKT_BUF_SKB))) { + dev_alloc_skb(PKT_BUF_SZ))) { /* there is not much, we can do at this point */ if (netif_msg_drv(lp)) printk(KERN_ERR @@ -2408,16 +2404,16 @@ static int pcnet32_init_ring(struct net_device *dev) dev->name); return -1; } - skb_reserve(rx_skbuff, NET_IP_ALIGN); + skb_reserve(rx_skbuff, 2); } rmb(); if (lp->rx_dma_addr[i] == 0) lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data, - PKT_BUF_SIZE, PCI_DMA_FROMDEVICE); + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE); lp->rx_ring[i].base = cpu_to_le32(lp->rx_dma_addr[i]); - lp->rx_ring[i].buf_length = cpu_to_le16(NEG_BUF_SIZE); + lp->rx_ring[i].buf_length = cpu_to_le16(2 - PKT_BUF_SZ); wmb(); /* Make sure owner changes after all others are visible */ lp->rx_ring[i].status = cpu_to_le16(0x8000); } diff --git a/trunk/drivers/net/phy/fixed.c b/trunk/drivers/net/phy/fixed.c index ca9b040f9ad9..73b6d39ef6b0 100644 --- a/trunk/drivers/net/phy/fixed.c +++ b/trunk/drivers/net/phy/fixed.c @@ -236,12 +236,12 @@ module_init(fixed_mdio_bus_init); static void __exit fixed_mdio_bus_exit(void) { struct fixed_mdio_bus *fmb = &platform_fmb; - struct fixed_phy *fp, *tmp; + struct fixed_phy *fp; mdiobus_unregister(&fmb->mii_bus); platform_device_unregister(pdev); - list_for_each_entry_safe(fp, tmp, &fmb->phys, node) { + list_for_each_entry(fp, &fmb->phys, node) { list_del(&fp->node); kfree(fp); } diff --git a/trunk/drivers/net/ps3_gelic_net.c b/trunk/drivers/net/ps3_gelic_net.c index 7eb6e7e848f4..055af081e027 100644 --- a/trunk/drivers/net/ps3_gelic_net.c +++ b/trunk/drivers/net/ps3_gelic_net.c @@ -46,25 +46,29 @@ #include #include "ps3_gelic_net.h" -#include "ps3_gelic_wireless.h" #define DRV_NAME "Gelic Network Driver" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.0" MODULE_AUTHOR("SCE Inc."); MODULE_DESCRIPTION("Gelic Network driver"); MODULE_LICENSE("GPL"); - -static inline void gelic_card_enable_rxdmac(struct gelic_card *card); -static inline void gelic_card_disable_rxdmac(struct gelic_card *card); -static inline void gelic_card_disable_txdmac(struct gelic_card *card); -static inline void gelic_card_reset_chain(struct gelic_card *card, - struct gelic_descr_chain *chain, - struct gelic_descr *start_descr); +static inline struct device *ctodev(struct gelic_net_card *card) +{ + return &card->dev->core; +} +static inline u64 bus_id(struct gelic_net_card *card) +{ + return card->dev->bus_id; +} +static inline u64 dev_id(struct gelic_net_card *card) +{ + return card->dev->dev_id; +} /* set irq_mask */ -int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask) +static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask) { int status; @@ -72,110 +76,54 @@ int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask) mask, 0); if (status) dev_info(ctodev(card), - "%s failed %d\n", __func__, status); + "lv1_net_set_interrupt_mask failed %d\n", status); return status; } - -static inline void gelic_card_rx_irq_on(struct gelic_card *card) +static inline void gelic_net_rx_irq_on(struct gelic_net_card *card) { - card->irq_mask |= GELIC_CARD_RXINT; - gelic_card_set_irq_mask(card, card->irq_mask); + gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT); } -static inline void gelic_card_rx_irq_off(struct gelic_card *card) +static inline void gelic_net_rx_irq_off(struct gelic_net_card *card) { - card->irq_mask &= ~GELIC_CARD_RXINT; - gelic_card_set_irq_mask(card, card->irq_mask); -} - -static void gelic_card_get_ether_port_status(struct gelic_card *card, - int inform) -{ - u64 v2; - struct net_device *ether_netdev; - - lv1_net_control(bus_id(card), dev_id(card), - GELIC_LV1_GET_ETH_PORT_STATUS, - GELIC_LV1_VLAN_TX_ETHERNET, 0, 0, - &card->ether_port_status, &v2); - - if (inform) { - ether_netdev = card->netdev[GELIC_PORT_ETHERNET]; - if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP) - netif_carrier_on(ether_netdev); - else - netif_carrier_off(ether_netdev); - } -} - -void gelic_card_up(struct gelic_card *card) -{ - pr_debug("%s: called\n", __func__); - down(&card->updown_lock); - if (atomic_inc_return(&card->users) == 1) { - pr_debug("%s: real do\n", __func__); - /* enable irq */ - gelic_card_set_irq_mask(card, card->irq_mask); - /* start rx */ - gelic_card_enable_rxdmac(card); - - napi_enable(&card->napi); - } - up(&card->updown_lock); - pr_debug("%s: done\n", __func__); + gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT); } - -void gelic_card_down(struct gelic_card *card) -{ - u64 mask; - pr_debug("%s: called\n", __func__); - down(&card->updown_lock); - if (atomic_dec_if_positive(&card->users) == 0) { - pr_debug("%s: real do\n", __func__); - napi_disable(&card->napi); - /* - * Disable irq. Wireless interrupts will - * be disabled later if any - */ - mask = card->irq_mask & (GELIC_CARD_WLAN_EVENT_RECEIVED | - GELIC_CARD_WLAN_COMMAND_COMPLETED); - gelic_card_set_irq_mask(card, mask); - /* stop rx */ - gelic_card_disable_rxdmac(card); - gelic_card_reset_chain(card, &card->rx_chain, - card->descr + GELIC_NET_TX_DESCRIPTORS); - /* stop tx */ - gelic_card_disable_txdmac(card); - } - up(&card->updown_lock); - pr_debug("%s: done\n", __func__); -} - /** - * gelic_descr_get_status -- returns the status of a descriptor + * gelic_net_get_descr_status -- returns the status of a descriptor * @descr: descriptor to look at * * returns the status as in the dmac_cmd_status field of the descriptor */ -static enum gelic_descr_dma_status -gelic_descr_get_status(struct gelic_descr *descr) +static enum gelic_net_descr_status +gelic_net_get_descr_status(struct gelic_net_descr *descr) { - return be32_to_cpu(descr->dmac_cmd_status) & GELIC_DESCR_DMA_STAT_MASK; + u32 cmd_status; + + cmd_status = descr->dmac_cmd_status; + cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT; + return cmd_status; } /** - * gelic_descr_set_status -- sets the status of a descriptor + * gelic_net_set_descr_status -- sets the status of a descriptor * @descr: descriptor to change * @status: status to set in the descriptor * * changes the status to the specified value. Doesn't change other bits * in the status */ -static void gelic_descr_set_status(struct gelic_descr *descr, - enum gelic_descr_dma_status status) +static void gelic_net_set_descr_status(struct gelic_net_descr *descr, + enum gelic_net_descr_status status) { - descr->dmac_cmd_status = cpu_to_be32(status | - (be32_to_cpu(descr->dmac_cmd_status) & - ~GELIC_DESCR_DMA_STAT_MASK)); + u32 cmd_status; + + /* read the status */ + cmd_status = descr->dmac_cmd_status; + /* clean the upper 4 bits */ + cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO; + /* add the status to it */ + cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT; + /* and write it back */ + descr->dmac_cmd_status = cmd_status; /* * dma_cmd_status field is used to indicate whether the descriptor * is valid or not. @@ -186,24 +134,24 @@ static void gelic_descr_set_status(struct gelic_descr *descr, } /** - * gelic_card_free_chain - free descriptor chain + * gelic_net_free_chain - free descriptor chain * @card: card structure * @descr_in: address of desc */ -static void gelic_card_free_chain(struct gelic_card *card, - struct gelic_descr *descr_in) +static void gelic_net_free_chain(struct gelic_net_card *card, + struct gelic_net_descr *descr_in) { - struct gelic_descr *descr; + struct gelic_net_descr *descr; for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) { dma_unmap_single(ctodev(card), descr->bus_addr, - GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL); + GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL); descr->bus_addr = 0; } } /** - * gelic_card_init_chain - links descriptor chain + * gelic_net_init_chain - links descriptor chain * @card: card structure * @chain: address of chain * @start_descr: address of descriptor array @@ -214,22 +162,22 @@ static void gelic_card_free_chain(struct gelic_card *card, * * returns 0 on success, <0 on failure */ -static int gelic_card_init_chain(struct gelic_card *card, - struct gelic_descr_chain *chain, - struct gelic_descr *start_descr, int no) +static int gelic_net_init_chain(struct gelic_net_card *card, + struct gelic_net_descr_chain *chain, + struct gelic_net_descr *start_descr, int no) { int i; - struct gelic_descr *descr; + struct gelic_net_descr *descr; descr = start_descr; memset(descr, 0, sizeof(*descr) * no); /* set up the hardware pointers in each descriptor */ for (i = 0; i < no; i++, descr++) { - gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE); + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); descr->bus_addr = dma_map_single(ctodev(card), descr, - GELIC_DESCR_SIZE, + GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL); if (!descr->bus_addr) @@ -245,7 +193,7 @@ static int gelic_card_init_chain(struct gelic_card *card, /* chain bus addr of hw descriptor */ descr = start_descr; for (i = 0; i < no; i++, descr++) { - descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr); + descr->next_descr_addr = descr->next->bus_addr; } chain->head = start_descr; @@ -260,38 +208,13 @@ static int gelic_card_init_chain(struct gelic_card *card, for (i--, descr--; 0 <= i; i--, descr--) if (descr->bus_addr) dma_unmap_single(ctodev(card), descr->bus_addr, - GELIC_DESCR_SIZE, + GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL); return -ENOMEM; } /** - * gelic_card_reset_chain - reset status of a descriptor chain - * @card: card structure - * @chain: address of chain - * @start_descr: address of descriptor array - * - * Reset the status of dma descriptors to ready state - * and re-initialize the hardware chain for later use - */ -static void gelic_card_reset_chain(struct gelic_card *card, - struct gelic_descr_chain *chain, - struct gelic_descr *start_descr) -{ - struct gelic_descr *descr; - - for (descr = start_descr; start_descr != descr->next; descr++) { - gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED); - descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr); - } - - chain->head = start_descr; - chain->tail = (descr - 1); - - (descr - 1)->next_descr_addr = 0; -} -/** - * gelic_descr_prepare_rx - reinitializes a rx descriptor + * gelic_net_prepare_rx_descr - reinitializes a rx descriptor * @card: card structure * @descr: descriptor to re-init * @@ -300,27 +223,29 @@ static void gelic_card_reset_chain(struct gelic_card *card, * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. * Activate the descriptor state-wise */ -static int gelic_descr_prepare_rx(struct gelic_card *card, - struct gelic_descr *descr) +static int gelic_net_prepare_rx_descr(struct gelic_net_card *card, + struct gelic_net_descr *descr) { int offset; unsigned int bufsize; - if (gelic_descr_get_status(descr) != GELIC_DESCR_DMA_NOT_IN_USE) + if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) { dev_info(ctodev(card), "%s: ERROR status \n", __func__); + } /* we need to round up the buffer size to a multiple of 128 */ bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN); /* and we need to have it 128 byte aligned, therefore we allocate a * bit more */ - descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1); + descr->skb = netdev_alloc_skb(card->netdev, + bufsize + GELIC_NET_RXBUF_ALIGN - 1); if (!descr->skb) { descr->buf_addr = 0; /* tell DMAC don't touch memory */ dev_info(ctodev(card), "%s:allocate skb failed !!\n", __func__); return -ENOMEM; } - descr->buf_size = cpu_to_be32(bufsize); + descr->buf_size = bufsize; descr->dmac_cmd_status = 0; descr->result_size = 0; descr->valid_size = 0; @@ -331,64 +256,63 @@ static int gelic_descr_prepare_rx(struct gelic_card *card, if (offset) skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset); /* io-mmu-map the skb */ - descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card), - descr->skb->data, - GELIC_NET_MAX_MTU, - DMA_FROM_DEVICE)); + descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data, + GELIC_NET_MAX_MTU, + DMA_FROM_DEVICE); if (!descr->buf_addr) { dev_kfree_skb_any(descr->skb); descr->skb = NULL; dev_info(ctodev(card), "%s:Could not iommu-map rx buffer\n", __func__); - gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE); + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); return -ENOMEM; } else { - gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED); + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED); return 0; } } /** - * gelic_card_release_rx_chain - free all skb of rx descr + * gelic_net_release_rx_chain - free all skb of rx descr * @card: card structure * */ -static void gelic_card_release_rx_chain(struct gelic_card *card) +static void gelic_net_release_rx_chain(struct gelic_net_card *card) { - struct gelic_descr *descr = card->rx_chain.head; + struct gelic_net_descr *descr = card->rx_chain.head; do { if (descr->skb) { dma_unmap_single(ctodev(card), - be32_to_cpu(descr->buf_addr), + descr->buf_addr, descr->skb->len, DMA_FROM_DEVICE); descr->buf_addr = 0; dev_kfree_skb_any(descr->skb); descr->skb = NULL; - gelic_descr_set_status(descr, - GELIC_DESCR_DMA_NOT_IN_USE); + gelic_net_set_descr_status(descr, + GELIC_NET_DESCR_NOT_IN_USE); } descr = descr->next; } while (descr != card->rx_chain.head); } /** - * gelic_card_fill_rx_chain - fills descriptors/skbs in the rx chains + * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains * @card: card structure * * fills all descriptors in the rx chain: allocates skbs * and iommu-maps them. - * returns 0 on success, < 0 on failure + * returns 0 on success, <0 on failure */ -static int gelic_card_fill_rx_chain(struct gelic_card *card) +static int gelic_net_fill_rx_chain(struct gelic_net_card *card) { - struct gelic_descr *descr = card->rx_chain.head; + struct gelic_net_descr *descr = card->rx_chain.head; int ret; do { if (!descr->skb) { - ret = gelic_descr_prepare_rx(card, descr); + ret = gelic_net_prepare_rx_descr(card, descr); if (ret) goto rewind; } @@ -397,41 +321,41 @@ static int gelic_card_fill_rx_chain(struct gelic_card *card) return 0; rewind: - gelic_card_release_rx_chain(card); + gelic_net_release_rx_chain(card); return ret; } /** - * gelic_card_alloc_rx_skbs - allocates rx skbs in rx descriptor chains + * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains * @card: card structure * - * returns 0 on success, < 0 on failure + * returns 0 on success, <0 on failure */ -static int gelic_card_alloc_rx_skbs(struct gelic_card *card) +static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card) { - struct gelic_descr_chain *chain; + struct gelic_net_descr_chain *chain; int ret; chain = &card->rx_chain; - ret = gelic_card_fill_rx_chain(card); - chain->tail = card->rx_top->prev; /* point to the last */ + ret = gelic_net_fill_rx_chain(card); + chain->head = card->rx_top->prev; /* point to the last */ return ret; } /** - * gelic_descr_release_tx - processes a used tx descriptor + * gelic_net_release_tx_descr - processes a used tx descriptor * @card: card structure * @descr: descriptor to release * * releases a used tx descriptor (unmapping, freeing of skb) */ -static void gelic_descr_release_tx(struct gelic_card *card, - struct gelic_descr *descr) +static void gelic_net_release_tx_descr(struct gelic_net_card *card, + struct gelic_net_descr *descr) { struct sk_buff *skb = descr->skb; - BUG_ON(!(be32_to_cpu(descr->data_status) & GELIC_DESCR_TX_TAIL)); + BUG_ON(!(descr->data_status & (1 << GELIC_NET_TXDESC_TAIL))); - dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr), skb->len, + dma_unmap_single(ctodev(card), descr->buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); @@ -445,75 +369,59 @@ static void gelic_descr_release_tx(struct gelic_card *card, descr->skb = NULL; /* set descr status */ - gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE); -} - -static void gelic_card_stop_queues(struct gelic_card *card) -{ - netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET]); - - if (card->netdev[GELIC_PORT_WIRELESS]) - netif_stop_queue(card->netdev[GELIC_PORT_WIRELESS]); + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); } -static void gelic_card_wake_queues(struct gelic_card *card) -{ - netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET]); - if (card->netdev[GELIC_PORT_WIRELESS]) - netif_wake_queue(card->netdev[GELIC_PORT_WIRELESS]); -} /** - * gelic_card_release_tx_chain - processes sent tx descriptors + * gelic_net_release_tx_chain - processes sent tx descriptors * @card: adapter structure * @stop: net_stop sequence * * releases the tx descriptors that gelic has finished with */ -static void gelic_card_release_tx_chain(struct gelic_card *card, int stop) +static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop) { - struct gelic_descr_chain *tx_chain; - enum gelic_descr_dma_status status; - struct net_device *netdev; + struct gelic_net_descr_chain *tx_chain; + enum gelic_net_descr_status status; int release = 0; for (tx_chain = &card->tx_chain; tx_chain->head != tx_chain->tail && tx_chain->tail; tx_chain->tail = tx_chain->tail->next) { - status = gelic_descr_get_status(tx_chain->tail); - netdev = tx_chain->tail->skb->dev; + status = gelic_net_get_descr_status(tx_chain->tail); switch (status) { - case GELIC_DESCR_DMA_RESPONSE_ERROR: - case GELIC_DESCR_DMA_PROTECTION_ERROR: - case GELIC_DESCR_DMA_FORCE_END: + case GELIC_NET_DESCR_RESPONSE_ERROR: + case GELIC_NET_DESCR_PROTECTION_ERROR: + case GELIC_NET_DESCR_FORCE_END: if (printk_ratelimit()) dev_info(ctodev(card), "%s: forcing end of tx descriptor " \ "with status %x\n", __func__, status); - netdev->stats.tx_dropped++; + card->netdev->stats.tx_dropped++; break; - case GELIC_DESCR_DMA_COMPLETE: + case GELIC_NET_DESCR_COMPLETE: if (tx_chain->tail->skb) { - netdev->stats.tx_packets++; - netdev->stats.tx_bytes += + card->netdev->stats.tx_packets++; + card->netdev->stats.tx_bytes += tx_chain->tail->skb->len; } break; - case GELIC_DESCR_DMA_CARDOWNED: + case GELIC_NET_DESCR_CARDOWNED: /* pending tx request */ default: - /* any other value (== GELIC_DESCR_DMA_NOT_IN_USE) */ + /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */ if (!stop) goto out; } - gelic_descr_release_tx(card, tx_chain->tail); + gelic_net_release_tx_descr(card, tx_chain->tail); release ++; } out: if (!stop && release) - gelic_card_wake_queues(card); + netif_wake_queue(card->netdev); } /** @@ -524,9 +432,9 @@ static void gelic_card_release_tx_chain(struct gelic_card *card, int stop) * netdev interface. It also sets up multicast, allmulti and promisc * flags appropriately */ -void gelic_net_set_multi(struct net_device *netdev) +static void gelic_net_set_multi(struct net_device *netdev) { - struct gelic_card *card = netdev_card(netdev); + struct gelic_net_card *card = netdev_priv(netdev); struct dev_mc_list *mc; unsigned int i; uint8_t *p; @@ -548,8 +456,8 @@ void gelic_net_set_multi(struct net_device *netdev) "lv1_net_add_multicast_address failed, %d\n", status); - if ((netdev->flags & IFF_ALLMULTI) || - (netdev->mc_count > GELIC_NET_MC_COUNT_MAX)) { + if (netdev->flags & IFF_ALLMULTI + || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */ status = lv1_net_add_multicast_address(bus_id(card), dev_id(card), 0, 1); @@ -560,7 +468,7 @@ void gelic_net_set_multi(struct net_device *netdev) return; } - /* set multicast addresses */ + /* set multicast address */ for (mc = netdev->mc_list; mc; mc = mc->next) { addr = 0; p = mc->dmi_addr; @@ -579,42 +487,31 @@ void gelic_net_set_multi(struct net_device *netdev) } /** - * gelic_card_enable_rxdmac - enables the receive DMA controller + * gelic_net_enable_rxdmac - enables the receive DMA controller * @card: card structure * - * gelic_card_enable_rxdmac enables the DMA controller by setting RX_DMA_EN + * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN * in the GDADMACCNTR register */ -static inline void gelic_card_enable_rxdmac(struct gelic_card *card) +static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card) { int status; -#ifdef DEBUG - if (gelic_descr_get_status(card->rx_chain.head) != - GELIC_DESCR_DMA_CARDOWNED) { - printk(KERN_ERR "%s: status=%x\n", __func__, - be32_to_cpu(card->rx_chain.head->dmac_cmd_status)); - printk(KERN_ERR "%s: nextphy=%x\n", __func__, - be32_to_cpu(card->rx_chain.head->next_descr_addr)); - printk(KERN_ERR "%s: head=%p\n", __func__, - card->rx_chain.head); - } -#endif status = lv1_net_start_rx_dma(bus_id(card), dev_id(card), - card->rx_chain.head->bus_addr, 0); + card->rx_chain.tail->bus_addr, 0); if (status) dev_info(ctodev(card), "lv1_net_start_rx_dma failed, status=%d\n", status); } /** - * gelic_card_disable_rxdmac - disables the receive DMA controller + * gelic_net_disable_rxdmac - disables the receive DMA controller * @card: card structure * - * gelic_card_disable_rxdmac terminates processing on the DMA controller by + * gelic_net_disable_rxdmac terminates processing on the DMA controller by * turing off DMA and issueing a force end */ -static inline void gelic_card_disable_rxdmac(struct gelic_card *card) +static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card) { int status; @@ -626,13 +523,13 @@ static inline void gelic_card_disable_rxdmac(struct gelic_card *card) } /** - * gelic_card_disable_txdmac - disables the transmit DMA controller + * gelic_net_disable_txdmac - disables the transmit DMA controller * @card: card structure * - * gelic_card_disable_txdmac terminates processing on the DMA controller by + * gelic_net_disable_txdmac terminates processing on the DMA controller by * turing off DMA and issueing a force end */ -static inline void gelic_card_disable_txdmac(struct gelic_card *card) +static inline void gelic_net_disable_txdmac(struct gelic_net_card *card) { int status; @@ -649,37 +546,51 @@ static inline void gelic_card_disable_txdmac(struct gelic_card *card) * * always returns 0 */ -int gelic_net_stop(struct net_device *netdev) +static int gelic_net_stop(struct net_device *netdev) { - struct gelic_card *card; - - pr_debug("%s: start\n", __func__); + struct gelic_net_card *card = netdev_priv(netdev); + napi_disable(&card->napi); netif_stop_queue(netdev); + + /* turn off DMA, force end */ + gelic_net_disable_rxdmac(card); + gelic_net_disable_txdmac(card); + + gelic_net_set_irq_mask(card, 0); + + /* disconnect event port */ + free_irq(card->netdev->irq, card->netdev); + ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq); + card->netdev->irq = NO_IRQ; + netif_carrier_off(netdev); - card = netdev_card(netdev); - gelic_card_down(card); + /* release chains */ + gelic_net_release_tx_chain(card, 1); + gelic_net_release_rx_chain(card); + + gelic_net_free_chain(card, card->tx_top); + gelic_net_free_chain(card, card->rx_top); - pr_debug("%s: done\n", __func__); return 0; } /** - * gelic_card_get_next_tx_descr - returns the next available tx descriptor + * gelic_net_get_next_tx_descr - returns the next available tx descriptor * @card: device structure to get descriptor from * * returns the address of the next descriptor, or NULL if not available. */ -static struct gelic_descr * -gelic_card_get_next_tx_descr(struct gelic_card *card) +static struct gelic_net_descr * +gelic_net_get_next_tx_descr(struct gelic_net_card *card) { if (!card->tx_chain.head) return NULL; /* see if the next descriptor is free */ if (card->tx_chain.tail != card->tx_chain.head->next && - gelic_descr_get_status(card->tx_chain.head) == - GELIC_DESCR_DMA_NOT_IN_USE) + gelic_net_get_descr_status(card->tx_chain.head) == + GELIC_NET_DESCR_NOT_IN_USE) return card->tx_chain.head; else return NULL; @@ -695,33 +606,32 @@ gelic_card_get_next_tx_descr(struct gelic_card *card) * depending on hardware checksum settings. This function assumes a wmb() * has executed before. */ -static void gelic_descr_set_tx_cmdstat(struct gelic_descr *descr, - struct sk_buff *skb) +static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr, + struct sk_buff *skb) { if (skb->ip_summed != CHECKSUM_PARTIAL) - descr->dmac_cmd_status = - cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM | - GELIC_DESCR_TX_DMA_FRAME_TAIL); + descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | + GELIC_NET_DMAC_CMDSTAT_END_FRAME; else { /* is packet ip? * if yes: tcp? udp? */ if (skb->protocol == htons(ETH_P_IP)) { if (ip_hdr(skb)->protocol == IPPROTO_TCP) descr->dmac_cmd_status = - cpu_to_be32(GELIC_DESCR_DMA_CMD_TCP_CHKSUM | - GELIC_DESCR_TX_DMA_FRAME_TAIL); + GELIC_NET_DMAC_CMDSTAT_TCPCS | + GELIC_NET_DMAC_CMDSTAT_END_FRAME; else if (ip_hdr(skb)->protocol == IPPROTO_UDP) descr->dmac_cmd_status = - cpu_to_be32(GELIC_DESCR_DMA_CMD_UDP_CHKSUM | - GELIC_DESCR_TX_DMA_FRAME_TAIL); + GELIC_NET_DMAC_CMDSTAT_UDPCS | + GELIC_NET_DMAC_CMDSTAT_END_FRAME; else /* * the stack should checksum non-tcp and non-udp * packets on his own: NETIF_F_IP_CSUM */ descr->dmac_cmd_status = - cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM | - GELIC_DESCR_TX_DMA_FRAME_TAIL); + GELIC_NET_DMAC_CMDSTAT_NOCS | + GELIC_NET_DMAC_CMDSTAT_END_FRAME; } } } @@ -752,7 +662,7 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb, } /** - * gelic_descr_prepare_tx - setup a descriptor for sending packets + * gelic_net_prepare_tx_descr_v - get dma address of skb_data * @card: card structure * @descr: descriptor structure * @skb: packet to use @@ -760,19 +670,16 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb, * returns 0 on success, <0 on failure. * */ -static int gelic_descr_prepare_tx(struct gelic_card *card, - struct gelic_descr *descr, - struct sk_buff *skb) +static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card, + struct gelic_net_descr *descr, + struct sk_buff *skb) { dma_addr_t buf; - if (card->vlan_required) { + if (card->vlan_index != -1) { struct sk_buff *skb_tmp; - enum gelic_port_type type; - - type = netdev_port(skb->dev)->type; skb_tmp = gelic_put_vlan_tag(skb, - card->vlan[type].tx); + card->vlan_id[card->vlan_index]); if (!skb_tmp) return -ENOMEM; skb = skb_tmp; @@ -787,12 +694,12 @@ static int gelic_descr_prepare_tx(struct gelic_card *card, return -ENOMEM; } - descr->buf_addr = cpu_to_be32(buf); - descr->buf_size = cpu_to_be32(skb->len); + descr->buf_addr = buf; + descr->buf_size = skb->len; descr->skb = skb; descr->data_status = 0; descr->next_descr_addr = 0; /* terminate hw descr */ - gelic_descr_set_tx_cmdstat(descr, skb); + gelic_net_set_txdescr_cmdstat(descr, skb); /* bump free descriptor pointer */ card->tx_chain.head = descr->next; @@ -800,20 +707,20 @@ static int gelic_descr_prepare_tx(struct gelic_card *card, } /** - * gelic_card_kick_txdma - enables TX DMA processing + * gelic_net_kick_txdma - enables TX DMA processing * @card: card structure * @descr: descriptor address to enable TX processing at * */ -static int gelic_card_kick_txdma(struct gelic_card *card, - struct gelic_descr *descr) +static int gelic_net_kick_txdma(struct gelic_net_card *card, + struct gelic_net_descr *descr) { int status = 0; if (card->tx_dma_progress) return 0; - if (gelic_descr_get_status(descr) == GELIC_DESCR_DMA_CARDOWNED) { + if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) { card->tx_dma_progress = 1; status = lv1_net_start_tx_dma(bus_id(card), dev_id(card), descr->bus_addr, 0); @@ -831,56 +738,56 @@ static int gelic_card_kick_txdma(struct gelic_card *card, * * returns 0 on success, <0 on failure */ -int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) +static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) { - struct gelic_card *card = netdev_card(netdev); - struct gelic_descr *descr; + struct gelic_net_card *card = netdev_priv(netdev); + struct gelic_net_descr *descr; int result; unsigned long flags; - spin_lock_irqsave(&card->tx_lock, flags); + spin_lock_irqsave(&card->tx_dma_lock, flags); - gelic_card_release_tx_chain(card, 0); + gelic_net_release_tx_chain(card, 0); - descr = gelic_card_get_next_tx_descr(card); + descr = gelic_net_get_next_tx_descr(card); if (!descr) { /* * no more descriptors free */ - gelic_card_stop_queues(card); - spin_unlock_irqrestore(&card->tx_lock, flags); + netif_stop_queue(netdev); + spin_unlock_irqrestore(&card->tx_dma_lock, flags); return NETDEV_TX_BUSY; } - result = gelic_descr_prepare_tx(card, descr, skb); + result = gelic_net_prepare_tx_descr_v(card, descr, skb); if (result) { /* * DMA map failed. As chanses are that failure * would continue, just release skb and return */ - netdev->stats.tx_dropped++; + card->netdev->stats.tx_dropped++; dev_kfree_skb_any(skb); - spin_unlock_irqrestore(&card->tx_lock, flags); + spin_unlock_irqrestore(&card->tx_dma_lock, flags); return NETDEV_TX_OK; } /* * link this prepared descriptor to previous one * to achieve high performance */ - descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr); + descr->prev->next_descr_addr = descr->bus_addr; /* * as hardware descriptor is modified in the above lines, * ensure that the hardware sees it */ wmb(); - if (gelic_card_kick_txdma(card, descr)) { + if (gelic_net_kick_txdma(card, descr)) { /* * kick failed. * release descriptors which were just prepared */ - netdev->stats.tx_dropped++; - gelic_descr_release_tx(card, descr); - gelic_descr_release_tx(card, descr->next); + card->netdev->stats.tx_dropped++; + gelic_net_release_tx_descr(card, descr); + gelic_net_release_tx_descr(card, descr->next); card->tx_chain.tail = descr->next->next; dev_info(ctodev(card), "%s: kick failure\n", __func__); } else { @@ -888,7 +795,7 @@ int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) netdev->trans_start = jiffies; } - spin_unlock_irqrestore(&card->tx_lock, flags); + spin_unlock_irqrestore(&card->tx_dma_lock, flags); return NETDEV_TX_OK; } @@ -896,34 +803,30 @@ int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev) * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on * @descr: descriptor to process * @card: card structure - * @netdev: net_device structure to be passed packet * * iommu-unmaps the skb, fills out skb structure and passes the data to the * stack. The descriptor state is not changed. */ -static void gelic_net_pass_skb_up(struct gelic_descr *descr, - struct gelic_card *card, - struct net_device *netdev) - +static void gelic_net_pass_skb_up(struct gelic_net_descr *descr, + struct gelic_net_card *card) { - struct sk_buff *skb = descr->skb; + struct sk_buff *skb; + struct net_device *netdev; u32 data_status, data_error; - data_status = be32_to_cpu(descr->data_status); - data_error = be32_to_cpu(descr->data_error); + data_status = descr->data_status; + data_error = descr->data_error; + netdev = card->netdev; /* unmap skb buffer */ - dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr), - GELIC_NET_MAX_MTU, + skb = descr->skb; + dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU, DMA_FROM_DEVICE); - skb_put(skb, be32_to_cpu(descr->valid_size)? - be32_to_cpu(descr->valid_size) : - be32_to_cpu(descr->result_size)); + skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size); if (!descr->valid_size) dev_info(ctodev(card), "buffer full %x %x %x\n", - be32_to_cpu(descr->result_size), - be32_to_cpu(descr->buf_size), - be32_to_cpu(descr->dmac_cmd_status)); + descr->result_size, descr->buf_size, + descr->dmac_cmd_status); descr->skb = NULL; /* @@ -935,8 +838,8 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, /* checksum offload */ if (card->rx_csum) { - if ((data_status & GELIC_DESCR_DATA_STATUS_CHK_MASK) && - (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK))) + if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) && + (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK))) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb->ip_summed = CHECKSUM_NONE; @@ -944,15 +847,15 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, skb->ip_summed = CHECKSUM_NONE; /* update netdevice statistics */ - netdev->stats.rx_packets++; - netdev->stats.rx_bytes += skb->len; + card->netdev->stats.rx_packets++; + card->netdev->stats.rx_bytes += skb->len; /* pass skb up to stack */ netif_receive_skb(skb); } /** - * gelic_card_decode_one_descr - processes an rx descriptor + * gelic_net_decode_one_descr - processes an rx descriptor * @card: card structure * * returns 1 if a packet has been sent to the stack, otherwise 0 @@ -960,56 +863,36 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, * processes an rx descriptor by iommu-unmapping the data buffer and passing * the packet up to the stack */ -static int gelic_card_decode_one_descr(struct gelic_card *card) +static int gelic_net_decode_one_descr(struct gelic_net_card *card) { - enum gelic_descr_dma_status status; - struct gelic_descr_chain *chain = &card->rx_chain; - struct gelic_descr *descr = chain->head; - struct net_device *netdev = NULL; + enum gelic_net_descr_status status; + struct gelic_net_descr_chain *chain = &card->rx_chain; + struct gelic_net_descr *descr = chain->tail; int dmac_chain_ended; - status = gelic_descr_get_status(descr); + status = gelic_net_get_descr_status(descr); /* is this descriptor terminated with next_descr == NULL? */ dmac_chain_ended = - be32_to_cpu(descr->dmac_cmd_status) & - GELIC_DESCR_RX_DMA_CHAIN_END; + descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS; - if (status == GELIC_DESCR_DMA_CARDOWNED) + if (status == GELIC_NET_DESCR_CARDOWNED) return 0; - if (status == GELIC_DESCR_DMA_NOT_IN_USE) { + if (status == GELIC_NET_DESCR_NOT_IN_USE) { dev_dbg(ctodev(card), "dormant descr? %p\n", descr); return 0; } - /* netdevice select */ - if (card->vlan_required) { - unsigned int i; - u16 vid; - vid = *(u16 *)(descr->skb->data) & VLAN_VID_MASK; - for (i = 0; i < GELIC_PORT_MAX; i++) { - if (card->vlan[i].rx == vid) { - netdev = card->netdev[i]; - break; - } - }; - if (GELIC_PORT_MAX <= i) { - pr_info("%s: unknown packet vid=%x\n", __func__, vid); - goto refill; - } - } else - netdev = card->netdev[GELIC_PORT_ETHERNET]; - - if ((status == GELIC_DESCR_DMA_RESPONSE_ERROR) || - (status == GELIC_DESCR_DMA_PROTECTION_ERROR) || - (status == GELIC_DESCR_DMA_FORCE_END)) { + if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) || + (status == GELIC_NET_DESCR_PROTECTION_ERROR) || + (status == GELIC_NET_DESCR_FORCE_END)) { dev_info(ctodev(card), "dropping RX descriptor with state %x\n", status); - netdev->stats.rx_dropped++; + card->netdev->stats.rx_dropped++; goto refill; } - if (status == GELIC_DESCR_DMA_BUFFER_FULL) { + if (status == GELIC_NET_DESCR_BUFFER_FULL) { /* * Buffer full would occur if and only if * the frame length was longer than the size of this @@ -1026,14 +909,14 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) * descriptoers any other than FRAME_END here should * be treated as error. */ - if (status != GELIC_DESCR_DMA_FRAME_END) { + if (status != GELIC_NET_DESCR_FRAME_END) { dev_dbg(ctodev(card), "RX descriptor with state %x\n", status); goto refill; } /* ok, we've got a packet in descr */ - gelic_net_pass_skb_up(descr, card, netdev); + gelic_net_pass_skb_up(descr, card); refill: /* * So that always DMAC can see the end @@ -1043,21 +926,21 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) descr->next_descr_addr = 0; /* change the descriptor state: */ - gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE); + gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE); /* * this call can fail, but for now, just leave this * decriptor without skb */ - gelic_descr_prepare_rx(card, descr); + gelic_net_prepare_rx_descr(card, descr); - chain->tail = descr; - chain->head = descr->next; + chain->head = descr; + chain->tail = descr->next; /* * Set this descriptor the end of the chain. */ - descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr); + descr->prev->next_descr_addr = descr->bus_addr; /* * If dmac chain was met, DMAC stopped. @@ -1073,27 +956,29 @@ static int gelic_card_decode_one_descr(struct gelic_card *card) /** * gelic_net_poll - NAPI poll function called by the stack to return packets - * @napi: napi structure + * @netdev: interface device structure * @budget: number of packets we can pass to the stack at most * - * returns the number of the processed packets + * returns 0 if no more packets available to the driver/stack. Returns 1, + * if the quota is exceeded, but the driver has still packets. * */ static int gelic_net_poll(struct napi_struct *napi, int budget) { - struct gelic_card *card = container_of(napi, struct gelic_card, napi); + struct gelic_net_card *card = container_of(napi, struct gelic_net_card, napi); + struct net_device *netdev = card->netdev; int packets_done = 0; while (packets_done < budget) { - if (!gelic_card_decode_one_descr(card)) + if (!gelic_net_decode_one_descr(card)) break; packets_done++; } if (packets_done < budget) { - napi_complete(napi); - gelic_card_rx_irq_on(card); + netif_rx_complete(netdev, napi); + gelic_net_rx_irq_on(card); } return packets_done; } @@ -1104,7 +989,7 @@ static int gelic_net_poll(struct napi_struct *napi, int budget) * * returns 0 on success, <0 on failure */ -int gelic_net_change_mtu(struct net_device *netdev, int new_mtu) +static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu) { /* no need to re-alloc skbs or so -- the max mtu is about 2.3k * and mtu is outbound only anyway */ @@ -1117,12 +1002,13 @@ int gelic_net_change_mtu(struct net_device *netdev, int new_mtu) } /** - * gelic_card_interrupt - event handler for gelic_net + * gelic_net_interrupt - event handler for gelic_net */ -static irqreturn_t gelic_card_interrupt(int irq, void *ptr) +static irqreturn_t gelic_net_interrupt(int irq, void *ptr) { unsigned long flags; - struct gelic_card *card = ptr; + struct net_device *netdev = ptr; + struct gelic_net_card *card = netdev_priv(netdev); u64 status; status = card->irq_status; @@ -1130,37 +1016,24 @@ static irqreturn_t gelic_card_interrupt(int irq, void *ptr) if (!status) return IRQ_NONE; - status &= card->irq_mask; - if (card->rx_dma_restart_required) { card->rx_dma_restart_required = 0; - gelic_card_enable_rxdmac(card); + gelic_net_enable_rxdmac(card); } - if (status & GELIC_CARD_RXINT) { - gelic_card_rx_irq_off(card); - napi_schedule(&card->napi); + if (status & GELIC_NET_RXINT) { + gelic_net_rx_irq_off(card); + netif_rx_schedule(netdev, &card->napi); } - if (status & GELIC_CARD_TXINT) { - spin_lock_irqsave(&card->tx_lock, flags); + if (status & GELIC_NET_TXINT) { + spin_lock_irqsave(&card->tx_dma_lock, flags); card->tx_dma_progress = 0; - gelic_card_release_tx_chain(card, 0); + gelic_net_release_tx_chain(card, 0); /* kick outstanding tx descriptor if any */ - gelic_card_kick_txdma(card, card->tx_chain.tail); - spin_unlock_irqrestore(&card->tx_lock, flags); + gelic_net_kick_txdma(card, card->tx_chain.tail); + spin_unlock_irqrestore(&card->tx_dma_lock, flags); } - - /* ether port status changed */ - if (status & GELIC_CARD_PORT_STATUS_CHANGED) - gelic_card_get_ether_port_status(card, 1); - -#ifdef CONFIG_GELIC_WIRELESS - if (status & (GELIC_CARD_WLAN_EVENT_RECEIVED | - GELIC_CARD_WLAN_COMMAND_COMPLETED)) - gelic_wl_interrupt(card->netdev[GELIC_PORT_WIRELESS], status); -#endif - return IRQ_HANDLED; } @@ -1171,16 +1044,54 @@ static irqreturn_t gelic_card_interrupt(int irq, void *ptr) * * see Documentation/networking/netconsole.txt */ -void gelic_net_poll_controller(struct net_device *netdev) +static void gelic_net_poll_controller(struct net_device *netdev) { - struct gelic_card *card = netdev_card(netdev); + struct gelic_net_card *card = netdev_priv(netdev); - gelic_card_set_irq_mask(card, 0); - gelic_card_interrupt(netdev->irq, netdev); - gelic_card_set_irq_mask(card, card->irq_mask); + gelic_net_set_irq_mask(card, 0); + gelic_net_interrupt(netdev->irq, netdev); + gelic_net_set_irq_mask(card, card->ghiintmask); } #endif /* CONFIG_NET_POLL_CONTROLLER */ +/** + * gelic_net_open_device - open device and map dma region + * @card: card structure + */ +static int gelic_net_open_device(struct gelic_net_card *card) +{ + int result; + + result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY, + &card->netdev->irq); + + if (result) { + dev_info(ctodev(card), + "%s:%d: gelic_net_open_device failed (%d)\n", + __func__, __LINE__, result); + result = -EPERM; + goto fail_alloc_irq; + } + + result = request_irq(card->netdev->irq, gelic_net_interrupt, + IRQF_DISABLED, card->netdev->name, card->netdev); + + if (result) { + dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n", + __func__, __LINE__, result); + goto fail_request_irq; + } + + return 0; + +fail_request_irq: + ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq); + card->netdev->irq = NO_IRQ; +fail_alloc_irq: + return result; +} + + /** * gelic_net_open - called upon ifonfig up * @netdev: interface device structure @@ -1190,88 +1101,169 @@ void gelic_net_poll_controller(struct net_device *netdev) * gelic_net_open allocates all the descriptors and memory needed for * operation, sets up multicast list and enables interrupts */ -int gelic_net_open(struct net_device *netdev) +static int gelic_net_open(struct net_device *netdev) { - struct gelic_card *card = netdev_card(netdev); + struct gelic_net_card *card = netdev_priv(netdev); + + dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__); + + gelic_net_open_device(card); + + if (gelic_net_init_chain(card, &card->tx_chain, + card->descr, GELIC_NET_TX_DESCRIPTORS)) + goto alloc_tx_failed; + if (gelic_net_init_chain(card, &card->rx_chain, + card->descr + GELIC_NET_TX_DESCRIPTORS, + GELIC_NET_RX_DESCRIPTORS)) + goto alloc_rx_failed; + + /* head of chain */ + card->tx_top = card->tx_chain.head; + card->rx_top = card->rx_chain.head; + dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n", + card->rx_top, card->tx_top, sizeof(struct gelic_net_descr), + GELIC_NET_RX_DESCRIPTORS); + /* allocate rx skbs */ + if (gelic_net_alloc_rx_skbs(card)) + goto alloc_skbs_failed; - dev_dbg(ctodev(card), " -> %s %p\n", __func__, netdev); + napi_enable(&card->napi); + + card->tx_dma_progress = 0; + card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT; - gelic_card_up(card); + gelic_net_set_irq_mask(card, card->ghiintmask); + gelic_net_enable_rxdmac(card); netif_start_queue(netdev); - gelic_card_get_ether_port_status(card, 1); + netif_carrier_on(netdev); - dev_dbg(ctodev(card), " <- %s\n", __func__); return 0; + +alloc_skbs_failed: + gelic_net_free_chain(card, card->rx_top); +alloc_rx_failed: + gelic_net_free_chain(card, card->tx_top); +alloc_tx_failed: + return -ENOMEM; } -void gelic_net_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *info) +static void gelic_net_get_drvinfo (struct net_device *netdev, + struct ethtool_drvinfo *info) { strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1); strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1); } -static int gelic_ether_get_settings(struct net_device *netdev, - struct ethtool_cmd *cmd) +static int gelic_net_get_settings(struct net_device *netdev, + struct ethtool_cmd *cmd) { - struct gelic_card *card = netdev_card(netdev); + struct gelic_net_card *card = netdev_priv(netdev); + int status; + u64 v1, v2; + int speed, duplex; - gelic_card_get_ether_port_status(card, 0); + speed = duplex = -1; + status = lv1_net_control(bus_id(card), dev_id(card), + GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0, + &v1, &v2); + if (status) { + /* link down */ + } else { + if (v1 & GELIC_NET_FULL_DUPLEX) { + duplex = DUPLEX_FULL; + } else { + duplex = DUPLEX_HALF; + } - if (card->ether_port_status & GELIC_LV1_ETHER_FULL_DUPLEX) - cmd->duplex = DUPLEX_FULL; - else - cmd->duplex = DUPLEX_HALF; - - switch (card->ether_port_status & GELIC_LV1_ETHER_SPEED_MASK) { - case GELIC_LV1_ETHER_SPEED_10: - cmd->speed = SPEED_10; - break; - case GELIC_LV1_ETHER_SPEED_100: - cmd->speed = SPEED_100; - break; - case GELIC_LV1_ETHER_SPEED_1000: - cmd->speed = SPEED_1000; - break; - default: - pr_info("%s: speed unknown\n", __func__); - cmd->speed = SPEED_10; - break; + if (v1 & GELIC_NET_SPEED_10 ) { + speed = SPEED_10; + } else if (v1 & GELIC_NET_SPEED_100) { + speed = SPEED_100; + } else if (v1 & GELIC_NET_SPEED_1000) { + speed = SPEED_1000; + } } - cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; cmd->advertising = cmd->supported; + cmd->speed = speed; + cmd->duplex = duplex; cmd->autoneg = AUTONEG_ENABLE; /* always enabled */ cmd->port = PORT_TP; return 0; } -u32 gelic_net_get_rx_csum(struct net_device *netdev) +static u32 gelic_net_get_link(struct net_device *netdev) { - struct gelic_card *card = netdev_card(netdev); + struct gelic_net_card *card = netdev_priv(netdev); + int status; + u64 v1, v2; + int link; + + status = lv1_net_control(bus_id(card), dev_id(card), + GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0, + &v1, &v2); + if (status) + return 0; /* link down */ + + if (v1 & GELIC_NET_LINK_UP) + link = 1; + else + link = 0; + + return link; +} + +static int gelic_net_nway_reset(struct net_device *netdev) +{ + if (netif_running(netdev)) { + gelic_net_stop(netdev); + gelic_net_open(netdev); + } + return 0; +} + +static u32 gelic_net_get_tx_csum(struct net_device *netdev) +{ + return (netdev->features & NETIF_F_IP_CSUM) != 0; +} + +static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data) +{ + if (data) + netdev->features |= NETIF_F_IP_CSUM; + else + netdev->features &= ~NETIF_F_IP_CSUM; + + return 0; +} + +static u32 gelic_net_get_rx_csum(struct net_device *netdev) +{ + struct gelic_net_card *card = netdev_priv(netdev); return card->rx_csum; } -int gelic_net_set_rx_csum(struct net_device *netdev, u32 data) +static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data) { - struct gelic_card *card = netdev_card(netdev); + struct gelic_net_card *card = netdev_priv(netdev); card->rx_csum = data; return 0; } -static struct ethtool_ops gelic_ether_ethtool_ops = { +static struct ethtool_ops gelic_net_ethtool_ops = { .get_drvinfo = gelic_net_get_drvinfo, - .get_settings = gelic_ether_get_settings, - .get_link = ethtool_op_get_link, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, + .get_settings = gelic_net_get_settings, + .get_link = gelic_net_get_link, + .nway_reset = gelic_net_nway_reset, + .get_tx_csum = gelic_net_get_tx_csum, + .set_tx_csum = gelic_net_set_tx_csum, .get_rx_csum = gelic_net_get_rx_csum, .set_rx_csum = gelic_net_set_rx_csum, }; @@ -1285,9 +1277,9 @@ static struct ethtool_ops gelic_ether_ethtool_ops = { */ static void gelic_net_tx_timeout_task(struct work_struct *work) { - struct gelic_card *card = - container_of(work, struct gelic_card, tx_timeout_task); - struct net_device *netdev = card->netdev[GELIC_PORT_ETHERNET]; + struct gelic_net_card *card = + container_of(work, struct gelic_net_card, tx_timeout_task); + struct net_device *netdev = card->netdev; dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__); @@ -1310,11 +1302,11 @@ static void gelic_net_tx_timeout_task(struct work_struct *work) * * called, if tx hangs. Schedules a task that resets the interface */ -void gelic_net_tx_timeout(struct net_device *netdev) +static void gelic_net_tx_timeout(struct net_device *netdev) { - struct gelic_card *card; + struct gelic_net_card *card; - card = netdev_card(netdev); + card = netdev_priv(netdev); atomic_inc(&card->tx_timeout_task_counter); if (netdev->flags & IFF_UP) schedule_work(&card->tx_timeout_task); @@ -1323,13 +1315,12 @@ void gelic_net_tx_timeout(struct net_device *netdev) } /** - * gelic_ether_setup_netdev_ops - initialization of net_device operations + * gelic_net_setup_netdev_ops - initialization of net_device operations * @netdev: net_device structure * * fills out function pointers in the net_device structure */ -static void gelic_ether_setup_netdev_ops(struct net_device *netdev, - struct napi_struct *napi) +static void gelic_net_setup_netdev_ops(struct net_device *netdev) { netdev->open = &gelic_net_open; netdev->stop = &gelic_net_stop; @@ -1339,239 +1330,163 @@ static void gelic_ether_setup_netdev_ops(struct net_device *netdev, /* tx watchdog */ netdev->tx_timeout = &gelic_net_tx_timeout; netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT; - /* NAPI */ - netif_napi_add(netdev, napi, - gelic_net_poll, GELIC_NET_NAPI_WEIGHT); - netdev->ethtool_ops = &gelic_ether_ethtool_ops; -#ifdef CONFIG_NET_POLL_CONTROLLER - netdev->poll_controller = gelic_net_poll_controller; -#endif + netdev->ethtool_ops = &gelic_net_ethtool_ops; } /** - * gelic_ether_setup_netdev - initialization of net_device - * @netdev: net_device structure + * gelic_net_setup_netdev - initialization of net_device * @card: card structure * * Returns 0 on success or <0 on failure * - * gelic_ether_setup_netdev initializes the net_device structure - * and register it. + * gelic_net_setup_netdev initializes the net_device structure **/ -int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card) +static int gelic_net_setup_netdev(struct gelic_net_card *card) { + struct net_device *netdev = card->netdev; + struct sockaddr addr; + unsigned int i; int status; u64 v1, v2; DECLARE_MAC_BUF(mac); + SET_NETDEV_DEV(netdev, &card->dev->core); + spin_lock_init(&card->tx_dma_lock); + + card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT; + + gelic_net_setup_netdev_ops(netdev); + + netif_napi_add(netdev, &card->napi, + gelic_net_poll, GELIC_NET_NAPI_WEIGHT); + netdev->features = NETIF_F_IP_CSUM; status = lv1_net_control(bus_id(card), dev_id(card), - GELIC_LV1_GET_MAC_ADDRESS, + GELIC_NET_GET_MAC_ADDRESS, 0, 0, 0, &v1, &v2); - v1 <<= 16; if (status || !is_valid_ether_addr((u8 *)&v1)) { dev_info(ctodev(card), "%s:lv1_net_control GET_MAC_ADDR failed %d\n", __func__, status); return -EINVAL; } - memcpy(netdev->dev_addr, &v1, ETH_ALEN); + v1 <<= 16; + memcpy(addr.sa_data, &v1, ETH_ALEN); + memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN); + dev_info(ctodev(card), "MAC addr %s\n", + print_mac(mac, netdev->dev_addr)); - if (card->vlan_required) { + card->vlan_index = -1; /* no vlan */ + for (i = 0; i < GELIC_NET_VLAN_MAX; i++) { + status = lv1_net_control(bus_id(card), dev_id(card), + GELIC_NET_GET_VLAN_ID, + i + 1, /* index; one based */ + 0, 0, &v1, &v2); + if (status == GELIC_NET_VLAN_NO_ENTRY) { + dev_dbg(ctodev(card), + "GELIC_VLAN_ID no entry:%d, VLAN disabled\n", + status); + card->vlan_id[i] = 0; + } else if (status) { + dev_dbg(ctodev(card), + "%s:GELIC_NET_VLAN_ID faild, status=%d\n", + __func__, status); + card->vlan_id[i] = 0; + } else { + card->vlan_id[i] = (u32)v1; + dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1); + } + } + + if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) { + card->vlan_index = GELIC_NET_VLAN_WIRED - 1; netdev->hard_header_len += VLAN_HLEN; - /* - * As vlan is internally used, - * we can not receive vlan packets - */ - netdev->features |= NETIF_F_VLAN_CHALLENGED; } status = register_netdev(netdev); if (status) { - dev_err(ctodev(card), "%s:Couldn't register %s %d\n", - __func__, netdev->name, status); + dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n", + __func__, status); return status; } - dev_info(ctodev(card), "%s: MAC addr %s\n", - netdev->name, - print_mac(mac, netdev->dev_addr)); return 0; } /** - * gelic_alloc_card_net - allocates net_device and card structure + * gelic_net_alloc_card - allocates net_device and card structure * * returns the card structure or NULL in case of errors * * the card and net_device structures are linked to each other */ -#define GELIC_ALIGN (32) -static struct gelic_card *gelic_alloc_card_net(struct net_device **netdev) +static struct gelic_net_card *gelic_net_alloc_card(void) { - struct gelic_card *card; - struct gelic_port *port; - void *p; + struct net_device *netdev; + struct gelic_net_card *card; size_t alloc_size; - /* - * gelic requires dma descriptor is 32 bytes aligned and - * the hypervisor requires irq_status is 8 bytes aligned. - */ - BUILD_BUG_ON(offsetof(struct gelic_card, irq_status) % 8); - BUILD_BUG_ON(offsetof(struct gelic_card, descr) % 32); - alloc_size = - sizeof(struct gelic_card) + - sizeof(struct gelic_descr) * GELIC_NET_RX_DESCRIPTORS + - sizeof(struct gelic_descr) * GELIC_NET_TX_DESCRIPTORS + - GELIC_ALIGN - 1; - - p = kzalloc(alloc_size, GFP_KERNEL); - if (!p) - return NULL; - card = PTR_ALIGN(p, GELIC_ALIGN); - card->unalign = p; + alloc_size = sizeof (*card) + + sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS + + sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS; /* - * alloc netdev + * we assume private data is allocated 32 bytes (or more) aligned + * so that gelic_net_descr should be 32 bytes aligned. + * Current alloc_etherdev() does do it because NETDEV_ALIGN + * is 32. + * check this assumption here. */ - *netdev = alloc_etherdev(sizeof(struct gelic_port)); - if (!netdev) { - kfree(card->unalign); - return NULL; - } - port = netdev_priv(*netdev); + BUILD_BUG_ON(NETDEV_ALIGN < 32); + BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8); + BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32); - /* gelic_port */ - port->netdev = *netdev; - port->card = card; - port->type = GELIC_PORT_ETHERNET; - - /* gelic_card */ - card->netdev[GELIC_PORT_ETHERNET] = *netdev; + netdev = alloc_etherdev(alloc_size); + if (!netdev) + return NULL; + card = netdev_priv(netdev); + card->netdev = netdev; INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task); init_waitqueue_head(&card->waitq); atomic_set(&card->tx_timeout_task_counter, 0); - init_MUTEX(&card->updown_lock); - atomic_set(&card->users, 0); return card; } -static void gelic_card_get_vlan_info(struct gelic_card *card) -{ - u64 v1, v2; - int status; - unsigned int i; - struct { - int tx; - int rx; - } vlan_id_ix[2] = { - [GELIC_PORT_ETHERNET] = { - .tx = GELIC_LV1_VLAN_TX_ETHERNET, - .rx = GELIC_LV1_VLAN_RX_ETHERNET - }, - [GELIC_PORT_WIRELESS] = { - .tx = GELIC_LV1_VLAN_TX_WIRELESS, - .rx = GELIC_LV1_VLAN_RX_WIRELESS - } - }; - - for (i = 0; i < ARRAY_SIZE(vlan_id_ix); i++) { - /* tx tag */ - status = lv1_net_control(bus_id(card), dev_id(card), - GELIC_LV1_GET_VLAN_ID, - vlan_id_ix[i].tx, - 0, 0, &v1, &v2); - if (status || !v1) { - if (status != LV1_NO_ENTRY) - dev_dbg(ctodev(card), - "get vlan id for tx(%d) failed(%d)\n", - vlan_id_ix[i].tx, status); - card->vlan[i].tx = 0; - card->vlan[i].rx = 0; - continue; - } - card->vlan[i].tx = (u16)v1; - - /* rx tag */ - status = lv1_net_control(bus_id(card), dev_id(card), - GELIC_LV1_GET_VLAN_ID, - vlan_id_ix[i].rx, - 0, 0, &v1, &v2); - if (status || !v1) { - if (status != LV1_NO_ENTRY) - dev_info(ctodev(card), - "get vlan id for rx(%d) failed(%d)\n", - vlan_id_ix[i].rx, status); - card->vlan[i].tx = 0; - card->vlan[i].rx = 0; - continue; - } - card->vlan[i].rx = (u16)v1; - - dev_dbg(ctodev(card), "vlan_id[%d] tx=%02x rx=%02x\n", - i, card->vlan[i].tx, card->vlan[i].rx); - } - - if (card->vlan[GELIC_PORT_ETHERNET].tx) { - BUG_ON(!card->vlan[GELIC_PORT_WIRELESS].tx); - card->vlan_required = 1; - } else - card->vlan_required = 0; - - /* check wirelss capable firmware */ - if (ps3_compare_firmware_version(1, 6, 0) < 0) { - card->vlan[GELIC_PORT_WIRELESS].tx = 0; - card->vlan[GELIC_PORT_WIRELESS].rx = 0; - } - - dev_info(ctodev(card), "internal vlan %s\n", - card->vlan_required? "enabled" : "disabled"); -} /** * ps3_gelic_driver_probe - add a device to the control of this driver */ -static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev) +static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev) { - struct gelic_card *card; - struct net_device *netdev; + struct gelic_net_card *card = gelic_net_alloc_card(); int result; - pr_debug("%s: called\n", __func__); + if (!card) { + dev_info(&dev->core, "gelic_net_alloc_card failed\n"); + result = -ENOMEM; + goto fail_alloc_card; + } + + ps3_system_bus_set_driver_data(dev, card); + card->dev = dev; + result = ps3_open_hv_device(dev); if (result) { - dev_dbg(&dev->core, "%s:ps3_open_hv_device failed\n", - __func__); + dev_dbg(&dev->core, "ps3_open_hv_device failed\n"); goto fail_open; } result = ps3_dma_region_create(dev->d_region); if (result) { - dev_dbg(&dev->core, "%s:ps3_dma_region_create failed(%d)\n", - __func__, result); + dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n", + result); BUG_ON("check region type"); goto fail_dma_region; } - /* alloc card/netdevice */ - card = gelic_alloc_card_net(&netdev); - if (!card) { - dev_info(&dev->core, "%s:gelic_net_alloc_card failed\n", - __func__); - result = -ENOMEM; - goto fail_alloc_card; - } - ps3_system_bus_set_driver_data(dev, card); - card->dev = dev; - - /* get internal vlan info */ - gelic_card_get_vlan_info(card); - - /* setup interrupt */ result = lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card), ps3_mm_phys_to_lpar(__pa(&card->irq_status)), @@ -1579,101 +1494,34 @@ static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev) if (result) { dev_dbg(&dev->core, - "%s:set_interrupt_status_indicator failed: %s\n", - __func__, ps3_result(result)); + "lv1_net_set_interrupt_status_indicator failed: %s\n", + ps3_result(result)); result = -EIO; goto fail_status_indicator; } - result = ps3_sb_event_receive_port_setup(dev, PS3_BINDING_CPU_ANY, - &card->irq); - - if (result) { - dev_info(ctodev(card), - "%s:gelic_net_open_device failed (%d)\n", - __func__, result); - result = -EPERM; - goto fail_alloc_irq; - } - result = request_irq(card->irq, gelic_card_interrupt, - IRQF_DISABLED, netdev->name, card); - - if (result) { - dev_info(ctodev(card), "%s:request_irq failed (%d)\n", - __func__, result); - goto fail_request_irq; - } - - /* setup card structure */ - card->irq_mask = GELIC_CARD_RXINT | GELIC_CARD_TXINT | - GELIC_CARD_PORT_STATUS_CHANGED; - card->rx_csum = GELIC_CARD_RX_CSUM_DEFAULT; + result = gelic_net_setup_netdev(card); - - if (gelic_card_init_chain(card, &card->tx_chain, - card->descr, GELIC_NET_TX_DESCRIPTORS)) - goto fail_alloc_tx; - if (gelic_card_init_chain(card, &card->rx_chain, - card->descr + GELIC_NET_TX_DESCRIPTORS, - GELIC_NET_RX_DESCRIPTORS)) - goto fail_alloc_rx; - - /* head of chain */ - card->tx_top = card->tx_chain.head; - card->rx_top = card->rx_chain.head; - dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n", - card->rx_top, card->tx_top, sizeof(struct gelic_descr), - GELIC_NET_RX_DESCRIPTORS); - /* allocate rx skbs */ - if (gelic_card_alloc_rx_skbs(card)) - goto fail_alloc_skbs; - - spin_lock_init(&card->tx_lock); - card->tx_dma_progress = 0; - - /* setup net_device structure */ - netdev->irq = card->irq; - SET_NETDEV_DEV(netdev, &card->dev->core); - gelic_ether_setup_netdev_ops(netdev, &card->napi); - result = gelic_net_setup_netdev(netdev, card); if (result) { - dev_dbg(&dev->core, "%s: setup_netdev failed %d", - __func__, result); + dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: " + "(%d)\n", __func__, __LINE__, result); goto fail_setup_netdev; } -#ifdef CONFIG_GELIC_WIRELESS - if (gelic_wl_driver_probe(card)) { - dev_dbg(&dev->core, "%s: WL init failed\n", __func__); - goto fail_setup_netdev; - } -#endif - pr_debug("%s: done\n", __func__); return 0; fail_setup_netdev: -fail_alloc_skbs: - gelic_card_free_chain(card, card->rx_chain.head); -fail_alloc_rx: - gelic_card_free_chain(card, card->tx_chain.head); -fail_alloc_tx: - free_irq(card->irq, card); - netdev->irq = NO_IRQ; -fail_request_irq: - ps3_sb_event_receive_port_destroy(dev, card->irq); -fail_alloc_irq: lv1_net_set_interrupt_status_indicator(bus_id(card), bus_id(card), - 0, 0); + 0 , 0); fail_status_indicator: - ps3_system_bus_set_driver_data(dev, NULL); - kfree(netdev_card(netdev)->unalign); - free_netdev(netdev); -fail_alloc_card: ps3_dma_region_free(dev->d_region); fail_dma_region: ps3_close_hv_device(dev); fail_open: + ps3_system_bus_set_driver_data(dev, NULL); + free_netdev(card->netdev); +fail_alloc_card: return result; } @@ -1681,34 +1529,9 @@ static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev) * ps3_gelic_driver_remove - remove a device from the control of this driver */ -static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) +static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev) { - struct gelic_card *card = ps3_system_bus_get_driver_data(dev); - struct net_device *netdev0; - pr_debug("%s: called\n", __func__); - -#ifdef CONFIG_GELIC_WIRELESS - gelic_wl_driver_remove(card); -#endif - /* stop interrupt */ - gelic_card_set_irq_mask(card, 0); - - /* turn off DMA, force end */ - gelic_card_disable_rxdmac(card); - gelic_card_disable_txdmac(card); - - /* release chains */ - gelic_card_release_tx_chain(card, 1); - gelic_card_release_rx_chain(card); - - gelic_card_free_chain(card, card->tx_top); - gelic_card_free_chain(card, card->rx_top); - - netdev0 = card->netdev[GELIC_PORT_ETHERNET]; - /* disconnect event port */ - free_irq(card->irq, card); - netdev0->irq = NO_IRQ; - ps3_sb_event_receive_port_destroy(card->dev, card->irq); + struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev); wait_event(card->waitq, atomic_read(&card->tx_timeout_task_counter) == 0); @@ -1716,9 +1539,8 @@ static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card), 0 , 0); - unregister_netdev(netdev0); - kfree(netdev_card(netdev0)->unalign); - free_netdev(netdev0); + unregister_netdev(card->netdev); + free_netdev(card->netdev); ps3_system_bus_set_driver_data(dev, NULL); @@ -1726,7 +1548,6 @@ static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) ps3_close_hv_device(dev); - pr_debug("%s: done\n", __func__); return 0; } @@ -1751,8 +1572,8 @@ static void __exit ps3_gelic_driver_exit (void) ps3_system_bus_driver_unregister(&ps3_gelic_driver); } -module_init(ps3_gelic_driver_init); -module_exit(ps3_gelic_driver_exit); +module_init (ps3_gelic_driver_init); +module_exit (ps3_gelic_driver_exit); MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC); diff --git a/trunk/drivers/net/ps3_gelic_net.h b/trunk/drivers/net/ps3_gelic_net.h index 1d39d06797e4..968560269a3b 100644 --- a/trunk/drivers/net/ps3_gelic_net.h +++ b/trunk/drivers/net/ps3_gelic_net.h @@ -35,323 +35,198 @@ #define GELIC_NET_MAX_MTU VLAN_ETH_FRAME_LEN #define GELIC_NET_MIN_MTU VLAN_ETH_ZLEN #define GELIC_NET_RXBUF_ALIGN 128 -#define GELIC_CARD_RX_CSUM_DEFAULT 1 /* hw chksum */ +#define GELIC_NET_RX_CSUM_DEFAULT 1 /* hw chksum */ #define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ #define GELIC_NET_NAPI_WEIGHT (GELIC_NET_RX_DESCRIPTORS) #define GELIC_NET_BROADCAST_ADDR 0xffffffffffffL - +#define GELIC_NET_VLAN_POS (VLAN_ETH_ALEN * 2) +#define GELIC_NET_VLAN_MAX 4 #define GELIC_NET_MC_COUNT_MAX 32 /* multicast address list */ -/* virtual interrupt status register bits */ - /* INT1 */ -#define GELIC_CARD_TX_RAM_FULL_ERR 0x0000000000000001L -#define GELIC_CARD_RX_RAM_FULL_ERR 0x0000000000000002L -#define GELIC_CARD_TX_SHORT_FRAME_ERR 0x0000000000000004L -#define GELIC_CARD_TX_INVALID_DESCR_ERR 0x0000000000000008L -#define GELIC_CARD_RX_FIFO_FULL_ERR 0x0000000000002000L -#define GELIC_CARD_RX_DESCR_CHAIN_END 0x0000000000004000L -#define GELIC_CARD_RX_INVALID_DESCR_ERR 0x0000000000008000L -#define GELIC_CARD_TX_RESPONCE_ERR 0x0000000000010000L -#define GELIC_CARD_RX_RESPONCE_ERR 0x0000000000100000L -#define GELIC_CARD_TX_PROTECTION_ERR 0x0000000000400000L -#define GELIC_CARD_RX_PROTECTION_ERR 0x0000000004000000L -#define GELIC_CARD_TX_TCP_UDP_CHECKSUM_ERR 0x0000000008000000L -#define GELIC_CARD_PORT_STATUS_CHANGED 0x0000000020000000L -#define GELIC_CARD_WLAN_EVENT_RECEIVED 0x0000000040000000L -#define GELIC_CARD_WLAN_COMMAND_COMPLETED 0x0000000080000000L - /* INT 0 */ -#define GELIC_CARD_TX_FLAGGED_DESCR 0x0004000000000000L -#define GELIC_CARD_RX_FLAGGED_DESCR 0x0040000000000000L -#define GELIC_CARD_TX_TRANSFER_END 0x0080000000000000L -#define GELIC_CARD_TX_DESCR_CHAIN_END 0x0100000000000000L -#define GELIC_CARD_NUMBER_OF_RX_FRAME 0x1000000000000000L -#define GELIC_CARD_ONE_TIME_COUNT_TIMER 0x4000000000000000L -#define GELIC_CARD_FREE_RUN_COUNT_TIMER 0x8000000000000000L - -/* initial interrupt mask */ -#define GELIC_CARD_TXINT GELIC_CARD_TX_DESCR_CHAIN_END - -#define GELIC_CARD_RXINT (GELIC_CARD_RX_DESCR_CHAIN_END | \ - GELIC_CARD_NUMBER_OF_RX_FRAME) - - /* RX descriptor data_status bits */ -enum gelic_descr_rx_status { - GELIC_DESCR_RXDMADU = 0x80000000, /* destination MAC addr unknown */ - GELIC_DESCR_RXLSTFBF = 0x40000000, /* last frame buffer */ - GELIC_DESCR_RXIPCHK = 0x20000000, /* IP checksum performed */ - GELIC_DESCR_RXTCPCHK = 0x10000000, /* TCP/UDP checksup performed */ - GELIC_DESCR_RXWTPKT = 0x00C00000, /* - * wakeup trigger packet - * 01: Magic Packet (TM) - * 10: ARP packet - * 11: Multicast MAC addr - */ - GELIC_DESCR_RXVLNPKT = 0x00200000, /* VLAN packet */ - /* bit 20..16 reserved */ - GELIC_DESCR_RXRRECNUM = 0x0000ff00, /* reception receipt number */ - /* bit 7..0 reserved */ +enum gelic_net_int0_status { + GELIC_NET_GDTDCEINT = 24, + GELIC_NET_GRFANMINT = 28, }; -#define GELIC_DESCR_DATA_STATUS_CHK_MASK \ - (GELIC_DESCR_RXIPCHK | GELIC_DESCR_RXTCPCHK) - - /* TX descriptor data_status bits */ -enum gelic_descr_tx_status { - GELIC_DESCR_TX_TAIL = 0x00000001, /* gelic treated this - * descriptor was end of - * a tx frame - */ +/* GHIINT1STS bits */ +enum gelic_net_int1_status { + GELIC_NET_GDADCEINT = 14, }; -/* RX descriptor data error bits */ -enum gelic_descr_rx_error { - /* bit 31 reserved */ - GELIC_DESCR_RXALNERR = 0x40000000, /* alignement error 10/100M */ - GELIC_DESCR_RXOVERERR = 0x20000000, /* oversize error */ - GELIC_DESCR_RXRNTERR = 0x10000000, /* Runt error */ - GELIC_DESCR_RXIPCHKERR = 0x08000000, /* IP checksum error */ - GELIC_DESCR_RXTCPCHKERR = 0x04000000, /* TCP/UDP checksum error */ - GELIC_DESCR_RXDRPPKT = 0x00100000, /* drop packet */ - GELIC_DESCR_RXIPFMTERR = 0x00080000, /* IP packet format error */ - /* bit 18 reserved */ - GELIC_DESCR_RXDATAERR = 0x00020000, /* IP packet format error */ - GELIC_DESCR_RXCALERR = 0x00010000, /* cariier extension length - * error */ - GELIC_DESCR_RXCREXERR = 0x00008000, /* carrier extention error */ - GELIC_DESCR_RXMLTCST = 0x00004000, /* multicast address frame */ - /* bit 13..0 reserved */ -}; -#define GELIC_DESCR_DATA_ERROR_CHK_MASK \ - (GELIC_DESCR_RXIPCHKERR | GELIC_DESCR_RXTCPCHKERR) - -/* DMA command and status (RX and TX)*/ -enum gelic_descr_dma_status { - GELIC_DESCR_DMA_COMPLETE = 0x00000000, /* used in tx */ - GELIC_DESCR_DMA_BUFFER_FULL = 0x00000000, /* used in rx */ - GELIC_DESCR_DMA_RESPONSE_ERROR = 0x10000000, /* used in rx, tx */ - GELIC_DESCR_DMA_PROTECTION_ERROR = 0x20000000, /* used in rx, tx */ - GELIC_DESCR_DMA_FRAME_END = 0x40000000, /* used in rx */ - GELIC_DESCR_DMA_FORCE_END = 0x50000000, /* used in rx, tx */ - GELIC_DESCR_DMA_CARDOWNED = 0xa0000000, /* used in rx, tx */ - GELIC_DESCR_DMA_NOT_IN_USE = 0xb0000000, /* any other value */ -}; +/* interrupt mask */ +#define GELIC_NET_TXINT (1L << (GELIC_NET_GDTDCEINT + 32)) -#define GELIC_DESCR_DMA_STAT_MASK (0xf0000000) - -/* tx descriptor command and status */ -enum gelic_descr_tx_dma_status { - /* [19] */ - GELIC_DESCR_TX_DMA_IKE = 0x00080000, /* IPSEC off */ - /* [18] */ - GELIC_DESCR_TX_DMA_FRAME_TAIL = 0x00040000, /* last descriptor of - * the packet - */ - /* [17..16] */ - GELIC_DESCR_TX_DMA_TCP_CHKSUM = 0x00020000, /* TCP packet */ - GELIC_DESCR_TX_DMA_UDP_CHKSUM = 0x00030000, /* UDP packet */ - GELIC_DESCR_TX_DMA_NO_CHKSUM = 0x00000000, /* no checksum */ +#define GELIC_NET_RXINT0 (1L << (GELIC_NET_GRFANMINT + 32)) +#define GELIC_NET_RXINT1 (1L << GELIC_NET_GDADCEINT) +#define GELIC_NET_RXINT (GELIC_NET_RXINT0 | GELIC_NET_RXINT1) - /* [1] */ - GELIC_DESCR_TX_DMA_CHAIN_END = 0x00000002, /* DMA terminated - * due to chain end - */ -}; - -#define GELIC_DESCR_DMA_CMD_NO_CHKSUM \ - (GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \ - GELIC_DESCR_TX_DMA_NO_CHKSUM) - -#define GELIC_DESCR_DMA_CMD_TCP_CHKSUM \ - (GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \ - GELIC_DESCR_TX_DMA_TCP_CHKSUM) + /* RX descriptor data_status bits */ +#define GELIC_NET_RXDMADU 0x80000000 /* destination MAC addr unknown */ +#define GELIC_NET_RXLSTFBF 0x40000000 /* last frame buffer */ +#define GELIC_NET_RXIPCHK 0x20000000 /* IP checksum performed */ +#define GELIC_NET_RXTCPCHK 0x10000000 /* TCP/UDP checksup performed */ +#define GELIC_NET_RXIPSPKT 0x08000000 /* IPsec packet */ +#define GELIC_NET_RXIPSAHPRT 0x04000000 /* IPsec AH protocol performed */ +#define GELIC_NET_RXIPSESPPRT 0x02000000 /* IPsec ESP protocol performed */ +#define GELIC_NET_RXSESPAH 0x01000000 /* + * IPsec ESP protocol auth + * performed + */ + +#define GELIC_NET_RXWTPKT 0x00C00000 /* + * wakeup trigger packet + * 01: Magic Packet (TM) + * 10: ARP packet + * 11: Multicast MAC addr + */ +#define GELIC_NET_RXVLNPKT 0x00200000 /* VLAN packet */ +/* bit 20..16 reserved */ +#define GELIC_NET_RXRRECNUM 0x0000ff00 /* reception receipt number */ +#define GELIC_NET_RXRRECNUM_SHIFT 8 +/* bit 7..0 reserved */ + +#define GELIC_NET_TXDESC_TAIL 0 +#define GELIC_NET_DATA_STATUS_CHK_MASK (GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK) + +/* RX descriptor data_error bits */ +/* bit 31 reserved */ +#define GELIC_NET_RXALNERR 0x40000000 /* alignement error 10/100M */ +#define GELIC_NET_RXOVERERR 0x20000000 /* oversize error */ +#define GELIC_NET_RXRNTERR 0x10000000 /* Runt error */ +#define GELIC_NET_RXIPCHKERR 0x08000000 /* IP checksum error */ +#define GELIC_NET_RXTCPCHKERR 0x04000000 /* TCP/UDP checksum error */ +#define GELIC_NET_RXUMCHSP 0x02000000 /* unmatched sp on sp */ +#define GELIC_NET_RXUMCHSPI 0x01000000 /* unmatched SPI on SAD */ +#define GELIC_NET_RXUMCHSAD 0x00800000 /* unmatched SAD */ +#define GELIC_NET_RXIPSAHERR 0x00400000 /* auth error on AH protocol + * processing */ +#define GELIC_NET_RXIPSESPAHERR 0x00200000 /* auth error on ESP protocol + * processing */ +#define GELIC_NET_RXDRPPKT 0x00100000 /* drop packet */ +#define GELIC_NET_RXIPFMTERR 0x00080000 /* IP packet format error */ +/* bit 18 reserved */ +#define GELIC_NET_RXDATAERR 0x00020000 /* IP packet format error */ +#define GELIC_NET_RXCALERR 0x00010000 /* cariier extension length + * error */ +#define GELIC_NET_RXCREXERR 0x00008000 /* carrier extention error */ +#define GELIC_NET_RXMLTCST 0x00004000 /* multicast address frame */ +/* bit 13..0 reserved */ +#define GELIC_NET_DATA_ERROR_CHK_MASK \ + (GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR) -#define GELIC_DESCR_DMA_CMD_UDP_CHKSUM \ - (GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \ - GELIC_DESCR_TX_DMA_UDP_CHKSUM) -enum gelic_descr_rx_dma_status { - /* [ 1 ] */ - GELIC_DESCR_RX_DMA_CHAIN_END = 0x00000002, /* DMA terminated - * due to chain end - */ +/* tx descriptor command and status */ +#define GELIC_NET_DMAC_CMDSTAT_NOCS 0xa0080000 /* middle of frame */ +#define GELIC_NET_DMAC_CMDSTAT_TCPCS 0xa00a0000 +#define GELIC_NET_DMAC_CMDSTAT_UDPCS 0xa00b0000 +#define GELIC_NET_DMAC_CMDSTAT_END_FRAME 0x00040000 /* end of frame */ + +#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS 0x00000002 /* descriptor chain end + * interrupt status */ + +#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END 0x00000002 /* RXDCEIS:DMA stopped */ +#define GELIC_NET_DESCR_IND_PROC_SHIFT 28 +#define GELIC_NET_DESCR_IND_PROC_MASKO 0x0fffffff + + +enum gelic_net_descr_status { + GELIC_NET_DESCR_COMPLETE = 0x00, /* used in tx */ + GELIC_NET_DESCR_BUFFER_FULL = 0x00, /* used in rx */ + GELIC_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ + GELIC_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ + GELIC_NET_DESCR_FRAME_END = 0x04, /* used in rx */ + GELIC_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */ + GELIC_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */ + GELIC_NET_DESCR_NOT_IN_USE = 0x0b /* any other value */ }; - /* for lv1_net_control */ -enum gelic_lv1_net_control_code { - GELIC_LV1_GET_MAC_ADDRESS = 1, - GELIC_LV1_GET_ETH_PORT_STATUS = 2, - GELIC_LV1_SET_NEGOTIATION_MODE = 3, - GELIC_LV1_GET_VLAN_ID = 4, - GELIC_LV1_GET_CHANNEL = 6, - GELIC_LV1_POST_WLAN_CMD = 9, - GELIC_LV1_GET_WLAN_CMD_RESULT = 10, - GELIC_LV1_GET_WLAN_EVENT = 11 -}; - -/* status returened from GET_ETH_PORT_STATUS */ -enum gelic_lv1_ether_port_status { - GELIC_LV1_ETHER_LINK_UP = 0x0000000000000001L, - GELIC_LV1_ETHER_FULL_DUPLEX = 0x0000000000000002L, - GELIC_LV1_ETHER_AUTO_NEG = 0x0000000000000004L, - - GELIC_LV1_ETHER_SPEED_10 = 0x0000000000000010L, - GELIC_LV1_ETHER_SPEED_100 = 0x0000000000000020L, - GELIC_LV1_ETHER_SPEED_1000 = 0x0000000000000040L, - GELIC_LV1_ETHER_SPEED_MASK = 0x0000000000000070L -}; - -enum gelic_lv1_vlan_index { - /* for outgoing packets */ - GELIC_LV1_VLAN_TX_ETHERNET = 0x0000000000000002L, - GELIC_LV1_VLAN_TX_WIRELESS = 0x0000000000000003L, - /* for incoming packets */ - GELIC_LV1_VLAN_RX_ETHERNET = 0x0000000000000012L, - GELIC_LV1_VLAN_RX_WIRELESS = 0x0000000000000013L -}; +#define GELIC_NET_GET_MAC_ADDRESS 0x0000000000000001 +#define GELIC_NET_GET_ETH_PORT_STATUS 0x0000000000000002 +#define GELIC_NET_SET_NEGOTIATION_MODE 0x0000000000000003 +#define GELIC_NET_GET_VLAN_ID 0x0000000000000004 + +#define GELIC_NET_LINK_UP 0x0000000000000001 +#define GELIC_NET_FULL_DUPLEX 0x0000000000000002 +#define GELIC_NET_AUTO_NEG 0x0000000000000004 +#define GELIC_NET_SPEED_10 0x0000000000000010 +#define GELIC_NET_SPEED_100 0x0000000000000020 +#define GELIC_NET_SPEED_1000 0x0000000000000040 + +#define GELIC_NET_VLAN_ALL 0x0000000000000001 +#define GELIC_NET_VLAN_WIRED 0x0000000000000002 +#define GELIC_NET_VLAN_WIRELESS 0x0000000000000003 +#define GELIC_NET_VLAN_PSP 0x0000000000000004 +#define GELIC_NET_VLAN_PORT0 0x0000000000000010 +#define GELIC_NET_VLAN_PORT1 0x0000000000000011 +#define GELIC_NET_VLAN_PORT2 0x0000000000000012 +#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS 0x0000000000000013 +#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS 0x0000000000000014 +#define GELIC_NET_VLAN_NO_ENTRY -6 + +#define GELIC_NET_PORT 2 /* for port status */ /* size of hardware part of gelic descriptor */ -#define GELIC_DESCR_SIZE (32) - -enum gelic_port_type { - GELIC_PORT_ETHERNET = 0, - GELIC_PORT_WIRELESS = 1, - GELIC_PORT_MAX -}; - -struct gelic_descr { +#define GELIC_NET_DESCR_SIZE (32) +struct gelic_net_descr { /* as defined by the hardware */ - __be32 buf_addr; - __be32 buf_size; - __be32 next_descr_addr; - __be32 dmac_cmd_status; - __be32 result_size; - __be32 valid_size; /* all zeroes for tx */ - __be32 data_status; - __be32 data_error; /* all zeroes for tx */ + u32 buf_addr; + u32 buf_size; + u32 next_descr_addr; + u32 dmac_cmd_status; + u32 result_size; + u32 valid_size; /* all zeroes for tx */ + u32 data_status; + u32 data_error; /* all zeroes for tx */ /* used in the driver */ struct sk_buff *skb; dma_addr_t bus_addr; - struct gelic_descr *next; - struct gelic_descr *prev; + struct gelic_net_descr *next; + struct gelic_net_descr *prev; + struct vlan_ethhdr vlan; } __attribute__((aligned(32))); -struct gelic_descr_chain { +struct gelic_net_descr_chain { /* we walk from tail to head */ - struct gelic_descr *head; - struct gelic_descr *tail; + struct gelic_net_descr *head; + struct gelic_net_descr *tail; }; -struct gelic_vlan_id { - u16 tx; - u16 rx; -}; - -struct gelic_card { +struct gelic_net_card { + struct net_device *netdev; struct napi_struct napi; - struct net_device *netdev[GELIC_PORT_MAX]; /* * hypervisor requires irq_status should be * 8 bytes aligned, but u64 member is * always disposed in that manner */ u64 irq_status; - u64 irq_mask; + u64 ghiintmask; struct ps3_system_bus_device *dev; - struct gelic_vlan_id vlan[GELIC_PORT_MAX]; - int vlan_required; + u32 vlan_id[GELIC_NET_VLAN_MAX]; + int vlan_index; - struct gelic_descr_chain tx_chain; - struct gelic_descr_chain rx_chain; + struct gelic_net_descr_chain tx_chain; + struct gelic_net_descr_chain rx_chain; int rx_dma_restart_required; + /* gurad dmac descriptor chain*/ + spinlock_t chain_lock; + int rx_csum; - /* - * tx_lock guards tx descriptor list and - * tx_dma_progress. - */ - spinlock_t tx_lock; + /* guard tx_dma_progress */ + spinlock_t tx_dma_lock; int tx_dma_progress; struct work_struct tx_timeout_task; atomic_t tx_timeout_task_counter; wait_queue_head_t waitq; - /* only first user should up the card */ - struct semaphore updown_lock; - atomic_t users; - - u64 ether_port_status; - /* original address returned by kzalloc */ - void *unalign; - - /* - * each netdevice has copy of irq - */ - unsigned int irq; - struct gelic_descr *tx_top, *rx_top; - struct gelic_descr descr[0]; /* must be the last */ -}; - -struct gelic_port { - struct gelic_card *card; - struct net_device *netdev; - enum gelic_port_type type; - long priv[0]; /* long for alignment */ + struct gelic_net_descr *tx_top, *rx_top; + struct gelic_net_descr descr[0]; }; -static inline struct gelic_card *port_to_card(struct gelic_port *p) -{ - return p->card; -} -static inline struct net_device *port_to_netdev(struct gelic_port *p) -{ - return p->netdev; -} -static inline struct gelic_card *netdev_card(struct net_device *d) -{ - return ((struct gelic_port *)netdev_priv(d))->card; -} -static inline struct gelic_port *netdev_port(struct net_device *d) -{ - return (struct gelic_port *)netdev_priv(d); -} -static inline struct device *ctodev(struct gelic_card *card) -{ - return &card->dev->core; -} -static inline u64 bus_id(struct gelic_card *card) -{ - return card->dev->bus_id; -} -static inline u64 dev_id(struct gelic_card *card) -{ - return card->dev->dev_id; -} - -static inline void *port_priv(struct gelic_port *port) -{ - return port->priv; -} - -extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask); -/* shared netdev ops */ -extern void gelic_card_up(struct gelic_card *card); -extern void gelic_card_down(struct gelic_card *card); -extern int gelic_net_open(struct net_device *netdev); -extern int gelic_net_stop(struct net_device *netdev); -extern int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev); -extern void gelic_net_set_multi(struct net_device *netdev); -extern void gelic_net_tx_timeout(struct net_device *netdev); -extern int gelic_net_change_mtu(struct net_device *netdev, int new_mtu); -extern int gelic_net_setup_netdev(struct net_device *netdev, - struct gelic_card *card); -/* shared ethtool ops */ -extern void gelic_net_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *info); -extern u32 gelic_net_get_rx_csum(struct net_device *netdev); -extern int gelic_net_set_rx_csum(struct net_device *netdev, u32 data); -extern void gelic_net_poll_controller(struct net_device *netdev); +extern unsigned long p_to_lp(long pa); #endif /* _GELIC_NET_H */ diff --git a/trunk/drivers/net/ps3_gelic_wireless.c b/trunk/drivers/net/ps3_gelic_wireless.c deleted file mode 100644 index 750d2a99cb4f..000000000000 --- a/trunk/drivers/net/ps3_gelic_wireless.c +++ /dev/null @@ -1,2753 +0,0 @@ -/* - * PS3 gelic network driver. - * - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * Copyright 2007 Sony Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#undef DEBUG - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "ps3_gelic_net.h" -#include "ps3_gelic_wireless.h" - - -static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan); -static int gelic_wl_try_associate(struct net_device *netdev); - -/* - * tables - */ - -/* 802.11b/g channel to freq in MHz */ -static const int channel_freq[] = { - 2412, 2417, 2422, 2427, 2432, - 2437, 2442, 2447, 2452, 2457, - 2462, 2467, 2472, 2484 -}; -#define NUM_CHANNELS ARRAY_SIZE(channel_freq) - -/* in bps */ -static const int bitrate_list[] = { - 1000000, - 2000000, - 5500000, - 11000000, - 6000000, - 9000000, - 12000000, - 18000000, - 24000000, - 36000000, - 48000000, - 54000000 -}; -#define NUM_BITRATES ARRAY_SIZE(bitrate_list) - -/* - * wpa2 support requires the hypervisor version 2.0 or later - */ -static inline int wpa2_capable(void) -{ - return (0 <= ps3_compare_firmware_version(2, 0, 0)); -} - -static inline int precise_ie(void) -{ - return 0; /* FIXME */ -} -/* - * post_eurus_cmd helpers - */ -struct eurus_cmd_arg_info { - int pre_arg; /* command requres arg1, arg2 at POST COMMAND */ - int post_arg; /* command requires arg1, arg2 at GET_RESULT */ -}; - -static const struct eurus_cmd_arg_info cmd_info[GELIC_EURUS_CMD_MAX_INDEX] = { - [GELIC_EURUS_CMD_SET_COMMON_CFG] = { .pre_arg = 1}, - [GELIC_EURUS_CMD_SET_WEP_CFG] = { .pre_arg = 1}, - [GELIC_EURUS_CMD_SET_WPA_CFG] = { .pre_arg = 1}, - [GELIC_EURUS_CMD_GET_COMMON_CFG] = { .post_arg = 1}, - [GELIC_EURUS_CMD_GET_WEP_CFG] = { .post_arg = 1}, - [GELIC_EURUS_CMD_GET_WPA_CFG] = { .post_arg = 1}, - [GELIC_EURUS_CMD_GET_RSSI_CFG] = { .post_arg = 1}, - [GELIC_EURUS_CMD_GET_SCAN] = { .post_arg = 1}, -}; - -#ifdef DEBUG -static const char *cmdstr(enum gelic_eurus_command ix) -{ - switch (ix) { - case GELIC_EURUS_CMD_ASSOC: - return "ASSOC"; - case GELIC_EURUS_CMD_DISASSOC: - return "DISASSOC"; - case GELIC_EURUS_CMD_START_SCAN: - return "SCAN"; - case GELIC_EURUS_CMD_GET_SCAN: - return "GET SCAN"; - case GELIC_EURUS_CMD_SET_COMMON_CFG: - return "SET_COMMON_CFG"; - case GELIC_EURUS_CMD_GET_COMMON_CFG: - return "GET_COMMON_CFG"; - case GELIC_EURUS_CMD_SET_WEP_CFG: - return "SET_WEP_CFG"; - case GELIC_EURUS_CMD_GET_WEP_CFG: - return "GET_WEP_CFG"; - case GELIC_EURUS_CMD_SET_WPA_CFG: - return "SET_WPA_CFG"; - case GELIC_EURUS_CMD_GET_WPA_CFG: - return "GET_WPA_CFG"; - case GELIC_EURUS_CMD_GET_RSSI_CFG: - return "GET_RSSI"; - default: - break; - } - return ""; -}; -#else -static inline const char *cmdstr(enum gelic_eurus_command ix) -{ - return ""; -} -#endif - -/* synchronously do eurus commands */ -static void gelic_eurus_sync_cmd_worker(struct work_struct *work) -{ - struct gelic_eurus_cmd *cmd; - struct gelic_card *card; - struct gelic_wl_info *wl; - - u64 arg1, arg2; - - pr_debug("%s: <-\n", __func__); - cmd = container_of(work, struct gelic_eurus_cmd, work); - BUG_ON(cmd_info[cmd->cmd].pre_arg && - cmd_info[cmd->cmd].post_arg); - wl = cmd->wl; - card = port_to_card(wl_port(wl)); - - if (cmd_info[cmd->cmd].pre_arg) { - arg1 = ps3_mm_phys_to_lpar(__pa(cmd->buffer)); - arg2 = cmd->buf_size; - } else { - arg1 = 0; - arg2 = 0; - } - init_completion(&wl->cmd_done_intr); - pr_debug("%s: cmd='%s' start\n", __func__, cmdstr(cmd->cmd)); - cmd->status = lv1_net_control(bus_id(card), dev_id(card), - GELIC_LV1_POST_WLAN_CMD, - cmd->cmd, arg1, arg2, - &cmd->tag, &cmd->size); - if (cmd->status) { - complete(&cmd->done); - pr_info("%s: cmd issue failed\n", __func__); - return; - } - - wait_for_completion(&wl->cmd_done_intr); - - if (cmd_info[cmd->cmd].post_arg) { - arg1 = ps3_mm_phys_to_lpar(__pa(cmd->buffer)); - arg2 = cmd->buf_size; - } else { - arg1 = 0; - arg2 = 0; - } - - cmd->status = lv1_net_control(bus_id(card), dev_id(card), - GELIC_LV1_GET_WLAN_CMD_RESULT, - cmd->tag, arg1, arg2, - &cmd->cmd_status, &cmd->size); -#ifdef DEBUG - if (cmd->status || cmd->cmd_status) { - pr_debug("%s: cmd done tag=%#lx arg1=%#lx, arg2=%#lx\n", __func__, - cmd->tag, arg1, arg2); - pr_debug("%s: cmd done status=%#x cmd_status=%#lx size=%#lx\n", - __func__, cmd->status, cmd->cmd_status, cmd->size); - } -#endif - complete(&cmd->done); - pr_debug("%s: cmd='%s' done\n", __func__, cmdstr(cmd->cmd)); -} - -static struct gelic_eurus_cmd *gelic_eurus_sync_cmd(struct gelic_wl_info *wl, - unsigned int eurus_cmd, - void *buffer, - unsigned int buf_size) -{ - struct gelic_eurus_cmd *cmd; - - /* allocate cmd */ - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return NULL; - - /* initialize members */ - cmd->cmd = eurus_cmd; - cmd->buffer = buffer; - cmd->buf_size = buf_size; - cmd->wl = wl; - INIT_WORK(&cmd->work, gelic_eurus_sync_cmd_worker); - init_completion(&cmd->done); - queue_work(wl->eurus_cmd_queue, &cmd->work); - - /* wait for command completion */ - wait_for_completion(&cmd->done); - - return cmd; -} - -static u32 gelic_wl_get_link(struct net_device *netdev) -{ - struct gelic_wl_info *wl = port_wl(netdev_port(netdev)); - u32 ret; - - pr_debug("%s: <-\n", __func__); - down(&wl->assoc_stat_lock); - if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) - ret = 1; - else - ret = 0; - up(&wl->assoc_stat_lock); - pr_debug("%s: ->\n", __func__); - return ret; -} - -static void gelic_wl_send_iwap_event(struct gelic_wl_info *wl, u8 *bssid) -{ - union iwreq_data data; - - memset(&data, 0, sizeof(data)); - if (bssid) - memcpy(data.ap_addr.sa_data, bssid, ETH_ALEN); - data.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWAP, - &data, NULL); -} - -/* - * wireless extension handlers and helpers - */ - -/* SIOGIWNAME */ -static int gelic_wl_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *iwreq, char *extra) -{ - strcpy(iwreq->name, "IEEE 802.11bg"); - return 0; -} - -static void gelic_wl_get_ch_info(struct gelic_wl_info *wl) -{ - struct gelic_card *card = port_to_card(wl_port(wl)); - u64 ch_info_raw, tmp; - int status; - - if (!test_and_set_bit(GELIC_WL_STAT_CH_INFO, &wl->stat)) { - status = lv1_net_control(bus_id(card), dev_id(card), - GELIC_LV1_GET_CHANNEL, 0, 0, 0, - &ch_info_raw, - &tmp); - /* some fw versions may return error */ - if (status) { - if (status != LV1_NO_ENTRY) - pr_info("%s: available ch unknown\n", __func__); - wl->ch_info = 0x07ff;/* 11 ch */ - } else - /* 16 bits of MSB has available channels */ - wl->ch_info = ch_info_raw >> 48; - } - return; -} - -/* SIOGIWRANGE */ -static int gelic_wl_get_range(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *iwreq, char *extra) -{ - struct iw_point *point = &iwreq->data; - struct iw_range *range = (struct iw_range *)extra; - struct gelic_wl_info *wl = port_wl(netdev_port(netdev)); - unsigned int i, chs; - - pr_debug("%s: <-\n", __func__); - point->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 22; - - /* available channels and frequencies */ - gelic_wl_get_ch_info(wl); - - for (i = 0, chs = 0; - i < NUM_CHANNELS && chs < IW_MAX_FREQUENCIES; i++) - if (wl->ch_info & (1 << i)) { - range->freq[chs].i = i + 1; - range->freq[chs].m = channel_freq[i]; - range->freq[chs].e = 6; - chs++; - } - range->num_frequency = chs; - range->old_num_frequency = chs; - range->num_channels = chs; - range->old_num_channels = chs; - - /* bitrates */ - for (i = 0; i < NUM_BITRATES; i++) - range->bitrate[i] = bitrate_list[i]; - range->num_bitrates = i; - - /* signal levels */ - range->max_qual.qual = 100; /* relative value */ - range->max_qual.level = 100; - range->avg_qual.qual = 50; - range->avg_qual.level = 50; - range->sensitivity = 0; - - /* Event capability */ - IW_EVENT_CAPA_SET_KERNEL(range->event_capa); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); - - /* encryption capability */ - range->enc_capa = IW_ENC_CAPA_WPA | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - if (wpa2_capable()) - range->enc_capa |= IW_ENC_CAPA_WPA2; - range->encoding_size[0] = 5; /* 40bit WEP */ - range->encoding_size[1] = 13; /* 104bit WEP */ - range->encoding_size[2] = 32; /* WPA-PSK */ - range->num_encoding_sizes = 3; - range->max_encoding_tokens = GELIC_WEP_KEYS; - - pr_debug("%s: ->\n", __func__); - return 0; - -} - -/* SIOC{G,S}IWSCAN */ -static int gelic_wl_set_scan(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - - return gelic_wl_start_scan(wl, 1); -} - -#define OUI_LEN 3 -static const u8 rsn_oui[OUI_LEN] = { 0x00, 0x0f, 0xac }; -static const u8 wpa_oui[OUI_LEN] = { 0x00, 0x50, 0xf2 }; - -/* - * synthesize WPA/RSN IE data - * See WiFi WPA specification and IEEE 802.11-2007 7.3.2.25 - * for the format - */ -static size_t gelic_wl_synthesize_ie(u8 *buf, - struct gelic_eurus_scan_info *scan) -{ - - const u8 *oui_header; - u8 *start = buf; - int rsn; - int ccmp; - - pr_debug("%s: <- sec=%16x\n", __func__, scan->security); - switch (be16_to_cpu(scan->security) & GELIC_EURUS_SCAN_SEC_MASK) { - case GELIC_EURUS_SCAN_SEC_WPA: - rsn = 0; - break; - case GELIC_EURUS_SCAN_SEC_WPA2: - rsn = 1; - break; - default: - /* WEP or none. No IE returned */ - return 0; - } - - switch (be16_to_cpu(scan->security) & GELIC_EURUS_SCAN_SEC_WPA_MASK) { - case GELIC_EURUS_SCAN_SEC_WPA_TKIP: - ccmp = 0; - break; - case GELIC_EURUS_SCAN_SEC_WPA_AES: - ccmp = 1; - break; - default: - if (rsn) { - ccmp = 1; - pr_info("%s: no cipher info. defaulted to CCMP\n", - __func__); - } else { - ccmp = 0; - pr_info("%s: no cipher info. defaulted to TKIP\n", - __func__); - } - } - - if (rsn) - oui_header = rsn_oui; - else - oui_header = wpa_oui; - - /* element id */ - if (rsn) - *buf++ = MFIE_TYPE_RSN; - else - *buf++ = MFIE_TYPE_GENERIC; - - /* length filed; set later */ - buf++; - - /* wpa special header */ - if (!rsn) { - memcpy(buf, wpa_oui, OUI_LEN); - buf += OUI_LEN; - *buf++ = 0x01; - } - - /* version */ - *buf++ = 0x01; /* version 1.0 */ - *buf++ = 0x00; - - /* group cipher */ - memcpy(buf, oui_header, OUI_LEN); - buf += OUI_LEN; - - if (ccmp) - *buf++ = 0x04; /* CCMP */ - else - *buf++ = 0x02; /* TKIP */ - - /* pairwise key count always 1 */ - *buf++ = 0x01; - *buf++ = 0x00; - - /* pairwise key suit */ - memcpy(buf, oui_header, OUI_LEN); - buf += OUI_LEN; - if (ccmp) - *buf++ = 0x04; /* CCMP */ - else - *buf++ = 0x02; /* TKIP */ - - /* AKM count is 1 */ - *buf++ = 0x01; - *buf++ = 0x00; - - /* AKM suite is assumed as PSK*/ - memcpy(buf, oui_header, OUI_LEN); - buf += OUI_LEN; - *buf++ = 0x02; /* PSK */ - - /* RSN capabilities is 0 */ - *buf++ = 0x00; - *buf++ = 0x00; - - /* set length field */ - start[1] = (buf - start - 2); - - pr_debug("%s: ->\n", __func__); - return (buf - start); -} - -struct ie_item { - u8 *data; - u8 len; -}; - -struct ie_info { - struct ie_item wpa; - struct ie_item rsn; -}; - -static void gelic_wl_parse_ie(u8 *data, size_t len, - struct ie_info *ie_info) -{ - size_t data_left = len; - u8 *pos = data; - u8 item_len; - u8 item_id; - - pr_debug("%s: data=%p len=%ld \n", __func__, - data, len); - memset(ie_info, 0, sizeof(struct ie_info)); - - while (0 < data_left) { - item_id = *pos++; - item_len = *pos++; - - switch (item_id) { - case MFIE_TYPE_GENERIC: - if (!memcmp(pos, wpa_oui, OUI_LEN) && - pos[OUI_LEN] == 0x01) { - ie_info->wpa.data = pos - 2; - ie_info->wpa.len = item_len + 2; - } - break; - case MFIE_TYPE_RSN: - ie_info->rsn.data = pos - 2; - /* length includes the header */ - ie_info->rsn.len = item_len + 2; - break; - default: - pr_debug("%s: ignore %#x,%d\n", __func__, - item_id, item_len); - break; - } - pos += item_len; - data_left -= item_len + 2; - } - pr_debug("%s: wpa=%p,%d wpa2=%p,%d\n", __func__, - ie_info->wpa.data, ie_info->wpa.len, - ie_info->rsn.data, ie_info->rsn.len); -} - - -/* - * translate the scan informations from hypervisor to a - * independent format - */ -static char *gelic_wl_translate_scan(struct net_device *netdev, - char *ev, - char *stop, - struct gelic_wl_scan_info *network) -{ - struct iw_event iwe; - struct gelic_eurus_scan_info *scan = network->hwinfo; - char *tmp; - u8 rate; - unsigned int i, j, len; - u8 buf[MAX_WPA_IE_LEN]; - - pr_debug("%s: <-\n", __func__); - - /* first entry should be AP's mac address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN); - ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_ADDR_LEN); - - /* ESSID */ - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - iwe.u.data.length = strnlen(scan->essid, 32); - ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid); - - /* FREQUENCY */ - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = be16_to_cpu(scan->channel); - iwe.u.freq.e = 0; /* table value in MHz */ - iwe.u.freq.i = 0; - ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_FREQ_LEN); - - /* RATES */ - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - /* to stuff multiple values in one event */ - tmp = ev + IW_EV_LCP_LEN; - /* put them in ascendant order (older is first) */ - i = 0; - j = 0; - pr_debug("%s: rates=%d rate=%d\n", __func__, - network->rate_len, network->rate_ext_len); - while (i < network->rate_len) { - if (j < network->rate_ext_len && - ((scan->ext_rate[j] & 0x7f) < (scan->rate[i] & 0x7f))) - rate = scan->ext_rate[j++] & 0x7f; - else - rate = scan->rate[i++] & 0x7f; - iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */ - tmp = iwe_stream_add_value(ev, tmp, stop, &iwe, - IW_EV_PARAM_LEN); - } - while (j < network->rate_ext_len) { - iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000; - tmp = iwe_stream_add_value(ev, tmp, stop, &iwe, - IW_EV_PARAM_LEN); - } - /* Check if we added any rate */ - if (IW_EV_LCP_LEN < (tmp - ev)) - ev = tmp; - - /* ENCODE */ - iwe.cmd = SIOCGIWENCODE; - if (be16_to_cpu(scan->capability) & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid); - - /* MODE */ - iwe.cmd = SIOCGIWMODE; - if (be16_to_cpu(scan->capability) & - (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { - if (be16_to_cpu(scan->capability) & WLAN_CAPABILITY_ESS) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_ADHOC; - ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_UINT_LEN); - } - - /* QUAL */ - iwe.cmd = IWEVQUAL; - iwe.u.qual.updated = IW_QUAL_ALL_UPDATED | - IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID; - iwe.u.qual.level = be16_to_cpu(scan->rssi); - iwe.u.qual.qual = be16_to_cpu(scan->rssi); - iwe.u.qual.noise = 0; - ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_QUAL_LEN); - - /* RSN */ - memset(&iwe, 0, sizeof(iwe)); - if (be16_to_cpu(scan->size) <= sizeof(*scan)) { - /* If wpa[2] capable station, synthesize IE and put it */ - len = gelic_wl_synthesize_ie(buf, scan); - if (len) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = len; - ev = iwe_stream_add_point(ev, stop, &iwe, buf); - } - } else { - /* this scan info has IE data */ - struct ie_info ie_info; - size_t data_len; - - data_len = be16_to_cpu(scan->size) - sizeof(*scan); - - gelic_wl_parse_ie(scan->elements, data_len, &ie_info); - - if (ie_info.wpa.len && (ie_info.wpa.len <= sizeof(buf))) { - memcpy(buf, ie_info.wpa.data, ie_info.wpa.len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie_info.wpa.len; - ev = iwe_stream_add_point(ev, stop, &iwe, buf); - } - - if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) { - memset(&iwe, 0, sizeof(iwe)); - memcpy(buf, ie_info.rsn.data, ie_info.rsn.len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie_info.rsn.len; - ev = iwe_stream_add_point(ev, stop, &iwe, buf); - } - } - - pr_debug("%s: ->\n", __func__); - return ev; -} - - -static int gelic_wl_get_scan(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - struct gelic_wl_scan_info *scan_info; - char *ev = extra; - char *stop = ev + wrqu->data.length; - int ret = 0; - unsigned long this_time = jiffies; - - pr_debug("%s: <-\n", __func__); - if (down_interruptible(&wl->scan_lock)) - return -EAGAIN; - - switch (wl->scan_stat) { - case GELIC_WL_SCAN_STAT_SCANNING: - /* If a scan in progress, caller should call me again */ - ret = -EAGAIN; - goto out; - break; - - case GELIC_WL_SCAN_STAT_INIT: - /* last scan request failed or never issued */ - ret = -ENODEV; - goto out; - break; - case GELIC_WL_SCAN_STAT_GOT_LIST: - /* ok, use current list */ - break; - } - - list_for_each_entry(scan_info, &wl->network_list, list) { - if (wl->scan_age == 0 || - time_after(scan_info->last_scanned + wl->scan_age, - this_time)) - ev = gelic_wl_translate_scan(netdev, ev, stop, - scan_info); - else - pr_debug("%s:entry too old\n", __func__); - - if (stop - ev <= IW_EV_ADDR_LEN) { - ret = -E2BIG; - goto out; - } - } - - wrqu->data.length = ev - extra; - wrqu->data.flags = 0; -out: - up(&wl->scan_lock); - pr_debug("%s: -> %d %d\n", __func__, ret, wrqu->data.length); - return ret; -} - -#ifdef DEBUG -static void scan_list_dump(struct gelic_wl_info *wl) -{ - struct gelic_wl_scan_info *scan_info; - int i; - DECLARE_MAC_BUF(mac); - - i = 0; - list_for_each_entry(scan_info, &wl->network_list, list) { - pr_debug("%s: item %d\n", __func__, i++); - pr_debug("valid=%d eurusindex=%d last=%lx\n", - scan_info->valid, scan_info->eurus_index, - scan_info->last_scanned); - pr_debug("r_len=%d r_ext_len=%d essid_len=%d\n", - scan_info->rate_len, scan_info->rate_ext_len, - scan_info->essid_len); - /* -- */ - pr_debug("bssid=%s\n", - print_mac(mac, &scan_info->hwinfo->bssid[2])); - pr_debug("essid=%s\n", scan_info->hwinfo->essid); - } -} -#endif - -static int gelic_wl_set_auth(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct iw_param *param = &data->param; - struct gelic_wl_info *wl = port_wl(netdev_port(netdev)); - unsigned long irqflag; - int ret = 0; - - pr_debug("%s: <- %d\n", __func__, param->flags & IW_AUTH_INDEX); - spin_lock_irqsave(&wl->lock, irqflag); - switch (param->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - if (param->value & IW_AUTH_WPA_VERSION_DISABLED) { - pr_debug("%s: NO WPA selected\n", __func__); - wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE; - wl->group_cipher_method = GELIC_WL_CIPHER_WEP; - wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP; - } - if (param->value & IW_AUTH_WPA_VERSION_WPA) { - pr_debug("%s: WPA version 1 selected\n", __func__); - wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA; - wl->group_cipher_method = GELIC_WL_CIPHER_TKIP; - wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP; - wl->auth_method = GELIC_EURUS_AUTH_OPEN; - } - if (param->value & IW_AUTH_WPA_VERSION_WPA2) { - /* - * As the hypervisor may not tell the cipher - * information of the AP if it is WPA2, - * you will not decide suitable cipher from - * its beacon. - * You should have knowledge about the AP's - * cipher infomation in other method prior to - * the association. - */ - if (!precise_ie()) - pr_info("%s: WPA2 may not work\n", __func__); - if (wpa2_capable()) { - wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA2; - wl->group_cipher_method = GELIC_WL_CIPHER_AES; - wl->pairwise_cipher_method = - GELIC_WL_CIPHER_AES; - wl->auth_method = GELIC_EURUS_AUTH_OPEN; - } else - ret = -EINVAL; - } - break; - - case IW_AUTH_CIPHER_PAIRWISE: - if (param->value & - (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { - pr_debug("%s: WEP selected\n", __func__); - wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP; - } - if (param->value & IW_AUTH_CIPHER_TKIP) { - pr_debug("%s: TKIP selected\n", __func__); - wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP; - } - if (param->value & IW_AUTH_CIPHER_CCMP) { - pr_debug("%s: CCMP selected\n", __func__); - wl->pairwise_cipher_method = GELIC_WL_CIPHER_AES; - } - if (param->value & IW_AUTH_CIPHER_NONE) { - pr_debug("%s: no auth selected\n", __func__); - wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE; - } - break; - case IW_AUTH_CIPHER_GROUP: - if (param->value & - (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { - pr_debug("%s: WEP selected\n", __func__); - wl->group_cipher_method = GELIC_WL_CIPHER_WEP; - } - if (param->value & IW_AUTH_CIPHER_TKIP) { - pr_debug("%s: TKIP selected\n", __func__); - wl->group_cipher_method = GELIC_WL_CIPHER_TKIP; - } - if (param->value & IW_AUTH_CIPHER_CCMP) { - pr_debug("%s: CCMP selected\n", __func__); - wl->group_cipher_method = GELIC_WL_CIPHER_AES; - } - if (param->value & IW_AUTH_CIPHER_NONE) { - pr_debug("%s: no auth selected\n", __func__); - wl->group_cipher_method = GELIC_WL_CIPHER_NONE; - } - break; - case IW_AUTH_80211_AUTH_ALG: - if (param->value & IW_AUTH_ALG_SHARED_KEY) { - pr_debug("%s: shared key specified\n", __func__); - wl->auth_method = GELIC_EURUS_AUTH_SHARED; - } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { - pr_debug("%s: open system specified\n", __func__); - wl->auth_method = GELIC_EURUS_AUTH_OPEN; - } else - ret = -EINVAL; - break; - - case IW_AUTH_WPA_ENABLED: - if (param->value) { - pr_debug("%s: WPA enabled\n", __func__); - wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA; - } else { - pr_debug("%s: WPA disabled\n", __func__); - wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE; - } - break; - - case IW_AUTH_KEY_MGMT: - if (param->value & IW_AUTH_KEY_MGMT_PSK) - break; - /* intentionally fall through */ - default: - ret = -EOPNOTSUPP; - break; - }; - - if (!ret) - set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat); - - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s: -> %d\n", __func__, ret); - return ret; -} - -static int gelic_wl_get_auth(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *iwreq, char *extra) -{ - struct iw_param *param = &iwreq->param; - struct gelic_wl_info *wl = port_wl(netdev_port(netdev)); - unsigned long irqflag; - int ret = 0; - - pr_debug("%s: <- %d\n", __func__, param->flags & IW_AUTH_INDEX); - spin_lock_irqsave(&wl->lock, irqflag); - switch (param->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - switch (wl->wpa_level) { - case GELIC_WL_WPA_LEVEL_WPA: - param->value |= IW_AUTH_WPA_VERSION_WPA; - break; - case GELIC_WL_WPA_LEVEL_WPA2: - param->value |= IW_AUTH_WPA_VERSION_WPA2; - break; - default: - param->value |= IW_AUTH_WPA_VERSION_DISABLED; - } - break; - - case IW_AUTH_80211_AUTH_ALG: - if (wl->auth_method == GELIC_EURUS_AUTH_SHARED) - param->value = IW_AUTH_ALG_SHARED_KEY; - else if (wl->auth_method == GELIC_EURUS_AUTH_OPEN) - param->value = IW_AUTH_ALG_OPEN_SYSTEM; - break; - - case IW_AUTH_WPA_ENABLED: - switch (wl->wpa_level) { - case GELIC_WL_WPA_LEVEL_WPA: - case GELIC_WL_WPA_LEVEL_WPA2: - param->value = 1; - break; - default: - param->value = 0; - break; - } - break; - default: - ret = -EOPNOTSUPP; - } - - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s: -> %d\n", __func__, ret); - return ret; -} - -/* SIOC{S,G}IWESSID */ -static int gelic_wl_set_essid(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - unsigned long irqflag; - - pr_debug("%s: <- l=%d f=%d\n", __func__, - data->essid.length, data->essid.flags); - if (IW_ESSID_MAX_SIZE < data->essid.length) - return -EINVAL; - - spin_lock_irqsave(&wl->lock, irqflag); - if (data->essid.flags) { - wl->essid_len = data->essid.length; - memcpy(wl->essid, extra, wl->essid_len); - pr_debug("%s: essid = '%s'\n", __func__, extra); - set_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat); - } else { - pr_debug("%s: ESSID any \n", __func__); - clear_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat); - } - set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat); - spin_unlock_irqrestore(&wl->lock, irqflag); - - - gelic_wl_try_associate(netdev); /* FIXME */ - pr_debug("%s: -> \n", __func__); - return 0; -} - -static int gelic_wl_get_essid(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - unsigned long irqflag; - - pr_debug("%s: <- \n", __func__); - down(&wl->assoc_stat_lock); - spin_lock_irqsave(&wl->lock, irqflag); - if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat) || - wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) { - memcpy(extra, wl->essid, wl->essid_len); - data->essid.length = wl->essid_len; - data->essid.flags = 1; - } else - data->essid.flags = 0; - - up(&wl->assoc_stat_lock); - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s: -> len=%d \n", __func__, data->essid.length); - - return 0; -} - -/* SIO{S,G}IWENCODE */ -static int gelic_wl_set_encode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - struct iw_point *enc = &data->encoding; - __u16 flags; - unsigned int irqflag; - int key_index, index_specified; - int ret = 0; - - pr_debug("%s: <- \n", __func__); - flags = enc->flags & IW_ENCODE_FLAGS; - key_index = enc->flags & IW_ENCODE_INDEX; - - pr_debug("%s: key_index = %d\n", __func__, key_index); - pr_debug("%s: key_len = %d\n", __func__, enc->length); - pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS); - - if (GELIC_WEP_KEYS < key_index) - return -EINVAL; - - spin_lock_irqsave(&wl->lock, irqflag); - if (key_index) { - index_specified = 1; - key_index--; - } else { - index_specified = 0; - key_index = wl->current_key; - } - - if (flags & IW_ENCODE_NOKEY) { - /* if just IW_ENCODE_NOKEY, change current key index */ - if (!flags && index_specified) { - wl->current_key = key_index; - goto done; - } - - if (flags & IW_ENCODE_DISABLED) { - if (!index_specified) { - /* disable encryption */ - wl->group_cipher_method = GELIC_WL_CIPHER_NONE; - wl->pairwise_cipher_method = - GELIC_WL_CIPHER_NONE; - /* invalidate all key */ - wl->key_enabled = 0; - } else - clear_bit(key_index, &wl->key_enabled); - } - - if (flags & IW_ENCODE_OPEN) - wl->auth_method = GELIC_EURUS_AUTH_OPEN; - if (flags & IW_ENCODE_RESTRICTED) { - pr_info("%s: shared key mode enabled\n", __func__); - wl->auth_method = GELIC_EURUS_AUTH_SHARED; - } - } else { - if (IW_ENCODING_TOKEN_MAX < enc->length) { - ret = -EINVAL; - goto done; - } - wl->key_len[key_index] = enc->length; - memcpy(wl->key[key_index], extra, enc->length); - set_bit(key_index, &wl->key_enabled); - wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP; - wl->group_cipher_method = GELIC_WL_CIPHER_WEP; - } - set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat); -done: - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s: -> \n", __func__); - return ret; -} - -static int gelic_wl_get_encode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - struct iw_point *enc = &data->encoding; - unsigned int irqflag; - unsigned int key_index, index_specified; - int ret = 0; - - pr_debug("%s: <- \n", __func__); - key_index = enc->flags & IW_ENCODE_INDEX; - pr_debug("%s: flag=%#x point=%p len=%d extra=%p\n", __func__, - enc->flags, enc->pointer, enc->length, extra); - if (GELIC_WEP_KEYS < key_index) - return -EINVAL; - - spin_lock_irqsave(&wl->lock, irqflag); - if (key_index) { - index_specified = 1; - key_index--; - } else { - index_specified = 0; - key_index = wl->current_key; - } - - if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) { - switch (wl->auth_method) { - case GELIC_EURUS_AUTH_OPEN: - enc->flags = IW_ENCODE_OPEN; - break; - case GELIC_EURUS_AUTH_SHARED: - enc->flags = IW_ENCODE_RESTRICTED; - break; - } - } else - enc->flags = IW_ENCODE_DISABLED; - - if (test_bit(key_index, &wl->key_enabled)) { - if (enc->length < wl->key_len[key_index]) { - ret = -EINVAL; - goto done; - } - enc->length = wl->key_len[key_index]; - memcpy(extra, wl->key[key_index], wl->key_len[key_index]); - } else { - enc->length = 0; - enc->flags |= IW_ENCODE_NOKEY; - } - enc->flags |= key_index + 1; - pr_debug("%s: -> flag=%x len=%d\n", __func__, - enc->flags, enc->length); - -done: - spin_unlock_irqrestore(&wl->lock, irqflag); - return ret; -} - -/* SIOC{S,G}IWAP */ -static int gelic_wl_set_ap(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - unsigned long irqflag; - - pr_debug("%s: <-\n", __func__); - if (data->ap_addr.sa_family != ARPHRD_ETHER) - return -EINVAL; - - spin_lock_irqsave(&wl->lock, irqflag); - if (is_valid_ether_addr(data->ap_addr.sa_data)) { - memcpy(wl->bssid, data->ap_addr.sa_data, - ETH_ALEN); - set_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat); - set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat); - pr_debug("%s: bss=%02x:%02x:%02x:%02x:%02x:%02x\n", - __func__, - wl->bssid[0], wl->bssid[1], - wl->bssid[2], wl->bssid[3], - wl->bssid[4], wl->bssid[5]); - } else { - pr_debug("%s: clear bssid\n", __func__); - clear_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat); - memset(wl->bssid, 0, ETH_ALEN); - } - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s: ->\n", __func__); - return 0; -} - -static int gelic_wl_get_ap(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - unsigned long irqflag; - - pr_debug("%s: <-\n", __func__); - down(&wl->assoc_stat_lock); - spin_lock_irqsave(&wl->lock, irqflag); - if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) { - data->ap_addr.sa_family = ARPHRD_ETHER; - memcpy(data->ap_addr.sa_data, wl->active_bssid, - ETH_ALEN); - } else - memset(data->ap_addr.sa_data, 0, ETH_ALEN); - - spin_unlock_irqrestore(&wl->lock, irqflag); - up(&wl->assoc_stat_lock); - pr_debug("%s: ->\n", __func__); - return 0; -} - -/* SIOC{S,G}IWENCODEEXT */ -static int gelic_wl_set_encodeext(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - struct iw_point *enc = &data->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - __u16 alg; - __u16 flags; - unsigned int irqflag; - int key_index; - int ret = 0; - - pr_debug("%s: <- \n", __func__); - flags = enc->flags & IW_ENCODE_FLAGS; - alg = ext->alg; - key_index = enc->flags & IW_ENCODE_INDEX; - - pr_debug("%s: key_index = %d\n", __func__, key_index); - pr_debug("%s: key_len = %d\n", __func__, enc->length); - pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS); - pr_debug("%s: ext_flag=%x\n", __func__, ext->ext_flags); - pr_debug("%s: ext_key_len=%x\n", __func__, ext->key_len); - - if (GELIC_WEP_KEYS < key_index) - return -EINVAL; - - spin_lock_irqsave(&wl->lock, irqflag); - if (key_index) - key_index--; - else - key_index = wl->current_key; - - if (!enc->length && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) { - /* reques to change default key index */ - pr_debug("%s: request to change default key to %d\n", - __func__, key_index); - wl->current_key = key_index; - goto done; - } - - if (alg == IW_ENCODE_ALG_NONE || (flags & IW_ENCODE_DISABLED)) { - pr_debug("%s: alg disabled\n", __func__); - wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE; - wl->group_cipher_method = GELIC_WL_CIPHER_NONE; - wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE; - wl->auth_method = GELIC_EURUS_AUTH_OPEN; /* should be open */ - } else if (alg == IW_ENCODE_ALG_WEP) { - pr_debug("%s: WEP requested\n", __func__); - if (flags & IW_ENCODE_OPEN) { - pr_debug("%s: open key mode\n", __func__); - wl->auth_method = GELIC_EURUS_AUTH_OPEN; - } - if (flags & IW_ENCODE_RESTRICTED) { - pr_debug("%s: shared key mode\n", __func__); - wl->auth_method = GELIC_EURUS_AUTH_SHARED; - } - if (IW_ENCODING_TOKEN_MAX < ext->key_len) { - pr_info("%s: key is too long %d\n", __func__, - ext->key_len); - ret = -EINVAL; - goto done; - } - /* OK, update the key */ - wl->key_len[key_index] = ext->key_len; - memset(wl->key[key_index], 0, IW_ENCODING_TOKEN_MAX); - memcpy(wl->key[key_index], ext->key, ext->key_len); - set_bit(key_index, &wl->key_enabled); - /* remember wep info changed */ - set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat); - } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) { - pr_debug("%s: TKIP/CCMP requested alg=%d\n", __func__, alg); - /* check key length */ - if (IW_ENCODING_TOKEN_MAX < ext->key_len) { - pr_info("%s: key is too long %d\n", __func__, - ext->key_len); - ret = -EINVAL; - goto done; - } - if (alg == IW_ENCODE_ALG_CCMP) { - pr_debug("%s: AES selected\n", __func__); - wl->group_cipher_method = GELIC_WL_CIPHER_AES; - wl->pairwise_cipher_method = GELIC_WL_CIPHER_AES; - wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA2; - } else { - pr_debug("%s: TKIP selected, WPA forced\n", __func__); - wl->group_cipher_method = GELIC_WL_CIPHER_TKIP; - wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP; - /* FIXME: how do we do if WPA2 + TKIP? */ - wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA; - } - if (flags & IW_ENCODE_RESTRICTED) - BUG(); - wl->auth_method = GELIC_EURUS_AUTH_OPEN; - /* We should use same key for both and unicast */ - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) - pr_debug("%s: group key \n", __func__); - else - pr_debug("%s: unicast key \n", __func__); - /* OK, update the key */ - wl->key_len[key_index] = ext->key_len; - memset(wl->key[key_index], 0, IW_ENCODING_TOKEN_MAX); - memcpy(wl->key[key_index], ext->key, ext->key_len); - set_bit(key_index, &wl->key_enabled); - /* remember info changed */ - set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat); - } -done: - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s: -> \n", __func__); - return ret; -} - -static int gelic_wl_get_encodeext(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - struct iw_point *enc = &data->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - unsigned int irqflag; - int key_index; - int ret = 0; - int max_key_len; - - pr_debug("%s: <- \n", __func__); - - max_key_len = enc->length - sizeof(struct iw_encode_ext); - if (max_key_len < 0) - return -EINVAL; - key_index = enc->flags & IW_ENCODE_INDEX; - - pr_debug("%s: key_index = %d\n", __func__, key_index); - pr_debug("%s: key_len = %d\n", __func__, enc->length); - pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS); - - if (GELIC_WEP_KEYS < key_index) - return -EINVAL; - - spin_lock_irqsave(&wl->lock, irqflag); - if (key_index) - key_index--; - else - key_index = wl->current_key; - - memset(ext, 0, sizeof(struct iw_encode_ext)); - switch (wl->group_cipher_method) { - case GELIC_WL_CIPHER_WEP: - ext->alg = IW_ENCODE_ALG_WEP; - enc->flags |= IW_ENCODE_ENABLED; - break; - case GELIC_WL_CIPHER_TKIP: - ext->alg = IW_ENCODE_ALG_TKIP; - enc->flags |= IW_ENCODE_ENABLED; - break; - case GELIC_WL_CIPHER_AES: - ext->alg = IW_ENCODE_ALG_CCMP; - enc->flags |= IW_ENCODE_ENABLED; - break; - case GELIC_WL_CIPHER_NONE: - default: - ext->alg = IW_ENCODE_ALG_NONE; - enc->flags |= IW_ENCODE_NOKEY; - break; - } - - if (!(enc->flags & IW_ENCODE_NOKEY)) { - if (max_key_len < wl->key_len[key_index]) { - ret = -E2BIG; - goto out; - } - if (test_bit(key_index, &wl->key_enabled)) - memcpy(ext->key, wl->key[key_index], - wl->key_len[key_index]); - else - pr_debug("%s: disabled key requested ix=%d\n", - __func__, key_index); - } -out: - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s: -> \n", __func__); - return ret; -} -/* SIOC{S,G}IWMODE */ -static int gelic_wl_set_mode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - __u32 mode = data->mode; - int ret; - - pr_debug("%s: <- \n", __func__); - if (mode == IW_MODE_INFRA) - ret = 0; - else - ret = -EOPNOTSUPP; - pr_debug("%s: -> %d\n", __func__, ret); - return ret; -} - -static int gelic_wl_get_mode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - __u32 *mode = &data->mode; - pr_debug("%s: <- \n", __func__); - *mode = IW_MODE_INFRA; - pr_debug("%s: ->\n", __func__); - return 0; -} - -/* SIOCIWFIRSTPRIV */ -static int hex2bin(u8 *str, u8 *bin, unsigned int len) -{ - unsigned int i; - static unsigned char *hex = "0123456789ABCDEF"; - unsigned char *p, *q; - u8 tmp; - - if (len != WPA_PSK_LEN * 2) - return -EINVAL; - - for (i = 0; i < WPA_PSK_LEN * 2; i += 2) { - p = strchr(hex, toupper(str[i])); - q = strchr(hex, toupper(str[i + 1])); - if (!p || !q) { - pr_info("%s: unconvertible PSK digit=%d\n", - __func__, i); - return -EINVAL; - } - tmp = ((p - hex) << 4) + (q - hex); - *bin++ = tmp; - } - return 0; -}; - -static int gelic_wl_priv_set_psk(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev)); - unsigned int len; - unsigned int irqflag; - int ret = 0; - - pr_debug("%s:<- len=%d\n", __func__, data->data.length); - len = data->data.length - 1; - if (len <= 2) - return -EINVAL; - - spin_lock_irqsave(&wl->lock, irqflag); - if (extra[0] == '"' && extra[len - 1] == '"') { - pr_debug("%s: passphrase mode\n", __func__); - /* pass phrase */ - if (GELIC_WL_EURUS_PSK_MAX_LEN < (len - 2)) { - pr_info("%s: passphrase too long\n", __func__); - ret = -E2BIG; - goto out; - } - memset(wl->psk, 0, sizeof(wl->psk)); - wl->psk_len = len - 2; - memcpy(wl->psk, &(extra[1]), wl->psk_len); - wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE; - } else { - ret = hex2bin(extra, wl->psk, len); - if (ret) - goto out; - wl->psk_len = WPA_PSK_LEN; - wl->psk_type = GELIC_EURUS_WPA_PSK_BIN; - } - set_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat); -out: - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s:->\n", __func__); - return ret; -} - -static int gelic_wl_priv_get_psk(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev)); - char *p; - unsigned int irqflag; - unsigned int i; - - pr_debug("%s:<-\n", __func__); - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - spin_lock_irqsave(&wl->lock, irqflag); - p = extra; - if (test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat)) { - if (wl->psk_type == GELIC_EURUS_WPA_PSK_BIN) { - for (i = 0; i < wl->psk_len; i++) { - sprintf(p, "%02xu", wl->psk[i]); - p += 2; - } - *p = '\0'; - data->data.length = wl->psk_len * 2; - } else { - *p++ = '"'; - memcpy(p, wl->psk, wl->psk_len); - p += wl->psk_len; - *p++ = '"'; - *p = '\0'; - data->data.length = wl->psk_len + 2; - } - } else - /* no psk set */ - data->data.length = 0; - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s:-> %d\n", __func__, data->data.length); - return 0; -} - -/* SIOCGIWNICKN */ -static int gelic_wl_get_nick(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - strcpy(extra, "gelic_wl"); - data->data.length = strlen(extra); - data->data.flags = 1; - return 0; -} - - -/* --- */ - -static struct iw_statistics *gelic_wl_get_wireless_stats( - struct net_device *netdev) -{ - - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - struct gelic_eurus_cmd *cmd; - struct iw_statistics *is; - struct gelic_eurus_rssi_info *rssi; - - pr_debug("%s: <-\n", __func__); - - is = &wl->iwstat; - memset(is, 0, sizeof(*is)); - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_GET_RSSI_CFG, - wl->buf, sizeof(*rssi)); - if (cmd && !cmd->status && !cmd->cmd_status) { - rssi = wl->buf; - is->qual.level = be16_to_cpu(rssi->rssi); - is->qual.updated = IW_QUAL_LEVEL_UPDATED | - IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID; - } else - /* not associated */ - is->qual.updated = IW_QUAL_ALL_INVALID; - - kfree(cmd); - pr_debug("%s: ->\n", __func__); - return is; -} - -/* - * scanning helpers - */ -static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan) -{ - struct gelic_eurus_cmd *cmd; - int ret = 0; - - pr_debug("%s: <- always=%d\n", __func__, always_scan); - if (down_interruptible(&wl->scan_lock)) - return -ERESTARTSYS; - - /* - * If already a scan in progress, do not trigger more - */ - if (wl->scan_stat == GELIC_WL_SCAN_STAT_SCANNING) { - pr_debug("%s: scanning now\n", __func__); - goto out; - } - - init_completion(&wl->scan_done); - /* - * If we have already a bss list, don't try to get new - */ - if (!always_scan && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) { - pr_debug("%s: already has the list\n", __func__); - complete(&wl->scan_done); - goto out; - } - /* - * issue start scan request - */ - wl->scan_stat = GELIC_WL_SCAN_STAT_SCANNING; - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_START_SCAN, - NULL, 0); - if (!cmd || cmd->status || cmd->cmd_status) { - wl->scan_stat = GELIC_WL_SCAN_STAT_INIT; - complete(&wl->scan_done); - ret = -ENOMEM; - goto out; - } - kfree(cmd); -out: - up(&wl->scan_lock); - pr_debug("%s: ->\n", __func__); - return ret; -} - -/* - * retrieve scan result from the chip (hypervisor) - * this function is invoked by schedule work. - */ -static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) -{ - struct gelic_eurus_cmd *cmd = NULL; - struct gelic_wl_scan_info *target, *tmp; - struct gelic_wl_scan_info *oldest = NULL; - struct gelic_eurus_scan_info *scan_info; - unsigned int scan_info_size; - union iwreq_data data; - unsigned long this_time = jiffies; - unsigned int data_len, i, found, r; - DECLARE_MAC_BUF(mac); - - pr_debug("%s:start\n", __func__); - down(&wl->scan_lock); - - if (wl->scan_stat != GELIC_WL_SCAN_STAT_SCANNING) { - /* - * stop() may be called while scanning, ignore result - */ - pr_debug("%s: scan complete when stat != scanning(%d)\n", - __func__, wl->scan_stat); - goto out; - } - - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_GET_SCAN, - wl->buf, PAGE_SIZE); - if (!cmd || cmd->status || cmd->cmd_status) { - wl->scan_stat = GELIC_WL_SCAN_STAT_INIT; - pr_info("%s:cmd failed\n", __func__); - kfree(cmd); - goto out; - } - data_len = cmd->size; - pr_debug("%s: data_len = %d\n", __func__, data_len); - kfree(cmd); - - /* OK, bss list retrieved */ - wl->scan_stat = GELIC_WL_SCAN_STAT_GOT_LIST; - - /* mark all entries are old */ - list_for_each_entry_safe(target, tmp, &wl->network_list, list) { - target->valid = 0; - /* expire too old entries */ - if (time_before(target->last_scanned + wl->scan_age, - this_time)) { - kfree(target->hwinfo); - target->hwinfo = NULL; - list_move_tail(&target->list, &wl->network_free_list); - } - } - - /* put them in the newtork_list */ - scan_info = wl->buf; - scan_info_size = 0; - i = 0; - while (scan_info_size < data_len) { - pr_debug("%s:size=%d bssid=%s scan_info=%p\n", __func__, - be16_to_cpu(scan_info->size), - print_mac(mac, &scan_info->bssid[2]), scan_info); - found = 0; - oldest = NULL; - list_for_each_entry(target, &wl->network_list, list) { - if (!compare_ether_addr(&target->hwinfo->bssid[2], - &scan_info->bssid[2])) { - found = 1; - pr_debug("%s: same BBS found scanned list\n", - __func__); - break; - } - if (!oldest || - (target->last_scanned < oldest->last_scanned)) - oldest = target; - } - - if (!found) { - /* not found in the list */ - if (list_empty(&wl->network_free_list)) { - /* expire oldest */ - target = oldest; - } else { - target = list_entry(wl->network_free_list.next, - struct gelic_wl_scan_info, - list); - } - } - - /* update the item */ - target->last_scanned = this_time; - target->valid = 1; - target->eurus_index = i; - kfree(target->hwinfo); - target->hwinfo = kzalloc(be16_to_cpu(scan_info->size), - GFP_KERNEL); - if (!target->hwinfo) { - pr_info("%s: kzalloc failed\n", __func__); - i++; - scan_info_size += be16_to_cpu(scan_info->size); - scan_info = (void *)scan_info + - be16_to_cpu(scan_info->size); - continue; - } - /* copy hw scan info */ - memcpy(target->hwinfo, scan_info, scan_info->size); - target->essid_len = strnlen(scan_info->essid, - sizeof(scan_info->essid)); - target->rate_len = 0; - for (r = 0; r < MAX_RATES_LENGTH; r++) - if (scan_info->rate[r]) - target->rate_len++; - if (8 < target->rate_len) - pr_info("%s: AP returns %d rates\n", __func__, - target->rate_len); - target->rate_ext_len = 0; - for (r = 0; r < MAX_RATES_EX_LENGTH; r++) - if (scan_info->ext_rate[r]) - target->rate_ext_len++; - list_move_tail(&target->list, &wl->network_list); - /* bump pointer */ - i++; - scan_info_size += be16_to_cpu(scan_info->size); - scan_info = (void *)scan_info + be16_to_cpu(scan_info->size); - } - memset(&data, 0, sizeof(data)); - wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWSCAN, &data, - NULL); -out: - complete(&wl->scan_done); - up(&wl->scan_lock); - pr_debug("%s:end\n", __func__); -} - -/* - * Select an appropriate bss from current scan list regarding - * current settings from userspace. - * The caller must hold wl->scan_lock, - * and on the state of wl->scan_state == GELIC_WL_SCAN_GOT_LIST - */ -static void update_best(struct gelic_wl_scan_info **best, - struct gelic_wl_scan_info *candid, - int *best_weight, - int *weight) -{ - if (*best_weight < ++(*weight)) { - *best_weight = *weight; - *best = candid; - } -} - -static -struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl) -{ - struct gelic_wl_scan_info *scan_info; - struct gelic_wl_scan_info *best_bss; - int weight, best_weight; - u16 security; - DECLARE_MAC_BUF(mac); - - pr_debug("%s: <-\n", __func__); - - best_bss = NULL; - best_weight = 0; - - list_for_each_entry(scan_info, &wl->network_list, list) { - pr_debug("%s: station %p\n", __func__, scan_info); - - if (!scan_info->valid) { - pr_debug("%s: station invalid\n", __func__); - continue; - } - - /* If bss specified, check it only */ - if (test_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat)) { - if (!compare_ether_addr(&scan_info->hwinfo->bssid[2], - wl->bssid)) { - best_bss = scan_info; - pr_debug("%s: bssid matched\n", __func__); - break; - } else { - pr_debug("%s: bssid unmached\n", __func__); - continue; - } - } - - weight = 0; - - /* security */ - security = be16_to_cpu(scan_info->hwinfo->security) & - GELIC_EURUS_SCAN_SEC_MASK; - if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA2) { - if (security == GELIC_EURUS_SCAN_SEC_WPA2) - update_best(&best_bss, scan_info, - &best_weight, &weight); - else - continue; - } else if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA) { - if (security == GELIC_EURUS_SCAN_SEC_WPA) - update_best(&best_bss, scan_info, - &best_weight, &weight); - else - continue; - } else if (wl->wpa_level == GELIC_WL_WPA_LEVEL_NONE && - wl->group_cipher_method == GELIC_WL_CIPHER_WEP) { - if (security == GELIC_EURUS_SCAN_SEC_WEP) - update_best(&best_bss, scan_info, - &best_weight, &weight); - else - continue; - } - - /* If ESSID is set, check it */ - if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat)) { - if ((scan_info->essid_len == wl->essid_len) && - !strncmp(wl->essid, - scan_info->hwinfo->essid, - scan_info->essid_len)) - update_best(&best_bss, scan_info, - &best_weight, &weight); - else - continue; - } - } - -#ifdef DEBUG - pr_debug("%s: -> bss=%p\n", __func__, best_bss); - if (best_bss) { - pr_debug("%s:addr=%s\n", __func__, - print_mac(mac, &best_bss->hwinfo->bssid[2])); - } -#endif - return best_bss; -} - -/* - * Setup WEP configuration to the chip - * The caller must hold wl->scan_lock, - * and on the state of wl->scan_state == GELIC_WL_SCAN_GOT_LIST - */ -static int gelic_wl_do_wep_setup(struct gelic_wl_info *wl) -{ - unsigned int i; - struct gelic_eurus_wep_cfg *wep; - struct gelic_eurus_cmd *cmd; - int wep104 = 0; - int have_key = 0; - int ret = 0; - - pr_debug("%s: <-\n", __func__); - /* we can assume no one should uses the buffer */ - wep = wl->buf; - memset(wep, 0, sizeof(*wep)); - - if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) { - pr_debug("%s: WEP mode\n", __func__); - for (i = 0; i < GELIC_WEP_KEYS; i++) { - if (!test_bit(i, &wl->key_enabled)) - continue; - - pr_debug("%s: key#%d enabled\n", __func__, i); - have_key = 1; - if (wl->key_len[i] == 13) - wep104 = 1; - else if (wl->key_len[i] != 5) { - pr_info("%s: wrong wep key[%d]=%d\n", - __func__, i, wl->key_len[i]); - ret = -EINVAL; - goto out; - } - memcpy(wep->key[i], wl->key[i], wl->key_len[i]); - } - - if (!have_key) { - pr_info("%s: all wep key disabled\n", __func__); - ret = -EINVAL; - goto out; - } - - if (wep104) { - pr_debug("%s: 104bit key\n", __func__); - wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_104BIT); - } else { - pr_debug("%s: 40bit key\n", __func__); - wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_40BIT); - } - } else { - pr_debug("%s: NO encryption\n", __func__); - wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_NONE); - } - - /* issue wep setup */ - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_WEP_CFG, - wep, sizeof(*wep)); - if (!cmd) - ret = -ENOMEM; - else if (cmd->status || cmd->cmd_status) - ret = -ENXIO; - - kfree(cmd); -out: - pr_debug("%s: ->\n", __func__); - return ret; -} - -#ifdef DEBUG -static const char *wpasecstr(enum gelic_eurus_wpa_security sec) -{ - switch (sec) { - case GELIC_EURUS_WPA_SEC_NONE: - return "NONE"; - break; - case GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP: - return "WPA_TKIP_TKIP"; - break; - case GELIC_EURUS_WPA_SEC_WPA_TKIP_AES: - return "WPA_TKIP_AES"; - break; - case GELIC_EURUS_WPA_SEC_WPA_AES_AES: - return "WPA_AES_AES"; - break; - case GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP: - return "WPA2_TKIP_TKIP"; - break; - case GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES: - return "WPA2_TKIP_AES"; - break; - case GELIC_EURUS_WPA_SEC_WPA2_AES_AES: - return "WPA2_AES_AES"; - break; - } - return ""; -}; -#endif - -static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl) -{ - struct gelic_eurus_wpa_cfg *wpa; - struct gelic_eurus_cmd *cmd; - u16 security; - int ret = 0; - - pr_debug("%s: <-\n", __func__); - /* we can assume no one should uses the buffer */ - wpa = wl->buf; - memset(wpa, 0, sizeof(*wpa)); - - if (!test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat)) - pr_info("%s: PSK not configured yet\n", __func__); - - /* copy key */ - memcpy(wpa->psk, wl->psk, wl->psk_len); - - /* set security level */ - if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA2) { - if (wl->group_cipher_method == GELIC_WL_CIPHER_AES) { - security = GELIC_EURUS_WPA_SEC_WPA2_AES_AES; - } else { - if (wl->pairwise_cipher_method == GELIC_WL_CIPHER_AES && - precise_ie()) - security = GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES; - else - security = GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP; - } - } else { - if (wl->group_cipher_method == GELIC_WL_CIPHER_AES) { - security = GELIC_EURUS_WPA_SEC_WPA_AES_AES; - } else { - if (wl->pairwise_cipher_method == GELIC_WL_CIPHER_AES && - precise_ie()) - security = GELIC_EURUS_WPA_SEC_WPA_TKIP_AES; - else - security = GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP; - } - } - wpa->security = cpu_to_be16(security); - - /* PSK type */ - wpa->psk_type = cpu_to_be16(wl->psk_type); -#ifdef DEBUG - pr_debug("%s: sec=%s psktype=%s\nn", __func__, - wpasecstr(wpa->security), - (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ? - "BIN" : "passphrase"); -#if 0 - /* - * don't enable here if you plan to submit - * the debug log because this dumps your precious - * passphrase/key. - */ - pr_debug("%s: psk=%s\n", - (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ? - (char *)"N/A" : (char *)wpa->psk); -#endif -#endif - /* issue wpa setup */ - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_WPA_CFG, - wpa, sizeof(*wpa)); - if (!cmd) - ret = -ENOMEM; - else if (cmd->status || cmd->cmd_status) - ret = -ENXIO; - kfree(cmd); - pr_debug("%s: --> %d\n", __func__, ret); - return ret; -} - -/* - * Start association. caller must hold assoc_stat_lock - */ -static int gelic_wl_associate_bss(struct gelic_wl_info *wl, - struct gelic_wl_scan_info *bss) -{ - struct gelic_eurus_cmd *cmd; - struct gelic_eurus_common_cfg *common; - int ret = 0; - unsigned long rc; - - pr_debug("%s: <-\n", __func__); - - /* do common config */ - common = wl->buf; - memset(common, 0, sizeof(*common)); - common->bss_type = cpu_to_be16(GELIC_EURUS_BSS_INFRA); - common->op_mode = cpu_to_be16(GELIC_EURUS_OPMODE_11BG); - - common->scan_index = cpu_to_be16(bss->eurus_index); - switch (wl->auth_method) { - case GELIC_EURUS_AUTH_OPEN: - common->auth_method = cpu_to_be16(GELIC_EURUS_AUTH_OPEN); - break; - case GELIC_EURUS_AUTH_SHARED: - common->auth_method = cpu_to_be16(GELIC_EURUS_AUTH_SHARED); - break; - } - -#ifdef DEBUG - scan_list_dump(wl); -#endif - pr_debug("%s: common cfg index=%d bsstype=%d auth=%d\n", __func__, - be16_to_cpu(common->scan_index), - be16_to_cpu(common->bss_type), - be16_to_cpu(common->auth_method)); - - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_COMMON_CFG, - common, sizeof(*common)); - if (!cmd || cmd->status || cmd->cmd_status) { - ret = -ENOMEM; - kfree(cmd); - goto out; - } - kfree(cmd); - - /* WEP/WPA */ - switch (wl->wpa_level) { - case GELIC_WL_WPA_LEVEL_NONE: - /* If WEP or no security, setup WEP config */ - ret = gelic_wl_do_wep_setup(wl); - break; - case GELIC_WL_WPA_LEVEL_WPA: - case GELIC_WL_WPA_LEVEL_WPA2: - ret = gelic_wl_do_wpa_setup(wl); - break; - }; - - if (ret) { - pr_debug("%s: WEP/WPA setup failed %d\n", __func__, - ret); - } - - /* start association */ - init_completion(&wl->assoc_done); - wl->assoc_stat = GELIC_WL_ASSOC_STAT_ASSOCIATING; - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_ASSOC, - NULL, 0); - if (!cmd || cmd->status || cmd->cmd_status) { - pr_debug("%s: assoc request failed\n", __func__); - wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN; - kfree(cmd); - ret = -ENOMEM; - gelic_wl_send_iwap_event(wl, NULL); - goto out; - } - kfree(cmd); - - /* wait for connected event */ - rc = wait_for_completion_timeout(&wl->assoc_done, HZ * 4);/*FIXME*/ - - if (!rc) { - /* timeouted. Maybe key or cyrpt mode is wrong */ - pr_info("%s: connect timeout \n", __func__); - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC, - NULL, 0); - kfree(cmd); - wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN; - gelic_wl_send_iwap_event(wl, NULL); - ret = -ENXIO; - } else { - wl->assoc_stat = GELIC_WL_ASSOC_STAT_ASSOCIATED; - /* copy bssid */ - memcpy(wl->active_bssid, &bss->hwinfo->bssid[2], ETH_ALEN); - - /* send connect event */ - gelic_wl_send_iwap_event(wl, wl->active_bssid); - pr_info("%s: connected\n", __func__); - } -out: - pr_debug("%s: ->\n", __func__); - return ret; -} - -/* - * connected event - */ -static void gelic_wl_connected_event(struct gelic_wl_info *wl, - u64 event) -{ - u64 desired_event = 0; - - switch (wl->wpa_level) { - case GELIC_WL_WPA_LEVEL_NONE: - desired_event = GELIC_LV1_WL_EVENT_CONNECTED; - break; - case GELIC_WL_WPA_LEVEL_WPA: - case GELIC_WL_WPA_LEVEL_WPA2: - desired_event = GELIC_LV1_WL_EVENT_WPA_CONNECTED; - break; - } - - if (desired_event == event) { - pr_debug("%s: completed \n", __func__); - complete(&wl->assoc_done); - netif_carrier_on(port_to_netdev(wl_port(wl))); - } else - pr_debug("%s: event %#lx under wpa\n", - __func__, event); -} - -/* - * disconnect event - */ -static void gelic_wl_disconnect_event(struct gelic_wl_info *wl, - u64 event) -{ - struct gelic_eurus_cmd *cmd; - int lock; - - /* - * If we fall here in the middle of association, - * associate_bss() should be waiting for complation of - * wl->assoc_done. - * As it waits with timeout, just leave assoc_done - * uncompleted, then it terminates with timeout - */ - if (down_trylock(&wl->assoc_stat_lock)) { - pr_debug("%s: already locked\n", __func__); - lock = 0; - } else { - pr_debug("%s: obtain lock\n", __func__); - lock = 1; - } - - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC, NULL, 0); - kfree(cmd); - - /* send disconnected event to the supplicant */ - if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) - gelic_wl_send_iwap_event(wl, NULL); - - wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN; - netif_carrier_off(port_to_netdev(wl_port(wl))); - - if (lock) - up(&wl->assoc_stat_lock); -} -/* - * event worker - */ -#ifdef DEBUG -static const char *eventstr(enum gelic_lv1_wl_event event) -{ - static char buf[32]; - char *ret; - if (event & GELIC_LV1_WL_EVENT_DEVICE_READY) - ret = "EURUS_READY"; - else if (event & GELIC_LV1_WL_EVENT_SCAN_COMPLETED) - ret = "SCAN_COMPLETED"; - else if (event & GELIC_LV1_WL_EVENT_DEAUTH) - ret = "DEAUTH"; - else if (event & GELIC_LV1_WL_EVENT_BEACON_LOST) - ret = "BEACON_LOST"; - else if (event & GELIC_LV1_WL_EVENT_CONNECTED) - ret = "CONNECTED"; - else if (event & GELIC_LV1_WL_EVENT_WPA_CONNECTED) - ret = "WPA_CONNECTED"; - else if (event & GELIC_LV1_WL_EVENT_WPA_ERROR) - ret = "WPA_ERROR"; - else { - sprintf(buf, "Unknown(%#x)", event); - ret = buf; - } - return ret; -} -#else -static const char *eventstr(enum gelic_lv1_wl_event event) -{ - return NULL; -} -#endif -static void gelic_wl_event_worker(struct work_struct *work) -{ - struct gelic_wl_info *wl; - struct gelic_port *port; - u64 event, tmp; - int status; - - pr_debug("%s:start\n", __func__); - wl = container_of(work, struct gelic_wl_info, event_work.work); - port = wl_port(wl); - while (1) { - status = lv1_net_control(bus_id(port->card), dev_id(port->card), - GELIC_LV1_GET_WLAN_EVENT, 0, 0, 0, - &event, &tmp); - if (status) { - if (status != LV1_NO_ENTRY) - pr_debug("%s:wlan event failed %d\n", - __func__, status); - /* got all events */ - pr_debug("%s:end\n", __func__); - return; - } - pr_debug("%s: event=%s\n", __func__, eventstr(event)); - switch (event) { - case GELIC_LV1_WL_EVENT_SCAN_COMPLETED: - gelic_wl_scan_complete_event(wl); - break; - case GELIC_LV1_WL_EVENT_BEACON_LOST: - case GELIC_LV1_WL_EVENT_DEAUTH: - gelic_wl_disconnect_event(wl, event); - break; - case GELIC_LV1_WL_EVENT_CONNECTED: - case GELIC_LV1_WL_EVENT_WPA_CONNECTED: - gelic_wl_connected_event(wl, event); - break; - default: - break; - } - } /* while */ -} -/* - * association worker - */ -static void gelic_wl_assoc_worker(struct work_struct *work) -{ - struct gelic_wl_info *wl; - - struct gelic_wl_scan_info *best_bss; - int ret; - - wl = container_of(work, struct gelic_wl_info, assoc_work.work); - - down(&wl->assoc_stat_lock); - - if (wl->assoc_stat != GELIC_WL_ASSOC_STAT_DISCONN) - goto out; - - ret = gelic_wl_start_scan(wl, 0); - if (ret == -ERESTARTSYS) { - pr_debug("%s: scan start failed association\n", __func__); - schedule_delayed_work(&wl->assoc_work, HZ/10); /*FIXME*/ - goto out; - } else if (ret) { - pr_info("%s: scan prerequisite failed\n", __func__); - goto out; - } - - /* - * Wait for bss scan completion - * If we have scan list already, gelic_wl_start_scan() - * returns OK and raises the complete. Thus, - * it's ok to wait unconditionally here - */ - wait_for_completion(&wl->scan_done); - - pr_debug("%s: scan done\n", __func__); - down(&wl->scan_lock); - if (wl->scan_stat != GELIC_WL_SCAN_STAT_GOT_LIST) { - gelic_wl_send_iwap_event(wl, NULL); - pr_info("%s: no scan list. association failed\n", __func__); - goto scan_lock_out; - } - - /* find best matching bss */ - best_bss = gelic_wl_find_best_bss(wl); - if (!best_bss) { - gelic_wl_send_iwap_event(wl, NULL); - pr_info("%s: no bss matched. association failed\n", __func__); - goto scan_lock_out; - } - - /* ok, do association */ - ret = gelic_wl_associate_bss(wl, best_bss); - if (ret) - pr_info("%s: association failed %d\n", __func__, ret); -scan_lock_out: - up(&wl->scan_lock); -out: - up(&wl->assoc_stat_lock); -} -/* - * Interrupt handler - * Called from the ethernet interrupt handler - * Processes wireless specific virtual interrupts only - */ -void gelic_wl_interrupt(struct net_device *netdev, u64 status) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - - if (status & GELIC_CARD_WLAN_COMMAND_COMPLETED) { - pr_debug("%s:cmd complete\n", __func__); - complete(&wl->cmd_done_intr); - } - - if (status & GELIC_CARD_WLAN_EVENT_RECEIVED) { - pr_debug("%s:event received\n", __func__); - queue_delayed_work(wl->event_queue, &wl->event_work, 0); - } -} - -/* - * driver helpers - */ -#define IW_IOCTL(n) [(n) - SIOCSIWCOMMIT] -static const iw_handler gelic_wl_wext_handler[] = -{ - IW_IOCTL(SIOCGIWNAME) = gelic_wl_get_name, - IW_IOCTL(SIOCGIWRANGE) = gelic_wl_get_range, - IW_IOCTL(SIOCSIWSCAN) = gelic_wl_set_scan, - IW_IOCTL(SIOCGIWSCAN) = gelic_wl_get_scan, - IW_IOCTL(SIOCSIWAUTH) = gelic_wl_set_auth, - IW_IOCTL(SIOCGIWAUTH) = gelic_wl_get_auth, - IW_IOCTL(SIOCSIWESSID) = gelic_wl_set_essid, - IW_IOCTL(SIOCGIWESSID) = gelic_wl_get_essid, - IW_IOCTL(SIOCSIWENCODE) = gelic_wl_set_encode, - IW_IOCTL(SIOCGIWENCODE) = gelic_wl_get_encode, - IW_IOCTL(SIOCSIWAP) = gelic_wl_set_ap, - IW_IOCTL(SIOCGIWAP) = gelic_wl_get_ap, - IW_IOCTL(SIOCSIWENCODEEXT) = gelic_wl_set_encodeext, - IW_IOCTL(SIOCGIWENCODEEXT) = gelic_wl_get_encodeext, - IW_IOCTL(SIOCSIWMODE) = gelic_wl_set_mode, - IW_IOCTL(SIOCGIWMODE) = gelic_wl_get_mode, - IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick, -}; - -static struct iw_priv_args gelic_wl_private_args[] = -{ - { - .cmd = GELIC_WL_PRIV_SET_PSK, - .set_args = IW_PRIV_TYPE_CHAR | - (GELIC_WL_EURUS_PSK_MAX_LEN + 2), - .name = "set_psk" - }, - { - .cmd = GELIC_WL_PRIV_GET_PSK, - .get_args = IW_PRIV_TYPE_CHAR | - (GELIC_WL_EURUS_PSK_MAX_LEN + 2), - .name = "get_psk" - } -}; - -static const iw_handler gelic_wl_private_handler[] = -{ - gelic_wl_priv_set_psk, - gelic_wl_priv_get_psk, -}; - -static const struct iw_handler_def gelic_wl_wext_handler_def = { - .num_standard = ARRAY_SIZE(gelic_wl_wext_handler), - .standard = gelic_wl_wext_handler, - .get_wireless_stats = gelic_wl_get_wireless_stats, - .num_private = ARRAY_SIZE(gelic_wl_private_handler), - .num_private_args = ARRAY_SIZE(gelic_wl_private_args), - .private = gelic_wl_private_handler, - .private_args = gelic_wl_private_args, -}; - -static struct net_device *gelic_wl_alloc(struct gelic_card *card) -{ - struct net_device *netdev; - struct gelic_port *port; - struct gelic_wl_info *wl; - unsigned int i; - - pr_debug("%s:start\n", __func__); - netdev = alloc_etherdev(sizeof(struct gelic_port) + - sizeof(struct gelic_wl_info)); - pr_debug("%s: netdev =%p card=%p \np", __func__, netdev, card); - if (!netdev) - return NULL; - - port = netdev_priv(netdev); - port->netdev = netdev; - port->card = card; - port->type = GELIC_PORT_WIRELESS; - - wl = port_wl(port); - pr_debug("%s: wl=%p port=%p\n", __func__, wl, port); - - /* allocate scan list */ - wl->networks = kzalloc(sizeof(struct gelic_wl_scan_info) * - GELIC_WL_BSS_MAX_ENT, GFP_KERNEL); - - if (!wl->networks) - goto fail_bss; - - wl->eurus_cmd_queue = create_singlethread_workqueue("gelic_cmd"); - if (!wl->eurus_cmd_queue) - goto fail_cmd_workqueue; - - wl->event_queue = create_singlethread_workqueue("gelic_event"); - if (!wl->event_queue) - goto fail_event_workqueue; - - INIT_LIST_HEAD(&wl->network_free_list); - INIT_LIST_HEAD(&wl->network_list); - for (i = 0; i < GELIC_WL_BSS_MAX_ENT; i++) - list_add_tail(&wl->networks[i].list, - &wl->network_free_list); - init_completion(&wl->cmd_done_intr); - - INIT_DELAYED_WORK(&wl->event_work, gelic_wl_event_worker); - INIT_DELAYED_WORK(&wl->assoc_work, gelic_wl_assoc_worker); - init_MUTEX(&wl->scan_lock); - init_MUTEX(&wl->assoc_stat_lock); - - init_completion(&wl->scan_done); - /* for the case that no scan request is issued and stop() is called */ - complete(&wl->scan_done); - - spin_lock_init(&wl->lock); - - wl->scan_age = 5*HZ; /* FIXME */ - - /* buffer for receiving scanned list etc */ - BUILD_BUG_ON(PAGE_SIZE < - sizeof(struct gelic_eurus_scan_info) * - GELIC_EURUS_MAX_SCAN); - wl->buf = (void *)get_zeroed_page(GFP_KERNEL); - if (!wl->buf) { - pr_info("%s:buffer allocation failed\n", __func__); - goto fail_getpage; - } - pr_debug("%s:end\n", __func__); - return netdev; - -fail_getpage: - destroy_workqueue(wl->event_queue); -fail_event_workqueue: - destroy_workqueue(wl->eurus_cmd_queue); -fail_cmd_workqueue: - kfree(wl->networks); -fail_bss: - free_netdev(netdev); - pr_debug("%s:end error\n", __func__); - return NULL; - -} - -static void gelic_wl_free(struct gelic_wl_info *wl) -{ - struct gelic_wl_scan_info *scan_info; - unsigned int i; - - pr_debug("%s: <-\n", __func__); - - pr_debug("%s: destroy queues\n", __func__); - destroy_workqueue(wl->eurus_cmd_queue); - destroy_workqueue(wl->event_queue); - - scan_info = wl->networks; - for (i = 0; i < GELIC_WL_BSS_MAX_ENT; i++, scan_info++) - kfree(scan_info->hwinfo); - kfree(wl->networks); - - free_netdev(port_to_netdev(wl_port(wl))); - - pr_debug("%s: ->\n", __func__); -} - -static int gelic_wl_try_associate(struct net_device *netdev) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(netdev)); - int ret = -1; - unsigned int i; - - pr_debug("%s: <-\n", __func__); - - /* check constraits for start association */ - /* for no access restriction AP */ - if (wl->group_cipher_method == GELIC_WL_CIPHER_NONE) { - if (test_bit(GELIC_WL_STAT_CONFIGURED, - &wl->stat)) - goto do_associate; - else { - pr_debug("%s: no wep, not configured\n", __func__); - return ret; - } - } - - /* for WEP, one of four keys should be set */ - if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) { - /* one of keys set */ - for (i = 0; i < GELIC_WEP_KEYS; i++) { - if (test_bit(i, &wl->key_enabled)) - goto do_associate; - } - pr_debug("%s: WEP, but no key specified\n", __func__); - return ret; - } - - /* for WPA[2], psk should be set */ - if ((wl->group_cipher_method == GELIC_WL_CIPHER_TKIP) || - (wl->group_cipher_method == GELIC_WL_CIPHER_AES)) { - if (test_bit(GELIC_WL_STAT_WPA_PSK_SET, - &wl->stat)) - goto do_associate; - else { - pr_debug("%s: AES/TKIP, but PSK not configured\n", - __func__); - return ret; - } - } - -do_associate: - ret = schedule_delayed_work(&wl->assoc_work, 0); - pr_debug("%s: start association work %d\n", __func__, ret); - return ret; -} - -/* - * netdev handlers - */ -static int gelic_wl_open(struct net_device *netdev) -{ - struct gelic_card *card = netdev_card(netdev); - - pr_debug("%s:->%p\n", __func__, netdev); - - gelic_card_up(card); - - /* try to associate */ - gelic_wl_try_associate(netdev); - - netif_start_queue(netdev); - - pr_debug("%s:<-\n", __func__); - return 0; -} - -/* - * reset state machine - */ -static int gelic_wl_reset_state(struct gelic_wl_info *wl) -{ - struct gelic_wl_scan_info *target; - struct gelic_wl_scan_info *tmp; - - /* empty scan list */ - list_for_each_entry_safe(target, tmp, &wl->network_list, list) { - list_move_tail(&target->list, &wl->network_free_list); - } - wl->scan_stat = GELIC_WL_SCAN_STAT_INIT; - - /* clear configuration */ - wl->auth_method = GELIC_EURUS_AUTH_OPEN; - wl->group_cipher_method = GELIC_WL_CIPHER_NONE; - wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE; - wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE; - - wl->key_enabled = 0; - wl->current_key = 0; - - wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE; - wl->psk_len = 0; - - wl->essid_len = 0; - memset(wl->essid, 0, sizeof(wl->essid)); - memset(wl->bssid, 0, sizeof(wl->bssid)); - memset(wl->active_bssid, 0, sizeof(wl->active_bssid)); - - wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN; - - memset(&wl->iwstat, 0, sizeof(wl->iwstat)); - /* all status bit clear */ - wl->stat = 0; - return 0; -} - -/* - * Tell eurus to terminate association - */ -static void gelic_wl_disconnect(struct net_device *netdev) -{ - struct gelic_port *port = netdev_priv(netdev); - struct gelic_wl_info *wl = port_wl(port); - struct gelic_eurus_cmd *cmd; - - /* - * If scann process is running on chip, - * further requests will be rejected - */ - if (wl->scan_stat == GELIC_WL_SCAN_STAT_SCANNING) - wait_for_completion_timeout(&wl->scan_done, HZ); - - cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC, NULL, 0); - kfree(cmd); - gelic_wl_send_iwap_event(wl, NULL); -}; - -static int gelic_wl_stop(struct net_device *netdev) -{ - struct gelic_port *port = netdev_priv(netdev); - struct gelic_wl_info *wl = port_wl(port); - struct gelic_card *card = netdev_card(netdev); - - pr_debug("%s:<-\n", __func__); - - /* - * Cancel pending association work. - * event work can run after netdev down - */ - cancel_delayed_work(&wl->assoc_work); - - if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) - gelic_wl_disconnect(netdev); - - /* reset our state machine */ - gelic_wl_reset_state(wl); - - netif_stop_queue(netdev); - - gelic_card_down(card); - - pr_debug("%s:->\n", __func__); - return 0; -} - -/* -- */ - -static struct ethtool_ops gelic_wl_ethtool_ops = { - .get_drvinfo = gelic_net_get_drvinfo, - .get_link = gelic_wl_get_link, - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, - .get_rx_csum = gelic_net_get_rx_csum, - .set_rx_csum = gelic_net_set_rx_csum, -}; - -static void gelic_wl_setup_netdev_ops(struct net_device *netdev) -{ - struct gelic_wl_info *wl; - wl = port_wl(netdev_priv(netdev)); - BUG_ON(!wl); - netdev->open = &gelic_wl_open; - netdev->stop = &gelic_wl_stop; - netdev->hard_start_xmit = &gelic_net_xmit; - netdev->set_multicast_list = &gelic_net_set_multi; - netdev->change_mtu = &gelic_net_change_mtu; - netdev->wireless_data = &wl->wireless_data; - netdev->wireless_handlers = &gelic_wl_wext_handler_def; - /* tx watchdog */ - netdev->tx_timeout = &gelic_net_tx_timeout; - netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT; - - netdev->ethtool_ops = &gelic_wl_ethtool_ops; -#ifdef CONFIG_NET_POLL_CONTROLLER - netdev->poll_controller = gelic_net_poll_controller; -#endif -} - -/* - * driver probe/remove - */ -int gelic_wl_driver_probe(struct gelic_card *card) -{ - int ret; - struct net_device *netdev; - - pr_debug("%s:start\n", __func__); - - if (ps3_compare_firmware_version(1, 6, 0) < 0) - return 0; - if (!card->vlan[GELIC_PORT_WIRELESS].tx) - return 0; - - /* alloc netdevice for wireless */ - netdev = gelic_wl_alloc(card); - if (!netdev) - return -ENOMEM; - - /* setup net_device structure */ - gelic_wl_setup_netdev_ops(netdev); - - /* setup some of net_device and register it */ - ret = gelic_net_setup_netdev(netdev, card); - if (ret) - goto fail_setup; - card->netdev[GELIC_PORT_WIRELESS] = netdev; - - /* add enable wireless interrupt */ - card->irq_mask |= GELIC_CARD_WLAN_EVENT_RECEIVED | - GELIC_CARD_WLAN_COMMAND_COMPLETED; - /* to allow wireless commands while both interfaces are down */ - gelic_card_set_irq_mask(card, GELIC_CARD_WLAN_EVENT_RECEIVED | - GELIC_CARD_WLAN_COMMAND_COMPLETED); - pr_debug("%s:end\n", __func__); - return 0; - -fail_setup: - gelic_wl_free(port_wl(netdev_port(netdev))); - - return ret; -} - -int gelic_wl_driver_remove(struct gelic_card *card) -{ - struct gelic_wl_info *wl; - struct net_device *netdev; - - pr_debug("%s:start\n", __func__); - - if (ps3_compare_firmware_version(1, 6, 0) < 0) - return 0; - if (!card->vlan[GELIC_PORT_WIRELESS].tx) - return 0; - - netdev = card->netdev[GELIC_PORT_WIRELESS]; - wl = port_wl(netdev_priv(netdev)); - - /* if the interface was not up, but associated */ - if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) - gelic_wl_disconnect(netdev); - - complete(&wl->cmd_done_intr); - - /* cancel all work queue */ - cancel_delayed_work(&wl->assoc_work); - cancel_delayed_work(&wl->event_work); - flush_workqueue(wl->eurus_cmd_queue); - flush_workqueue(wl->event_queue); - - unregister_netdev(netdev); - - /* disable wireless interrupt */ - pr_debug("%s: disable intr\n", __func__); - card->irq_mask &= ~(GELIC_CARD_WLAN_EVENT_RECEIVED | - GELIC_CARD_WLAN_COMMAND_COMPLETED); - /* free bss list, netdev*/ - gelic_wl_free(wl); - pr_debug("%s:end\n", __func__); - return 0; -} diff --git a/trunk/drivers/net/ps3_gelic_wireless.h b/trunk/drivers/net/ps3_gelic_wireless.h deleted file mode 100644 index 103697166720..000000000000 --- a/trunk/drivers/net/ps3_gelic_wireless.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * PS3 gelic network driver. - * - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * Copyright 2007 Sony Corporation - * - * 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 version 2. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef _GELIC_WIRELESS_H -#define _GELIC_WIRELESS_H - -#include -#include - - -/* return value from GELIC_LV1_GET_WLAN_EVENT netcontrol */ -enum gelic_lv1_wl_event { - GELIC_LV1_WL_EVENT_DEVICE_READY = 0x01, /* Eurus ready */ - GELIC_LV1_WL_EVENT_SCAN_COMPLETED = 0x02, /* Scan has completed */ - GELIC_LV1_WL_EVENT_DEAUTH = 0x04, /* Deauthed by the AP */ - GELIC_LV1_WL_EVENT_BEACON_LOST = 0x08, /* Beacon lost detected */ - GELIC_LV1_WL_EVENT_CONNECTED = 0x10, /* Connected to AP */ - GELIC_LV1_WL_EVENT_WPA_CONNECTED = 0x20, /* WPA connection */ - GELIC_LV1_WL_EVENT_WPA_ERROR = 0x40, /* MIC error */ -}; - -/* arguments for GELIC_LV1_POST_WLAN_COMMAND netcontrol */ -enum gelic_eurus_command { - GELIC_EURUS_CMD_ASSOC = 1, /* association start */ - GELIC_EURUS_CMD_DISASSOC = 2, /* disassociate */ - GELIC_EURUS_CMD_START_SCAN = 3, /* scan start */ - GELIC_EURUS_CMD_GET_SCAN = 4, /* get scan result */ - GELIC_EURUS_CMD_SET_COMMON_CFG = 5, /* set common config */ - GELIC_EURUS_CMD_GET_COMMON_CFG = 6, /* set common config */ - GELIC_EURUS_CMD_SET_WEP_CFG = 7, /* set WEP config */ - GELIC_EURUS_CMD_GET_WEP_CFG = 8, /* get WEP config */ - GELIC_EURUS_CMD_SET_WPA_CFG = 9, /* set WPA config */ - GELIC_EURUS_CMD_GET_WPA_CFG = 10, /* get WPA config */ - GELIC_EURUS_CMD_GET_RSSI_CFG = 11, /* get RSSI info. */ - GELIC_EURUS_CMD_MAX_INDEX -}; - -/* for GELIC_EURUS_CMD_COMMON_CFG */ -enum gelic_eurus_bss_type { - GELIC_EURUS_BSS_INFRA = 0, - GELIC_EURUS_BSS_ADHOC = 1, /* not supported */ -}; - -enum gelic_eurus_auth_method { - GELIC_EURUS_AUTH_OPEN = 0, /* FIXME: WLAN_AUTH_OPEN */ - GELIC_EURUS_AUTH_SHARED = 1, /* not supported */ -}; - -enum gelic_eurus_opmode { - GELIC_EURUS_OPMODE_11BG = 0, /* 802.11b/g */ - GELIC_EURUS_OPMODE_11B = 1, /* 802.11b only */ - GELIC_EURUS_OPMODE_11G = 2, /* 802.11g only */ -}; - -struct gelic_eurus_common_cfg { - /* all fields are big endian */ - u16 scan_index; - u16 bss_type; /* infra or adhoc */ - u16 auth_method; /* shared key or open */ - u16 op_mode; /* B/G */ -} __attribute__((packed)); - - -/* for GELIC_EURUS_CMD_WEP_CFG */ -enum gelic_eurus_wep_security { - GELIC_EURUS_WEP_SEC_NONE = 0, - GELIC_EURUS_WEP_SEC_40BIT = 1, - GELIC_EURUS_WEP_SEC_104BIT = 2, -}; - -struct gelic_eurus_wep_cfg { - /* all fields are big endian */ - u16 security; - u8 key[4][16]; -} __attribute__((packed)); - -/* for GELIC_EURUS_CMD_WPA_CFG */ -enum gelic_eurus_wpa_security { - GELIC_EURUS_WPA_SEC_NONE = 0x0000, - /* group=TKIP, pairwise=TKIP */ - GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP = 0x0001, - /* group=AES, pairwise=AES */ - GELIC_EURUS_WPA_SEC_WPA_AES_AES = 0x0002, - /* group=TKIP, pairwise=TKIP */ - GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP = 0x0004, - /* group=AES, pairwise=AES */ - GELIC_EURUS_WPA_SEC_WPA2_AES_AES = 0x0008, - /* group=TKIP, pairwise=AES */ - GELIC_EURUS_WPA_SEC_WPA_TKIP_AES = 0x0010, - /* group=TKIP, pairwise=AES */ - GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES = 0x0020, -}; - -enum gelic_eurus_wpa_psk_type { - GELIC_EURUS_WPA_PSK_PASSPHRASE = 0, /* passphrase string */ - GELIC_EURUS_WPA_PSK_BIN = 1, /* 32 bytes binary key */ -}; - -#define GELIC_WL_EURUS_PSK_MAX_LEN 64 -#define WPA_PSK_LEN 32 /* WPA spec says 256bit */ - -struct gelic_eurus_wpa_cfg { - /* all fields are big endian */ - u16 security; - u16 psk_type; /* psk key encoding type */ - u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN]; /* psk key; hex or passphrase */ -} __attribute__((packed)); - -/* for GELIC_EURUS_CMD_{START,GET}_SCAN */ -enum gelic_eurus_scan_capability { - GELIC_EURUS_SCAN_CAP_ADHOC = 0x0000, - GELIC_EURUS_SCAN_CAP_INFRA = 0x0001, - GELIC_EURUS_SCAN_CAP_MASK = 0x0001, -}; - -enum gelic_eurus_scan_sec_type { - GELIC_EURUS_SCAN_SEC_NONE = 0x0000, - GELIC_EURUS_SCAN_SEC_WEP = 0x0100, - GELIC_EURUS_SCAN_SEC_WPA = 0x0200, - GELIC_EURUS_SCAN_SEC_WPA2 = 0x0400, - GELIC_EURUS_SCAN_SEC_MASK = 0x0f00, -}; - -enum gelic_eurus_scan_sec_wep_type { - GELIC_EURUS_SCAN_SEC_WEP_UNKNOWN = 0x0000, - GELIC_EURUS_SCAN_SEC_WEP_40 = 0x0001, - GELIC_EURUS_SCAN_SEC_WEP_104 = 0x0002, - GELIC_EURUS_SCAN_SEC_WEP_MASK = 0x0003, -}; - -enum gelic_eurus_scan_sec_wpa_type { - GELIC_EURUS_SCAN_SEC_WPA_UNKNOWN = 0x0000, - GELIC_EURUS_SCAN_SEC_WPA_TKIP = 0x0001, - GELIC_EURUS_SCAN_SEC_WPA_AES = 0x0002, - GELIC_EURUS_SCAN_SEC_WPA_MASK = 0x0003, -}; - -/* - * hw BSS information structure returned from GELIC_EURUS_CMD_GET_SCAN - */ -struct gelic_eurus_scan_info { - /* all fields are big endian */ - __be16 size; - __be16 rssi; /* percentage */ - __be16 channel; /* channel number */ - __be16 beacon_period; /* FIXME: in msec unit */ - __be16 capability; - __be16 security; - u8 bssid[8]; /* last ETH_ALEN are valid. bssid[0],[1] are unused */ - u8 essid[32]; /* IW_ESSID_MAX_SIZE */ - u8 rate[16]; /* first MAX_RATES_LENGTH(12) are valid */ - u8 ext_rate[16]; /* first MAX_RATES_EX_LENGTH(16) are valid */ - __be32 reserved1; - __be32 reserved2; - __be32 reserved3; - __be32 reserved4; - u8 elements[0]; /* ie */ -} __attribute__ ((packed)); - -/* the hypervisor returns bbs up to 16 */ -#define GELIC_EURUS_MAX_SCAN (16) -struct gelic_wl_scan_info { - struct list_head list; - struct gelic_eurus_scan_info *hwinfo; - - int valid; /* set 1 if this entry was in latest scanned list - * from Eurus */ - unsigned int eurus_index; /* index in the Eurus list */ - unsigned long last_scanned; /* acquired time */ - - unsigned int rate_len; - unsigned int rate_ext_len; - unsigned int essid_len; -}; - -/* for GELIC_EURUS_CMD_GET_RSSI */ -struct gelic_eurus_rssi_info { - /* big endian */ - __be16 rssi; -} __attribute__ ((packed)); - - -/* for 'stat' member of gelic_wl_info */ -enum gelic_wl_info_status_bit { - GELIC_WL_STAT_CONFIGURED, - GELIC_WL_STAT_CH_INFO, /* ch info aquired */ - GELIC_WL_STAT_ESSID_SET, /* ESSID specified by userspace */ - GELIC_WL_STAT_BSSID_SET, /* BSSID specified by userspace */ - GELIC_WL_STAT_WPA_PSK_SET, /* PMK specified by userspace */ - GELIC_WL_STAT_WPA_LEVEL_SET, /* WEP or WPA[2] selected */ -}; - -/* for 'scan_stat' member of gelic_wl_info */ -enum gelic_wl_scan_state { - /* just initialized or get last scan result failed */ - GELIC_WL_SCAN_STAT_INIT, - /* scan request issued, accepted or chip is scanning */ - GELIC_WL_SCAN_STAT_SCANNING, - /* scan results retrieved */ - GELIC_WL_SCAN_STAT_GOT_LIST, -}; - -/* for 'cipher_method' */ -enum gelic_wl_cipher_method { - GELIC_WL_CIPHER_NONE, - GELIC_WL_CIPHER_WEP, - GELIC_WL_CIPHER_TKIP, - GELIC_WL_CIPHER_AES, -}; - -/* for 'wpa_level' */ -enum gelic_wl_wpa_level { - GELIC_WL_WPA_LEVEL_NONE, - GELIC_WL_WPA_LEVEL_WPA, - GELIC_WL_WPA_LEVEL_WPA2, -}; - -/* for 'assoc_stat' */ -enum gelic_wl_assoc_state { - GELIC_WL_ASSOC_STAT_DISCONN, - GELIC_WL_ASSOC_STAT_ASSOCIATING, - GELIC_WL_ASSOC_STAT_ASSOCIATED, -}; -/* part of private data alloc_etherdev() allocated */ -#define GELIC_WEP_KEYS 4 -struct gelic_wl_info { - /* bss list */ - struct semaphore scan_lock; - struct list_head network_list; - struct list_head network_free_list; - struct gelic_wl_scan_info *networks; - - unsigned long scan_age; /* last scanned time */ - enum gelic_wl_scan_state scan_stat; - struct completion scan_done; - - /* eurus command queue */ - struct workqueue_struct *eurus_cmd_queue; - struct completion cmd_done_intr; - - /* eurus event handling */ - struct workqueue_struct *event_queue; - struct delayed_work event_work; - - /* wl status bits */ - unsigned long stat; - enum gelic_eurus_auth_method auth_method; /* open/shared */ - enum gelic_wl_cipher_method group_cipher_method; - enum gelic_wl_cipher_method pairwise_cipher_method; - enum gelic_wl_wpa_level wpa_level; /* wpa/wpa2 */ - - /* association handling */ - struct semaphore assoc_stat_lock; - struct delayed_work assoc_work; - enum gelic_wl_assoc_state assoc_stat; - struct completion assoc_done; - - spinlock_t lock; - u16 ch_info; /* available channels. bit0 = ch1 */ - /* WEP keys */ - u8 key[GELIC_WEP_KEYS][IW_ENCODING_TOKEN_MAX]; - unsigned long key_enabled; - unsigned int key_len[GELIC_WEP_KEYS]; - unsigned int current_key; - /* WWPA PSK */ - u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN]; - enum gelic_eurus_wpa_psk_type psk_type; - unsigned int psk_len; - - u8 essid[IW_ESSID_MAX_SIZE]; - u8 bssid[ETH_ALEN]; /* userland requested */ - u8 active_bssid[ETH_ALEN]; /* associated bssid */ - unsigned int essid_len; - - /* buffer for hypervisor IO */ - void *buf; - - struct iw_public_data wireless_data; - struct iw_statistics iwstat; -}; - -#define GELIC_WL_BSS_MAX_ENT 32 -#define GELIC_WL_ASSOC_RETRY 50 -static inline struct gelic_port *wl_port(struct gelic_wl_info *wl) -{ - return container_of((void *)wl, struct gelic_port, priv); -} -static inline struct gelic_wl_info *port_wl(struct gelic_port *port) -{ - return port_priv(port); -} - -struct gelic_eurus_cmd { - struct work_struct work; - struct gelic_wl_info *wl; - unsigned int cmd; /* command code */ - u64 tag; - u64 size; - void *buffer; - unsigned int buf_size; - struct completion done; - int status; - u64 cmd_status; -}; - -/* private ioctls to pass PSK */ -#define GELIC_WL_PRIV_SET_PSK (SIOCIWFIRSTPRIV + 0) -#define GELIC_WL_PRIV_GET_PSK (SIOCIWFIRSTPRIV + 1) - -extern int gelic_wl_driver_probe(struct gelic_card *card); -extern int gelic_wl_driver_remove(struct gelic_card *card); -extern void gelic_wl_interrupt(struct net_device *netdev, u64 status); -#endif /* _GELIC_WIRELESS_H */ diff --git a/trunk/drivers/net/r6040.c b/trunk/drivers/net/r6040.c index 19184e486ae9..2334f4ebf907 100644 --- a/trunk/drivers/net/r6040.c +++ b/trunk/drivers/net/r6040.c @@ -61,6 +61,7 @@ /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (6000 * HZ / 1000) +#define TIMER_WUT (jiffies + HZ * 1)/* timer wakeup time : 1 second */ /* RDC MAC I/O Size */ #define R6040_IO_SIZE 256 @@ -173,6 +174,8 @@ struct r6040_private { struct net_device *dev; struct mii_if_info mii_if; struct napi_struct napi; + struct net_device_stats stats; + u16 napi_rx_running; void __iomem *base; }; @@ -232,53 +235,17 @@ static void mdio_write(struct net_device *dev, int mii_id, int reg, int val) phy_write(ioaddr, lp->phy_addr, reg, val); } -static void r6040_free_txbufs(struct net_device *dev) -{ - struct r6040_private *lp = netdev_priv(dev); - int i; - - for (i = 0; i < TX_DCNT; i++) { - if (lp->tx_insert_ptr->skb_ptr) { - pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf, - MAX_BUF_SIZE, PCI_DMA_TODEVICE); - dev_kfree_skb(lp->tx_insert_ptr->skb_ptr); - lp->rx_insert_ptr->skb_ptr = NULL; - } - lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp; - } -} - -static void r6040_free_rxbufs(struct net_device *dev) +static void r6040_tx_timeout(struct net_device *dev) { - struct r6040_private *lp = netdev_priv(dev); - int i; - - for (i = 0; i < RX_DCNT; i++) { - if (lp->rx_insert_ptr->skb_ptr) { - pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf, - MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); - dev_kfree_skb(lp->rx_insert_ptr->skb_ptr); - lp->rx_insert_ptr->skb_ptr = NULL; - } - lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp; - } -} + struct r6040_private *priv = netdev_priv(dev); -static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, - dma_addr_t desc_dma, int size) -{ - struct r6040_descriptor *desc = desc_ring; - dma_addr_t mapping = desc_dma; + disable_irq(dev->irq); + napi_disable(&priv->napi); + spin_lock(&priv->lock); + dev->stats.tx_errors++; + spin_unlock(&priv->lock); - while (size-- > 0) { - mapping += sizeof(sizeof(*desc)); - desc->ndesc = cpu_to_le32(mapping); - desc->vndescp = desc + 1; - desc++; - } - desc--; - desc->ndesc = cpu_to_le32(desc_dma); - desc->vndescp = desc_ring; + netif_stop_queue(dev); } /* Allocate skb buffer for rx descriptor */ @@ -289,7 +256,7 @@ static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) descptr = lp->rx_insert_ptr; while (lp->rx_free_desc < RX_DCNT) { - descptr->skb_ptr = netdev_alloc_skb(dev, MAX_BUF_SIZE); + descptr->skb_ptr = dev_alloc_skb(MAX_BUF_SIZE); if (!descptr->skb_ptr) break; @@ -305,63 +272,6 @@ static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) lp->rx_insert_ptr = descptr; } -static void r6040_alloc_txbufs(struct net_device *dev) -{ - struct r6040_private *lp = netdev_priv(dev); - void __iomem *ioaddr = lp->base; - - lp->tx_free_desc = TX_DCNT; - - lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; - r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); - - iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); - iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); -} - -static void r6040_alloc_rxbufs(struct net_device *dev) -{ - struct r6040_private *lp = netdev_priv(dev); - void __iomem *ioaddr = lp->base; - - lp->rx_free_desc = 0; - - lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; - r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); - - rx_buf_alloc(lp, dev); - - iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); - iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); -} - -static void r6040_tx_timeout(struct net_device *dev) -{ - struct r6040_private *priv = netdev_priv(dev); - void __iomem *ioaddr = priv->base; - - printk(KERN_WARNING "%s: transmit timed out, status %4.4x, PHY status " - "%4.4x\n", - dev->name, ioread16(ioaddr + MIER), - mdio_read(dev, priv->mii_if.phy_id, MII_BMSR)); - - disable_irq(dev->irq); - napi_disable(&priv->napi); - spin_lock(&priv->lock); - /* Clear all descriptors */ - r6040_free_txbufs(dev); - r6040_free_rxbufs(dev); - r6040_alloc_txbufs(dev); - r6040_alloc_rxbufs(dev); - - /* Reset MAC */ - iowrite16(MAC_RST, ioaddr + MCR1); - spin_unlock(&priv->lock); - enable_irq(dev->irq); - - dev->stats.tx_errors++; - netif_wake_queue(dev); -} static struct net_device_stats *r6040_get_stats(struct net_device *dev) { @@ -370,11 +280,11 @@ static struct net_device_stats *r6040_get_stats(struct net_device *dev) unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - dev->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1); - dev->stats.multicast += ioread8(ioaddr + ME_CNT0); + priv->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1); + priv->stats.multicast += ioread8(ioaddr + ME_CNT0); spin_unlock_irqrestore(&priv->lock, flags); - return &dev->stats; + return &priv->stats; } /* Stop RDC MAC and Free the allocated resource */ @@ -383,6 +293,7 @@ static void r6040_down(struct net_device *dev) struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; struct pci_dev *pdev = lp->pdev; + int i; int limit = 2048; u16 *adrp; u16 cmd; @@ -402,12 +313,27 @@ static void r6040_down(struct net_device *dev) iowrite16(adrp[1], ioaddr + MID_0M); iowrite16(adrp[2], ioaddr + MID_0H); free_irq(dev->irq, dev); - /* Free RX buffer */ - r6040_free_rxbufs(dev); + for (i = 0; i < RX_DCNT; i++) { + if (lp->rx_insert_ptr->skb_ptr) { + pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf, + MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); + dev_kfree_skb(lp->rx_insert_ptr->skb_ptr); + lp->rx_insert_ptr->skb_ptr = NULL; + } + lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp; + } /* Free TX buffer */ - r6040_free_txbufs(dev); + for (i = 0; i < TX_DCNT; i++) { + if (lp->tx_insert_ptr->skb_ptr) { + pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf, + MAX_BUF_SIZE, PCI_DMA_TODEVICE); + dev_kfree_skb(lp->tx_insert_ptr->skb_ptr); + lp->rx_insert_ptr->skb_ptr = NULL; + } + lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp; + } /* Free Descriptor memory */ pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); @@ -506,24 +432,19 @@ static int r6040_rx(struct net_device *dev, int limit) /* Check for errors */ err = ioread16(ioaddr + MLSR); - if (err & 0x0400) - dev->stats.rx_errors++; + if (err & 0x0400) priv->stats.rx_errors++; /* RX FIFO over-run */ - if (err & 0x8000) - dev->stats.rx_fifo_errors++; + if (err & 0x8000) priv->stats.rx_fifo_errors++; /* RX descriptor unavailable */ - if (err & 0x0080) - dev->stats.rx_frame_errors++; + if (err & 0x0080) priv->stats.rx_frame_errors++; /* Received packet with length over buffer lenght */ - if (err & 0x0020) - dev->stats.rx_over_errors++; + if (err & 0x0020) priv->stats.rx_over_errors++; /* Received packet with too long or short */ - if (err & (0x0010 | 0x0008)) - dev->stats.rx_length_errors++; + if (err & (0x0010|0x0008)) priv->stats.rx_length_errors++; /* Received packet with CRC errors */ if (err & 0x0004) { spin_lock(&priv->lock); - dev->stats.rx_crc_errors++; + priv->stats.rx_crc_errors++; spin_unlock(&priv->lock); } @@ -548,8 +469,8 @@ static int r6040_rx(struct net_device *dev, int limit) /* Send to upper layer */ netif_receive_skb(skb_ptr); dev->last_rx = jiffies; - dev->stats.rx_packets++; - dev->stats.rx_bytes += descptr->len; + priv->dev->stats.rx_packets++; + priv->dev->stats.rx_bytes += descptr->len; /* To next descriptor */ descptr = descptr->vndescp; priv->rx_free_desc--; @@ -577,13 +498,11 @@ static void r6040_tx(struct net_device *dev) /* Check for errors */ err = ioread16(ioaddr + MLSR); - if (err & 0x0200) - dev->stats.rx_fifo_errors++; - if (err & (0x2000 | 0x4000)) - dev->stats.tx_carrier_errors++; + if (err & 0x0200) priv->stats.rx_fifo_errors++; + if (err & (0x2000 | 0x4000)) priv->stats.tx_carrier_errors++; if (descptr->status & 0x8000) - break; /* Not complete */ + break; /* Not complte */ skb_ptr = descptr->skb_ptr; pci_unmap_single(priv->pdev, descptr->buf, skb_ptr->len, PCI_DMA_TODEVICE); @@ -626,6 +545,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id) struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; u16 status; + int handled = 1; /* Mask off RDC MAC interrupt */ iowrite16(MSK_INT, ioaddr + MIER); @@ -645,7 +565,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id) if (status & 0x10) r6040_tx(dev); - return IRQ_HANDLED; + return IRQ_RETVAL(handled); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -657,15 +577,53 @@ static void r6040_poll_controller(struct net_device *dev) } #endif +static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, + dma_addr_t desc_dma, int size) +{ + struct r6040_descriptor *desc = desc_ring; + dma_addr_t mapping = desc_dma; + + while (size-- > 0) { + mapping += sizeof(sizeof(*desc)); + desc->ndesc = cpu_to_le32(mapping); + desc->vndescp = desc + 1; + desc++; + } + desc--; + desc->ndesc = cpu_to_le32(desc_dma); + desc->vndescp = desc_ring; +} + /* Init RDC MAC */ static void r6040_up(struct net_device *dev) { struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; - /* Initialise and alloc RX/TX buffers */ - r6040_alloc_txbufs(dev); - r6040_alloc_rxbufs(dev); + /* Initialize */ + lp->tx_free_desc = TX_DCNT; + lp->rx_free_desc = 0; + /* Init descriptor */ + lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; + lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; + /* Init TX descriptor */ + r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); + + /* Init RX descriptor */ + r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); + + /* Allocate buffer for RX descriptor */ + rx_buf_alloc(lp, dev); + + /* + * TX and RX descriptor start registers. + * Lower 16-bits to MxD_SA0. Higher 16-bits to MxD_SA1. + */ + iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); + iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); + + iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); + iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); /* Buffer Size Register */ iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR); @@ -731,7 +689,8 @@ static void r6040_timer(unsigned long data) } /* Timer active again */ - mod_timer(&lp->timer, jiffies + round_jiffies(HZ)); + lp->timer.expires = TIMER_WUT; + add_timer(&lp->timer); } /* Read/set MAC address routines */ @@ -787,10 +746,14 @@ static int r6040_open(struct net_device *dev) napi_enable(&lp->napi); netif_start_queue(dev); - /* set and active a timer process */ - setup_timer(&lp->timer, r6040_timer, (unsigned long) dev); - if (lp->switch_sig != ICPLUS_PHY_ID) - mod_timer(&lp->timer, jiffies + HZ); + if (lp->switch_sig != ICPLUS_PHY_ID) { + /* set and active a timer process */ + init_timer(&lp->timer); + lp->timer.expires = TIMER_WUT; + lp->timer.data = (unsigned long)dev; + lp->timer.function = &r6040_timer; + add_timer(&lp->timer); + } return 0; } diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index 202fdf356621..2e9e88be7b33 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -1630,8 +1630,7 @@ static inline void sis190_init_rxfilter(struct net_device *dev) SIS_PCI_COMMIT(); } -static int __devinit sis190_get_mac_addr(struct pci_dev *pdev, - struct net_device *dev) +static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev) { u8 from; diff --git a/trunk/drivers/oprofile/buffer_sync.c b/trunk/drivers/oprofile/buffer_sync.c index b07ba2a14119..8134c7e198a5 100644 --- a/trunk/drivers/oprofile/buffer_sync.c +++ b/trunk/drivers/oprofile/buffer_sync.c @@ -187,22 +187,23 @@ void sync_stop(void) end_sync(); } - + /* Optimisation. We can manage without taking the dcookie sem * because we cannot reach this code without at least one * dcookie user still being registered (namely, the reader * of the event buffer). */ -static inline unsigned long fast_get_dcookie(struct path *path) +static inline unsigned long fast_get_dcookie(struct dentry * dentry, + struct vfsmount * vfsmnt) { unsigned long cookie; - - if (path->dentry->d_cookie) - return (unsigned long)path->dentry; - get_dcookie(path, &cookie); + + if (dentry->d_cookie) + return (unsigned long)dentry; + get_dcookie(dentry, vfsmnt, &cookie); return cookie; } - + /* Look up the dcookie for the task's first VM_EXECUTABLE mapping, * which corresponds loosely to "application name". This is * not strictly necessary but allows oprofile to associate @@ -221,7 +222,8 @@ static unsigned long get_exec_dcookie(struct mm_struct * mm) continue; if (!(vma->vm_flags & VM_EXECUTABLE)) continue; - cookie = fast_get_dcookie(&vma->vm_file->f_path); + cookie = fast_get_dcookie(vma->vm_file->f_path.dentry, + vma->vm_file->f_path.mnt); break; } @@ -246,7 +248,8 @@ static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, o continue; if (vma->vm_file) { - cookie = fast_get_dcookie(&vma->vm_file->f_path); + cookie = fast_get_dcookie(vma->vm_file->f_path.dentry, + vma->vm_file->f_path.mnt); *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; } else { diff --git a/trunk/drivers/pnp/pnpacpi/core.c b/trunk/drivers/pnp/pnpacpi/core.c index c283a9a70d83..662b4c279cfc 100644 --- a/trunk/drivers/pnp/pnpacpi/core.c +++ b/trunk/drivers/pnp/pnpacpi/core.c @@ -36,7 +36,7 @@ static int num = 0; * have irqs (PIC, Timer) because we call acpi_register_gsi. * Finally, only devices that have a CRS method need to be in this list. */ -static struct acpi_device_id excluded_id_list[] __initdata = { +static struct __initdata acpi_device_id excluded_id_list[] = { {"PNP0C09", 0}, /* EC */ {"PNP0C0F", 0}, /* Link device */ {"PNP0000", 0}, /* PIC */ diff --git a/trunk/drivers/pnp/pnpbios/core.c b/trunk/drivers/pnp/pnpbios/core.c index a8a51500e1e9..f7e67197a568 100644 --- a/trunk/drivers/pnp/pnpbios/core.c +++ b/trunk/drivers/pnp/pnpbios/core.c @@ -105,6 +105,8 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) char *argv[3], **envp, *buf, *scratch; int i = 0, value; + if (!current->fs->root) + return -EAGAIN; if (!(envp = kcalloc(20, sizeof(char *), GFP_KERNEL))) return -ENOMEM; if (!(buf = kzalloc(256, GFP_KERNEL))) { diff --git a/trunk/drivers/ps3/ps3-lpm.c b/trunk/drivers/ps3/ps3-lpm.c index 6c9592ce4996..4c066545d176 100644 --- a/trunk/drivers/ps3/ps3-lpm.c +++ b/trunk/drivers/ps3/ps3-lpm.c @@ -76,6 +76,7 @@ * * @pm_control: Shadow of the processor's pm_control register. * @pm_start_stop: Shadow of the processor's pm_start_stop register. + * @pm_interval: Shadow of the processor's pm_interval register. * @group_control: Shadow of the processor's group_control register. * @debug_bus_control: Shadow of the processor's debug_bus_control register. * @@ -90,6 +91,7 @@ struct ps3_lpm_shadow_regs { u64 pm_control; u64 pm_start_stop; + u64 pm_interval; u64 group_control; u64 debug_bus_control; }; @@ -179,9 +181,9 @@ void ps3_set_bookmark(u64 bookmark) * includes cycles before the call. */ - asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;"); + asm volatile("or 29, 29, 29;"); /* db10cyc */ mtspr(SPRN_BKMK, bookmark); - asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;"); + asm volatile("or 29, 29, 29;"); /* db10cyc */ } EXPORT_SYMBOL_GPL(ps3_set_bookmark); @@ -406,14 +408,7 @@ u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg) case pm_start_stop: return lpm_priv->shadow.pm_start_stop; case pm_interval: - result = lv1_set_lpm_interval(lpm_priv->lpm_id, 0, 0, &val); - if (result) { - val = 0; - dev_dbg(sbd_core(), "%s:%u: lv1 set_inteval failed: " - "reg %u, %s\n", __func__, __LINE__, reg, - ps3_result(result)); - } - return (u32)val; + return lpm_priv->shadow.pm_interval; case group_control: return lpm_priv->shadow.group_control; case debug_bus_control: @@ -480,8 +475,10 @@ void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val) lpm_priv->shadow.pm_control = val; break; case pm_interval: - result = lv1_set_lpm_interval(lpm_priv->lpm_id, val, - PS3_WRITE_PM_MASK, &dummy); + if (val != lpm_priv->shadow.pm_interval) + result = lv1_set_lpm_interval(lpm_priv->lpm_id, val, + PS3_WRITE_PM_MASK, &dummy); + lpm_priv->shadow.pm_interval = val; break; case pm_start_stop: if (val != lpm_priv->shadow.pm_start_stop) @@ -1143,6 +1140,7 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache, lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT; lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT; + lpm_priv->shadow.pm_interval = PS3_LPM_SHADOW_REG_INIT; lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT; lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT; diff --git a/trunk/drivers/ps3/ps3-sys-manager.c b/trunk/drivers/ps3/ps3-sys-manager.c index d4f6f960dd18..c3c3aba3ffce 100644 --- a/trunk/drivers/ps3/ps3-sys-manager.c +++ b/trunk/drivers/ps3/ps3-sys-manager.c @@ -28,6 +28,10 @@ #include "vuart.h" +MODULE_AUTHOR("Sony Corporation"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("PS3 System Manager"); + /** * ps3_sys_manager - PS3 system manager driver. * @@ -138,11 +142,9 @@ enum ps3_sys_manager_attr { /** * enum ps3_sys_manager_event - External event type, reported by system manager. - * @PS3_SM_EVENT_POWER_PRESSED: payload.value = - * enum ps3_sys_manager_button_event. + * @PS3_SM_EVENT_POWER_PRESSED: payload.value not used. * @PS3_SM_EVENT_POWER_RELEASED: payload.value = time pressed in millisec. - * @PS3_SM_EVENT_RESET_PRESSED: payload.value = - * enum ps3_sys_manager_button_event. + * @PS3_SM_EVENT_RESET_PRESSED: payload.value not used. * @PS3_SM_EVENT_RESET_RELEASED: payload.value = time pressed in millisec. * @PS3_SM_EVENT_THERMAL_ALERT: payload.value = thermal zone id. * @PS3_SM_EVENT_THERMAL_CLEARED: payload.value = thermal zone id. @@ -159,17 +161,6 @@ enum ps3_sys_manager_event { /* no info on controller events */ }; -/** - * enum ps3_sys_manager_button_event - Button event payload values. - * @PS3_SM_BUTTON_EVENT_HARD: Hardware generated event. - * @PS3_SM_BUTTON_EVENT_SOFT: Software generated event. - */ - -enum ps3_sys_manager_button_event { - PS3_SM_BUTTON_EVENT_HARD = 0, - PS3_SM_BUTTON_EVENT_SOFT = 1, -}; - /** * enum ps3_sys_manager_next_op - Operation to perform after lpar is destroyed. */ @@ -190,9 +181,7 @@ enum ps3_sys_manager_next_op { * @PS3_SM_WAKE_P_O_R: Power on reset. * * Additional wakeup sources when specifying PS3_SM_NEXT_OP_SYS_SHUTDOWN. - * The system will always wake from the PS3_SM_WAKE_DEFAULT sources. - * Sources listed here are the only ones available to guests in the - * other-os lpar. + * System will always wake from the PS3_SM_WAKE_DEFAULT sources. */ enum ps3_sys_manager_wake_source { @@ -200,7 +189,7 @@ enum ps3_sys_manager_wake_source { PS3_SM_WAKE_DEFAULT = 0, PS3_SM_WAKE_RTC = 0x00000040, PS3_SM_WAKE_RTC_ERROR = 0x00000080, - PS3_SM_WAKE_P_O_R = 0x80000000, + PS3_SM_WAKE_P_O_R = 0x10000000, }; /** @@ -429,10 +418,8 @@ static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev) switch (event.type) { case PS3_SM_EVENT_POWER_PRESSED: - dev_dbg(&dev->core, "%s:%d: POWER_PRESSED (%s)\n", - __func__, __LINE__, - (event.value == PS3_SM_BUTTON_EVENT_SOFT ? "soft" - : "hard")); + dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n", + __func__, __LINE__); ps3_sm_force_power_off = 1; /* * A memory barrier is use here to sync memory since @@ -447,10 +434,8 @@ static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev) __func__, __LINE__, event.value); break; case PS3_SM_EVENT_RESET_PRESSED: - dev_dbg(&dev->core, "%s:%d: RESET_PRESSED (%s)\n", - __func__, __LINE__, - (event.value == PS3_SM_BUTTON_EVENT_SOFT ? "soft" - : "hard")); + dev_dbg(&dev->core, "%s:%d: RESET_PRESSED\n", + __func__, __LINE__); ps3_sm_force_power_off = 0; /* * A memory barrier is use here to sync memory since @@ -637,7 +622,7 @@ static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev) ps3_vuart_cancel_async(dev); ps3_sys_manager_send_attr(dev, 0); - ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_REBOOT, + ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT, PS3_SM_WAKE_DEFAULT); ps3_sys_manager_send_request_shutdown(dev); @@ -714,7 +699,4 @@ static int __init ps3_sys_manager_init(void) module_init(ps3_sys_manager_init); /* Module remove not supported. */ -MODULE_AUTHOR("Sony Corporation"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("PS3 System Manager"); MODULE_ALIAS(PS3_MODULE_ALIAS_SYSTEM_MANAGER); diff --git a/trunk/drivers/s390/net/claw.h b/trunk/drivers/s390/net/claw.h index 1a89d989f348..1ee9a6f06541 100644 --- a/trunk/drivers/s390/net/claw.h +++ b/trunk/drivers/s390/net/claw.h @@ -114,20 +114,11 @@ do { \ debug_event(claw_dbf_##name,level,(void*)(addr),len); \ } while (0) -/* Allow to sort out low debug levels early to avoid wasted sprints */ -static inline int claw_dbf_passes(debug_info_t *dbf_grp, int level) -{ - return (level <= dbf_grp->level); -} - #define CLAW_DBF_TEXT_(level,name,text...) \ - do { \ - if (claw_dbf_passes(claw_dbf_##name, level)) { \ - sprintf(debug_buffer, text); \ - debug_text_event(claw_dbf_##name, level, \ - debug_buffer); \ - } \ - } while (0) +do { \ + sprintf(debug_buffer, text); \ + debug_text_event(claw_dbf_##name,level, debug_buffer);\ +} while (0) /******************************************************* * Define Control Blocks * @@ -287,6 +278,8 @@ struct claw_env { __u16 write_size; /* write buffer size */ __u16 dev_id; /* device ident */ __u8 packing; /* are we packing? */ + volatile __u8 queme_switch; /* gate for imed packing */ + volatile unsigned long pk_delay; /* Delay for adaptive packing */ __u8 in_use; /* device active flag */ struct net_device *ndev; /* backward ptr to the net dev*/ }; diff --git a/trunk/drivers/s390/net/lcs.c b/trunk/drivers/s390/net/lcs.c index f51ed9972587..7bfe8d707a34 100644 --- a/trunk/drivers/s390/net/lcs.c +++ b/trunk/drivers/s390/net/lcs.c @@ -94,7 +94,7 @@ static int lcs_register_debug_facility(void) { lcs_dbf_setup = debug_register("lcs_setup", 2, 1, 8); - lcs_dbf_trace = debug_register("lcs_trace", 4, 1, 8); + lcs_dbf_trace = debug_register("lcs_trace", 2, 2, 8); if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) { PRINT_ERR("Not enough memory for debug facility.\n"); lcs_unregister_debug_facility(); diff --git a/trunk/drivers/s390/net/lcs.h b/trunk/drivers/s390/net/lcs.h index d58fea52557d..8976fb0b070a 100644 --- a/trunk/drivers/s390/net/lcs.h +++ b/trunk/drivers/s390/net/lcs.h @@ -16,19 +16,11 @@ do { \ debug_event(lcs_dbf_##name,level,(void*)(addr),len); \ } while (0) -/* Allow to sort out low debug levels early to avoid wasted sprints */ -static inline int lcs_dbf_passes(debug_info_t *dbf_grp, int level) -{ - return (level <= dbf_grp->level); -} - #define LCS_DBF_TEXT_(level,name,text...) \ - do { \ - if (lcs_dbf_passes(lcs_dbf_##name, level)) { \ - sprintf(debug_buffer, text); \ - debug_text_event(lcs_dbf_##name, level, debug_buffer); \ - } \ - } while (0) +do { \ + sprintf(debug_buffer, text); \ + debug_text_event(lcs_dbf_##name,level, debug_buffer);\ +} while (0) /** * sysfs related stuff diff --git a/trunk/drivers/s390/net/netiucv.c b/trunk/drivers/s390/net/netiucv.c index 874a19994489..f3d893cfe61d 100644 --- a/trunk/drivers/s390/net/netiucv.c +++ b/trunk/drivers/s390/net/netiucv.c @@ -97,22 +97,12 @@ MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf); -/* Allow to sort out low debug levels early to avoid wasted sprints */ -static inline int iucv_dbf_passes(debug_info_t *dbf_grp, int level) -{ - return (level <= dbf_grp->level); -} - -#define IUCV_DBF_TEXT_(name, level, text...) \ - do { \ - if (iucv_dbf_passes(iucv_dbf_##name, level)) { \ - char* iucv_dbf_txt_buf = \ - get_cpu_var(iucv_dbf_txt_buf); \ - sprintf(iucv_dbf_txt_buf, text); \ - debug_text_event(iucv_dbf_##name, level, \ - iucv_dbf_txt_buf); \ - put_cpu_var(iucv_dbf_txt_buf); \ - } \ +#define IUCV_DBF_TEXT_(name,level,text...) \ + do { \ + char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf); \ + sprintf(iucv_dbf_txt_buf, text); \ + debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \ + put_cpu_var(iucv_dbf_txt_buf); \ } while (0) #define IUCV_DBF_SPRINTF(name,level,text...) \ @@ -147,7 +137,6 @@ PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ #define PRINTK_HEADER " iucv: " /* for debugging */ static struct device_driver netiucv_driver = { - .owner = THIS_MODULE, .name = "netiucv", .bus = &iucv_bus, }; @@ -583,9 +572,9 @@ static void netiucv_callback_connres(struct iucv_path *path, u8 ipuser[16]) } /** - * NOP action for statemachines + * Dummy NOP action for all statemachines */ -static void netiucv_action_nop(fsm_instance *fi, int event, void *arg) +static void fsm_action_nop(fsm_instance *fi, int event, void *arg) { } @@ -1121,7 +1110,7 @@ static const fsm_node dev_fsm[] = { { DEV_STATE_RUNNING, DEV_EVENT_STOP, dev_action_stop }, { DEV_STATE_RUNNING, DEV_EVENT_CONDOWN, dev_action_conndown }, - { DEV_STATE_RUNNING, DEV_EVENT_CONUP, netiucv_action_nop }, + { DEV_STATE_RUNNING, DEV_EVENT_CONUP, fsm_action_nop }, }; static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node); diff --git a/trunk/drivers/serial/sh-sci.c b/trunk/drivers/serial/sh-sci.c index 9ce12cb2cebc..ddf639144538 100644 --- a/trunk/drivers/serial/sh-sci.c +++ b/trunk/drivers/serial/sh-sci.c @@ -393,7 +393,7 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) if (cflag & CRTSCTS) { fcr_val |= SCFCR_MCE; } else { -#if defined(CONFIG_CPU_SUBTYPE_SH7343) || defined(CONFIG_CPU_SUBTYPE_SH7366) +#ifdef CONFIG_CPU_SUBTYPE_SH7343 /* Nothing */ #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) || \ diff --git a/trunk/drivers/serial/sh-sci.h b/trunk/drivers/serial/sh-sci.h index 01a9dd715f5d..f5764ebcfe07 100644 --- a/trunk/drivers/serial/sh-sci.h +++ b/trunk/drivers/serial/sh-sci.h @@ -97,18 +97,13 @@ # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY # define PORT_PSCR 0xA405011E -#elif defined(CONFIG_CPU_SUBTYPE_SH7366) -# define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ -# define SCSPTR0 SCPDR0 -# define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ -# define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) +# include # define SCIF_BASE_ADDR 0x01030000 # define SCIF_ADDR_SH5 PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR # define SCIF_PTR2_OFFS 0x0000020 @@ -582,7 +577,7 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } -#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || defined(CONFIG_CPU_SUBTYPE_SH7366) +#elif defined(CONFIG_CPU_SUBTYPE_SH7722) static inline int sci_rxd_in(struct uart_port *port) { if (port->mapbase == 0xffe00000) diff --git a/trunk/drivers/sh/maple/maple.c b/trunk/drivers/sh/maple/maple.c index 9cfcfd8dad5e..e52a6296ca46 100644 --- a/trunk/drivers/sh/maple/maple.c +++ b/trunk/drivers/sh/maple/maple.c @@ -31,7 +31,6 @@ #include #include #include -#include MODULE_AUTHOR("Yaegshi Takeshi, Paul Mundt, M.R. Brown, Adrian McMenamin"); MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); @@ -54,12 +53,12 @@ static struct device maple_bus; static int subdevice_map[MAPLE_PORTS]; static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; static unsigned long maple_pnp_time; -static int started, scanning, liststatus, realscan; +static int started, scanning, liststatus; static struct kmem_cache *maple_queue_cache; struct maple_device_specify { - int port; - int unit; + int port; + int unit; }; /** @@ -69,22 +68,22 @@ struct maple_device_specify { */ int maple_driver_register(struct device_driver *drv) { - if (!drv) - return -EINVAL; - drv->bus = &maple_bus_type; - return driver_register(drv); + if (!drv) + return -EINVAL; + drv->bus = &maple_bus_type; + return driver_register(drv); } EXPORT_SYMBOL_GPL(maple_driver_register); /* set hardware registers to enable next round of dma */ static void maplebus_dma_reset(void) { - ctrl_outl(MAPLE_MAGIC, MAPLE_RESET); - /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */ - ctrl_outl(1, MAPLE_TRIGTYPE); - ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(50000), MAPLE_SPEED); - ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); - ctrl_outl(1, MAPLE_ENABLE); + ctrl_outl(MAPLE_MAGIC, MAPLE_RESET); + /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */ + ctrl_outl(1, MAPLE_TRIGTYPE); + ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(50000), MAPLE_SPEED); + ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); + ctrl_outl(1, MAPLE_ENABLE); } /** @@ -95,36 +94,27 @@ static void maplebus_dma_reset(void) * @function: the function code for the device */ void maple_getcond_callback(struct maple_device *dev, - void (*callback) (struct mapleq *mq), - unsigned long interval, unsigned long function) + void (*callback) (struct mapleq * mq), + unsigned long interval, unsigned long function) { - dev->callback = callback; - dev->interval = interval; - dev->function = cpu_to_be32(function); - dev->when = jiffies; + dev->callback = callback; + dev->interval = interval; + dev->function = cpu_to_be32(function); + dev->when = jiffies; } EXPORT_SYMBOL_GPL(maple_getcond_callback); static int maple_dma_done(void) { - return (ctrl_inl(MAPLE_STATE) & 1) == 0; + return (ctrl_inl(MAPLE_STATE) & 1) == 0; } static void maple_release_device(struct device *dev) { - struct maple_device *mdev; - struct mapleq *mq; - if (!dev) - return; - mdev = to_maple_dev(dev); - mq = mdev->mq; - if (mq) { - if (mq->recvbufdcsp) - kmem_cache_free(maple_queue_cache, mq->recvbufdcsp); - kfree(mq); - mq = NULL; - } - kfree(mdev); + if (dev->type) { + kfree(dev->type->name); + kfree(dev->type); + } } /** @@ -133,64 +123,60 @@ static void maple_release_device(struct device *dev) */ void maple_add_packet(struct mapleq *mq) { - mutex_lock(&maple_list_lock); - list_add(&mq->list, &maple_waitq); - mutex_unlock(&maple_list_lock); + mutex_lock(&maple_list_lock); + list_add(&mq->list, &maple_waitq); + mutex_unlock(&maple_list_lock); } EXPORT_SYMBOL_GPL(maple_add_packet); -static struct mapleq *maple_allocq(struct maple_device *mdev) +static struct mapleq *maple_allocq(struct maple_device *dev) { - struct mapleq *mq; + struct mapleq *mq; - mq = kmalloc(sizeof(*mq), GFP_KERNEL); - if (!mq) - return NULL; + mq = kmalloc(sizeof(*mq), GFP_KERNEL); + if (!mq) + return NULL; - mq->dev = mdev; - mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL); - mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp); - if (!mq->recvbuf) { - kfree(mq); - return NULL; - } + mq->dev = dev; + mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL); + mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp); + if (!mq->recvbuf) { + kfree(mq); + return NULL; + } - return mq; + return mq; } static struct maple_device *maple_alloc_dev(int port, int unit) { - struct maple_device *mdev; - - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); - if (!mdev) - return NULL; - - mdev->port = port; - mdev->unit = unit; - mdev->mq = maple_allocq(mdev); - - if (!mdev->mq) { - kfree(mdev); - return NULL; - } - mdev->dev.bus = &maple_bus_type; - mdev->dev.parent = &maple_bus; - mdev->function = 0; - return mdev; + struct maple_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->port = port; + dev->unit = unit; + dev->mq = maple_allocq(dev); + + if (!dev->mq) { + kfree(dev); + return NULL; + } + + return dev; } static void maple_free_dev(struct maple_device *mdev) { - if (!mdev) - return; - if (mdev->mq) { - if (mdev->mq->recvbufdcsp) - kmem_cache_free(maple_queue_cache, - mdev->mq->recvbufdcsp); - kfree(mdev->mq); - } - kfree(mdev); + if (!mdev) + return; + if (mdev->mq) { + kmem_cache_free(maple_queue_cache, mdev->mq->recvbufdcsp); + kfree(mdev->mq); + } + kfree(mdev); } /* process the command queue into a maple command block @@ -198,162 +184,153 @@ static void maple_free_dev(struct maple_device *mdev) */ static void maple_build_block(struct mapleq *mq) { - int port, unit, from, to, len; - unsigned long *lsendbuf = mq->sendbuf; + int port, unit, from, to, len; + unsigned long *lsendbuf = mq->sendbuf; - port = mq->dev->port & 3; - unit = mq->dev->unit; - len = mq->length; - from = port << 6; - to = (port << 6) | (unit > 0 ? (1 << (unit - 1)) & 0x1f : 0x20); + port = mq->dev->port & 3; + unit = mq->dev->unit; + len = mq->length; + from = port << 6; + to = (port << 6) | (unit > 0 ? (1 << (unit - 1)) & 0x1f : 0x20); - *maple_lastptr &= 0x7fffffff; - maple_lastptr = maple_sendptr; + *maple_lastptr &= 0x7fffffff; + maple_lastptr = maple_sendptr; - *maple_sendptr++ = (port << 16) | len | 0x80000000; - *maple_sendptr++ = PHYSADDR(mq->recvbuf); - *maple_sendptr++ = - mq->command | (to << 8) | (from << 16) | (len << 24); + *maple_sendptr++ = (port << 16) | len | 0x80000000; + *maple_sendptr++ = PHYSADDR(mq->recvbuf); + *maple_sendptr++ = + mq->command | (to << 8) | (from << 16) | (len << 24); - while (len-- > 0) - *maple_sendptr++ = *lsendbuf++; + while (len-- > 0) + *maple_sendptr++ = *lsendbuf++; } /* build up command queue */ static void maple_send(void) { - int i; - int maple_packets; - struct mapleq *mq, *nmq; - - if (!list_empty(&maple_sentq)) - return; - if (list_empty(&maple_waitq) || !maple_dma_done()) - return; - maple_packets = 0; - maple_sendptr = maple_lastptr = maple_sendbuf; - list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { - maple_build_block(mq); - list_move(&mq->list, &maple_sentq); - if (maple_packets++ > MAPLE_MAXPACKETS) - break; - } - if (maple_packets > 0) { - for (i = 0; i < (1 << MAPLE_DMA_PAGES); i++) - dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE, - PAGE_SIZE, DMA_BIDIRECTIONAL); - } + int i; + int maple_packets; + struct mapleq *mq, *nmq; + + if (!list_empty(&maple_sentq)) + return; + if (list_empty(&maple_waitq) || !maple_dma_done()) + return; + maple_packets = 0; + maple_sendptr = maple_lastptr = maple_sendbuf; + list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { + maple_build_block(mq); + list_move(&mq->list, &maple_sentq); + if (maple_packets++ > MAPLE_MAXPACKETS) + break; + } + if (maple_packets > 0) { + for (i = 0; i < (1 << MAPLE_DMA_PAGES); i++) + dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE, + PAGE_SIZE, DMA_BIDIRECTIONAL); + } } static int attach_matching_maple_driver(struct device_driver *driver, - void *devptr) + void *devptr) { - struct maple_driver *maple_drv; - struct maple_device *mdev; - - mdev = devptr; - maple_drv = to_maple_driver(driver); - if (mdev->devinfo.function & be32_to_cpu(maple_drv->function)) { - if (maple_drv->connect(mdev) == 0) { - mdev->driver = maple_drv; - return 1; - } - } - return 0; + struct maple_driver *maple_drv; + struct maple_device *mdev; + + mdev = devptr; + maple_drv = to_maple_driver(driver); + if (mdev->devinfo.function & be32_to_cpu(maple_drv->function)) { + if (maple_drv->connect(mdev) == 0) { + mdev->driver = maple_drv; + return 1; + } + } + return 0; } static void maple_detach_driver(struct maple_device *mdev) { - if (!mdev) - return; - if (mdev->driver) { - if (mdev->driver->disconnect) - mdev->driver->disconnect(mdev); - } - mdev->driver = NULL; - device_unregister(&mdev->dev); - mdev = NULL; + if (!mdev) + return; + if (mdev->driver) { + if (mdev->driver->disconnect) + mdev->driver->disconnect(mdev); + } + mdev->driver = NULL; + if (mdev->registered) { + maple_release_device(&mdev->dev); + device_unregister(&mdev->dev); + } + mdev->registered = 0; + maple_free_dev(mdev); } /* process initial MAPLE_COMMAND_DEVINFO for each device or port */ -static void maple_attach_driver(struct maple_device *mdev) +static void maple_attach_driver(struct maple_device *dev) { - char *p, *recvbuf; - unsigned long function; - int matched, retval; - - recvbuf = mdev->mq->recvbuf; - /* copy the data as individual elements in - * case of memory optimisation */ - memcpy(&mdev->devinfo.function, recvbuf + 4, 4); - memcpy(&mdev->devinfo.function_data[0], recvbuf + 8, 12); - memcpy(&mdev->devinfo.area_code, recvbuf + 20, 1); - memcpy(&mdev->devinfo.connector_direction, recvbuf + 21, 1); - memcpy(&mdev->devinfo.product_name[0], recvbuf + 22, 30); - memcpy(&mdev->devinfo.product_licence[0], recvbuf + 52, 60); - memcpy(&mdev->devinfo.standby_power, recvbuf + 112, 2); - memcpy(&mdev->devinfo.max_power, recvbuf + 114, 2); - memcpy(mdev->product_name, mdev->devinfo.product_name, 30); - mdev->product_name[30] = '\0'; - memcpy(mdev->product_licence, mdev->devinfo.product_licence, 60); - mdev->product_licence[60] = '\0'; - - for (p = mdev->product_name + 29; mdev->product_name <= p; p--) - if (*p == ' ') - *p = '\0'; - else - break; - for (p = mdev->product_licence + 59; mdev->product_licence <= p; p--) - if (*p == ' ') - *p = '\0'; - else - break; - - if (realscan) { - printk(KERN_INFO "Maple device detected: %s\n", - mdev->product_name); - printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); - } - - function = be32_to_cpu(mdev->devinfo.function); - - if (function > 0x200) { - /* Do this silently - as not a real device */ - function = 0; - mdev->driver = &maple_dummy_driver; - sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port); - } else { - if (realscan) - printk(KERN_INFO - "Maple bus at (%d, %d): Function 0x%lX\n", - mdev->port, mdev->unit, function); - - matched = - bus_for_each_drv(&maple_bus_type, NULL, mdev, - attach_matching_maple_driver); - - if (matched == 0) { - /* Driver does not exist yet */ - if (realscan) - printk(KERN_INFO - "No maple driver found.\n"); - mdev->driver = &maple_dummy_driver; - } - sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port, - mdev->unit, function); - } - mdev->function = function; - mdev->dev.release = &maple_release_device; - retval = device_register(&mdev->dev); - if (retval) { - printk(KERN_INFO - "Maple bus: Attempt to register device" - " (%x, %x) failed.\n", - mdev->port, mdev->unit); - maple_free_dev(mdev); - mdev = NULL; - return; - } + char *p; + + char *recvbuf; + unsigned long function; + int matched, retval; + + recvbuf = dev->mq->recvbuf; + memcpy(&dev->devinfo, recvbuf + 4, sizeof(dev->devinfo)); + memcpy(dev->product_name, dev->devinfo.product_name, 30); + memcpy(dev->product_licence, dev->devinfo.product_licence, 60); + dev->product_name[30] = '\0'; + dev->product_licence[60] = '\0'; + + for (p = dev->product_name + 29; dev->product_name <= p; p--) + if (*p == ' ') + *p = '\0'; + else + break; + + for (p = dev->product_licence + 59; dev->product_licence <= p; p--) + if (*p == ' ') + *p = '\0'; + else + break; + + function = be32_to_cpu(dev->devinfo.function); + + if (function > 0x200) { + /* Do this silently - as not a real device */ + function = 0; + dev->driver = &maple_dummy_driver; + sprintf(dev->dev.bus_id, "%d:0.port", dev->port); + } else { + printk(KERN_INFO + "Maple bus at (%d, %d): Connected function 0x%lX\n", + dev->port, dev->unit, function); + + matched = + bus_for_each_drv(&maple_bus_type, NULL, dev, + attach_matching_maple_driver); + + if (matched == 0) { + /* Driver does not exist yet */ + printk(KERN_INFO + "No maple driver found for this device\n"); + dev->driver = &maple_dummy_driver; + } + + sprintf(dev->dev.bus_id, "%d:0%d.%lX", dev->port, + dev->unit, function); + } + dev->function = function; + dev->dev.bus = &maple_bus_type; + dev->dev.parent = &maple_bus; + dev->dev.release = &maple_release_device; + retval = device_register(&dev->dev); + if (retval) { + printk(KERN_INFO + "Maple bus: Attempt to register device (%x, %x) failed.\n", + dev->port, dev->unit); + maple_free_dev(dev); + } + dev->registered = 1; } /* @@ -363,262 +340,270 @@ static void maple_attach_driver(struct maple_device *mdev) */ static int detach_maple_device(struct device *device, void *portptr) { - struct maple_device_specify *ds; - struct maple_device *mdev; - - ds = portptr; - mdev = to_maple_dev(device); - if (mdev->port == ds->port && mdev->unit == ds->unit) - return 1; - return 0; + struct maple_device_specify *ds; + struct maple_device *mdev; + + ds = portptr; + mdev = to_maple_dev(device); + if (mdev->port == ds->port && mdev->unit == ds->unit) + return 1; + return 0; } static int setup_maple_commands(struct device *device, void *ignored) { - struct maple_device *maple_dev = to_maple_dev(device); - - if ((maple_dev->interval > 0) - && time_after(jiffies, maple_dev->when)) { - maple_dev->when = jiffies + maple_dev->interval; - maple_dev->mq->command = MAPLE_COMMAND_GETCOND; - maple_dev->mq->sendbuf = &maple_dev->function; - maple_dev->mq->length = 1; - maple_add_packet(maple_dev->mq); - liststatus++; - } else { - if (time_after(jiffies, maple_pnp_time)) { - maple_dev->mq->command = MAPLE_COMMAND_DEVINFO; - maple_dev->mq->length = 0; - maple_add_packet(maple_dev->mq); - liststatus++; - } - } - - return 0; + struct maple_device *maple_dev = to_maple_dev(device); + + if ((maple_dev->interval > 0) + && time_after(jiffies, maple_dev->when)) { + maple_dev->when = jiffies + maple_dev->interval; + maple_dev->mq->command = MAPLE_COMMAND_GETCOND; + maple_dev->mq->sendbuf = &maple_dev->function; + maple_dev->mq->length = 1; + maple_add_packet(maple_dev->mq); + liststatus++; + } else { + if (time_after(jiffies, maple_pnp_time)) { + maple_dev->mq->command = MAPLE_COMMAND_DEVINFO; + maple_dev->mq->length = 0; + maple_add_packet(maple_dev->mq); + liststatus++; + } + } + + return 0; } /* VBLANK bottom half - implemented via workqueue */ static void maple_vblank_handler(struct work_struct *work) { - if (!maple_dma_done()) - return; - if (!list_empty(&maple_sentq)) - return; - ctrl_outl(0, MAPLE_ENABLE); - liststatus = 0; - bus_for_each_dev(&maple_bus_type, NULL, NULL, - setup_maple_commands); - if (time_after(jiffies, maple_pnp_time)) - maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; - if (liststatus && list_empty(&maple_sentq)) { - INIT_LIST_HEAD(&maple_sentq); - maple_send(); - } - maplebus_dma_reset(); + if (!maple_dma_done()) + return; + if (!list_empty(&maple_sentq)) + return; + ctrl_outl(0, MAPLE_ENABLE); + liststatus = 0; + bus_for_each_dev(&maple_bus_type, NULL, NULL, + setup_maple_commands); + if (time_after(jiffies, maple_pnp_time)) + maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; + if (liststatus && list_empty(&maple_sentq)) { + INIT_LIST_HEAD(&maple_sentq); + maple_send(); + } + maplebus_dma_reset(); } /* handle devices added via hotplugs - placing them on queue for DEVINFO*/ static void maple_map_subunits(struct maple_device *mdev, int submask) { - int retval, k, devcheck; - struct maple_device *mdev_add; - struct maple_device_specify ds; - - for (k = 0; k < 5; k++) { - ds.port = mdev->port; - ds.unit = k + 1; - retval = - bus_for_each_dev(&maple_bus_type, NULL, &ds, - detach_maple_device); - if (retval) { - submask = submask >> 1; - continue; - } - devcheck = submask & 0x01; - if (devcheck) { - mdev_add = maple_alloc_dev(mdev->port, k + 1); - if (!mdev_add) - return; - mdev_add->mq->command = MAPLE_COMMAND_DEVINFO; - mdev_add->mq->length = 0; - maple_add_packet(mdev_add->mq); - scanning = 1; - } - submask = submask >> 1; - } + int retval, k, devcheck; + struct maple_device *mdev_add; + struct maple_device_specify ds; + + for (k = 0; k < 5; k++) { + ds.port = mdev->port; + ds.unit = k + 1; + retval = + bus_for_each_dev(&maple_bus_type, NULL, &ds, + detach_maple_device); + if (retval) { + submask = submask >> 1; + continue; + } + devcheck = submask & 0x01; + if (devcheck) { + mdev_add = maple_alloc_dev(mdev->port, k + 1); + if (!mdev_add) + return; + mdev_add->mq->command = MAPLE_COMMAND_DEVINFO; + mdev_add->mq->length = 0; + maple_add_packet(mdev_add->mq); + scanning = 1; + } + submask = submask >> 1; + } } /* mark a device as removed */ static void maple_clean_submap(struct maple_device *mdev) { - int killbit; + int killbit; - killbit = (mdev->unit > 0 ? (1 << (mdev->unit - 1)) & 0x1f : 0x20); - killbit = ~killbit; - killbit &= 0xFF; - subdevice_map[mdev->port] = subdevice_map[mdev->port] & killbit; + killbit = (mdev->unit > 0 ? (1 << (mdev->unit - 1)) & 0x1f : 0x20); + killbit = ~killbit; + killbit &= 0xFF; + subdevice_map[mdev->port] = subdevice_map[mdev->port] & killbit; } /* handle empty port or hotplug removal */ static void maple_response_none(struct maple_device *mdev, - struct mapleq *mq) + struct mapleq *mq) { - if (mdev->unit != 0) { - list_del(&mq->list); - maple_clean_submap(mdev); - printk(KERN_INFO - "Maple bus device detaching at (%d, %d)\n", - mdev->port, mdev->unit); - maple_detach_driver(mdev); - return; - } - if (!started) { - printk(KERN_INFO "No maple devices attached to port %d\n", - mdev->port); - return; - } - maple_clean_submap(mdev); + if (mdev->unit != 0) { + list_del(&mq->list); + maple_clean_submap(mdev); + printk(KERN_INFO + "Maple bus device detaching at (%d, %d)\n", + mdev->port, mdev->unit); + maple_detach_driver(mdev); + return; + } + if (!started) { + printk(KERN_INFO "No maple devices attached to port %d\n", + mdev->port); + return; + } + maple_clean_submap(mdev); } /* preprocess hotplugs or scans */ static void maple_response_devinfo(struct maple_device *mdev, - char *recvbuf) + char *recvbuf) { - char submask; - if ((!started) || (scanning == 2)) { - maple_attach_driver(mdev); - return; - } - if (mdev->unit == 0) { - submask = recvbuf[2] & 0x1F; - if (submask ^ subdevice_map[mdev->port]) { - maple_map_subunits(mdev, submask); - subdevice_map[mdev->port] = submask; - } - } + char submask; + if ((!started) || (scanning == 2)) { + maple_attach_driver(mdev); + return; + } + if (mdev->unit == 0) { + submask = recvbuf[2] & 0x1F; + if (submask ^ subdevice_map[mdev->port]) { + maple_map_subunits(mdev, submask); + subdevice_map[mdev->port] = submask; + } + } } /* maple dma end bottom half - implemented via workqueue */ static void maple_dma_handler(struct work_struct *work) { - struct mapleq *mq, *nmq; - struct maple_device *dev; - char *recvbuf; - enum maple_code code; - - if (!maple_dma_done()) - return; - ctrl_outl(0, MAPLE_ENABLE); - if (!list_empty(&maple_sentq)) { - list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { - recvbuf = mq->recvbuf; - code = recvbuf[0]; - dev = mq->dev; - switch (code) { - case MAPLE_RESPONSE_NONE: - maple_response_none(dev, mq); - break; - - case MAPLE_RESPONSE_DEVINFO: - maple_response_devinfo(dev, recvbuf); - break; - - case MAPLE_RESPONSE_DATATRF: - if (dev->callback) - dev->callback(mq); - break; - - case MAPLE_RESPONSE_FILEERR: - case MAPLE_RESPONSE_AGAIN: - case MAPLE_RESPONSE_BADCMD: - case MAPLE_RESPONSE_BADFUNC: - printk(KERN_DEBUG - "Maple non-fatal error 0x%X\n", - code); - break; - - case MAPLE_RESPONSE_ALLINFO: - printk(KERN_DEBUG - "Maple - extended device information" - " not supported\n"); - break; - - case MAPLE_RESPONSE_OK: - break; - - default: - break; - } - } - INIT_LIST_HEAD(&maple_sentq); - if (scanning == 1) { - maple_send(); - scanning = 2; - } else - scanning = 0; - - if (started == 0) - started = 1; - } - maplebus_dma_reset(); + struct mapleq *mq, *nmq; + struct maple_device *dev; + char *recvbuf; + enum maple_code code; + + if (!maple_dma_done()) + return; + ctrl_outl(0, MAPLE_ENABLE); + if (!list_empty(&maple_sentq)) { + list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { + recvbuf = mq->recvbuf; + code = recvbuf[0]; + dev = mq->dev; + switch (code) { + case MAPLE_RESPONSE_NONE: + maple_response_none(dev, mq); + break; + + case MAPLE_RESPONSE_DEVINFO: + maple_response_devinfo(dev, recvbuf); + break; + + case MAPLE_RESPONSE_DATATRF: + if (dev->callback) + dev->callback(mq); + break; + + case MAPLE_RESPONSE_FILEERR: + case MAPLE_RESPONSE_AGAIN: + case MAPLE_RESPONSE_BADCMD: + case MAPLE_RESPONSE_BADFUNC: + printk(KERN_DEBUG + "Maple non-fatal error 0x%X\n", + code); + break; + + case MAPLE_RESPONSE_ALLINFO: + printk(KERN_DEBUG + "Maple - extended device information not supported\n"); + break; + + case MAPLE_RESPONSE_OK: + break; + + default: + break; + } + } + INIT_LIST_HEAD(&maple_sentq); + if (scanning == 1) { + maple_send(); + scanning = 2; + } else + scanning = 0; + + if (started == 0) + started = 1; + } + maplebus_dma_reset(); } static irqreturn_t maplebus_dma_interrupt(int irq, void *dev_id) { - /* Load everything into the bottom half */ - schedule_work(&maple_dma_process); - return IRQ_HANDLED; + /* Load everything into the bottom half */ + schedule_work(&maple_dma_process); + return IRQ_HANDLED; } static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id) { - schedule_work(&maple_vblank_process); - return IRQ_HANDLED; + schedule_work(&maple_vblank_process); + return IRQ_HANDLED; } +static struct irqaction maple_dma_irq = { + .name = "maple bus DMA handler", + .handler = maplebus_dma_interrupt, + .flags = IRQF_SHARED, +}; + +static struct irqaction maple_vblank_irq = { + .name = "maple bus VBLANK handler", + .handler = maplebus_vblank_interrupt, + .flags = IRQF_SHARED, +}; + static int maple_set_dma_interrupt_handler(void) { - return request_irq(HW_EVENT_MAPLE_DMA, maplebus_dma_interrupt, - IRQF_SHARED, "maple bus DMA", &maple_dummy_driver); + return setup_irq(HW_EVENT_MAPLE_DMA, &maple_dma_irq); } static int maple_set_vblank_interrupt_handler(void) { - return request_irq(HW_EVENT_VSYNC, maplebus_vblank_interrupt, - IRQF_SHARED, "maple bus VBLANK", &maple_dummy_driver); + return setup_irq(HW_EVENT_VSYNC, &maple_vblank_irq); } static int maple_get_dma_buffer(void) { - maple_sendbuf = - (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, - MAPLE_DMA_PAGES); - if (!maple_sendbuf) - return -ENOMEM; - return 0; + maple_sendbuf = + (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, + MAPLE_DMA_PAGES); + if (!maple_sendbuf) + return -ENOMEM; + return 0; } static int match_maple_bus_driver(struct device *devptr, - struct device_driver *drvptr) + struct device_driver *drvptr) { - struct maple_driver *maple_drv; - struct maple_device *maple_dev; - - maple_drv = container_of(drvptr, struct maple_driver, drv); - maple_dev = container_of(devptr, struct maple_device, dev); - /* Trap empty port case */ - if (maple_dev->devinfo.function == 0xFFFFFFFF) - return 0; - else if (maple_dev->devinfo.function & - be32_to_cpu(maple_drv->function)) - return 1; - return 0; + struct maple_driver *maple_drv; + struct maple_device *maple_dev; + + maple_drv = container_of(drvptr, struct maple_driver, drv); + maple_dev = container_of(devptr, struct maple_device, dev); + /* Trap empty port case */ + if (maple_dev->devinfo.function == 0xFFFFFFFF) + return 0; + else if (maple_dev->devinfo.function & + be32_to_cpu(maple_drv->function)) + return 1; + return 0; } -static int maple_bus_uevent(struct device *dev, - struct kobj_uevent_env *env) +static int maple_bus_uevent(struct device *dev, struct kobj_uevent_env *env) { - return 0; + return 0; } static void maple_bus_release(struct device *dev) @@ -626,122 +611,124 @@ static void maple_bus_release(struct device *dev) } static struct maple_driver maple_dummy_driver = { - .drv = { - .name = "maple_dummy_driver", - .bus = &maple_bus_type, - }, + .drv = { + .name = "maple_dummy_driver", + .bus = &maple_bus_type, + }, }; struct bus_type maple_bus_type = { - .name = "maple", - .match = match_maple_bus_driver, - .uevent = maple_bus_uevent, + .name = "maple", + .match = match_maple_bus_driver, + .uevent = maple_bus_uevent, }; EXPORT_SYMBOL_GPL(maple_bus_type); static struct device maple_bus = { - .bus_id = "maple", - .release = maple_bus_release, + .bus_id = "maple", + .release = maple_bus_release, }; static int __init maple_bus_init(void) { - int retval, i; - struct maple_device *mdev[MAPLE_PORTS]; - ctrl_outl(0, MAPLE_STATE); - - retval = device_register(&maple_bus); - if (retval) - goto cleanup; - - retval = bus_register(&maple_bus_type); - if (retval) - goto cleanup_device; - - retval = driver_register(&maple_dummy_driver.drv); - if (retval) - goto cleanup_bus; - - /* allocate memory for maple bus dma */ - retval = maple_get_dma_buffer(); - if (retval) { - printk(KERN_INFO - "Maple bus: Failed to allocate Maple DMA buffers\n"); - goto cleanup_basic; - } - - /* set up DMA interrupt handler */ - retval = maple_set_dma_interrupt_handler(); - if (retval) { - printk(KERN_INFO - "Maple bus: Failed to grab maple DMA IRQ\n"); - goto cleanup_dma; - } - - /* set up VBLANK interrupt handler */ - retval = maple_set_vblank_interrupt_handler(); - if (retval) { - printk(KERN_INFO "Maple bus: Failed to grab VBLANK IRQ\n"); - goto cleanup_irq; - } - - maple_queue_cache = - kmem_cache_create("maple_queue_cache", 0x400, 0, - SLAB_POISON|SLAB_HWCACHE_ALIGN, NULL); - - if (!maple_queue_cache) - goto cleanup_bothirqs; - - /* setup maple ports */ - for (i = 0; i < MAPLE_PORTS; i++) { - mdev[i] = maple_alloc_dev(i, 0); - if (!mdev[i]) { - while (i-- > 0) - maple_free_dev(mdev[i]); - goto cleanup_cache; - } - mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO; - mdev[i]->mq->length = 0; - maple_add_packet(mdev[i]->mq); - /* delay aids hardware detection */ - mdelay(5); - subdevice_map[i] = 0; - } - - realscan = 1; - /* setup maplebus hardware */ - maplebus_dma_reset(); - /* initial detection */ - maple_send(); - maple_pnp_time = jiffies; - printk(KERN_INFO "Maple bus core now registered.\n"); - - return 0; + int retval, i; + struct maple_device *mdev[MAPLE_PORTS]; + ctrl_outl(0, MAPLE_STATE); + + retval = device_register(&maple_bus); + if (retval) + goto cleanup; + + retval = bus_register(&maple_bus_type); + if (retval) + goto cleanup_device; + + retval = driver_register(&maple_dummy_driver.drv); + + if (retval) + goto cleanup_bus; + + /* allocate memory for maple bus dma */ + retval = maple_get_dma_buffer(); + if (retval) { + printk(KERN_INFO + "Maple bus: Failed to allocate Maple DMA buffers\n"); + goto cleanup_basic; + } + + /* set up DMA interrupt handler */ + retval = maple_set_dma_interrupt_handler(); + if (retval) { + printk(KERN_INFO + "Maple bus: Failed to grab maple DMA IRQ\n"); + goto cleanup_dma; + } + + /* set up VBLANK interrupt handler */ + retval = maple_set_vblank_interrupt_handler(); + if (retval) { + printk(KERN_INFO "Maple bus: Failed to grab VBLANK IRQ\n"); + goto cleanup_irq; + } + + maple_queue_cache = + kmem_cache_create("maple_queue_cache", 0x400, 0, + SLAB_HWCACHE_ALIGN, NULL); + + if (!maple_queue_cache) + goto cleanup_bothirqs; + + /* setup maple ports */ + for (i = 0; i < MAPLE_PORTS; i++) { + mdev[i] = maple_alloc_dev(i, 0); + if (!mdev[i]) { + while (i-- > 0) + maple_free_dev(mdev[i]); + goto cleanup_cache; + } + mdev[i]->registered = 0; + mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO; + mdev[i]->mq->length = 0; + maple_attach_driver(mdev[i]); + maple_add_packet(mdev[i]->mq); + subdevice_map[i] = 0; + } + + /* setup maplebus hardware */ + maplebus_dma_reset(); + + /* initial detection */ + maple_send(); + + maple_pnp_time = jiffies; + + printk(KERN_INFO "Maple bus core now registered.\n"); + + return 0; cleanup_cache: - kmem_cache_destroy(maple_queue_cache); + kmem_cache_destroy(maple_queue_cache); cleanup_bothirqs: - free_irq(HW_EVENT_VSYNC, 0); + free_irq(HW_EVENT_VSYNC, 0); cleanup_irq: - free_irq(HW_EVENT_MAPLE_DMA, 0); + free_irq(HW_EVENT_MAPLE_DMA, 0); cleanup_dma: - free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES); + free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES); cleanup_basic: - driver_unregister(&maple_dummy_driver.drv); + driver_unregister(&maple_dummy_driver.drv); cleanup_bus: - bus_unregister(&maple_bus_type); + bus_unregister(&maple_bus_type); cleanup_device: - device_unregister(&maple_bus); + device_unregister(&maple_bus); cleanup: - printk(KERN_INFO "Maple bus registration failed\n"); - return retval; + printk(KERN_INFO "Maple bus registration failed\n"); + return retval; } -/* Push init to later to ensure hardware gets detected */ -fs_initcall(maple_bus_init); +subsys_initcall(maple_bus_init); diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index 017a196d041f..3301167d4f2a 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -3563,7 +3563,8 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, down_read(&fsg->filesem); if (backing_file_is_open(curlun)) { // Get the complete pathname - p = d_path(&curlun->filp->f_path, buf, PAGE_SIZE - 1); + p = d_path(curlun->filp->f_path.dentry, + curlun->filp->f_path.mnt, buf, PAGE_SIZE - 1); if (IS_ERR(p)) rc = PTR_ERR(p); else { @@ -3980,8 +3981,9 @@ static int __init fsg_bind(struct usb_gadget *gadget) if (backing_file_is_open(curlun)) { p = NULL; if (pathbuf) { - p = d_path(&curlun->filp->f_path, - pathbuf, PATH_MAX); + p = d_path(curlun->filp->f_path.dentry, + curlun->filp->f_path.mnt, + pathbuf, PATH_MAX); if (IS_ERR(p)) p = NULL; } diff --git a/trunk/fs/afs/mntpt.c b/trunk/fs/afs/mntpt.c index a3510b8ba3e7..5ce43b63c60e 100644 --- a/trunk/fs/afs/mntpt.c +++ b/trunk/fs/afs/mntpt.c @@ -218,16 +218,16 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) _enter("%p{%s},{%s:%p{%s},}", dentry, dentry->d_name.name, - nd->path.mnt->mnt_devname, + nd->mnt->mnt_devname, dentry, - nd->path.dentry->d_name.name); + nd->dentry->d_name.name); - dput(nd->path.dentry); - nd->path.dentry = dget(dentry); + dput(nd->dentry); + nd->dentry = dget(dentry); - newmnt = afs_mntpt_do_automount(nd->path.dentry); + newmnt = afs_mntpt_do_automount(nd->dentry); if (IS_ERR(newmnt)) { - path_put(&nd->path); + path_release(nd); return (void *)newmnt; } @@ -235,16 +235,17 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts); switch (err) { case 0: - path_put(&nd->path); - nd->path.mnt = newmnt; - nd->path.dentry = dget(newmnt->mnt_root); + dput(nd->dentry); + mntput(nd->mnt); + nd->mnt = newmnt; + nd->dentry = dget(newmnt->mnt_root); schedule_delayed_work(&afs_mntpt_expiry_timer, afs_mntpt_expiry_timeout * HZ); break; case -EBUSY: /* someone else made a mount here whilst we were busy */ - while (d_mountpoint(nd->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while (d_mountpoint(nd->dentry) && + follow_down(&nd->mnt, &nd->dentry)) ; err = 0; default: diff --git a/trunk/fs/autofs4/root.c b/trunk/fs/autofs4/root.c index a54a946a50ae..2bbcc8151dc3 100644 --- a/trunk/fs/autofs4/root.c +++ b/trunk/fs/autofs4/root.c @@ -368,8 +368,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) * so we don't need to follow the mount. */ if (d_mountpoint(dentry)) { - if (!autofs4_follow_mount(&nd->path.mnt, - &nd->path.dentry)) { + if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) { status = -ENOENT; goto out_error; } @@ -383,7 +382,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) return NULL; out_error: - path_put(&nd->path); + path_release(nd); return ERR_PTR(status); } diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 0498b181dd52..d8a02f1e08cc 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -443,12 +443,12 @@ static int load_flat_file(struct linux_binprm * bprm, if (strncmp(hdr->magic, "bFLT", 4)) { /* - * Previously, here was a printk to tell people - * "BINFMT_FLAT: bad header magic". - * But for the kernel which also use ELF FD-PIC format, this - * error message is confusing. * because a lot of people do not manage to produce good + * flat binaries, we leave this printk to help them realise + * the problem. We only print the error if its not a script file */ + if (strncmp(hdr->magic, "#!", 2)) + printk("BINFMT_FLAT: bad header magic\n"); ret = -ENOEXEC; goto err; } diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 67fe72ce6ac7..e63067d25cdb 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -1397,19 +1397,19 @@ struct block_device *lookup_bdev(const char *path) if (error) return ERR_PTR(error); - inode = nd.path.dentry->d_inode; + inode = nd.dentry->d_inode; error = -ENOTBLK; if (!S_ISBLK(inode->i_mode)) goto fail; error = -EACCES; - if (nd.path.mnt->mnt_flags & MNT_NODEV) + if (nd.mnt->mnt_flags & MNT_NODEV) goto fail; error = -ENOMEM; bdev = bd_acquire(inode); if (!bdev) goto fail; out: - path_put(&nd.path); + path_release(&nd); return bdev; fail: bdev = ERR_PTR(error); diff --git a/trunk/fs/cifs/cifs_dfs_ref.c b/trunk/fs/cifs/cifs_dfs_ref.c index 6ad447529961..413ee2349d1a 100644 --- a/trunk/fs/cifs/cifs_dfs_ref.c +++ b/trunk/fs/cifs/cifs_dfs_ref.c @@ -259,18 +259,18 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd, int err; mntget(newmnt); - err = do_add_mount(newmnt, nd, nd->path.mnt->mnt_flags, mntlist); + err = do_add_mount(newmnt, nd, nd->mnt->mnt_flags, mntlist); switch (err) { case 0: - dput(nd->path.dentry); - mntput(nd->path.mnt); - nd->path.mnt = newmnt; - nd->path.dentry = dget(newmnt->mnt_root); + dput(nd->dentry); + mntput(nd->mnt); + nd->mnt = newmnt; + nd->dentry = dget(newmnt->mnt_root); break; case -EBUSY: /* someone else made a mount here whilst we were busy */ - while (d_mountpoint(nd->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while (d_mountpoint(nd->dentry) && + follow_down(&nd->mnt, &nd->dentry)) ; err = 0; default: @@ -307,8 +307,8 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) xid = GetXid(); - dput(nd->path.dentry); - nd->path.dentry = dget(dentry); + dput(nd->dentry); + nd->dentry = dget(dentry); cifs_sb = CIFS_SB(dentry->d_inode->i_sb); ses = cifs_sb->tcon->ses; @@ -340,8 +340,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) rc = -EINVAL; goto out_err; } - mnt = cifs_dfs_do_refmount(nd->path.mnt, - nd->path.dentry, + mnt = cifs_dfs_do_refmount(nd->mnt, nd->dentry, referrals[i].node_name); cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", __FUNCTION__, @@ -358,7 +357,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) if (IS_ERR(mnt)) goto out_err; - nd->path.mnt->mnt_flags |= MNT_SHRINKABLE; + nd->mnt->mnt_flags |= MNT_SHRINKABLE; rc = add_mount_helper(mnt, nd, &cifs_dfs_automount_list); out: @@ -368,7 +367,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) cFYI(1, ("leaving %s" , __FUNCTION__)); return ERR_PTR(rc); out_err: - path_put(&nd->path); + path_release(nd); goto out; } diff --git a/trunk/fs/coda/pioctl.c b/trunk/fs/coda/pioctl.c index c21a1f552a63..2bf3026adc80 100644 --- a/trunk/fs/coda/pioctl.c +++ b/trunk/fs/coda/pioctl.c @@ -75,12 +75,12 @@ static int coda_pioctl(struct inode * inode, struct file * filp, if ( error ) { return error; } else { - target_inode = nd.path.dentry->d_inode; + target_inode = nd.dentry->d_inode; } /* return if it is not a Coda inode */ if ( target_inode->i_sb != inode->i_sb ) { - path_put(&nd.path); + path_release(&nd); return -EINVAL; } @@ -89,7 +89,7 @@ static int coda_pioctl(struct inode * inode, struct file * filp, error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); - path_put(&nd.path); + path_release(&nd); return error; } diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index 2ce4456aad30..ee80ff341d37 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -241,10 +241,10 @@ asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs error = user_path_walk(path, &nd); if (!error) { struct kstatfs tmp; - error = vfs_statfs(nd.path.dentry, &tmp); + error = vfs_statfs(nd.dentry, &tmp); if (!error) error = put_compat_statfs(buf, &tmp); - path_put(&nd.path); + path_release(&nd); } return error; } @@ -309,10 +309,10 @@ asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, s error = user_path_walk(path, &nd); if (!error) { struct kstatfs tmp; - error = vfs_statfs(nd.path.dentry, &tmp); + error = vfs_statfs(nd.dentry, &tmp); if (!error) error = put_compat_statfs64(buf, &tmp); - path_put(&nd.path); + path_release(&nd); } return error; } @@ -702,6 +702,9 @@ static int do_nfs4_super_data_conv(void *raw_data) real->flags = raw->flags; real->version = raw->version; } + else { + return -EINVAL; + } return 0; } diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index c6e72aebd16b..ee32c0eac7c1 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -2853,7 +2853,7 @@ static void compat_ioctl_error(struct file *filp, unsigned int fd, /* find the name of the device. */ path = (char *)__get_free_page(GFP_KERNEL); if (path) { - fn = d_path(&filp->f_path, path, PAGE_SIZE); + fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE); if (IS_ERR(fn)) fn = "?"; } diff --git a/trunk/fs/configfs/symlink.c b/trunk/fs/configfs/symlink.c index 78929ea84ff2..22700d2857da 100644 --- a/trunk/fs/configfs/symlink.c +++ b/trunk/fs/configfs/symlink.c @@ -99,11 +99,11 @@ static int get_target(const char *symname, struct nameidata *nd, ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, nd); if (!ret) { - if (nd->path.dentry->d_sb == configfs_sb) { - *target = configfs_get_config_item(nd->path.dentry); + if (nd->dentry->d_sb == configfs_sb) { + *target = configfs_get_config_item(nd->dentry); if (!*target) { ret = -ENOENT; - path_put(&nd->path); + path_release(nd); } } else ret = -EPERM; @@ -141,7 +141,7 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna ret = create_link(parent_item, target_item, dentry); config_item_put(target_item); - path_put(&nd.path); + path_release(&nd); out_put: config_item_put(parent_item); diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 43455776711e..44f6cf23b70e 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -95,14 +95,6 @@ static void d_free(struct dentry *dentry) call_rcu(&dentry->d_u.d_rcu, d_callback); } -static void dentry_lru_remove(struct dentry *dentry) -{ - if (!list_empty(&dentry->d_lru)) { - list_del_init(&dentry->d_lru); - dentry_stat.nr_unused--; - } -} - /* * Release the dentry's inode, using the filesystem * d_iput() operation if defined. @@ -219,7 +211,13 @@ void dput(struct dentry *dentry) unhash_it: __d_drop(dentry); kill_it: - dentry_lru_remove(dentry); + /* If dentry was on d_lru list + * delete it from there + */ + if (!list_empty(&dentry->d_lru)) { + list_del(&dentry->d_lru); + dentry_stat.nr_unused--; + } dentry = d_kill(dentry); if (dentry) goto repeat; @@ -287,7 +285,10 @@ int d_invalidate(struct dentry * dentry) static inline struct dentry * __dget_locked(struct dentry *dentry) { atomic_inc(&dentry->d_count); - dentry_lru_remove(dentry); + if (!list_empty(&dentry->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&dentry->d_lru); + } return dentry; } @@ -403,7 +404,10 @@ static void prune_one_dentry(struct dentry * dentry) if (dentry->d_op && dentry->d_op->d_delete) dentry->d_op->d_delete(dentry); - dentry_lru_remove(dentry); + if (!list_empty(&dentry->d_lru)) { + list_del(&dentry->d_lru); + dentry_stat.nr_unused--; + } __d_drop(dentry); dentry = d_kill(dentry); spin_lock(&dcache_lock); @@ -592,7 +596,10 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) /* detach this root from the system */ spin_lock(&dcache_lock); - dentry_lru_remove(dentry); + if (!list_empty(&dentry->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&dentry->d_lru); + } __d_drop(dentry); spin_unlock(&dcache_lock); @@ -606,7 +613,11 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) spin_lock(&dcache_lock); list_for_each_entry(loop, &dentry->d_subdirs, d_u.d_child) { - dentry_lru_remove(loop); + if (!list_empty(&loop->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&loop->d_lru); + } + __d_drop(loop); cond_resched_lock(&dcache_lock); } @@ -788,7 +799,10 @@ static int select_parent(struct dentry * parent) struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); next = tmp->next; - dentry_lru_remove(dentry); + if (!list_empty(&dentry->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&dentry->d_lru); + } /* * move only zero ref count dentries to the end * of the unused list for prune_dcache @@ -1762,8 +1776,9 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) * * "buflen" should be positive. Caller holds the dcache_lock. */ -static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, - struct path *root, char *buffer, int buflen) +static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt, + struct dentry *root, struct vfsmount *rootmnt, + char *buffer, int buflen) { char * end = buffer+buflen; char * retval; @@ -1788,7 +1803,7 @@ static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, for (;;) { struct dentry * parent; - if (dentry == root->dentry && vfsmnt == root->mnt) + if (dentry == root && vfsmnt == rootmnt) break; if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { /* Global root? */ @@ -1829,23 +1844,13 @@ static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt, return ERR_PTR(-ENAMETOOLONG); } -/** - * d_path - return the path of a dentry - * @path: path to report - * @buf: buffer to return value in - * @buflen: buffer length - * - * Convert a dentry into an ASCII path name. If the entry has been deleted - * the string " (deleted)" is appended. Note that this is ambiguous. - * - * Returns the buffer or an error code if the path was too long. - * - * "buflen" should be positive. Caller holds the dcache_lock. - */ -char *d_path(struct path *path, char *buf, int buflen) +/* write full pathname into buffer and return start of pathname */ +char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, + char *buf, int buflen) { char *res; - struct path root; + struct vfsmount *rootmnt; + struct dentry *root; /* * We have various synthetic filesystems that never get mounted. On @@ -1854,17 +1859,18 @@ char *d_path(struct path *path, char *buf, int buflen) * user wants to identify the object in /proc/pid/fd/. The little hack * below allows us to generate a name for these objects on demand: */ - if (path->dentry->d_op && path->dentry->d_op->d_dname) - return path->dentry->d_op->d_dname(path->dentry, buf, buflen); + if (dentry->d_op && dentry->d_op->d_dname) + return dentry->d_op->d_dname(dentry, buf, buflen); read_lock(¤t->fs->lock); - root = current->fs->root; - path_get(¤t->fs->root); + rootmnt = mntget(current->fs->rootmnt); + root = dget(current->fs->root); read_unlock(¤t->fs->lock); spin_lock(&dcache_lock); - res = __d_path(path->dentry, path->mnt, &root, buf, buflen); + res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); spin_unlock(&dcache_lock); - path_put(&root); + dput(root); + mntput(rootmnt); return res; } @@ -1910,27 +1916,28 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen, asmlinkage long sys_getcwd(char __user *buf, unsigned long size) { int error; - struct path pwd, root; + struct vfsmount *pwdmnt, *rootmnt; + struct dentry *pwd, *root; char *page = (char *) __get_free_page(GFP_USER); if (!page) return -ENOMEM; read_lock(¤t->fs->lock); - pwd = current->fs->pwd; - path_get(¤t->fs->pwd); - root = current->fs->root; - path_get(¤t->fs->root); + pwdmnt = mntget(current->fs->pwdmnt); + pwd = dget(current->fs->pwd); + rootmnt = mntget(current->fs->rootmnt); + root = dget(current->fs->root); read_unlock(¤t->fs->lock); error = -ENOENT; /* Has the current directory has been unlinked? */ spin_lock(&dcache_lock); - if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) { + if (pwd->d_parent == pwd || !d_unhashed(pwd)) { unsigned long len; char * cwd; - cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE); + cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); spin_unlock(&dcache_lock); error = PTR_ERR(cwd); @@ -1948,8 +1955,10 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) spin_unlock(&dcache_lock); out: - path_put(&pwd); - path_put(&root); + dput(pwd); + mntput(pwdmnt); + dput(root); + mntput(rootmnt); free_page((unsigned long) page); return error; } diff --git a/trunk/fs/dcookies.c b/trunk/fs/dcookies.c index 855d4b1d619a..792cbf55fa95 100644 --- a/trunk/fs/dcookies.c +++ b/trunk/fs/dcookies.c @@ -24,7 +24,6 @@ #include #include #include -#include #include /* The dcookies are allocated from a kmem_cache and @@ -32,7 +31,8 @@ * code here is particularly performance critical */ struct dcookie_struct { - struct path path; + struct dentry * dentry; + struct vfsmount * vfsmnt; struct list_head hash_list; }; @@ -51,7 +51,7 @@ static inline int is_live(void) /* The dentry is locked, its address will do for the cookie */ static inline unsigned long dcookie_value(struct dcookie_struct * dcs) { - return (unsigned long)dcs->path.dentry; + return (unsigned long)dcs->dentry; } @@ -89,17 +89,19 @@ static void hash_dcookie(struct dcookie_struct * dcs) } -static struct dcookie_struct *alloc_dcookie(struct path *path) +static struct dcookie_struct * alloc_dcookie(struct dentry * dentry, + struct vfsmount * vfsmnt) { - struct dcookie_struct *dcs = kmem_cache_alloc(dcookie_cache, - GFP_KERNEL); + struct dcookie_struct * dcs = kmem_cache_alloc(dcookie_cache, GFP_KERNEL); if (!dcs) return NULL; - path->dentry->d_cookie = dcs; - dcs->path = *path; - path_get(path); + dentry->d_cookie = dcs; + + dcs->dentry = dget(dentry); + dcs->vfsmnt = mntget(vfsmnt); hash_dcookie(dcs); + return dcs; } @@ -107,7 +109,8 @@ static struct dcookie_struct *alloc_dcookie(struct path *path) /* This is the main kernel-side routine that retrieves the cookie * value for a dentry/vfsmnt pair. */ -int get_dcookie(struct path *path, unsigned long *cookie) +int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt, + unsigned long * cookie) { int err = 0; struct dcookie_struct * dcs; @@ -119,10 +122,10 @@ int get_dcookie(struct path *path, unsigned long *cookie) goto out; } - dcs = path->dentry->d_cookie; + dcs = dentry->d_cookie; if (!dcs) - dcs = alloc_dcookie(path); + dcs = alloc_dcookie(dentry, vfsmnt); if (!dcs) { err = -ENOMEM; @@ -171,7 +174,7 @@ asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len) goto out; /* FIXME: (deleted) ? */ - path = d_path(&dcs->path, kbuf, PAGE_SIZE); + path = d_path(dcs->dentry, dcs->vfsmnt, kbuf, PAGE_SIZE); if (IS_ERR(path)) { err = PTR_ERR(path); @@ -251,8 +254,9 @@ static int dcookie_init(void) static void free_dcookie(struct dcookie_struct * dcs) { - dcs->path.dentry->d_cookie = NULL; - path_put(&dcs->path); + dcs->dentry->d_cookie = NULL; + dput(dcs->dentry); + mntput(dcs->vfsmnt); kmem_cache_free(dcookie_cache, dcs); } diff --git a/trunk/fs/dquot.c b/trunk/fs/dquot.c index 9c7feb62eed1..def4e969df77 100644 --- a/trunk/fs/dquot.c +++ b/trunk/fs/dquot.c @@ -1633,17 +1633,16 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path) error = path_lookup(path, LOOKUP_FOLLOW, &nd); if (error < 0) return error; - error = security_quota_on(nd.path.dentry); + error = security_quota_on(nd.dentry); if (error) goto out_path; /* Quota file not on the same filesystem? */ - if (nd.path.mnt->mnt_sb != sb) + if (nd.mnt->mnt_sb != sb) error = -EXDEV; else - error = vfs_quota_on_inode(nd.path.dentry->d_inode, type, - format_id); + error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id); out_path: - path_put(&nd.path); + path_release(&nd); return error; } diff --git a/trunk/fs/ecryptfs/dentry.c b/trunk/fs/ecryptfs/dentry.c index 841a032050a7..cb20b964419f 100644 --- a/trunk/fs/ecryptfs/dentry.c +++ b/trunk/fs/ecryptfs/dentry.c @@ -51,13 +51,13 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) goto out; - dentry_save = nd->path.dentry; - vfsmount_save = nd->path.mnt; - nd->path.dentry = lower_dentry; - nd->path.mnt = lower_mnt; + dentry_save = nd->dentry; + vfsmount_save = nd->mnt; + nd->dentry = lower_dentry; + nd->mnt = lower_mnt; rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); - nd->path.dentry = dentry_save; - nd->path.mnt = vfsmount_save; + nd->dentry = dentry_save; + nd->mnt = vfsmount_save; if (dentry->d_inode) { struct inode *lower_inode = ecryptfs_inode_to_lower(dentry->d_inode); diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index e23861152101..edd1e44e9d47 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -77,13 +77,13 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode, struct vfsmount *vfsmount_save; int rc; - dentry_save = nd->path.dentry; - vfsmount_save = nd->path.mnt; - nd->path.dentry = lower_dentry; - nd->path.mnt = lower_mnt; + dentry_save = nd->dentry; + vfsmount_save = nd->mnt; + nd->dentry = lower_dentry; + nd->mnt = lower_mnt; rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd); - nd->path.dentry = dentry_save; - nd->path.mnt = vfsmount_save; + nd->dentry = dentry_save; + nd->mnt = vfsmount_save; return rc; } @@ -819,14 +819,14 @@ ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd) int rc; if (nd) { - struct vfsmount *vfsmnt_save = nd->path.mnt; - struct dentry *dentry_save = nd->path.dentry; + struct vfsmount *vfsmnt_save = nd->mnt; + struct dentry *dentry_save = nd->dentry; - nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry); - nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry); + nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry); + nd->dentry = ecryptfs_dentry_to_lower(nd->dentry); rc = permission(ecryptfs_inode_to_lower(inode), mask, nd); - nd->path.mnt = vfsmnt_save; - nd->path.dentry = dentry_save; + nd->mnt = vfsmnt_save; + nd->dentry = dentry_save; } else rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL); return rc; diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index d25ac9500a92..778c420e4cac 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -513,8 +513,8 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); goto out; } - lower_root = nd.path.dentry; - lower_mnt = nd.path.mnt; + lower_root = nd.dentry; + lower_mnt = nd.mnt; ecryptfs_set_superblock_lower(sb, lower_root->d_sb); sb->s_maxbytes = lower_root->d_sb->s_maxbytes; sb->s_blocksize = lower_root->d_sb->s_blocksize; @@ -526,7 +526,7 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) rc = 0; goto out; out_free: - path_put(&nd.path); + path_release(&nd); out: return rc; } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index a44b142fb460..9ff6069094d8 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -112,7 +112,7 @@ asmlinkage long sys_uselib(const char __user * library) goto out; error = -EINVAL; - if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) + if (!S_ISREG(nd.dentry->d_inode->i_mode)) goto exit; error = vfs_permission(&nd, MAY_READ | MAY_EXEC); @@ -148,7 +148,7 @@ asmlinkage long sys_uselib(const char __user * library) return error; exit: release_open_intent(&nd); - path_put(&nd.path); + path_release(&nd); goto out; } @@ -652,7 +652,7 @@ struct file *open_exec(const char *name) file = ERR_PTR(err); if (!err) { - struct inode *inode = nd.path.dentry->d_inode; + struct inode *inode = nd.dentry->d_inode; file = ERR_PTR(-EACCES); if (S_ISREG(inode->i_mode)) { int err = vfs_permission(&nd, MAY_EXEC); @@ -672,7 +672,7 @@ struct file *open_exec(const char *name) } } release_open_intent(&nd); - path_put(&nd.path); + path_release(&nd); } goto out; } diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 18769cc32377..8e02cbfb1123 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -2758,16 +2758,16 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, if (err) return err; /* Quotafile not on the same filesystem? */ - if (nd.path.mnt->mnt_sb != sb) { - path_put(&nd.path); + if (nd.mnt->mnt_sb != sb) { + path_release(&nd); return -EXDEV; } /* Quotafile not of fs root? */ - if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) + if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) printk(KERN_WARNING "EXT3-fs: Quota file not on filesystem root. " "Journalled quota will not work.\n"); - path_put(&nd.path); + path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 13383ba18f1d..0072da75221f 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -3158,16 +3158,16 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, if (err) return err; /* Quotafile not on the same filesystem? */ - if (nd.path.mnt->mnt_sb != sb) { - path_put(&nd.path); + if (nd.mnt->mnt_sb != sb) { + path_release(&nd); return -EXDEV; } /* Quotafile not of fs root? */ - if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) + if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) printk(KERN_WARNING "EXT4-fs: Quota file not on filesystem root. " "Journalled quota will not work.\n"); - path_put(&nd.path); + path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } diff --git a/trunk/fs/gfs2/ops_fstype.c b/trunk/fs/gfs2/ops_fstype.c index 4bee6aa845e4..43d511bba52d 100644 --- a/trunk/fs/gfs2/ops_fstype.c +++ b/trunk/fs/gfs2/ops_fstype.c @@ -884,13 +884,12 @@ static struct super_block* get_gfs2_sb(const char *dev_name) dev_name); goto out; } - error = vfs_getattr(nd.path.mnt, nd.path.dentry, &stat); + error = vfs_getattr(nd.mnt, nd.dentry, &stat); fstype = get_fs_type("gfs2"); list_for_each_entry(s, &fstype->fs_supers, s_instances) { if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) || - (S_ISDIR(stat.mode) && - s == nd.path.dentry->d_inode->i_sb)) { + (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) { sb = s; goto free_nd; } @@ -900,7 +899,7 @@ static struct super_block* get_gfs2_sb(const char *dev_name) "mount point %s\n", dev_name); free_nd: - path_put(&nd.path); + path_release(&nd); out: return sb; } diff --git a/trunk/fs/inotify_user.c b/trunk/fs/inotify_user.c index 7b94a1e3c015..3ab09a65c456 100644 --- a/trunk/fs/inotify_user.c +++ b/trunk/fs/inotify_user.c @@ -41,9 +41,9 @@ static struct kmem_cache *event_cachep __read_mostly; static struct vfsmount *inotify_mnt __read_mostly; /* these are configurable via /proc/sys/fs/inotify/ */ -static int inotify_max_user_instances __read_mostly; -static int inotify_max_user_watches __read_mostly; -static int inotify_max_queued_events __read_mostly; +int inotify_max_user_instances __read_mostly; +int inotify_max_user_watches __read_mostly; +int inotify_max_queued_events __read_mostly; /* * Lock ordering: @@ -367,7 +367,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd, /* you can only watch an inode if you have read permissions on it */ error = vfs_permission(nd, MAY_READ); if (error) - path_put(&nd->path); + path_release(nd); return error; } @@ -667,7 +667,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) goto fput_and_out; /* inode held in place by reference to nd; dev by fget on fd */ - inode = nd.path.dentry->d_inode; + inode = nd.dentry->d_inode; dev = filp->private_data; mutex_lock(&dev->up_mutex); @@ -676,7 +676,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) ret = create_watch(dev, inode, mask); mutex_unlock(&dev->up_mutex); - path_put(&nd.path); + path_release(&nd); fput_and_out: fput_light(filp, fput_needed); return ret; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 941c8e8228c0..52703986323a 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -231,7 +231,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) struct vfsmount *mnt = NULL; if (nd) - mnt = nd->path.mnt; + mnt = nd->mnt; if (mask & MAY_WRITE) { umode_t mode = inode->i_mode; @@ -296,7 +296,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) */ int vfs_permission(struct nameidata *nd, int mask) { - return permission(nd->path.dentry->d_inode, mask, nd); + return permission(nd->dentry->d_inode, mask, nd); } /** @@ -362,31 +362,21 @@ int deny_write_access(struct file * file) return 0; } -/** - * path_get - get a reference to a path - * @path: path to get the reference to - * - * Given a path increment the reference count to the dentry and the vfsmount. - */ -void path_get(struct path *path) +void path_release(struct nameidata *nd) { - mntget(path->mnt); - dget(path->dentry); + dput(nd->dentry); + mntput(nd->mnt); } -EXPORT_SYMBOL(path_get); -/** - * path_put - put a reference to a path - * @path: path to put the reference to - * - * Given a path decrement the reference count to the dentry and the vfsmount. +/* + * umount() mustn't call path_release()/mntput() as that would clear + * mnt_expiry_mark */ -void path_put(struct path *path) +void path_release_on_umount(struct nameidata *nd) { - dput(path->dentry); - mntput(path->mnt); + dput(nd->dentry); + mntput_no_expire(nd->mnt); } -EXPORT_SYMBOL(path_put); /** * release_open_intent - free up open intent resources @@ -549,16 +539,16 @@ walk_init_root(const char *name, struct nameidata *nd) struct fs_struct *fs = current->fs; read_lock(&fs->lock); - if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { - nd->path = fs->altroot; - path_get(&fs->altroot); + if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { + nd->mnt = mntget(fs->altrootmnt); + nd->dentry = dget(fs->altroot); read_unlock(&fs->lock); if (__emul_lookup_dentry(name,nd)) return 0; read_lock(&fs->lock); } - nd->path = fs->root; - path_get(&fs->root); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); read_unlock(&fs->lock); return 1; } @@ -571,7 +561,7 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l goto fail; if (*link == '/') { - path_put(&nd->path); + path_release(nd); if (!walk_init_root(link, nd)) /* weird __emul_prefix() stuff did it */ goto out; @@ -587,31 +577,31 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l */ name = __getname(); if (unlikely(!name)) { - path_put(&nd->path); + path_release(nd); return -ENOMEM; } strcpy(name, nd->last.name); nd->last.name = name; return 0; fail: - path_put(&nd->path); + path_release(nd); return PTR_ERR(link); } -static void path_put_conditional(struct path *path, struct nameidata *nd) +static inline void dput_path(struct path *path, struct nameidata *nd) { dput(path->dentry); - if (path->mnt != nd->path.mnt) + if (path->mnt != nd->mnt) mntput(path->mnt); } static inline void path_to_nameidata(struct path *path, struct nameidata *nd) { - dput(nd->path.dentry); - if (nd->path.mnt != path->mnt) - mntput(nd->path.mnt); - nd->path.mnt = path->mnt; - nd->path.dentry = path->dentry; + dput(nd->dentry); + if (nd->mnt != path->mnt) + mntput(nd->mnt); + nd->mnt = path->mnt; + nd->dentry = path->dentry; } static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd) @@ -623,7 +613,7 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata touch_atime(path->mnt, dentry); nd_set_link(nd, NULL); - if (path->mnt != nd->path.mnt) { + if (path->mnt != nd->mnt) { path_to_nameidata(path, nd); dget(dentry); } @@ -638,7 +628,8 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata if (dentry->d_inode->i_op->put_link) dentry->d_inode->i_op->put_link(dentry, nd, cookie); } - path_put(path); + dput(dentry); + mntput(path->mnt); return error; } @@ -670,8 +661,8 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) nd->depth--; return err; loop: - path_put_conditional(path, nd); - path_put(&nd->path); + dput_path(path, nd); + path_release(nd); return err; } @@ -752,37 +743,37 @@ static __always_inline void follow_dotdot(struct nameidata *nd) while(1) { struct vfsmount *parent; - struct dentry *old = nd->path.dentry; + struct dentry *old = nd->dentry; read_lock(&fs->lock); - if (nd->path.dentry == fs->root.dentry && - nd->path.mnt == fs->root.mnt) { + if (nd->dentry == fs->root && + nd->mnt == fs->rootmnt) { read_unlock(&fs->lock); break; } read_unlock(&fs->lock); spin_lock(&dcache_lock); - if (nd->path.dentry != nd->path.mnt->mnt_root) { - nd->path.dentry = dget(nd->path.dentry->d_parent); + if (nd->dentry != nd->mnt->mnt_root) { + nd->dentry = dget(nd->dentry->d_parent); spin_unlock(&dcache_lock); dput(old); break; } spin_unlock(&dcache_lock); spin_lock(&vfsmount_lock); - parent = nd->path.mnt->mnt_parent; - if (parent == nd->path.mnt) { + parent = nd->mnt->mnt_parent; + if (parent == nd->mnt) { spin_unlock(&vfsmount_lock); break; } mntget(parent); - nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint); + nd->dentry = dget(nd->mnt->mnt_mountpoint); spin_unlock(&vfsmount_lock); dput(old); - mntput(nd->path.mnt); - nd->path.mnt = parent; + mntput(nd->mnt); + nd->mnt = parent; } - follow_mount(&nd->path.mnt, &nd->path.dentry); + follow_mount(&nd->mnt, &nd->dentry); } /* @@ -793,8 +784,8 @@ static __always_inline void follow_dotdot(struct nameidata *nd) static int do_lookup(struct nameidata *nd, struct qstr *name, struct path *path) { - struct vfsmount *mnt = nd->path.mnt; - struct dentry *dentry = __d_lookup(nd->path.dentry, name); + struct vfsmount *mnt = nd->mnt; + struct dentry *dentry = __d_lookup(nd->dentry, name); if (!dentry) goto need_lookup; @@ -807,7 +798,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, return 0; need_lookup: - dentry = real_lookup(nd->path.dentry, name, nd); + dentry = real_lookup(nd->dentry, name, nd); if (IS_ERR(dentry)) goto fail; goto done; @@ -844,7 +835,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) if (!*name) goto return_reval; - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; if (nd->depth) lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE); @@ -892,7 +883,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) if (this.name[1] != '.') break; follow_dotdot(nd); - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; /* fallthrough */ case 1: continue; @@ -901,9 +892,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd) * See if the low-level filesystem might want * to use its own hash.. */ - if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { - err = nd->path.dentry->d_op->d_hash(nd->path.dentry, - &this); + if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { + err = nd->dentry->d_op->d_hash(nd->dentry, &this); if (err < 0) break; } @@ -925,7 +915,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) if (err) goto return_err; err = -ENOENT; - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; if (!inode) break; err = -ENOTDIR; @@ -953,14 +943,13 @@ static int __link_path_walk(const char *name, struct nameidata *nd) if (this.name[1] != '.') break; follow_dotdot(nd); - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; /* fallthrough */ case 1: goto return_reval; } - if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { - err = nd->path.dentry->d_op->d_hash(nd->path.dentry, - &this); + if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { + err = nd->dentry->d_op->d_hash(nd->dentry, &this); if (err < 0) break; } @@ -973,7 +962,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) err = do_follow_link(&next, nd); if (err) goto return_err; - inode = nd->path.dentry->d_inode; + inode = nd->dentry->d_inode; } else path_to_nameidata(&next, nd); err = -ENOENT; @@ -1001,21 +990,20 @@ static int __link_path_walk(const char *name, struct nameidata *nd) * We bypassed the ordinary revalidation routines. * We may need to check the cached dentry for staleness. */ - if (nd->path.dentry && nd->path.dentry->d_sb && - (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { + if (nd->dentry && nd->dentry->d_sb && + (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { err = -ESTALE; /* Note: we do not d_invalidate() */ - if (!nd->path.dentry->d_op->d_revalidate( - nd->path.dentry, nd)) + if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd)) break; } return_base: return 0; out_dput: - path_put_conditional(&next, nd); + dput_path(&next, nd); break; } - path_put(&nd->path); + path_release(nd); return_err: return err; } @@ -1033,19 +1021,20 @@ static int link_path_walk(const char *name, struct nameidata *nd) int result; /* make sure the stuff we saved doesn't go away */ - dget(save.path.dentry); - mntget(save.path.mnt); + dget(save.dentry); + mntget(save.mnt); result = __link_path_walk(name, nd); if (result == -ESTALE) { *nd = save; - dget(nd->path.dentry); - mntget(nd->path.mnt); + dget(nd->dentry); + mntget(nd->mnt); nd->flags |= LOOKUP_REVAL; result = __link_path_walk(name, nd); } - path_put(&save.path); + dput(save.dentry); + mntput(save.mnt); return result; } @@ -1065,9 +1054,9 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) if (path_walk(name, nd)) return 0; /* something went wrong... */ - if (!nd->path.dentry->d_inode || - S_ISDIR(nd->path.dentry->d_inode->i_mode)) { - struct path old_path = nd->path; + if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) { + struct dentry *old_dentry = nd->dentry; + struct vfsmount *old_mnt = nd->mnt; struct qstr last = nd->last; int last_type = nd->last_type; struct fs_struct *fs = current->fs; @@ -1078,17 +1067,19 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) */ nd->last_type = LAST_ROOT; read_lock(&fs->lock); - nd->path = fs->root; - path_get(&fs->root); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); read_unlock(&fs->lock); if (path_walk(name, nd) == 0) { - if (nd->path.dentry->d_inode) { - path_put(&old_path); + if (nd->dentry->d_inode) { + dput(old_dentry); + mntput(old_mnt); return 1; } - path_put(&nd->path); + path_release(nd); } - nd->path = old_path; + nd->dentry = old_dentry; + nd->mnt = old_mnt; nd->last = last; nd->last_type = last_type; } @@ -1099,22 +1090,29 @@ void set_fs_altroot(void) { char *emul = __emul_prefix(); struct nameidata nd; - struct path path = {}, old_path; + struct vfsmount *mnt = NULL, *oldmnt; + struct dentry *dentry = NULL, *olddentry; int err; struct fs_struct *fs = current->fs; if (!emul) goto set_it; err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); - if (!err) - path = nd.path; + if (!err) { + mnt = nd.mnt; + dentry = nd.dentry; + } set_it: write_lock(&fs->lock); - old_path = fs->altroot; - fs->altroot = path; + oldmnt = fs->altrootmnt; + olddentry = fs->altroot; + fs->altrootmnt = mnt; + fs->altroot = dentry; write_unlock(&fs->lock); - if (old_path.dentry) - path_put(&old_path); + if (olddentry) { + dput(olddentry); + mntput(oldmnt); + } } /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ @@ -1132,21 +1130,21 @@ static int do_path_lookup(int dfd, const char *name, if (*name=='/') { read_lock(&fs->lock); - if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { - nd->path = fs->altroot; - path_get(&fs->altroot); + if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { + nd->mnt = mntget(fs->altrootmnt); + nd->dentry = dget(fs->altroot); read_unlock(&fs->lock); if (__emul_lookup_dentry(name,nd)) goto out; /* found in altroot */ read_lock(&fs->lock); } - nd->path = fs->root; - path_get(&fs->root); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); read_unlock(&fs->lock); } else if (dfd == AT_FDCWD) { read_lock(&fs->lock); - nd->path = fs->pwd; - path_get(&fs->pwd); + nd->mnt = mntget(fs->pwdmnt); + nd->dentry = dget(fs->pwd); read_unlock(&fs->lock); } else { struct dentry *dentry; @@ -1166,17 +1164,17 @@ static int do_path_lookup(int dfd, const char *name, if (retval) goto fput_fail; - nd->path = file->f_path; - path_get(&file->f_path); + nd->mnt = mntget(file->f_path.mnt); + nd->dentry = dget(dentry); fput_light(file, fput_needed); } retval = path_walk(name, nd); out: - if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && - nd->path.dentry->d_inode)) - audit_inode(name, nd->path.dentry); + if (unlikely(!retval && !audit_dummy_context() && nd->dentry && + nd->dentry->d_inode)) + audit_inode(name, nd->dentry); out_fail: return retval; @@ -1210,13 +1208,13 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, nd->flags = flags; nd->depth = 0; - nd->path.mnt = mntget(mnt); - nd->path.dentry = dget(dentry); + nd->mnt = mntget(mnt); + nd->dentry = dget(dentry); retval = path_walk(name, nd); - if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && - nd->path.dentry->d_inode)) - audit_inode(name, nd->path.dentry); + if (unlikely(!retval && !audit_dummy_context() && nd->dentry && + nd->dentry->d_inode)) + audit_inode(name, nd->dentry); return retval; @@ -1238,7 +1236,7 @@ static int __path_lookup_intent_open(int dfd, const char *name, if (IS_ERR(nd->intent.open.file)) { if (err == 0) { err = PTR_ERR(nd->intent.open.file); - path_put(&nd->path); + path_release(nd); } } else if (err != 0) release_open_intent(nd); @@ -1335,10 +1333,10 @@ static struct dentry *lookup_hash(struct nameidata *nd) { int err; - err = permission(nd->path.dentry->d_inode, MAY_EXEC, nd); + err = permission(nd->dentry->d_inode, MAY_EXEC, nd); if (err) return ERR_PTR(err); - return __lookup_hash(&nd->last, nd->path.dentry, nd); + return __lookup_hash(&nd->last, nd->dentry, nd); } static int __lookup_one_len(const char *name, struct qstr *this, @@ -1597,7 +1595,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, int may_open(struct nameidata *nd, int acc_mode, int flag) { - struct dentry *dentry = nd->path.dentry; + struct dentry *dentry = nd->dentry; struct inode *inode = dentry->d_inode; int error; @@ -1618,7 +1616,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { flag &= ~O_TRUNC; } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { - if (nd->path.mnt->mnt_flags & MNT_NODEV) + if (nd->mnt->mnt_flags & MNT_NODEV) return -EACCES; flag &= ~O_TRUNC; @@ -1680,14 +1678,14 @@ static int open_namei_create(struct nameidata *nd, struct path *path, int flag, int mode) { int error; - struct dentry *dir = nd->path.dentry; + struct dentry *dir = nd->dentry; if (!IS_POSIXACL(dir->d_inode)) mode &= ~current->fs->umask; error = vfs_create(dir->d_inode, path->dentry, mode, nd); mutex_unlock(&dir->d_inode->i_mutex); - dput(nd->path.dentry); - nd->path.dentry = path->dentry; + dput(nd->dentry); + nd->dentry = path->dentry; if (error) return error; /* Don't check for write permission, don't truncate */ @@ -1754,11 +1752,11 @@ int open_namei(int dfd, const char *pathname, int flag, if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len]) goto exit; - dir = nd->path.dentry; + dir = nd->dentry; nd->flags &= ~LOOKUP_PARENT; mutex_lock(&dir->d_inode->i_mutex); path.dentry = lookup_hash(nd); - path.mnt = nd->path.mnt; + path.mnt = nd->mnt; do_last: error = PTR_ERR(path.dentry); @@ -1814,11 +1812,11 @@ int open_namei(int dfd, const char *pathname, int flag, return 0; exit_dput: - path_put_conditional(&path, nd); + dput_path(&path, nd); exit: if (!IS_ERR(nd->intent.open.file)) release_open_intent(nd); - path_put(&nd->path); + path_release(nd); return error; do_link: @@ -1863,10 +1861,10 @@ int open_namei(int dfd, const char *pathname, int flag, __putname(nd->last.name); goto exit; } - dir = nd->path.dentry; + dir = nd->dentry; mutex_lock(&dir->d_inode->i_mutex); path.dentry = lookup_hash(nd); - path.mnt = nd->path.mnt; + path.mnt = nd->mnt; __putname(nd->last.name); goto do_last; } @@ -1879,13 +1877,13 @@ int open_namei(int dfd, const char *pathname, int flag, * Simple function to lookup and return a dentry and create it * if it doesn't exist. Is SMP-safe. * - * Returns with nd->path.dentry->d_inode->i_mutex locked. + * Returns with nd->dentry->d_inode->i_mutex locked. */ struct dentry *lookup_create(struct nameidata *nd, int is_dir) { struct dentry *dentry = ERR_PTR(-EEXIST); - mutex_lock_nested(&nd->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT); /* * Yucky last component or no last component at all? * (foo/., foo/.., /////) @@ -1964,19 +1962,19 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, dentry = lookup_create(&nd, 0); error = PTR_ERR(dentry); - if (!IS_POSIXACL(nd.path.dentry->d_inode)) + if (!IS_POSIXACL(nd.dentry->d_inode)) mode &= ~current->fs->umask; if (!IS_ERR(dentry)) { switch (mode & S_IFMT) { case 0: case S_IFREG: - error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); + error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); break; case S_IFCHR: case S_IFBLK: - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode, + error = vfs_mknod(nd.dentry->d_inode,dentry,mode, new_decode_dev(dev)); break; case S_IFIFO: case S_IFSOCK: - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); + error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); break; case S_IFDIR: error = -EPERM; @@ -1986,8 +1984,8 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, } dput(dentry); } - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_put(&nd.path); + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out: putname(tmp); @@ -2041,13 +2039,13 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) if (IS_ERR(dentry)) goto out_unlock; - if (!IS_POSIXACL(nd.path.dentry->d_inode)) + if (!IS_POSIXACL(nd.dentry->d_inode)) mode &= ~current->fs->umask; - error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); + error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); dput(dentry); out_unlock: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_put(&nd.path); + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out: putname(tmp); out_err: @@ -2145,17 +2143,17 @@ static long do_rmdir(int dfd, const char __user *pathname) error = -EBUSY; goto exit1; } - mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); dentry = lookup_hash(&nd); error = PTR_ERR(dentry); if (IS_ERR(dentry)) goto exit2; - error = vfs_rmdir(nd.path.dentry->d_inode, dentry); + error = vfs_rmdir(nd.dentry->d_inode, dentry); dput(dentry); exit2: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.dentry->d_inode->i_mutex); exit1: - path_put(&nd.path); + path_release(&nd); exit: putname(name); return error; @@ -2221,7 +2219,7 @@ static long do_unlinkat(int dfd, const char __user *pathname) error = -EISDIR; if (nd.last_type != LAST_NORM) goto exit1; - mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); dentry = lookup_hash(&nd); error = PTR_ERR(dentry); if (!IS_ERR(dentry)) { @@ -2231,15 +2229,15 @@ static long do_unlinkat(int dfd, const char __user *pathname) inode = dentry->d_inode; if (inode) atomic_inc(&inode->i_count); - error = vfs_unlink(nd.path.dentry->d_inode, dentry); + error = vfs_unlink(nd.dentry->d_inode, dentry); exit2: dput(dentry); } - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.dentry->d_inode->i_mutex); if (inode) iput(inode); /* truncate the inode here */ exit1: - path_put(&nd.path); + path_release(&nd); exit: putname(name); return error; @@ -2312,11 +2310,11 @@ asmlinkage long sys_symlinkat(const char __user *oldname, if (IS_ERR(dentry)) goto out_unlock; - error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); + error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); dput(dentry); out_unlock: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_put(&nd.path); + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out: putname(to); out_putname: @@ -2401,20 +2399,20 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, if (error) goto out; error = -EXDEV; - if (old_nd.path.mnt != nd.path.mnt) + if (old_nd.mnt != nd.mnt) goto out_release; new_dentry = lookup_create(&nd, 0); error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) goto out_unlock; - error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); dput(new_dentry); out_unlock: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&nd.dentry->d_inode->i_mutex); out_release: - path_put(&nd.path); + path_release(&nd); out: - path_put(&old_nd.path); + path_release(&old_nd); exit: putname(to); @@ -2590,15 +2588,15 @@ static int do_rename(int olddfd, const char *oldname, goto exit1; error = -EXDEV; - if (oldnd.path.mnt != newnd.path.mnt) + if (oldnd.mnt != newnd.mnt) goto exit2; - old_dir = oldnd.path.dentry; + old_dir = oldnd.dentry; error = -EBUSY; if (oldnd.last_type != LAST_NORM) goto exit2; - new_dir = newnd.path.dentry; + new_dir = newnd.dentry; if (newnd.last_type != LAST_NORM) goto exit2; @@ -2642,9 +2640,9 @@ static int do_rename(int olddfd, const char *oldname, exit3: unlock_rename(new_dir, old_dir); exit2: - path_put(&newnd.path); + path_release(&newnd); exit1: - path_put(&oldnd.path); + path_release(&oldnd); exit: return error; } @@ -2818,6 +2816,7 @@ EXPORT_SYMBOL(page_symlink); EXPORT_SYMBOL(page_symlink_inode_operations); EXPORT_SYMBOL(path_lookup); EXPORT_SYMBOL(vfs_path_lookup); +EXPORT_SYMBOL(path_release); EXPORT_SYMBOL(permission); EXPORT_SYMBOL(vfs_permission); EXPORT_SYMBOL(file_permission); diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 7953c96a2071..63ced21c12dc 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -157,13 +157,13 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns) static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd) { - old_nd->path.dentry = mnt->mnt_mountpoint; - old_nd->path.mnt = mnt->mnt_parent; + old_nd->dentry = mnt->mnt_mountpoint; + old_nd->mnt = mnt->mnt_parent; mnt->mnt_parent = mnt; mnt->mnt_mountpoint = mnt->mnt_root; list_del_init(&mnt->mnt_child); list_del_init(&mnt->mnt_hash); - old_nd->path.dentry->d_mounted--; + old_nd->dentry->d_mounted--; } void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, @@ -176,10 +176,10 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd) { - mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt); + mnt_set_mountpoint(nd->mnt, nd->dentry, mnt); list_add_tail(&mnt->mnt_hash, mount_hashtable + - hash(nd->path.mnt, nd->path.dentry)); - list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts); + hash(nd->mnt, nd->dentry)); + list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts); } /* @@ -408,11 +408,10 @@ static int show_vfsmnt(struct seq_file *m, void *v) { 0, NULL } }; struct proc_fs_info *fs_infop; - struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); seq_putc(m, ' '); - seq_path(m, &mnt_path, " \t\n\\"); + seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); seq_putc(m, ' '); mangle(m, mnt->mnt_sb->s_type->name); if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) { @@ -444,7 +443,6 @@ struct seq_operations mounts_op = { static int show_vfsstat(struct seq_file *m, void *v) { struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list); - struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; int err = 0; /* device */ @@ -456,7 +454,7 @@ static int show_vfsstat(struct seq_file *m, void *v) /* mount point */ seq_puts(m, " mounted on "); - seq_path(m, &mnt_path, " \t\n\\"); + seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); seq_putc(m, ' '); /* file system type */ @@ -595,7 +593,7 @@ static int do_umount(struct vfsmount *mnt, int flags) * (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount] */ if (flags & MNT_EXPIRE) { - if (mnt == current->fs->root.mnt || + if (mnt == current->fs->rootmnt || flags & (MNT_FORCE | MNT_DETACH)) return -EINVAL; @@ -630,7 +628,7 @@ static int do_umount(struct vfsmount *mnt, int flags) * /reboot - static binary that would close all descriptors and * call reboot(9). Then init(8) could umount root and exec /reboot. */ - if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) { + if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) { /* * Special case for "unmounting" root ... * we just try to remount it readonly. @@ -681,20 +679,18 @@ asmlinkage long sys_umount(char __user * name, int flags) if (retval) goto out; retval = -EINVAL; - if (nd.path.dentry != nd.path.mnt->mnt_root) + if (nd.dentry != nd.mnt->mnt_root) goto dput_and_out; - if (!check_mnt(nd.path.mnt)) + if (!check_mnt(nd.mnt)) goto dput_and_out; retval = -EPERM; if (!capable(CAP_SYS_ADMIN)) goto dput_and_out; - retval = do_umount(nd.path.mnt, flags); + retval = do_umount(nd.mnt, flags); dput_and_out: - /* we mustn't call path_put() as that would clear mnt_expiry_mark */ - dput(nd.path.dentry); - mntput_no_expire(nd.path.mnt); + path_release_on_umount(&nd); out: return retval; } @@ -717,10 +713,10 @@ static int mount_is_safe(struct nameidata *nd) return 0; return -EPERM; #ifdef notyet - if (S_ISLNK(nd->path.dentry->d_inode->i_mode)) + if (S_ISLNK(nd->dentry->d_inode->i_mode)) return -EPERM; - if (nd->path.dentry->d_inode->i_mode & S_ISVTX) { - if (current->uid != nd->path.dentry->d_inode->i_uid) + if (nd->dentry->d_inode->i_mode & S_ISVTX) { + if (current->uid != nd->dentry->d_inode->i_uid) return -EPERM; } if (vfs_permission(nd, MAY_WRITE)) @@ -769,8 +765,8 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, q = q->mnt_parent; } p = s; - nd.path.mnt = q; - nd.path.dentry = p->mnt_mountpoint; + nd.mnt = q; + nd.dentry = p->mnt_mountpoint; q = clone_mnt(p, p->mnt_root, flag); if (!q) goto Enomem; @@ -879,8 +875,8 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, struct nameidata *nd, struct nameidata *parent_nd) { LIST_HEAD(tree_list); - struct vfsmount *dest_mnt = nd->path.mnt; - struct dentry *dest_dentry = nd->path.dentry; + struct vfsmount *dest_mnt = nd->mnt; + struct dentry *dest_dentry = nd->dentry; struct vfsmount *child, *p; if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list)) @@ -915,13 +911,13 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) if (mnt->mnt_sb->s_flags & MS_NOUSER) return -EINVAL; - if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != + if (S_ISDIR(nd->dentry->d_inode->i_mode) != S_ISDIR(mnt->mnt_root->d_inode->i_mode)) return -ENOTDIR; err = -ENOENT; - mutex_lock(&nd->path.dentry->d_inode->i_mutex); - if (IS_DEADDIR(nd->path.dentry->d_inode)) + mutex_lock(&nd->dentry->d_inode->i_mutex); + if (IS_DEADDIR(nd->dentry->d_inode)) goto out_unlock; err = security_sb_check_sb(mnt, nd); @@ -929,10 +925,10 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) goto out_unlock; err = -ENOENT; - if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) + if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) err = attach_recursive_mnt(mnt, nd, NULL); out_unlock: - mutex_unlock(&nd->path.dentry->d_inode->i_mutex); + mutex_unlock(&nd->dentry->d_inode->i_mutex); if (!err) security_sb_post_addmount(mnt, nd); return err; @@ -944,14 +940,14 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) */ static noinline int do_change_type(struct nameidata *nd, int flag) { - struct vfsmount *m, *mnt = nd->path.mnt; + struct vfsmount *m, *mnt = nd->mnt; int recurse = flag & MS_REC; int type = flag & ~MS_REC; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (nd->path.dentry != nd->path.mnt->mnt_root) + if (nd->dentry != nd->mnt->mnt_root) return -EINVAL; down_write(&namespace_sem); @@ -983,17 +979,17 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name, down_write(&namespace_sem); err = -EINVAL; - if (IS_MNT_UNBINDABLE(old_nd.path.mnt)) - goto out; + if (IS_MNT_UNBINDABLE(old_nd.mnt)) + goto out; - if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) + if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) goto out; err = -ENOMEM; if (recurse) - mnt = copy_tree(old_nd.path.mnt, old_nd.path.dentry, 0); + mnt = copy_tree(old_nd.mnt, old_nd.dentry, 0); else - mnt = clone_mnt(old_nd.path.mnt, old_nd.path.dentry, 0); + mnt = clone_mnt(old_nd.mnt, old_nd.dentry, 0); if (!mnt) goto out; @@ -1009,7 +1005,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name, out: up_write(&namespace_sem); - path_put(&old_nd.path); + path_release(&old_nd); return err; } @@ -1023,24 +1019,24 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags, void *data) { int err; - struct super_block *sb = nd->path.mnt->mnt_sb; + struct super_block *sb = nd->mnt->mnt_sb; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!check_mnt(nd->path.mnt)) + if (!check_mnt(nd->mnt)) return -EINVAL; - if (nd->path.dentry != nd->path.mnt->mnt_root) + if (nd->dentry != nd->mnt->mnt_root) return -EINVAL; down_write(&sb->s_umount); err = do_remount_sb(sb, flags, data, 0); if (!err) - nd->path.mnt->mnt_flags = mnt_flags; + nd->mnt->mnt_flags = mnt_flags; up_write(&sb->s_umount); if (!err) - security_sb_post_remount(nd->path.mnt, flags, data); + security_sb_post_remount(nd->mnt, flags, data); return err; } @@ -1071,65 +1067,61 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name) return err; down_write(&namespace_sem); - while (d_mountpoint(nd->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) ; err = -EINVAL; - if (!check_mnt(nd->path.mnt) || !check_mnt(old_nd.path.mnt)) + if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt)) goto out; err = -ENOENT; - mutex_lock(&nd->path.dentry->d_inode->i_mutex); - if (IS_DEADDIR(nd->path.dentry->d_inode)) + mutex_lock(&nd->dentry->d_inode->i_mutex); + if (IS_DEADDIR(nd->dentry->d_inode)) goto out1; - if (!IS_ROOT(nd->path.dentry) && d_unhashed(nd->path.dentry)) + if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry)) goto out1; err = -EINVAL; - if (old_nd.path.dentry != old_nd.path.mnt->mnt_root) + if (old_nd.dentry != old_nd.mnt->mnt_root) goto out1; - if (old_nd.path.mnt == old_nd.path.mnt->mnt_parent) + if (old_nd.mnt == old_nd.mnt->mnt_parent) goto out1; - if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != - S_ISDIR(old_nd.path.dentry->d_inode->i_mode)) + if (S_ISDIR(nd->dentry->d_inode->i_mode) != + S_ISDIR(old_nd.dentry->d_inode->i_mode)) goto out1; /* * Don't move a mount residing in a shared parent. */ - if (old_nd.path.mnt->mnt_parent && - IS_MNT_SHARED(old_nd.path.mnt->mnt_parent)) + if (old_nd.mnt->mnt_parent && IS_MNT_SHARED(old_nd.mnt->mnt_parent)) goto out1; /* * Don't move a mount tree containing unbindable mounts to a destination * mount which is shared. */ - if (IS_MNT_SHARED(nd->path.mnt) && - tree_contains_unbindable(old_nd.path.mnt)) + if (IS_MNT_SHARED(nd->mnt) && tree_contains_unbindable(old_nd.mnt)) goto out1; err = -ELOOP; - for (p = nd->path.mnt; p->mnt_parent != p; p = p->mnt_parent) - if (p == old_nd.path.mnt) + for (p = nd->mnt; p->mnt_parent != p; p = p->mnt_parent) + if (p == old_nd.mnt) goto out1; - err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd); - if (err) + if ((err = attach_recursive_mnt(old_nd.mnt, nd, &parent_nd))) goto out1; spin_lock(&vfsmount_lock); /* if the mount is moved, it should no longer be expire * automatically */ - list_del_init(&old_nd.path.mnt->mnt_expire); + list_del_init(&old_nd.mnt->mnt_expire); spin_unlock(&vfsmount_lock); out1: - mutex_unlock(&nd->path.dentry->d_inode->i_mutex); + mutex_unlock(&nd->dentry->d_inode->i_mutex); out: up_write(&namespace_sem); if (!err) - path_put(&parent_nd.path); - path_put(&old_nd.path); + path_release(&parent_nd); + path_release(&old_nd); return err; } @@ -1168,17 +1160,16 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd, down_write(&namespace_sem); /* Something was mounted here while we slept */ - while (d_mountpoint(nd->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) ; err = -EINVAL; - if (!check_mnt(nd->path.mnt)) + if (!check_mnt(nd->mnt)) goto unlock; /* Refuse the same filesystem on the same mount point */ err = -EBUSY; - if (nd->path.mnt->mnt_sb == newmnt->mnt_sb && - nd->path.mnt->mnt_root == nd->path.dentry) + if (nd->mnt->mnt_sb == newmnt->mnt_sb && + nd->mnt->mnt_root == nd->dentry) goto unlock; err = -EINVAL; @@ -1514,7 +1505,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, retval = do_new_mount(&nd, type_page, flags, mnt_flags, dev_name, data_page); dput_out: - path_put(&nd.path); + path_release(&nd); return retval; } @@ -1561,17 +1552,17 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, while (p) { q->mnt_ns = new_ns; if (fs) { - if (p == fs->root.mnt) { + if (p == fs->rootmnt) { rootmnt = p; - fs->root.mnt = mntget(q); + fs->rootmnt = mntget(q); } - if (p == fs->pwd.mnt) { + if (p == fs->pwdmnt) { pwdmnt = p; - fs->pwd.mnt = mntget(q); + fs->pwdmnt = mntget(q); } - if (p == fs->altroot.mnt) { + if (p == fs->altrootmnt) { altrootmnt = p; - fs->altroot.mnt = mntget(q); + fs->altrootmnt = mntget(q); } } p = next_mnt(p, mnt_ns->root); @@ -1652,35 +1643,44 @@ asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. * It can block. Requires the big lock held. */ -void set_fs_root(struct fs_struct *fs, struct path *path) +void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt, + struct dentry *dentry) { - struct path old_root; - + struct dentry *old_root; + struct vfsmount *old_rootmnt; write_lock(&fs->lock); old_root = fs->root; - fs->root = *path; - path_get(path); + old_rootmnt = fs->rootmnt; + fs->rootmnt = mntget(mnt); + fs->root = dget(dentry); write_unlock(&fs->lock); - if (old_root.dentry) - path_put(&old_root); + if (old_root) { + dput(old_root); + mntput(old_rootmnt); + } } /* * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. * It can block. Requires the big lock held. */ -void set_fs_pwd(struct fs_struct *fs, struct path *path) +void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, + struct dentry *dentry) { - struct path old_pwd; + struct dentry *old_pwd; + struct vfsmount *old_pwdmnt; write_lock(&fs->lock); old_pwd = fs->pwd; - fs->pwd = *path; - path_get(path); + old_pwdmnt = fs->pwdmnt; + fs->pwdmnt = mntget(mnt); + fs->pwd = dget(dentry); write_unlock(&fs->lock); - if (old_pwd.dentry) - path_put(&old_pwd); + if (old_pwd) { + dput(old_pwd); + mntput(old_pwdmnt); + } } static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) @@ -1695,12 +1695,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) if (fs) { atomic_inc(&fs->count); task_unlock(p); - if (fs->root.dentry == old_nd->path.dentry - && fs->root.mnt == old_nd->path.mnt) - set_fs_root(fs, &new_nd->path); - if (fs->pwd.dentry == old_nd->path.dentry - && fs->pwd.mnt == old_nd->path.mnt) - set_fs_pwd(fs, &new_nd->path); + if (fs->root == old_nd->dentry + && fs->rootmnt == old_nd->mnt) + set_fs_root(fs, new_nd->mnt, new_nd->dentry); + if (fs->pwd == old_nd->dentry + && fs->pwdmnt == old_nd->mnt) + set_fs_pwd(fs, new_nd->mnt, new_nd->dentry); put_fs_struct(fs); } else task_unlock(p); @@ -1750,7 +1750,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root, if (error) goto out0; error = -EINVAL; - if (!check_mnt(new_nd.path.mnt)) + if (!check_mnt(new_nd.mnt)) goto out1; error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd); @@ -1759,78 +1759,74 @@ asmlinkage long sys_pivot_root(const char __user * new_root, error = security_sb_pivotroot(&old_nd, &new_nd); if (error) { - path_put(&old_nd.path); + path_release(&old_nd); goto out1; } read_lock(¤t->fs->lock); - user_nd.path = current->fs->root; - path_get(¤t->fs->root); + user_nd.mnt = mntget(current->fs->rootmnt); + user_nd.dentry = dget(current->fs->root); read_unlock(¤t->fs->lock); down_write(&namespace_sem); - mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); + mutex_lock(&old_nd.dentry->d_inode->i_mutex); error = -EINVAL; - if (IS_MNT_SHARED(old_nd.path.mnt) || - IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || - IS_MNT_SHARED(user_nd.path.mnt->mnt_parent)) + if (IS_MNT_SHARED(old_nd.mnt) || + IS_MNT_SHARED(new_nd.mnt->mnt_parent) || + IS_MNT_SHARED(user_nd.mnt->mnt_parent)) goto out2; - if (!check_mnt(user_nd.path.mnt)) + if (!check_mnt(user_nd.mnt)) goto out2; error = -ENOENT; - if (IS_DEADDIR(new_nd.path.dentry->d_inode)) + if (IS_DEADDIR(new_nd.dentry->d_inode)) goto out2; - if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry)) + if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry)) goto out2; - if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) + if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry)) goto out2; error = -EBUSY; - if (new_nd.path.mnt == user_nd.path.mnt || - old_nd.path.mnt == user_nd.path.mnt) + if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt) goto out2; /* loop, on the same file system */ error = -EINVAL; - if (user_nd.path.mnt->mnt_root != user_nd.path.dentry) + if (user_nd.mnt->mnt_root != user_nd.dentry) goto out2; /* not a mountpoint */ - if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt) + if (user_nd.mnt->mnt_parent == user_nd.mnt) goto out2; /* not attached */ - if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) + if (new_nd.mnt->mnt_root != new_nd.dentry) goto out2; /* not a mountpoint */ - if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt) + if (new_nd.mnt->mnt_parent == new_nd.mnt) goto out2; /* not attached */ - /* make sure we can reach put_old from new_root */ - tmp = old_nd.path.mnt; + tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */ spin_lock(&vfsmount_lock); - if (tmp != new_nd.path.mnt) { + if (tmp != new_nd.mnt) { for (;;) { if (tmp->mnt_parent == tmp) goto out3; /* already mounted on put_old */ - if (tmp->mnt_parent == new_nd.path.mnt) + if (tmp->mnt_parent == new_nd.mnt) break; tmp = tmp->mnt_parent; } - if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry)) + if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry)) goto out3; - } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) + } else if (!is_subdir(old_nd.dentry, new_nd.dentry)) goto out3; - detach_mnt(new_nd.path.mnt, &parent_nd); - detach_mnt(user_nd.path.mnt, &root_parent); - /* mount old root on put_old */ - attach_mnt(user_nd.path.mnt, &old_nd); - /* mount new_root on / */ - attach_mnt(new_nd.path.mnt, &root_parent); + detach_mnt(new_nd.mnt, &parent_nd); + detach_mnt(user_nd.mnt, &root_parent); + attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */ + attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */ touch_mnt_namespace(current->nsproxy->mnt_ns); spin_unlock(&vfsmount_lock); chroot_fs_refs(&user_nd, &new_nd); security_sb_post_pivotroot(&user_nd, &new_nd); error = 0; - path_put(&root_parent.path); - path_put(&parent_nd.path); + path_release(&root_parent); + path_release(&parent_nd); out2: - mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); + mutex_unlock(&old_nd.dentry->d_inode->i_mutex); up_write(&namespace_sem); - path_put(&user_nd.path); - path_put(&old_nd.path); + path_release(&user_nd); + path_release(&old_nd); out1: - path_put(&new_nd.path); + path_release(&new_nd); out0: unlock_kernel(); return error; @@ -1843,7 +1839,6 @@ static void __init init_mount_tree(void) { struct vfsmount *mnt; struct mnt_namespace *ns; - struct path root; mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); if (IS_ERR(mnt)) @@ -1862,11 +1857,8 @@ static void __init init_mount_tree(void) init_task.nsproxy->mnt_ns = ns; get_mnt_ns(ns); - root.mnt = ns->root; - root.dentry = ns->root->mnt_root; - - set_fs_pwd(current->fs, &root); - set_fs_root(current->fs, &root); + set_fs_pwd(current->fs, ns->root, ns->root->mnt_root); + set_fs_root(current->fs, ns->root, ns->root->mnt_root); } void __init mnt_init(void) diff --git a/trunk/fs/nfs/callback.c b/trunk/fs/nfs/callback.c index ecc06c619494..bd185a572a23 100644 --- a/trunk/fs/nfs/callback.c +++ b/trunk/fs/nfs/callback.c @@ -105,7 +105,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp) */ int nfs_callback_up(void) { - struct svc_serv *serv = NULL; + struct svc_serv *serv; int ret = 0; lock_kernel(); @@ -122,30 +122,24 @@ int nfs_callback_up(void) ret = svc_create_xprt(serv, "tcp", nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); if (ret <= 0) - goto out_err; + goto out_destroy; nfs_callback_tcpport = ret; dprintk("Callback port = 0x%x\n", nfs_callback_tcpport); ret = svc_create_thread(nfs_callback_svc, serv); if (ret < 0) - goto out_err; + goto out_destroy; nfs_callback_info.serv = serv; wait_for_completion(&nfs_callback_info.started); out: - /* - * svc_create creates the svc_serv with sv_nrthreads == 1, and then - * svc_create_thread increments that. So we need to call svc_destroy - * on both success and failure so that the refcount is 1 when the - * thread exits. - */ - if (serv) - svc_destroy(serv); mutex_unlock(&nfs_callback_mutex); unlock_kernel(); return ret; -out_err: +out_destroy: dprintk("Couldn't create callback socket or server thread; err = %d\n", ret); + svc_destroy(serv); +out_err: nfs_callback_info.users--; goto out; } diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index ae04892a5e5d..476cb0f837fd 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -154,6 +154,7 @@ typedef struct { struct nfs_entry *entry; decode_dirent_t decode; int plus; + int error; unsigned long timestamp; int timestamp_valid; } nfs_readdir_descriptor_t; @@ -212,6 +213,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) return 0; error: unlock_page(page); + desc->error = error; return -EIO; } @@ -481,13 +483,13 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, goto out; } timestamp = jiffies; - status = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, - *desc->dir_cookie, page, + desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie, + page, NFS_SERVER(inode)->dtsize, desc->plus); desc->page = page; desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ - if (status >= 0) { + if (desc->error >= 0) { desc->timestamp = timestamp; desc->timestamp_valid = 1; if ((status = dir_decode(desc)) == 0) diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index 607f6eb9cdb5..be4ce1c3a3d8 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -107,40 +107,38 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) BUG_ON(IS_ROOT(dentry)); dprintk("%s: enter\n", __FUNCTION__); - dput(nd->path.dentry); - nd->path.dentry = dget(dentry); + dput(nd->dentry); + nd->dentry = dget(dentry); /* Look it up again */ - parent = dget_parent(nd->path.dentry); + parent = dget_parent(nd->dentry); err = server->nfs_client->rpc_ops->lookup(parent->d_inode, - &nd->path.dentry->d_name, + &nd->dentry->d_name, &fh, &fattr); dput(parent); if (err != 0) goto out_err; if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) - mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry); + mnt = nfs_do_refmount(nd->mnt, nd->dentry); else - mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh, - &fattr); + mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr); err = PTR_ERR(mnt); if (IS_ERR(mnt)) goto out_err; mntget(mnt); - err = do_add_mount(mnt, nd, nd->path.mnt->mnt_flags|MNT_SHRINKABLE, - &nfs_automount_list); + err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list); if (err < 0) { mntput(mnt); if (err == -EBUSY) goto out_follow; goto out_err; } - mntput(nd->path.mnt); - dput(nd->path.dentry); - nd->path.mnt = mnt; - nd->path.dentry = dget(mnt->mnt_root); + mntput(nd->mnt); + dput(nd->dentry); + nd->mnt = mnt; + nd->dentry = dget(mnt->mnt_root); schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); out: dprintk("%s: done, returned %d\n", __FUNCTION__, err); @@ -148,11 +146,10 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) dprintk("<-- nfs_follow_mountpoint() = %d\n", err); return ERR_PTR(err); out_err: - path_put(&nd->path); + path_release(nd); goto out; out_follow: - while (d_mountpoint(nd->path.dentry) && - follow_down(&nd->path.mnt, &nd->path.dentry)) + while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry)) ; err = 0; goto out; diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 7ce07862c2fb..027e1095256e 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -1384,11 +1384,11 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct struct dentry * nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { + struct dentry *parent; struct path path = { - .mnt = nd->path.mnt, + .mnt = nd->mnt, .dentry = dentry, }; - struct dentry *parent; struct iattr attr; struct rpc_cred *cred; struct nfs4_state *state; @@ -1433,7 +1433,7 @@ int nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd) { struct path path = { - .mnt = nd->path.mnt, + .mnt = nd->mnt, .dentry = dentry, }; struct rpc_cred *cred; @@ -1885,7 +1885,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, int flags, struct nameidata *nd) { struct path path = { - .mnt = nd->path.mnt, + .mnt = nd->mnt, .dentry = dentry, }; struct nfs4_state *state; diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index 6233eb5e98c1..f9c7432471dc 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -682,8 +682,8 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid) if (seqid->sequence->flags & NFS_SEQID_CONFIRMED) return; printk(KERN_WARNING "NFS: v4 server returned a bad" - " sequence-id error on an" - " unconfirmed sequence %p!\n", + "sequence-id error on an" + "unconfirmed sequence %p!\n", seqid->sequence); case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_STATEID: diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 1fb381843650..7f4505f6ac6f 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -190,10 +190,6 @@ static match_table_t nfs_secflavor_tokens = { { Opt_sec_lkeyi, "lkeyi" }, { Opt_sec_lkeyp, "lkeyp" }, - { Opt_sec_spkm, "spkm3" }, - { Opt_sec_spkmi, "spkm3i" }, - { Opt_sec_spkmp, "spkm3p" }, - { Opt_sec_err, NULL } }; diff --git a/trunk/fs/nfsctl.c b/trunk/fs/nfsctl.c index aed8145d9087..51f1b31acbf6 100644 --- a/trunk/fs/nfsctl.c +++ b/trunk/fs/nfsctl.c @@ -41,9 +41,9 @@ static struct file *do_open(char *name, int flags) error = may_open(&nd, MAY_WRITE, FMODE_WRITE); if (!error) - return dentry_open(nd.path.dentry, nd.path.mnt, flags); + return dentry_open(nd.dentry, nd.mnt, flags); - path_put(&nd.path); + path_release(&nd); return ERR_PTR(error); } diff --git a/trunk/fs/nfsd/export.c b/trunk/fs/nfsd/export.c index 8a6f7c924c75..346570f6d848 100644 --- a/trunk/fs/nfsd/export.c +++ b/trunk/fs/nfsd/export.c @@ -63,8 +63,10 @@ static void expkey_put(struct kref *ref) struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); if (test_bit(CACHE_VALID, &key->h.flags) && - !test_bit(CACHE_NEGATIVE, &key->h.flags)) - path_put(&key->ek_path); + !test_bit(CACHE_NEGATIVE, &key->h.flags)) { + dput(key->ek_dentry); + mntput(key->ek_mnt); + } auth_domain_put(key->ek_client); kfree(key); } @@ -167,14 +169,15 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen) goto out; dprintk("Found the path %s\n", buf); - key.ek_path = nd.path; - + key.ek_mnt = nd.mnt; + key.ek_dentry = nd.dentry; + ek = svc_expkey_update(&key, ek); if (ek) cache_put(&ek->h, &svc_expkey_cache); else err = -ENOMEM; - path_put(&nd.path); + path_release(&nd); } cache_flush(); out: @@ -203,7 +206,7 @@ static int expkey_show(struct seq_file *m, if (test_bit(CACHE_VALID, &h->flags) && !test_bit(CACHE_NEGATIVE, &h->flags)) { seq_printf(m, " "); - seq_path(m, &ek->ek_path, "\\ \t\n"); + seq_path(m, ek->ek_mnt, ek->ek_dentry, "\\ \t\n"); } seq_printf(m, "\n"); return 0; @@ -240,8 +243,8 @@ static inline void expkey_update(struct cache_head *cnew, struct svc_expkey *new = container_of(cnew, struct svc_expkey, h); struct svc_expkey *item = container_of(citem, struct svc_expkey, h); - new->ek_path = item->ek_path; - path_get(&item->ek_path); + new->ek_mnt = mntget(item->ek_mnt); + new->ek_dentry = dget(item->ek_dentry); } static struct cache_head *expkey_alloc(void) @@ -329,9 +332,10 @@ static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc) static void svc_export_put(struct kref *ref) { struct svc_export *exp = container_of(ref, struct svc_export, h.ref); - path_put(&exp->ex_path); + dput(exp->ex_dentry); + mntput(exp->ex_mnt); auth_domain_put(exp->ex_client); - kfree(exp->ex_pathname); + kfree(exp->ex_path); nfsd4_fslocs_free(&exp->ex_fslocs); kfree(exp); } @@ -345,7 +349,7 @@ static void svc_export_request(struct cache_detail *cd, char *pth; qword_add(bpp, blen, exp->ex_client->name); - pth = d_path(&exp->ex_path, *bpp, *blen); + pth = d_path(exp->ex_dentry, exp->ex_mnt, *bpp, *blen); if (IS_ERR(pth)) { /* is this correct? */ (*bpp)[0] = '\n'; @@ -503,8 +507,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) struct svc_export exp, *expp; int an_int; - nd.path.dentry = NULL; - exp.ex_pathname = NULL; + nd.dentry = NULL; + exp.ex_path = NULL; /* fs locations */ exp.ex_fslocs.locations = NULL; @@ -543,11 +547,11 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) exp.h.flags = 0; exp.ex_client = dom; - exp.ex_path.mnt = nd.path.mnt; - exp.ex_path.dentry = nd.path.dentry; - exp.ex_pathname = kstrdup(buf, GFP_KERNEL); + exp.ex_mnt = nd.mnt; + exp.ex_dentry = nd.dentry; + exp.ex_path = kstrdup(buf, GFP_KERNEL); err = -ENOMEM; - if (!exp.ex_pathname) + if (!exp.ex_path) goto out; /* expiry */ @@ -606,7 +610,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) goto out; } - err = check_export(nd.path.dentry->d_inode, exp.ex_flags, + err = check_export(nd.dentry->d_inode, exp.ex_flags, exp.ex_uuid); if (err) goto out; } @@ -624,9 +628,9 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) out: nfsd4_fslocs_free(&exp.ex_fslocs); kfree(exp.ex_uuid); - kfree(exp.ex_pathname); - if (nd.path.dentry) - path_put(&nd.path); + kfree(exp.ex_path); + if (nd.dentry) + path_release(&nd); out_no_path: if (dom) auth_domain_put(dom); @@ -649,7 +653,7 @@ static int svc_export_show(struct seq_file *m, return 0; } exp = container_of(h, struct svc_export, h); - seq_path(m, &exp->ex_path, " \t\n\\"); + seq_path(m, exp->ex_mnt, exp->ex_dentry, " \t\n\\"); seq_putc(m, '\t'); seq_escape(m, exp->ex_client->name, " \t\n\\"); seq_putc(m, '('); @@ -676,8 +680,8 @@ static int svc_export_match(struct cache_head *a, struct cache_head *b) struct svc_export *orig = container_of(a, struct svc_export, h); struct svc_export *new = container_of(b, struct svc_export, h); return orig->ex_client == new->ex_client && - orig->ex_path.dentry == new->ex_path.dentry && - orig->ex_path.mnt == new->ex_path.mnt; + orig->ex_dentry == new->ex_dentry && + orig->ex_mnt == new->ex_mnt; } static void svc_export_init(struct cache_head *cnew, struct cache_head *citem) @@ -687,9 +691,9 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem) kref_get(&item->ex_client->ref); new->ex_client = item->ex_client; - new->ex_path.dentry = dget(item->ex_path.dentry); - new->ex_path.mnt = mntget(item->ex_path.mnt); - new->ex_pathname = NULL; + new->ex_dentry = dget(item->ex_dentry); + new->ex_mnt = mntget(item->ex_mnt); + new->ex_path = NULL; new->ex_fslocs.locations = NULL; new->ex_fslocs.locations_count = 0; new->ex_fslocs.migrated = 0; @@ -707,8 +711,8 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem) new->ex_fsid = item->ex_fsid; new->ex_uuid = item->ex_uuid; item->ex_uuid = NULL; - new->ex_pathname = item->ex_pathname; - item->ex_pathname = NULL; + new->ex_path = item->ex_path; + item->ex_path = NULL; new->ex_fslocs.locations = item->ex_fslocs.locations; item->ex_fslocs.locations = NULL; new->ex_fslocs.locations_count = item->ex_fslocs.locations_count; @@ -751,8 +755,8 @@ svc_export_lookup(struct svc_export *exp) struct cache_head *ch; int hash; hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS); - hash ^= hash_ptr(exp->ex_path.dentry, EXPORT_HASHBITS); - hash ^= hash_ptr(exp->ex_path.mnt, EXPORT_HASHBITS); + hash ^= hash_ptr(exp->ex_dentry, EXPORT_HASHBITS); + hash ^= hash_ptr(exp->ex_mnt, EXPORT_HASHBITS); ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h, hash); @@ -768,8 +772,8 @@ svc_export_update(struct svc_export *new, struct svc_export *old) struct cache_head *ch; int hash; hash = hash_ptr(old->ex_client, EXPORT_HASHBITS); - hash ^= hash_ptr(old->ex_path.dentry, EXPORT_HASHBITS); - hash ^= hash_ptr(old->ex_path.mnt, EXPORT_HASHBITS); + hash ^= hash_ptr(old->ex_dentry, EXPORT_HASHBITS); + hash ^= hash_ptr(old->ex_mnt, EXPORT_HASHBITS); ch = sunrpc_cache_update(&svc_export_cache, &new->h, &old->h, @@ -811,7 +815,8 @@ static int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv, key.ek_client = clp; key.ek_fsidtype = fsid_type; memcpy(key.ek_fsid, fsidv, key_len(fsid_type)); - key.ek_path = exp->ex_path; + key.ek_mnt = exp->ex_mnt; + key.ek_dentry = exp->ex_dentry; key.h.expiry_time = NEVER; key.h.flags = 0; @@ -860,13 +865,13 @@ static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt, { struct svc_export *exp, key; int err; - + if (!clp) return ERR_PTR(-ENOENT); key.ex_client = clp; - key.ex_path.mnt = mnt; - key.ex_path.dentry = dentry; + key.ex_mnt = mnt; + key.ex_dentry = dentry; exp = svc_export_lookup(&key); if (exp == NULL) @@ -963,7 +968,7 @@ static int exp_fsid_hash(svc_client *clp, struct svc_export *exp) static int exp_hash(struct auth_domain *clp, struct svc_export *exp) { u32 fsid[2]; - struct inode *inode = exp->ex_path.dentry->d_inode; + struct inode *inode = exp->ex_dentry->d_inode; dev_t dev = inode->i_sb->s_dev; if (old_valid_dev(dev)) { @@ -977,7 +982,7 @@ static int exp_hash(struct auth_domain *clp, struct svc_export *exp) static void exp_unhash(struct svc_export *exp) { struct svc_expkey *ek; - struct inode *inode = exp->ex_path.dentry->d_inode; + struct inode *inode = exp->ex_dentry->d_inode; ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino); if (!IS_ERR(ek)) { @@ -1025,16 +1030,15 @@ exp_export(struct nfsctl_export *nxp) goto out_unlock; err = -EINVAL; - exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL); + exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL); memset(&new, 0, sizeof(new)); /* must make sure there won't be an ex_fsid clash */ if ((nxp->ex_flags & NFSEXP_FSID) && (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) && - fsid_key->ek_path.mnt && - (fsid_key->ek_path.mnt != nd.path.mnt || - fsid_key->ek_path.dentry != nd.path.dentry)) + fsid_key->ek_mnt && + (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) ) goto finish; if (!IS_ERR(exp)) { @@ -1050,7 +1054,7 @@ exp_export(struct nfsctl_export *nxp) goto finish; } - err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL); + err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL); if (err) goto finish; err = -ENOMEM; @@ -1059,11 +1063,12 @@ exp_export(struct nfsctl_export *nxp) new.h.expiry_time = NEVER; new.h.flags = 0; - new.ex_pathname = kstrdup(nxp->ex_path, GFP_KERNEL); - if (!new.ex_pathname) + new.ex_path = kstrdup(nxp->ex_path, GFP_KERNEL); + if (!new.ex_path) goto finish; new.ex_client = clp; - new.ex_path = nd.path; + new.ex_mnt = nd.mnt; + new.ex_dentry = nd.dentry; new.ex_flags = nxp->ex_flags; new.ex_anon_uid = nxp->ex_anon_uid; new.ex_anon_gid = nxp->ex_anon_gid; @@ -1084,14 +1089,15 @@ exp_export(struct nfsctl_export *nxp) } else err = 0; finish: - kfree(new.ex_pathname); + if (new.ex_path) + kfree(new.ex_path); if (exp) exp_put(exp); if (fsid_key && !IS_ERR(fsid_key)) cache_put(&fsid_key->h, &svc_expkey_cache); if (clp) auth_domain_put(clp); - path_put(&nd.path); + path_release(&nd); out_unlock: exp_writeunlock(); out: @@ -1142,8 +1148,8 @@ exp_unexport(struct nfsctl_export *nxp) goto out_domain; err = -EINVAL; - exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL); - path_put(&nd.path); + exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL); + path_release(&nd); if (IS_ERR(exp)) goto out_domain; @@ -1179,12 +1185,12 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) printk("nfsd: exp_rootfh path not found %s", path); return err; } - inode = nd.path.dentry->d_inode; + inode = nd.dentry->d_inode; dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n", - path, nd.path.dentry, clp->name, + path, nd.dentry, clp->name, inode->i_sb->s_id, inode->i_ino); - exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL); + exp = exp_parent(clp, nd.mnt, nd.dentry, NULL); if (IS_ERR(exp)) { err = PTR_ERR(exp); goto out; @@ -1194,7 +1200,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) * fh must be initialized before calling fh_compose */ fh_init(&fh, maxsize); - if (fh_compose(&fh, exp, nd.path.dentry, NULL)) + if (fh_compose(&fh, exp, nd.dentry, NULL)) err = -EINVAL; else err = 0; @@ -1202,7 +1208,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize) fh_put(&fh); exp_put(exp); out: - path_put(&nd.path); + path_release(&nd); return err; } @@ -1214,7 +1220,7 @@ static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type, if (IS_ERR(ek)) return ERR_CAST(ek); - exp = exp_get_by_name(clp, ek->ek_path.mnt, ek->ek_path.dentry, reqp); + exp = exp_get_by_name(clp, ek->ek_mnt, ek->ek_dentry, reqp); cache_put(&ek->h, &svc_expkey_cache); if (IS_ERR(exp)) @@ -1353,7 +1359,7 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp) exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); if (IS_ERR(exp)) return nfserrno(PTR_ERR(exp)); - rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); + rv = fh_compose(fhp, exp, exp->ex_dentry, NULL); if (rv) goto out; rv = check_nfsd_access(exp, rqstp); diff --git a/trunk/fs/nfsd/nfs3proc.c b/trunk/fs/nfsd/nfs3proc.c index c721a1e6e9dd..eac82830bfd7 100644 --- a/trunk/fs/nfsd/nfs3proc.c +++ b/trunk/fs/nfsd/nfs3proc.c @@ -67,7 +67,7 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, if (nfserr) RETURN_STATUS(nfserr); - err = vfs_getattr(resp->fh.fh_export->ex_path.mnt, + err = vfs_getattr(resp->fh.fh_export->ex_mnt, resp->fh.fh_dentry, &resp->stat); nfserr = nfserrno(err); diff --git a/trunk/fs/nfsd/nfs3xdr.c b/trunk/fs/nfsd/nfs3xdr.c index 17d0dd997204..d7647f70e02b 100644 --- a/trunk/fs/nfsd/nfs3xdr.c +++ b/trunk/fs/nfsd/nfs3xdr.c @@ -218,7 +218,7 @@ encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) int err; struct kstat stat; - err = vfs_getattr(fhp->fh_export->ex_path.mnt, dentry, &stat); + err = vfs_getattr(fhp->fh_export->ex_mnt, dentry, &stat); if (!err) { *p++ = xdr_one; /* attributes follow */ lease_get_mtime(dentry->d_inode, &stat.mtime); @@ -270,7 +270,7 @@ void fill_post_wcc(struct svc_fh *fhp) if (fhp->fh_post_saved) printk("nfsd: inode locked twice during operation.\n"); - err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, + err = vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &fhp->fh_post_attr); if (err) fhp->fh_post_saved = 0; diff --git a/trunk/fs/nfsd/nfs4recover.c b/trunk/fs/nfsd/nfs4recover.c index 1ff90625860f..1602cd00dd45 100644 --- a/trunk/fs/nfsd/nfs4recover.c +++ b/trunk/fs/nfsd/nfs4recover.c @@ -120,9 +120,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) static void nfsd4_sync_rec_dir(void) { - mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex); - nfsd_sync_dir(rec_dir.path.dentry); - mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex); + mutex_lock(&rec_dir.dentry->d_inode->i_mutex); + nfsd_sync_dir(rec_dir.dentry); + mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); } int @@ -142,9 +142,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) nfs4_save_user(&uid, &gid); /* lock the parent */ - mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex); + mutex_lock(&rec_dir.dentry->d_inode->i_mutex); - dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1); + dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1); if (IS_ERR(dentry)) { status = PTR_ERR(dentry); goto out_unlock; @@ -154,11 +154,11 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); goto out_put; } - status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU); + status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); out_put: dput(dentry); out_unlock: - mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex); + mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); if (status == 0) { clp->cl_firststate = 1; nfsd4_sync_rec_dir(); @@ -221,7 +221,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f) nfs4_save_user(&uid, &gid); - filp = dentry_open(dget(dir), mntget(rec_dir.path.mnt), O_RDONLY); + filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY); status = PTR_ERR(filp); if (IS_ERR(filp)) goto out; @@ -286,9 +286,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen) dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); - mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex); - dentry = lookup_one_len(name, rec_dir.path.dentry, namlen); - mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex); + mutex_lock(&rec_dir.dentry->d_inode->i_mutex); + dentry = lookup_one_len(name, rec_dir.dentry, namlen); + mutex_unlock(&rec_dir.dentry->d_inode->i_mutex); if (IS_ERR(dentry)) { status = PTR_ERR(dentry); return status; @@ -297,7 +297,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen) if (!dentry->d_inode) goto out; - status = nfsd4_clear_clid_dir(rec_dir.path.dentry, dentry); + status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry); out: dput(dentry); return status; @@ -347,12 +347,12 @@ nfsd4_recdir_purge_old(void) { if (!rec_dir_init) return; - status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old); + status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old); if (status == 0) nfsd4_sync_rec_dir(); if (status) printk("nfsd4: failed to purge old clients from recovery" - " directory %s\n", rec_dir.path.dentry->d_name.name); + " directory %s\n", rec_dir.dentry->d_name.name); return; } @@ -373,10 +373,10 @@ int nfsd4_recdir_load(void) { int status; - status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir); + status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir); if (status) printk("nfsd4: failed loading clients from recovery" - " directory %s\n", rec_dir.path.dentry->d_name.name); + " directory %s\n", rec_dir.dentry->d_name.name); return status; } @@ -415,5 +415,5 @@ nfsd4_shutdown_recdir(void) if (!rec_dir_init) return; rec_dir_init = 0; - path_put(&rec_dir.path); + path_release(&rec_dir); } diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index bcb97d8e8b8b..f6744bc03dae 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -3261,11 +3261,11 @@ nfs4_reset_recoverydir(char *recdir) if (status) return status; status = -ENOTDIR; - if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) { + if (S_ISDIR(nd.dentry->d_inode->i_mode)) { nfs4_set_recdir(recdir); status = 0; } - path_put(&nd.path); + path_release(&nd); return status; } diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index 0e6a179eccaf..b0592e7c378d 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -1330,9 +1330,9 @@ static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 * *stat = exp_pseudoroot(rqstp, &tmp_fh); if (*stat) return NULL; - rootpath = tmp_fh.fh_export->ex_pathname; + rootpath = tmp_fh.fh_export->ex_path; - path = exp->ex_pathname; + path = exp->ex_path; if (strncmp(path, rootpath, strlen(rootpath))) { dprintk("nfsd: fs_locations failed;" @@ -1481,7 +1481,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, goto out; } - err = vfs_getattr(exp->ex_path.mnt, dentry, &stat); + err = vfs_getattr(exp->ex_mnt, dentry, &stat); if (err) goto out_nfserr; if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | @@ -1838,9 +1838,9 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, * and this is the root of a cross-mounted filesystem. */ if (ignore_crossmnt == 0 && - exp->ex_path.mnt->mnt_root->d_inode == dentry->d_inode) { - err = vfs_getattr(exp->ex_path.mnt->mnt_parent, - exp->ex_path.mnt->mnt_mountpoint, &stat); + exp->ex_mnt->mnt_root->d_inode == dentry->d_inode) { + err = vfs_getattr(exp->ex_mnt->mnt_parent, + exp->ex_mnt->mnt_mountpoint, &stat); if (err) goto out_nfserr; } diff --git a/trunk/fs/nfsd/nfsfh.c b/trunk/fs/nfsd/nfsfh.c index 0130b345234d..8fbd2dc08a92 100644 --- a/trunk/fs/nfsd/nfsfh.c +++ b/trunk/fs/nfsd/nfsfh.c @@ -47,7 +47,7 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry) return 1; tdentry = dget(dentry); - while (tdentry != exp->ex_path.dentry && !IS_ROOT(tdentry)) { + while (tdentry != exp->ex_dentry && ! IS_ROOT(tdentry)) { /* make sure parents give x permission to user */ int err; parent = dget_parent(tdentry); @@ -59,9 +59,9 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry) dput(tdentry); tdentry = parent; } - if (tdentry != exp->ex_path.dentry) + if (tdentry != exp->ex_dentry) dprintk("nfsd_acceptable failed at %p %s\n", tdentry, tdentry->d_name.name); - rv = (tdentry == exp->ex_path.dentry); + rv = (tdentry == exp->ex_dentry); dput(tdentry); return rv; } @@ -209,9 +209,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) fileid_type = fh->fh_fileid_type; if (fileid_type == FILEID_ROOT) - dentry = dget(exp->ex_path.dentry); + dentry = dget(exp->ex_dentry); else { - dentry = exportfs_decode_fh(exp->ex_path.mnt, fid, + dentry = exportfs_decode_fh(exp->ex_mnt, fid, data_left, fileid_type, nfsd_acceptable, exp); } @@ -299,7 +299,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) static void _fh_update(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry) { - if (dentry != exp->ex_path.dentry) { + if (dentry != exp->ex_dentry) { struct fid *fid = (struct fid *) (fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1); int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; @@ -344,12 +344,12 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct inode * inode = dentry->d_inode; struct dentry *parent = dentry->d_parent; __u32 *datap; - dev_t ex_dev = exp->ex_path.dentry->d_inode->i_sb->s_dev; - int root_export = (exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root); + dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev; + int root_export = (exp->ex_dentry == exp->ex_dentry->d_sb->s_root); dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n", MAJOR(ex_dev), MINOR(ex_dev), - (long) exp->ex_path.dentry->d_inode->i_ino, + (long) exp->ex_dentry->d_inode->i_ino, parent->d_name.name, dentry->d_name.name, (inode ? inode->i_ino : 0)); @@ -391,7 +391,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, /* FALL THROUGH */ case FSID_MAJOR_MINOR: case FSID_ENCODE_DEV: - if (!(exp->ex_path.dentry->d_inode->i_sb->s_type->fs_flags + if (!(exp->ex_dentry->d_inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV)) goto retry; break; @@ -454,7 +454,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev); fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev; fhp->fh_handle.ofh_xino = - ino_t_to_u32(exp->ex_path.dentry->d_inode->i_ino); + ino_t_to_u32(exp->ex_dentry->d_inode->i_ino); fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry)); if (inode) _fh_update_old(dentry, exp, &fhp->fh_handle); @@ -465,7 +465,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, datap = fhp->fh_handle.fh_auth+0; fhp->fh_handle.fh_fsid_type = fsid_type; mk_fsid(fsid_type, datap, ex_dev, - exp->ex_path.dentry->d_inode->i_ino, + exp->ex_dentry->d_inode->i_ino, exp->ex_fsid, exp->ex_uuid); len = key_len(fsid_type); @@ -571,7 +571,7 @@ enum fsid_source fsid_source(struct svc_fh *fhp) case FSID_DEV: case FSID_ENCODE_DEV: case FSID_MAJOR_MINOR: - if (fhp->fh_export->ex_path.dentry->d_inode->i_sb->s_type->fs_flags + if (fhp->fh_export->ex_dentry->d_inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) return FSIDSOURCE_DEV; break; diff --git a/trunk/fs/nfsd/nfsproc.c b/trunk/fs/nfsd/nfsproc.c index 6cfc96a12483..977a71f64e19 100644 --- a/trunk/fs/nfsd/nfsproc.c +++ b/trunk/fs/nfsd/nfsproc.c @@ -41,7 +41,7 @@ static __be32 nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp) { if (err) return err; - return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt, + return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, resp->fh.fh_dentry, &resp->stat)); } @@ -49,7 +49,7 @@ static __be32 nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp) { if (err) return err; - return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt, + return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, resp->fh.fh_dentry, &resp->stat)); } @@ -164,7 +164,7 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, &resp->count); if (nfserr) return nfserr; - return nfserrno(vfs_getattr(resp->fh.fh_export->ex_path.mnt, + return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt, resp->fh.fh_dentry, &resp->stat)); } diff --git a/trunk/fs/nfsd/nfsxdr.c b/trunk/fs/nfsd/nfsxdr.c index afd08e2c90a5..61ad61743d94 100644 --- a/trunk/fs/nfsd/nfsxdr.c +++ b/trunk/fs/nfsd/nfsxdr.c @@ -207,7 +207,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) { struct kstat stat; - vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, &stat); + vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat); return encode_fattr(rqstp, p, fhp, &stat); } diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 46f59d5365a0..cc75e4fcd02b 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -101,7 +101,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, { struct svc_export *exp = *expp, *exp2 = NULL; struct dentry *dentry = *dpp; - struct vfsmount *mnt = mntget(exp->ex_path.mnt); + struct vfsmount *mnt = mntget(exp->ex_mnt); struct dentry *mounts = dget(dentry); int err = 0; @@ -156,15 +156,15 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(name, len)) { if (len==1) dentry = dget(dparent); - else if (dparent != exp->ex_path.dentry) + else if (dparent != exp->ex_dentry) { dentry = dget_parent(dparent); - else if (!EX_NOHIDE(exp)) + } else if (!EX_NOHIDE(exp)) dentry = dget(dparent); /* .. == . just like at / */ else { /* checking mountpoint crossing is very different when stepping up */ struct svc_export *exp2 = NULL; struct dentry *dp; - struct vfsmount *mnt = mntget(exp->ex_path.mnt); + struct vfsmount *mnt = mntget(exp->ex_mnt); dentry = dget(dparent); while(dentry == mnt->mnt_root && follow_up(&mnt, &dentry)) ; @@ -721,8 +721,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, DQUOT_INIT(inode); } - *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), - flags); + *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_mnt), flags); if (IS_ERR(*filp)) host_err = PTR_ERR(*filp); out_nfserr: @@ -1463,7 +1462,7 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) if (!inode->i_op || !inode->i_op->readlink) goto out; - touch_atime(fhp->fh_export->ex_path.mnt, dentry); + touch_atime(fhp->fh_export->ex_mnt, dentry); /* N.B. Why does this call need a get_fs()?? * Remove the set_fs and watch the fireworks:-) --okir */ diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 54198538b67e..43fcd6031969 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -127,10 +127,10 @@ asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf) error = user_path_walk(path, &nd); if (!error) { struct statfs tmp; - error = vfs_statfs_native(nd.path.dentry, &tmp); + error = vfs_statfs_native(nd.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&nd.path); + path_release(&nd); } return error; } @@ -146,10 +146,10 @@ asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 error = user_path_walk(path, &nd); if (!error) { struct statfs64 tmp; - error = vfs_statfs64(nd.path.dentry, &tmp); + error = vfs_statfs64(nd.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; - path_put(&nd.path); + path_release(&nd); } return error; } @@ -233,7 +233,7 @@ static long do_sys_truncate(const char __user * path, loff_t length) error = user_path_walk(path, &nd); if (error) goto out; - inode = nd.path.dentry->d_inode; + inode = nd.dentry->d_inode; /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ error = -EISDIR; @@ -271,13 +271,13 @@ static long do_sys_truncate(const char __user * path, loff_t length) error = locks_verify_truncate(inode, NULL, length); if (!error) { DQUOT_INIT(inode); - error = do_truncate(nd.path.dentry, length, 0, NULL); + error = do_truncate(nd.dentry, length, 0, NULL); } put_write_and_out: put_write_access(inode); dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -455,14 +455,14 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) res = vfs_permission(&nd, mode); /* SuS v2 requires we report a read only fs too */ if(res || !(mode & S_IWOTH) || - special_file(nd.path.dentry->d_inode->i_mode)) + special_file(nd.dentry->d_inode->i_mode)) goto out_path_release; - if(IS_RDONLY(nd.path.dentry->d_inode)) + if(IS_RDONLY(nd.dentry->d_inode)) res = -EROFS; out_path_release: - path_put(&nd.path); + path_release(&nd); out: current->fsuid = old_fsuid; current->fsgid = old_fsgid; @@ -490,10 +490,10 @@ asmlinkage long sys_chdir(const char __user * filename) if (error) goto dput_and_out; - set_fs_pwd(current->fs, &nd.path); + set_fs_pwd(current->fs, nd.mnt, nd.dentry); dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -501,7 +501,9 @@ asmlinkage long sys_chdir(const char __user * filename) asmlinkage long sys_fchdir(unsigned int fd) { struct file *file; + struct dentry *dentry; struct inode *inode; + struct vfsmount *mnt; int error; error = -EBADF; @@ -509,7 +511,9 @@ asmlinkage long sys_fchdir(unsigned int fd) if (!file) goto out; - inode = file->f_path.dentry->d_inode; + dentry = file->f_path.dentry; + mnt = file->f_path.mnt; + inode = dentry->d_inode; error = -ENOTDIR; if (!S_ISDIR(inode->i_mode)) @@ -517,7 +521,7 @@ asmlinkage long sys_fchdir(unsigned int fd) error = file_permission(file, MAY_EXEC); if (!error) - set_fs_pwd(current->fs, &file->f_path); + set_fs_pwd(current->fs, mnt, dentry); out_putf: fput(file); out: @@ -541,11 +545,11 @@ asmlinkage long sys_chroot(const char __user * filename) if (!capable(CAP_SYS_CHROOT)) goto dput_and_out; - set_fs_root(current->fs, &nd.path); + set_fs_root(current->fs, nd.mnt, nd.dentry); set_fs_altroot(); error = 0; dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -598,7 +602,7 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename, error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); if (error) goto out; - inode = nd.path.dentry->d_inode; + inode = nd.dentry->d_inode; error = -EROFS; if (IS_RDONLY(inode)) @@ -613,11 +617,11 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename, mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - error = notify_change(nd.path.dentry, &newattrs); + error = notify_change(nd.dentry, &newattrs); mutex_unlock(&inode->i_mutex); dput_and_out: - path_put(&nd.path); + path_release(&nd); out: return error; } @@ -671,8 +675,8 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) error = user_path_walk(filename, &nd); if (error) goto out; - error = chown_common(nd.path.dentry, user, group); - path_put(&nd.path); + error = chown_common(nd.dentry, user, group); + path_release(&nd); out: return error; } @@ -691,8 +695,8 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, error = __user_walk_fd(dfd, filename, follow, &nd); if (error) goto out; - error = chown_common(nd.path.dentry, user, group); - path_put(&nd.path); + error = chown_common(nd.dentry, user, group); + path_release(&nd); out: return error; } @@ -705,8 +709,8 @@ asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group error = user_path_walk_link(filename, &nd); if (error) goto out; - error = chown_common(nd.path.dentry, user, group); - path_put(&nd.path); + error = chown_common(nd.dentry, user, group); + path_release(&nd); out: return error; } @@ -859,7 +863,7 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry goto out; if (IS_ERR(dentry)) goto out_err; - nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), + nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt), nd->intent.open.flags - 1, nd->intent.open.file, open); @@ -887,10 +891,9 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags) filp = nd->intent.open.file; /* Has the filesystem initialised the file for us? */ if (filp->f_path.dentry == NULL) - filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, - NULL); + filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL); else - path_put(&nd->path); + path_release(nd); return filp; } diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 88f8edf18258..7c6b4ec83cb7 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -153,7 +153,7 @@ static int get_nr_threads(struct task_struct *tsk) return count; } -static int proc_cwd_link(struct inode *inode, struct path *path) +static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { struct task_struct *task = get_proc_task(inode); struct fs_struct *fs = NULL; @@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct path *path) } if (fs) { read_lock(&fs->lock); - *path = fs->pwd; - path_get(&fs->pwd); + *mnt = mntget(fs->pwdmnt); + *dentry = dget(fs->pwd); read_unlock(&fs->lock); result = 0; put_fs_struct(fs); @@ -174,7 +174,7 @@ static int proc_cwd_link(struct inode *inode, struct path *path) return result; } -static int proc_root_link(struct inode *inode, struct path *path) +static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { struct task_struct *task = get_proc_task(inode); struct fs_struct *fs = NULL; @@ -186,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct path *path) } if (fs) { read_lock(&fs->lock); - *path = fs->root; - path_get(&fs->root); + *mnt = mntget(fs->rootmnt); + *dentry = dget(fs->root); read_unlock(&fs->lock); result = 0; put_fs_struct(fs); @@ -1164,36 +1164,39 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) int error = -EACCES; /* We don't need a base pointer in the /proc filesystem */ - path_put(&nd->path); + path_release(nd); /* Are we allowed to snoop on the tasks file descriptors? */ if (!proc_fd_access_allowed(inode)) goto out; - error = PROC_I(inode)->op.proc_get_link(inode, &nd->path); + error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); nd->last_type = LAST_BIND; out: return ERR_PTR(error); } -static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) +static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, + char __user *buffer, int buflen) { + struct inode * inode; char *tmp = (char*)__get_free_page(GFP_TEMPORARY); - char *pathname; + char *path; int len; if (!tmp) return -ENOMEM; - pathname = d_path(path, tmp, PAGE_SIZE); - len = PTR_ERR(pathname); - if (IS_ERR(pathname)) + inode = dentry->d_inode; + path = d_path(dentry, mnt, tmp, PAGE_SIZE); + len = PTR_ERR(path); + if (IS_ERR(path)) goto out; - len = tmp + PAGE_SIZE - 1 - pathname; + len = tmp + PAGE_SIZE - 1 - path; if (len > buflen) len = buflen; - if (copy_to_user(buffer, pathname, len)) + if (copy_to_user(buffer, path, len)) len = -EFAULT; out: free_page((unsigned long)tmp); @@ -1204,18 +1207,20 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b { int error = -EACCES; struct inode *inode = dentry->d_inode; - struct path path; + struct dentry *de; + struct vfsmount *mnt = NULL; /* Are we allowed to snoop on the tasks file descriptors? */ if (!proc_fd_access_allowed(inode)) goto out; - error = PROC_I(inode)->op.proc_get_link(inode, &path); + error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt); if (error) goto out; - error = do_proc_readlink(&path, buffer, buflen); - path_put(&path); + error = do_proc_readlink(de, mnt, buffer, buflen); + dput(de); + mntput(mnt); out: return error; } @@ -1442,7 +1447,8 @@ static unsigned name_to_int(struct dentry *dentry) #define PROC_FDINFO_MAX 64 -static int proc_fd_info(struct inode *inode, struct path *path, char *info) +static int proc_fd_info(struct inode *inode, struct dentry **dentry, + struct vfsmount **mnt, char *info) { struct task_struct *task = get_proc_task(inode); struct files_struct *files = NULL; @@ -1461,10 +1467,10 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info) spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (file) { - if (path) { - *path = file->f_path; - path_get(&file->f_path); - } + if (mnt) + *mnt = mntget(file->f_path.mnt); + if (dentry) + *dentry = dget(file->f_path.dentry); if (info) snprintf(info, PROC_FDINFO_MAX, "pos:\t%lli\n" @@ -1481,9 +1487,10 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info) return -ENOENT; } -static int proc_fd_link(struct inode *inode, struct path *path) +static int proc_fd_link(struct inode *inode, struct dentry **dentry, + struct vfsmount **mnt) { - return proc_fd_info(inode, path, NULL); + return proc_fd_info(inode, dentry, mnt, NULL); } static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) @@ -1677,7 +1684,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { char tmp[PROC_FDINFO_MAX]; - int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp); + int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp); if (!err) err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp)); return err; diff --git a/trunk/fs/proc/internal.h b/trunk/fs/proc/internal.h index 1c81c8f1aeed..ea496ffeabe7 100644 --- a/trunk/fs/proc/internal.h +++ b/trunk/fs/proc/internal.h @@ -48,7 +48,7 @@ extern int maps_protect; extern void create_seq_entry(char *name, mode_t mode, const struct file_operations *f); -extern int proc_exe_link(struct inode *, struct path *); +extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **); extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task); extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, diff --git a/trunk/fs/proc/nommu.c b/trunk/fs/proc/nommu.c index 941e95114b5a..5d9147b9d738 100644 --- a/trunk/fs/proc/nommu.c +++ b/trunk/fs/proc/nommu.c @@ -67,7 +67,7 @@ int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) if (len < 1) len = 1; seq_printf(m, "%*c", len, ' '); - seq_path(m, &file->f_path, ""); + seq_path(m, file->f_path.mnt, file->f_path.dentry, ""); } seq_putc(m, '\n'); diff --git a/trunk/fs/proc/proc_sysctl.c b/trunk/fs/proc/proc_sysctl.c index 614c34b6d1c2..b9cb23c08f63 100644 --- a/trunk/fs/proc/proc_sysctl.c +++ b/trunk/fs/proc/proc_sysctl.c @@ -407,7 +407,7 @@ static int proc_sys_permission(struct inode *inode, int mask, struct nameidata * if (!nd || !depth) goto out; - dentry = nd->path.dentry; + dentry = nd->dentry; table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); /* If the entry does not exist deny permission */ diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index 49958cffbd8d..ae4d3f2c8cb2 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -75,7 +75,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, return mm->total_vm; } -int proc_exe_link(struct inode *inode, struct path *path) +int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { struct vm_area_struct * vma; int result = -ENOENT; @@ -98,8 +98,8 @@ int proc_exe_link(struct inode *inode, struct path *path) } if (vma) { - *path = vma->vm_file->f_path; - path_get(&vma->vm_file->f_path); + *mnt = mntget(vma->vm_file->f_path.mnt); + *dentry = dget(vma->vm_file->f_path.dentry); result = 0; } @@ -271,7 +271,7 @@ static int show_map(struct seq_file *m, void *v) */ if (file) { pad_len_spaces(m, len); - seq_path(m, &file->f_path, "\n"); + seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n"); } else { const char *name = arch_vma_name(vma); if (!name) { diff --git a/trunk/fs/proc/task_nommu.c b/trunk/fs/proc/task_nommu.c index 8011528518bd..abfc6f5e56ca 100644 --- a/trunk/fs/proc/task_nommu.c +++ b/trunk/fs/proc/task_nommu.c @@ -103,7 +103,7 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, return size; } -int proc_exe_link(struct inode *inode, struct path *path) +int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { struct vm_list_struct *vml; struct vm_area_struct *vma; @@ -126,8 +126,8 @@ int proc_exe_link(struct inode *inode, struct path *path) } if (vma) { - *path = vma->vm_file->f_path; - path_get(&vma->vm_file->f_path); + *mnt = mntget(vma->vm_file->f_path.mnt); + *dentry = dget(vma->vm_file->f_path.dentry); result = 0; } diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 6841452e0dea..6033f0c3bd0b 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -2026,29 +2026,29 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, if (err) return err; /* Quotafile not on the same filesystem? */ - if (nd.path.mnt->mnt_sb != sb) { - path_put(&nd.path); + if (nd.mnt->mnt_sb != sb) { + path_release(&nd); return -EXDEV; } /* We must not pack tails for quota files on reiserfs for quota IO to work */ - if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) { + if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) { reiserfs_warning(sb, "reiserfs: Quota file must have tail packing disabled."); - path_put(&nd.path); + path_release(&nd); return -EINVAL; } /* Not journalling quota? No more tests needed... */ if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] && !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) { - path_put(&nd.path); + path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } /* Quotafile not of fs root? */ - if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode) + if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) reiserfs_warning(sb, "reiserfs: Quota file not on filesystem root. " "Journalled quota will not work."); - path_put(&nd.path); + path_release(&nd); return vfs_quota_on(sb, type, format_id, path); } diff --git a/trunk/fs/seq_file.c b/trunk/fs/seq_file.c index 853770274f20..ca71c115bdaa 100644 --- a/trunk/fs/seq_file.c +++ b/trunk/fs/seq_file.c @@ -342,11 +342,13 @@ int seq_printf(struct seq_file *m, const char *f, ...) } EXPORT_SYMBOL(seq_printf); -int seq_path(struct seq_file *m, struct path *path, char *esc) +int seq_path(struct seq_file *m, + struct vfsmount *mnt, struct dentry *dentry, + char *esc) { if (m->count < m->size) { char *s = m->buf + m->count; - char *p = d_path(path, s, m->size - m->count); + char *p = d_path(dentry, mnt, s, m->size - m->count); if (!IS_ERR(p)) { while (s <= p) { char c = *p++; diff --git a/trunk/fs/stat.c b/trunk/fs/stat.c index 9cf41f719d50..68510068a641 100644 --- a/trunk/fs/stat.c +++ b/trunk/fs/stat.c @@ -62,8 +62,8 @@ int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd); if (!error) { - error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); - path_put(&nd.path); + error = vfs_getattr(nd.mnt, nd.dentry, stat); + path_release(&nd); } return error; } @@ -82,8 +82,8 @@ int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat) error = __user_walk_fd(dfd, name, 0, &nd); if (!error) { - error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); - path_put(&nd.path); + error = vfs_getattr(nd.mnt, nd.dentry, stat); + path_release(&nd); } return error; } @@ -302,18 +302,17 @@ asmlinkage long sys_readlinkat(int dfd, const char __user *path, error = __user_walk_fd(dfd, path, 0, &nd); if (!error) { - struct inode *inode = nd.path.dentry->d_inode; + struct inode * inode = nd.dentry->d_inode; error = -EINVAL; if (inode->i_op && inode->i_op->readlink) { - error = security_inode_readlink(nd.path.dentry); + error = security_inode_readlink(nd.dentry); if (!error) { - touch_atime(nd.path.mnt, nd.path.dentry); - error = inode->i_op->readlink(nd.path.dentry, - buf, bufsiz); + touch_atime(nd.mnt, nd.dentry); + error = inode->i_op->readlink(nd.dentry, buf, bufsiz); } } - path_put(&nd.path); + path_release(&nd); } return error; } diff --git a/trunk/fs/utimes.c b/trunk/fs/utimes.c index b18da9c0b97f..e5588cd8530e 100644 --- a/trunk/fs/utimes.c +++ b/trunk/fs/utimes.c @@ -84,7 +84,7 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags if (error) goto out; - dentry = nd.path.dentry; + dentry = nd.dentry; } inode = dentry->d_inode; @@ -138,7 +138,7 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags if (f) fput(f); else - path_put(&nd.path); + path_release(&nd); out: return error; } diff --git a/trunk/fs/xattr.c b/trunk/fs/xattr.c index 3acab1615460..f7c8f87bb390 100644 --- a/trunk/fs/xattr.c +++ b/trunk/fs/xattr.c @@ -262,8 +262,8 @@ sys_setxattr(char __user *path, char __user *name, void __user *value, error = user_path_walk(path, &nd); if (error) return error; - error = setxattr(nd.path.dentry, name, value, size, flags); - path_put(&nd.path); + error = setxattr(nd.dentry, name, value, size, flags); + path_release(&nd); return error; } @@ -277,8 +277,8 @@ sys_lsetxattr(char __user *path, char __user *name, void __user *value, error = user_path_walk_link(path, &nd); if (error) return error; - error = setxattr(nd.path.dentry, name, value, size, flags); - path_put(&nd.path); + error = setxattr(nd.dentry, name, value, size, flags); + path_release(&nd); return error; } @@ -347,8 +347,8 @@ sys_getxattr(char __user *path, char __user *name, void __user *value, error = user_path_walk(path, &nd); if (error) return error; - error = getxattr(nd.path.dentry, name, value, size); - path_put(&nd.path); + error = getxattr(nd.dentry, name, value, size); + path_release(&nd); return error; } @@ -362,8 +362,8 @@ sys_lgetxattr(char __user *path, char __user *name, void __user *value, error = user_path_walk_link(path, &nd); if (error) return error; - error = getxattr(nd.path.dentry, name, value, size); - path_put(&nd.path); + error = getxattr(nd.dentry, name, value, size); + path_release(&nd); return error; } @@ -421,8 +421,8 @@ sys_listxattr(char __user *path, char __user *list, size_t size) error = user_path_walk(path, &nd); if (error) return error; - error = listxattr(nd.path.dentry, list, size); - path_put(&nd.path); + error = listxattr(nd.dentry, list, size); + path_release(&nd); return error; } @@ -435,8 +435,8 @@ sys_llistxattr(char __user *path, char __user *list, size_t size) error = user_path_walk_link(path, &nd); if (error) return error; - error = listxattr(nd.path.dentry, list, size); - path_put(&nd.path); + error = listxattr(nd.dentry, list, size); + path_release(&nd); return error; } @@ -482,8 +482,8 @@ sys_removexattr(char __user *path, char __user *name) error = user_path_walk(path, &nd); if (error) return error; - error = removexattr(nd.path.dentry, name); - path_put(&nd.path); + error = removexattr(nd.dentry, name); + path_release(&nd); return error; } @@ -496,8 +496,8 @@ sys_lremovexattr(char __user *path, char __user *name) error = user_path_walk_link(path, &nd); if (error) return error; - error = removexattr(nd.path.dentry, name); - path_put(&nd.path); + error = removexattr(nd.dentry, name); + path_release(&nd); return error; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index a9952e490ac9..4c82a050a3a8 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -91,10 +91,10 @@ xfs_find_handle( if (error) return error; - ASSERT(nd.path.dentry); - ASSERT(nd.path.dentry->d_inode); - inode = igrab(nd.path.dentry->d_inode); - path_put(&nd.path); + ASSERT(nd.dentry); + ASSERT(nd.dentry->d_inode); + inode = igrab(nd.dentry->d_inode); + path_release(&nd); break; } diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 06480bcabfdc..cdc8004cfd12 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -32,11 +32,9 @@ #define DOMAIN_COORD_TYPE_SW_ANY 0xfd #define DOMAIN_COORD_TYPE_HW_ALL 0xfe -#define ACPI_CSTATE_SYSTEMIO 0 -#define ACPI_CSTATE_FFH 1 -#define ACPI_CSTATE_HALT 2 - -#define ACPI_CX_DESC_LEN 32 +#define ACPI_CSTATE_SYSTEMIO (0) +#define ACPI_CSTATE_FFH (1) +#define ACPI_CSTATE_HALT (2) /* Power Management */ @@ -76,7 +74,6 @@ struct acpi_processor_cx { u64 time; struct acpi_processor_cx_policy promotion; struct acpi_processor_cx_policy demotion; - char desc[ACPI_CX_DESC_LEN]; }; struct acpi_processor_power { diff --git a/trunk/include/asm-m68knommu/cacheflush.h b/trunk/include/asm-m68knommu/cacheflush.h index 87e5dc0413b4..29bc0aad2ebc 100644 --- a/trunk/include/asm-m68knommu/cacheflush.h +++ b/trunk/include/asm-m68knommu/cacheflush.h @@ -54,28 +54,28 @@ static inline void __flush_cache_all(void) #if defined(CONFIG_M527x) || defined(CONFIG_M528x) __asm__ __volatile__ ( "movel #0x81000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" + "movec %%d0, %%CACR\n\t" "nop\n\t" : : : "d0" ); #endif /* CONFIG_M527x || CONFIG_M528x */ #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272) __asm__ __volatile__ ( - "movel #0x81000100, %%d0\n\t" - "movec %%d0, %%CACR\n\t" + "movel #0x81000100, %%d0\n\t" + "movec %%d0, %%CACR\n\t" "nop\n\t" : : : "d0" ); #endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */ #ifdef CONFIG_M5249 __asm__ __volatile__ ( - "movel #0xa1000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" + "movel #0xa1000200, %%d0\n\t" + "movec %%d0, %%CACR\n\t" "nop\n\t" : : : "d0" ); #endif /* CONFIG_M5249 */ #ifdef CONFIG_M532x __asm__ __volatile__ ( - "movel #0x81000200, %%d0\n\t" - "movec %%d0, %%CACR\n\t" + "movel #0x81000200, %%d0\n\t" + "movec %%d0, %%CACR\n\t" "nop\n\t" : : : "d0" ); #endif /* CONFIG_M532x */ diff --git a/trunk/include/asm-m68knommu/system.h b/trunk/include/asm-m68knommu/system.h index 64c64432bbb8..039ab3f81732 100644 --- a/trunk/include/asm-m68knommu/system.h +++ b/trunk/include/asm-m68knommu/system.h @@ -104,7 +104,7 @@ asmlinkage void resume(void); #define mb() asm volatile ("" : : :"memory") #define rmb() asm volatile ("" : : :"memory") #define wmb() asm volatile ("" : : :"memory") -#define set_mb(var, value) ({ (var) = (value); wmb(); }) +#define set_mb(var, value) do { xchg(&var, value); } while (0) #ifdef CONFIG_SMP #define smp_mb() mb() diff --git a/trunk/include/asm-powerpc/systbl.h b/trunk/include/asm-powerpc/systbl.h index ae7085c65692..e996521fb3a6 100644 --- a/trunk/include/asm-powerpc/systbl.h +++ b/trunk/include/asm-powerpc/systbl.h @@ -309,10 +309,8 @@ SYSCALL_SPU(getcpu) COMPAT_SYS(epoll_pwait) COMPAT_SYS_SPU(utimensat) COMPAT_SYS_SPU(signalfd) -SYSCALL_SPU(timerfd_create) +SYSCALL(ni_syscall) SYSCALL_SPU(eventfd) COMPAT_SYS_SPU(sync_file_range2) COMPAT_SYS(fallocate) SYSCALL(subpage_prot) -COMPAT_SYS_SPU(timerfd_settime) -COMPAT_SYS_SPU(timerfd_gettime) diff --git a/trunk/include/asm-powerpc/unistd.h b/trunk/include/asm-powerpc/unistd.h index ce91bb662063..fedc4b8e49e2 100644 --- a/trunk/include/asm-powerpc/unistd.h +++ b/trunk/include/asm-powerpc/unistd.h @@ -328,17 +328,15 @@ #define __NR_epoll_pwait 303 #define __NR_utimensat 304 #define __NR_signalfd 305 -#define __NR_timerfd_create 306 +#define __NR_timerfd 306 #define __NR_eventfd 307 #define __NR_sync_file_range2 308 #define __NR_fallocate 309 #define __NR_subpage_prot 310 -#define __NR_timerfd_settime 311 -#define __NR_timerfd_gettime 312 #ifdef __KERNEL__ -#define __NR_syscalls 313 +#define __NR_syscalls 311 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/trunk/include/asm-ppc/page.h b/trunk/include/asm-ppc/page.h index 37e4756b6b2d..ad4c5a1bc9d6 100644 --- a/trunk/include/asm-ppc/page.h +++ b/trunk/include/asm-ppc/page.h @@ -125,8 +125,6 @@ extern __inline__ int get_order(unsigned long size) return 32 - lz; } -typedef struct page *pgtable_t; - #endif /* __ASSEMBLY__ */ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ diff --git a/trunk/include/asm-sh/bugs.h b/trunk/include/asm-sh/bugs.h index cfda7d5bf026..def8128b8b78 100644 --- a/trunk/include/asm-sh/bugs.h +++ b/trunk/include/asm-sh/bugs.h @@ -39,7 +39,7 @@ static void __init check_bugs(void) *p++ = '4'; *p++ = 'a'; break; - case CPU_SH7343 ... CPU_SH7366: + case CPU_SH7343 ... CPU_SH7722: *p++ = '4'; *p++ = 'a'; *p++ = 'l'; diff --git a/trunk/include/asm-sh/cpu-sh4/freq.h b/trunk/include/asm-sh/cpu-sh4/freq.h index ec028c649215..1ac10b9a078f 100644 --- a/trunk/include/asm-sh/cpu-sh4/freq.h +++ b/trunk/include/asm-sh/cpu-sh4/freq.h @@ -10,14 +10,12 @@ #ifndef __ASM_CPU_SH4_FREQ_H #define __ASM_CPU_SH4_FREQ_H -#if defined(CONFIG_CPU_SUBTYPE_SH7722) || defined(CONFIG_CPU_SUBTYPE_SH7366) +#if defined(CONFIG_CPU_SUBTYPE_SH7722) #define FRQCR 0xa4150000 #define VCLKCR 0xa4150004 #define SCLKACR 0xa4150008 #define SCLKBCR 0xa415000c -#if defined(CONFIG_CPU_SUBTYPE_SH7722) #define IrDACLKCR 0xa4150010 -#endif #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) #define FRQCR 0xffc80000 diff --git a/trunk/include/asm-sh/cpu-sh5/cacheflush.h b/trunk/include/asm-sh/cpu-sh5/cacheflush.h index 5a11f0b7e66a..98edb5b1da32 100644 --- a/trunk/include/asm-sh/cpu-sh5/cacheflush.h +++ b/trunk/include/asm-sh/cpu-sh5/cacheflush.h @@ -3,13 +3,15 @@ #ifndef __ASSEMBLY__ +#include + struct vm_area_struct; struct page; struct mm_struct; extern void flush_cache_all(void); extern void flush_cache_mm(struct mm_struct *mm); -extern void flush_cache_sigtramp(unsigned long vaddr); +extern void flush_cache_sigtramp(unsigned long start, unsigned long end); extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); @@ -25,7 +27,7 @@ extern void flush_icache_user_range(struct vm_area_struct *vma, #define flush_dcache_mmap_unlock(mapping) do { } while (0) #define flush_icache_page(vma, page) do { } while (0) -void p3_cache_init(void); +#define p3_cache_init() do { } while (0) #endif /* __ASSEMBLY__ */ diff --git a/trunk/include/asm-sh/cpu-sh5/mmu_context.h b/trunk/include/asm-sh/cpu-sh5/mmu_context.h index 68a1d2cff457..df857fc09960 100644 --- a/trunk/include/asm-sh/cpu-sh5/mmu_context.h +++ b/trunk/include/asm-sh/cpu-sh5/mmu_context.h @@ -16,6 +16,12 @@ /* This has to be a common function because the next location to fill * information is shared. */ extern void __do_tlb_refill(unsigned long address, unsigned long long is_text_not_data, pte_t *pte); + +/* Profiling counter. */ +#ifdef CONFIG_SH64_PROC_TLB +extern unsigned long long calls_to_do_fast_page_fault; +#endif + #endif /* __ASSEMBLY__ */ #endif /* __ASM_SH_CPU_SH5_MMU_CONTEXT_H */ diff --git a/trunk/include/asm-sh/hp6xx.h b/trunk/include/asm-sh/hp6xx.h index 0d4165a32dcd..53ca5643d9c7 100644 --- a/trunk/include/asm-sh/hp6xx.h +++ b/trunk/include/asm-sh/hp6xx.h @@ -10,9 +10,9 @@ * */ -#define HP680_BTN_IRQ 32 /* IRQ0_IRQ */ -#define HP680_TS_IRQ 35 /* IRQ3_IRQ */ -#define HP680_HD64461_IRQ 36 /* IRQ4_IRQ */ +#define HP680_BTN_IRQ 32 /* IRQ0_IRQ */ +#define HP680_TS_IRQ 35 /* IRQ3_IRQ */ +#define HP680_HD64461_IRQ 36 /* IRQ4_IRQ */ #define DAC_LCD_BRIGHTNESS 0 #define DAC_SPEAKER_VOLUME 1 @@ -55,4 +55,26 @@ #define PJDR 0xa4000130 #define PKDR 0xa4000132 +static inline void hp6xx_led_red(int on) +{ + u16 v16; + v16 = ctrl_inw(CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000); + if (on) + ctrl_outw(v16 & (~HD64461_GPBDR_LED_RED), CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000); + else + ctrl_outw(v16 | HD64461_GPBDR_LED_RED, CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000); +} + +static inline void hp6xx_led_green(int on) +{ + u8 v8; + + v8 = ctrl_inb(PKDR); + if (on) + ctrl_outb(v8 & (~PKDR_LED_GREEN), PKDR); + else + ctrl_outb(v8 | PKDR_LED_GREEN, PKDR); +} + + #endif /* __ASM_SH_HP6XX_H */ diff --git a/trunk/include/asm-sh/io.h b/trunk/include/asm-sh/io.h index 356e50d06745..94900c089519 100644 --- a/trunk/include/asm-sh/io.h +++ b/trunk/include/asm-sh/io.h @@ -38,7 +38,6 @@ */ #define __IO_PREFIX generic #include -#include #define maybebadio(port) \ printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \ @@ -182,13 +181,13 @@ __BUILD_MEMORY_STRING(w, u16) #define iowrite32(v,a) writel((v),(a)) #define iowrite32be(v,a) __raw_writel(cpu_to_be32((v)),(a)) -#define ioread8_rep(a, d, c) readsb((a), (d), (c)) -#define ioread16_rep(a, d, c) readsw((a), (d), (c)) -#define ioread32_rep(a, d, c) readsl((a), (d), (c)) +#define ioread8_rep(a,d,c) insb((a),(d),(c)) +#define ioread16_rep(a,d,c) insw((a),(d),(c)) +#define ioread32_rep(a,d,c) insl((a),(d),(c)) -#define iowrite8_rep(a, s, c) writesb((a), (s), (c)) -#define iowrite16_rep(a, s, c) writesw((a), (s), (c)) -#define iowrite32_rep(a, s, c) writesl((a), (s), (c)) +#define iowrite8_rep(a,s,c) outsb((a),(s),(c)) +#define iowrite16_rep(a,s,c) outsw((a),(s),(c)) +#define iowrite32_rep(a,s,c) outsl((a),(s),(c)) #define mmiowb() wmb() /* synco on SH-4A, otherwise a nop */ @@ -208,8 +207,6 @@ static inline void __set_io_port_base(unsigned long pbase) generic_io_base = pbase; } -#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n)) - /* We really want to try and get these to memcpy etc */ extern void memcpy_fromio(void *, volatile void __iomem *, unsigned long); extern void memcpy_toio(volatile void __iomem *, const void *, unsigned long); @@ -312,14 +309,7 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) { #ifdef CONFIG_SUPERH32 unsigned long last_addr = offset + size - 1; -#endif - void __iomem *ret; - ret = __ioremap_trapped(offset, size); - if (ret) - return ret; - -#ifdef CONFIG_SUPERH32 /* * For P1 and P2 space this is trivial, as everything is already * mapped. Uncached access for P1 addresses are done through P2. diff --git a/trunk/include/asm-sh/io_trapped.h b/trunk/include/asm-sh/io_trapped.h deleted file mode 100644 index f1251d4f0ba9..000000000000 --- a/trunk/include/asm-sh/io_trapped.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __ASM_SH_IO_TRAPPED_H -#define __ASM_SH_IO_TRAPPED_H - -#include -#include -#include - -#define IO_TRAPPED_MAGIC 0xfeedbeef - -struct trapped_io { - unsigned int magic; - struct resource *resource; - unsigned int num_resources; - unsigned int minimum_bus_width; - struct list_head list; - void __iomem *virt_base; -} __aligned(PAGE_SIZE); - -#ifdef CONFIG_IO_TRAPPED -int register_trapped_io(struct trapped_io *tiop); -int handle_trapped_io(struct pt_regs *regs, unsigned long address); - -void __iomem *match_trapped_io_handler(struct list_head *list, - unsigned long offset, - unsigned long size); - -#ifdef CONFIG_HAS_IOMEM -extern struct list_head trapped_mem; - -static inline void __iomem * -__ioremap_trapped(unsigned long offset, unsigned long size) -{ - return match_trapped_io_handler(&trapped_mem, offset, size); -} -#else -#define __ioremap_trapped(offset, size) NULL -#endif - -#ifdef CONFIG_HAS_IOPORT -extern struct list_head trapped_io; - -static inline void __iomem * -__ioport_map_trapped(unsigned long offset, unsigned long size) -{ - return match_trapped_io_handler(&trapped_io, offset, size); -} -#else -#define __ioport_map_trapped(offset, size) NULL -#endif - -#else -#define register_trapped_io(tiop) (-1) -#define handle_trapped_io(tiop, address) 0 -#define __ioremap_trapped(offset, size) NULL -#define __ioport_map_trapped(offset, size) NULL -#endif - -#endif /* __ASM_SH_IO_TRAPPED_H */ diff --git a/trunk/include/asm-sh/ioctls.h b/trunk/include/asm-sh/ioctls.h index c212c371a4a5..35805df010a0 100644 --- a/trunk/include/asm-sh/ioctls.h +++ b/trunk/include/asm-sh/ioctls.h @@ -78,10 +78,6 @@ #define TIOCSBRK _IO('T', 39) /* 0x5427 */ /* BSD compatibility */ #define TIOCCBRK _IO('T', 40) /* 0x5428 */ /* BSD compatibility */ #define TIOCGSID _IOR('T', 41, pid_t) /* 0x5429 */ /* Return the session ID of FD */ -#define TCGETS2 _IOR('T', 42, struct termios2) -#define TCSETS2 _IOW('T', 43, struct termios2) -#define TCSETSW2 _IOW('T', 44, struct termios2) -#define TCSETSF2 _IOW('T', 45, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ diff --git a/trunk/include/asm-sh/irq.h b/trunk/include/asm-sh/irq.h index ca66e5df69dc..11850f65c922 100644 --- a/trunk/include/asm-sh/irq.h +++ b/trunk/include/asm-sh/irq.h @@ -50,8 +50,4 @@ extern void irq_ctx_exit(int cpu); # define irq_ctx_exit(cpu) do { } while (0) #endif -#ifdef CONFIG_CPU_SH5 -#include -#endif - #endif /* __ASM_SH_IRQ_H */ diff --git a/trunk/include/asm-sh/mmu_context_64.h b/trunk/include/asm-sh/mmu_context_64.h index 9649f1c07caf..020be744b088 100644 --- a/trunk/include/asm-sh/mmu_context_64.h +++ b/trunk/include/asm-sh/mmu_context_64.h @@ -66,9 +66,6 @@ static inline void set_asid(unsigned long asid) : "=r" (sr), "=r" (pc) : "0" (sr)); } -/* arch/sh/kernel/cpu/sh5/entry.S */ -extern unsigned long switch_and_save_asid(unsigned long new_asid); - /* No spare register to twiddle, so use a software cache */ extern pgd_t *mmu_pdtp_cache; diff --git a/trunk/include/asm-sh/page.h b/trunk/include/asm-sh/page.h index 304c30b5d947..134562dc8c45 100644 --- a/trunk/include/asm-sh/page.h +++ b/trunk/include/asm-sh/page.h @@ -55,14 +55,11 @@ extern void clear_page(void *to); extern void copy_page(void *to, void *from); #if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ - (defined(CONFIG_CPU_SH5) || defined(CONFIG_CPU_SH4) || \ - defined(CONFIG_SH7705_CACHE_32KB)) + (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) struct page; struct vm_area_struct; extern void clear_user_page(void *to, unsigned long address, struct page *page); -extern void copy_user_page(void *to, void *from, unsigned long address, - struct page *page); -#if defined(CONFIG_CPU_SH4) +#ifdef CONFIG_CPU_SH4 extern void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr, struct vm_area_struct *vma); #define __HAVE_ARCH_COPY_USER_HIGHPAGE diff --git a/trunk/include/asm-sh/pgtable_64.h b/trunk/include/asm-sh/pgtable_64.h index f9dd9d311441..972211671c9a 100644 --- a/trunk/include/asm-sh/pgtable_64.h +++ b/trunk/include/asm-sh/pgtable_64.h @@ -137,14 +137,6 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep) #define _PAGE_SZHUGE (_PAGE_SIZE0 | _PAGE_SIZE1) #endif -/* - * Stub out _PAGE_SZHUGE if we don't have a good definition for it, - * to make pte_mkhuge() happy. - */ -#ifndef _PAGE_SZHUGE -# define _PAGE_SZHUGE (0) -#endif - /* * Default flags for a Kernel page. * This is fundametally also SHARED because the main use of this define @@ -187,11 +179,6 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep) _PAGE_WRITE | _PAGE_EXECUTE) #define PAGE_KERNEL __pgprot(_KERNPG_TABLE) -#define PAGE_KERNEL_NOCACHE \ - __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ - _PAGE_EXECUTE | _PAGE_ACCESSED | \ - _PAGE_DIRTY | _PAGE_SHARED) - /* Make it a device mapping for maximum safety (e.g. for mapping device registers into user-space via /dev/map). */ #define pgprot_noncached(x) __pgprot(((x).pgprot & ~(_PAGE_CACHABLE)) | _PAGE_DEVICE) diff --git a/trunk/include/asm-sh/processor.h b/trunk/include/asm-sh/processor.h index 19fe47c1ca17..c9b14161f73d 100644 --- a/trunk/include/asm-sh/processor.h +++ b/trunk/include/asm-sh/processor.h @@ -33,7 +33,7 @@ enum cpu_type { CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SHX3, /* SH4AL-DSP types */ - CPU_SH7343, CPU_SH7722, CPU_SH7366, + CPU_SH7343, CPU_SH7722, /* SH-5 types */ CPU_SH5_101, CPU_SH5_103, diff --git a/trunk/include/asm-sh/r7780rp.h b/trunk/include/asm-sh/r7780rp.h index 1770460a4616..bdecea0840a0 100644 --- a/trunk/include/asm-sh/r7780rp.h +++ b/trunk/include/asm-sh/r7780rp.h @@ -195,4 +195,7 @@ unsigned char *highlander_init_irq_r7780mp(void); unsigned char *highlander_init_irq_r7780rp(void); unsigned char *highlander_init_irq_r7785rp(void); +#define __IO_PREFIX r7780rp +#include + #endif /* __ASM_SH_RENESAS_R7780RP */ diff --git a/trunk/include/asm-sh/rts7751r2d.h b/trunk/include/asm-sh/rts7751r2d.h index 0a800157b826..83b9c111f171 100644 --- a/trunk/include/asm-sh/rts7751r2d.h +++ b/trunk/include/asm-sh/rts7751r2d.h @@ -67,4 +67,7 @@ void init_rts7751r2d_IRQ(void); int rts7751r2d_irq_demux(int); +#define __IO_PREFIX rts7751r2d +#include + #endif /* __ASM_SH_RENESAS_RTS7751R2D */ diff --git a/trunk/include/asm-sh/system.h b/trunk/include/asm-sh/system.h index 5145aa2a0ce9..772cd1a0a674 100644 --- a/trunk/include/asm-sh/system.h +++ b/trunk/include/asm-sh/system.h @@ -182,11 +182,6 @@ BUILD_TRAP_HANDLER(fpu_state_restore); #define arch_align_stack(x) (x) -struct mem_access { - unsigned long (*from)(void *dst, const void *src, unsigned long cnt); - unsigned long (*to)(void *dst, const void *src, unsigned long cnt); -}; - #ifdef CONFIG_SUPERH32 # include "system_32.h" #else diff --git a/trunk/include/asm-sh/system_32.h b/trunk/include/asm-sh/system_32.h index f11bcf0855ed..7ff08d956ba8 100644 --- a/trunk/include/asm-sh/system_32.h +++ b/trunk/include/asm-sh/system_32.h @@ -96,7 +96,4 @@ do { \ : "=&r" (__dummy)); \ } while (0) -int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs, - struct mem_access *ma); - #endif /* __ASM_SH_SYSTEM_32_H */ diff --git a/trunk/include/asm-sh/termbits.h b/trunk/include/asm-sh/termbits.h index 77db116948cf..7ee1b42eeab0 100644 --- a/trunk/include/asm-sh/termbits.h +++ b/trunk/include/asm-sh/termbits.h @@ -140,7 +140,6 @@ struct ktermios { #define HUPCL 0002000 #define CLOCAL 0004000 #define CBAUDEX 0010000 -#define BOTHER 0010000 #define B57600 0010001 #define B115200 0010002 #define B230400 0010003 @@ -156,12 +155,10 @@ struct ktermios { #define B3000000 0010015 #define B3500000 0010016 #define B4000000 0010017 -#define CIBAUD 002003600000 /* input baud rate */ +#define CIBAUD 002003600000 /* input baud rate (not used) */ #define CMSPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ -#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ - /* c_lflag bits */ #define ISIG 0000001 #define ICANON 0000002 diff --git a/trunk/include/asm-sh/termios.h b/trunk/include/asm-sh/termios.h index 0a8c793c76f2..e7c8f86ef890 100644 --- a/trunk/include/asm-sh/termios.h +++ b/trunk/include/asm-sh/termios.h @@ -80,10 +80,8 @@ struct termio { copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ }) -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) -#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-sh/tlb.h b/trunk/include/asm-sh/tlb.h index 88ff1ae8a6b8..56ad1fb888a2 100644 --- a/trunk/include/asm-sh/tlb.h +++ b/trunk/include/asm-sh/tlb.h @@ -20,7 +20,6 @@ */ #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) -#include #include #endif /* __ASSEMBLY__ */ diff --git a/trunk/include/asm-sh/uaccess.h b/trunk/include/asm-sh/uaccess.h index b3440c305b5d..ff24ce95b238 100644 --- a/trunk/include/asm-sh/uaccess.h +++ b/trunk/include/asm-sh/uaccess.h @@ -1,34 +1,5 @@ -#ifndef __ASM_SH_UACCESS_H -#define __ASM_SH_UACCESS_H - #ifdef CONFIG_SUPERH32 # include "uaccess_32.h" #else # include "uaccess_64.h" #endif - -static inline unsigned long -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - unsigned long __copy_from = (unsigned long) from; - __kernel_size_t __copy_size = (__kernel_size_t) n; - - if (__copy_size && __access_ok(__copy_from, __copy_size)) - return __copy_user(to, from, __copy_size); - - return __copy_size; -} - -static inline unsigned long -copy_to_user(void __user *to, const void *from, unsigned long n) -{ - unsigned long __copy_to = (unsigned long) to; - __kernel_size_t __copy_size = (__kernel_size_t) n; - - if (__copy_size && __access_ok(__copy_to, __copy_size)) - return __copy_user(to, from, __copy_size); - - return __copy_size; -} - -#endif /* __ASM_SH_UACCESS_H */ diff --git a/trunk/include/asm-sh/uaccess_32.h b/trunk/include/asm-sh/uaccess_32.h index c0318b608893..b6082f3c1dc4 100644 --- a/trunk/include/asm-sh/uaccess_32.h +++ b/trunk/include/asm-sh/uaccess_32.h @@ -10,8 +10,8 @@ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle * and i386 version. */ -#ifndef __ASM_SH_UACCESS_32_H -#define __ASM_SH_UACCESS_32_H +#ifndef __ASM_SH_UACCESS_H +#define __ASM_SH_UACCESS_H #include #include @@ -302,6 +302,24 @@ extern void __put_user_unknown(void); /* Return the number of bytes NOT copied */ __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); +#define copy_to_user(to,from,n) ({ \ +void *__copy_to = (void *) (to); \ +__kernel_size_t __copy_size = (__kernel_size_t) (n); \ +__kernel_size_t __copy_res; \ +if(__copy_size && __access_ok((unsigned long)__copy_to, __copy_size)) { \ +__copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \ +} else __copy_res = __copy_size; \ +__copy_res; }) + +#define copy_from_user(to,from,n) ({ \ +void *__copy_to = (void *) (to); \ +void *__copy_from = (void *) (from); \ +__kernel_size_t __copy_size = (__kernel_size_t) (n); \ +__kernel_size_t __copy_res; \ +if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \ +__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \ +} else __copy_res = __copy_size; \ +__copy_res; }) static __always_inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) @@ -489,4 +507,4 @@ struct exception_table_entry extern int fixup_exception(struct pt_regs *regs); -#endif /* __ASM_SH_UACCESS_32_H */ +#endif /* __ASM_SH_UACCESS_H */ diff --git a/trunk/include/asm-sh/uaccess_64.h b/trunk/include/asm-sh/uaccess_64.h index f956b7b316c7..d54ec082d25a 100644 --- a/trunk/include/asm-sh/uaccess_64.h +++ b/trunk/include/asm-sh/uaccess_64.h @@ -202,6 +202,15 @@ extern void __put_user_unknown(void); /* XXX: should be such that: 4byte and the rest. */ extern __kernel_size_t __copy_user(void *__to, const void *__from, __kernel_size_t __n); +#define copy_to_user(to,from,n) ({ \ +void *__copy_to = (void *) (to); \ +__kernel_size_t __copy_size = (__kernel_size_t) (n); \ +__kernel_size_t __copy_res; \ +if(__copy_size && __access_ok((unsigned long)__copy_to, __copy_size)) { \ +__copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \ +} else __copy_res = __copy_size; \ +__copy_res; }) + #define copy_to_user_ret(to,from,n,retval) ({ \ if (copy_to_user(to,from,n)) \ return retval; \ @@ -216,6 +225,16 @@ if (__copy_to_user(to,from,n)) \ return retval; \ }) +#define copy_from_user(to,from,n) ({ \ +void *__copy_to = (void *) (to); \ +void *__copy_from = (void *) (from); \ +__kernel_size_t __copy_size = (__kernel_size_t) (n); \ +__kernel_size_t __copy_res; \ +if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \ +__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \ +} else __copy_res = __copy_size; \ +__copy_res; }) + #define copy_from_user_ret(to,from,n,retval) ({ \ if (copy_from_user(to,from,n)) \ return retval; \ diff --git a/trunk/include/asm-sh/unistd_32.h b/trunk/include/asm-sh/unistd_32.h index 0b07212ec659..433fd1b48fa2 100644 --- a/trunk/include/asm-sh/unistd_32.h +++ b/trunk/include/asm-sh/unistd_32.h @@ -330,13 +330,11 @@ #define __NR_epoll_pwait 319 #define __NR_utimensat 320 #define __NR_signalfd 321 -#define __NR_timerfd_create 322 +/* #define __NR_timerfd 322 removed */ #define __NR_eventfd 323 #define __NR_fallocate 324 -#define __NR_timerfd_settime 325 -#define __NR_timerfd_gettime 326 -#define NR_syscalls 327 +#define NR_syscalls 325 #ifdef __KERNEL__ diff --git a/trunk/include/asm-sh/unistd_64.h b/trunk/include/asm-sh/unistd_64.h index 9d21eab52427..108d2ba897fe 100644 --- a/trunk/include/asm-sh/unistd_64.h +++ b/trunk/include/asm-sh/unistd_64.h @@ -90,7 +90,7 @@ #define __NR_sigpending 73 #define __NR_sethostname 74 #define __NR_setrlimit 75 -#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ +#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */ #define __NR_getrusage 77 #define __NR_gettimeofday 78 #define __NR_settimeofday 79 @@ -370,11 +370,9 @@ #define __NR_epoll_pwait 347 #define __NR_utimensat 348 #define __NR_signalfd 349 -#define __NR_timerfd_create 350 +/* #define __NR_timerfd 350 removed */ #define __NR_eventfd 351 #define __NR_fallocate 352 -#define __NR_timerfd_settime 353 -#define __NR_timerfd_gettime 354 #ifdef __KERNEL__ diff --git a/trunk/include/asm-x86/cacheflush.h b/trunk/include/asm-x86/cacheflush.h index 5396c212d8c0..6a22212b4b20 100644 --- a/trunk/include/asm-x86/cacheflush.h +++ b/trunk/include/asm-x86/cacheflush.h @@ -48,15 +48,12 @@ void cpa_init(void); #ifdef CONFIG_DEBUG_RODATA void mark_rodata_ro(void); -extern const int rodata_test_data; #endif - #ifdef CONFIG_DEBUG_RODATA_TEST -int rodata_test(void); +void rodata_test(void); #else -static inline int rodata_test(void) +static inline void rodata_test(void) { - return 0; } #endif diff --git a/trunk/include/asm-x86/kdebug.h b/trunk/include/asm-x86/kdebug.h index 99dcbafa1511..dd442a1632c0 100644 --- a/trunk/include/asm-x86/kdebug.h +++ b/trunk/include/asm-x86/kdebug.h @@ -31,6 +31,7 @@ extern void show_trace(struct task_struct *t, struct pt_regs *regs, unsigned long *sp, unsigned long bp); extern void __show_regs(struct pt_regs *regs); extern void show_regs(struct pt_regs *regs); +extern void dump_pagetable(unsigned long); extern unsigned long oops_begin(void); extern void oops_end(unsigned long, struct pt_regs *, int signr); diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 2c7e003356ac..ddbe7efe590e 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -203,7 +203,6 @@ extern bool wmi_has_guid(const char *guid); extern int acpi_blacklisted(void); #ifdef CONFIG_DMI extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); -extern int acpi_osi_setup(char *str); #endif #ifdef CONFIG_ACPI_NUMA diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 2af9ec025015..97153027207a 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -534,7 +534,8 @@ extern void audit_log_n_untrustedstring(struct audit_buffer *ab, const char *string); extern void audit_log_d_path(struct audit_buffer *ab, const char *prefix, - struct path *path); + struct dentry *dentry, + struct vfsmount *vfsmnt); extern void audit_log_lost(const char *message); /* Private API (for audit.c only) */ extern int audit_filter_user(struct netlink_skb_parms *cb, int type); @@ -551,7 +552,7 @@ extern int audit_enabled; #define audit_log_hex(a,b,l) do { ; } while (0) #define audit_log_untrustedstring(a,s) do { ; } while (0) #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) -#define audit_log_d_path(b, p, d) do { ; } while (0) +#define audit_log_d_path(b,p,d,v) do { ; } while (0) #define audit_enabled 0 #endif #endif diff --git a/trunk/include/linux/configfs.h b/trunk/include/linux/configfs.h index 4b287ad9371a..8c6967f3fb11 100644 --- a/trunk/include/linux/configfs.h +++ b/trunk/include/linux/configfs.h @@ -37,7 +37,6 @@ #ifdef __KERNEL__ -#include #include #include #include diff --git a/trunk/include/linux/cpuidle.h b/trunk/include/linux/cpuidle.h index 6b72a4584086..385d45b616db 100644 --- a/trunk/include/linux/cpuidle.h +++ b/trunk/include/linux/cpuidle.h @@ -19,7 +19,6 @@ #define CPUIDLE_STATE_MAX 8 #define CPUIDLE_NAME_LEN 16 -#define CPUIDLE_DESC_LEN 32 struct cpuidle_device; @@ -30,7 +29,6 @@ struct cpuidle_device; struct cpuidle_state { char name[CPUIDLE_NAME_LEN]; - char desc[CPUIDLE_DESC_LEN]; void *driver_data; unsigned int flags; diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index 6bd646096fa6..c2c153f97e8f 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -10,7 +10,6 @@ #include struct nameidata; -struct path; struct vfsmount; /* @@ -301,8 +300,8 @@ extern int d_validate(struct dentry *, struct dentry *); */ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); -extern char *d_path(struct path *, char *, int); - +extern char * d_path(struct dentry *, struct vfsmount *, char *, int); + /* Allocation counts.. */ /** diff --git a/trunk/include/linux/dcookies.h b/trunk/include/linux/dcookies.h index 24c806f12a6c..98c69ab80c84 100644 --- a/trunk/include/linux/dcookies.h +++ b/trunk/include/linux/dcookies.h @@ -13,7 +13,6 @@ #ifdef CONFIG_PROFILING #include -#include #include struct dcookie_user; @@ -44,7 +43,8 @@ void dcookie_unregister(struct dcookie_user * user); * * Returns 0 on success, with *cookie filled in */ -int get_dcookie(struct path *path, unsigned long *cookie); +int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt, + unsigned long * cookie); #else @@ -57,12 +57,13 @@ static inline void dcookie_unregister(struct dcookie_user * user) { return; } - -static inline int get_dcookie(struct path *path, unsigned long *cookie) + +static inline int get_dcookie(struct dentry * dentry, + struct vfsmount * vfsmnt, unsigned long * cookie) { return -ENOSYS; -} - +} + #endif /* CONFIG_PROFILING */ - + #endif /* DCOOKIES_H */ diff --git a/trunk/include/linux/dm9000.h b/trunk/include/linux/dm9000.h index a3750462f9e3..0008e2ad0c9f 100644 --- a/trunk/include/linux/dm9000.h +++ b/trunk/include/linux/dm9000.h @@ -19,8 +19,6 @@ #define DM9000_PLATF_8BITONLY (0x0001) #define DM9000_PLATF_16BITONLY (0x0002) #define DM9000_PLATF_32BITONLY (0x0004) -#define DM9000_PLATF_EXT_PHY (0x0008) -#define DM9000_PLATF_NO_EEPROM (0x0010) /* platfrom data for platfrom device structure's platfrom_data field */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 98ffb6ead434..18cfbf76ec5b 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1284,10 +1284,8 @@ struct super_operations { * * I_DIRTY_SYNC Inode is dirty, but doesn't have to be written on * fdatasync(). i_atime is the usual cause. - * I_DIRTY_DATASYNC Data-related inode changes pending. We keep track of - * these changes separately from I_DIRTY_SYNC so that we - * don't have to write inode on fdatasync() when only - * mtime has changed in it. + * I_DIRTY_DATASYNC Inode is dirty and must be written on fdatasync(), f.e. + * because i_size changed. * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean. * I_NEW get_new_inode() sets i_state to I_LOCK|I_NEW. Both * are cleared by unlock_new_inode(), called from iget(). diff --git a/trunk/include/linux/fs_struct.h b/trunk/include/linux/fs_struct.h index 282f54219129..11a36ceddf73 100644 --- a/trunk/include/linux/fs_struct.h +++ b/trunk/include/linux/fs_struct.h @@ -1,13 +1,15 @@ #ifndef _LINUX_FS_STRUCT_H #define _LINUX_FS_STRUCT_H -#include +struct dentry; +struct vfsmount; struct fs_struct { atomic_t count; rwlock_t lock; int umask; - struct path root, pwd, altroot; + struct dentry * root, * pwd, * altroot; + struct vfsmount * rootmnt, * pwdmnt, * altrootmnt; }; #define INIT_FS { \ @@ -20,8 +22,8 @@ extern struct kmem_cache *fs_cachep; extern void exit_fs(struct task_struct *); extern void set_fs_altroot(void); -extern void set_fs_root(struct fs_struct *, struct path *); -extern void set_fs_pwd(struct fs_struct *, struct path *); +extern void set_fs_root(struct fs_struct *, struct vfsmount *, struct dentry *); +extern void set_fs_pwd(struct fs_struct *, struct vfsmount *, struct dentry *); extern struct fs_struct *copy_fs_struct(struct fs_struct *); extern void put_fs_struct(struct fs_struct *); diff --git a/trunk/include/linux/hid.h b/trunk/include/linux/hid.h index 74ff57596eb1..3902690647b0 100644 --- a/trunk/include/linux/hid.h +++ b/trunk/include/linux/hid.h @@ -528,7 +528,7 @@ int hid_set_field(struct hid_field *, unsigned, __s32); int hid_input_report(struct hid_device *, int type, u8 *, int, int); int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long **, int *); -int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); +void hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); void hid_output_report(struct hid_report *report, __u8 *data); diff --git a/trunk/include/linux/ktime.h b/trunk/include/linux/ktime.h index 2cd7fa73d1af..36c542b70c6d 100644 --- a/trunk/include/linux/ktime.h +++ b/trunk/include/linux/ktime.h @@ -310,8 +310,6 @@ static inline ktime_t ktime_sub_us(const ktime_t kt, const u64 usec) return ktime_sub_ns(kt, usec * 1000); } -extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs); - /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an diff --git a/trunk/include/linux/maple.h b/trunk/include/linux/maple.h index 3f01e2bae1a1..bad9a7b319de 100644 --- a/trunk/include/linux/maple.h +++ b/trunk/include/linux/maple.h @@ -7,74 +7,74 @@ extern struct bus_type maple_bus_type; /* Maple Bus command and response codes */ enum maple_code { - MAPLE_RESPONSE_FILEERR = -5, - MAPLE_RESPONSE_AGAIN = -4, /* request should be retransmitted */ - MAPLE_RESPONSE_BADCMD = -3, - MAPLE_RESPONSE_BADFUNC = -2, - MAPLE_RESPONSE_NONE = -1, /* unit didn't respond at all */ - MAPLE_COMMAND_DEVINFO = 1, - MAPLE_COMMAND_ALLINFO = 2, - MAPLE_COMMAND_RESET = 3, - MAPLE_COMMAND_KILL = 4, - MAPLE_RESPONSE_DEVINFO = 5, - MAPLE_RESPONSE_ALLINFO = 6, - MAPLE_RESPONSE_OK = 7, - MAPLE_RESPONSE_DATATRF = 8, - MAPLE_COMMAND_GETCOND = 9, - MAPLE_COMMAND_GETMINFO = 10, - MAPLE_COMMAND_BREAD = 11, - MAPLE_COMMAND_BWRITE = 12, - MAPLE_COMMAND_SETCOND = 14 + MAPLE_RESPONSE_FILEERR = -5, + MAPLE_RESPONSE_AGAIN = -4, /* request should be retransmitted */ + MAPLE_RESPONSE_BADCMD = -3, + MAPLE_RESPONSE_BADFUNC = -2, + MAPLE_RESPONSE_NONE = -1, /* unit didn't respond at all */ + MAPLE_COMMAND_DEVINFO = 1, + MAPLE_COMMAND_ALLINFO = 2, + MAPLE_COMMAND_RESET = 3, + MAPLE_COMMAND_KILL = 4, + MAPLE_RESPONSE_DEVINFO = 5, + MAPLE_RESPONSE_ALLINFO = 6, + MAPLE_RESPONSE_OK = 7, + MAPLE_RESPONSE_DATATRF = 8, + MAPLE_COMMAND_GETCOND = 9, + MAPLE_COMMAND_GETMINFO = 10, + MAPLE_COMMAND_BREAD = 11, + MAPLE_COMMAND_BWRITE = 12, + MAPLE_COMMAND_SETCOND = 14 }; struct mapleq { - struct list_head list; - struct maple_device *dev; - void *sendbuf, *recvbuf, *recvbufdcsp; - unsigned char length; - enum maple_code command; + struct list_head list; + struct maple_device *dev; + void *sendbuf, *recvbuf, *recvbufdcsp; + unsigned char length; + enum maple_code command; }; struct maple_devinfo { - unsigned long function; - unsigned long function_data[3]; - unsigned char area_code; - unsigned char connector_direction; - char product_name[31]; - char product_licence[61]; - unsigned short standby_power; - unsigned short max_power; + unsigned long function; + unsigned long function_data[3]; + unsigned char area_code; + unsigned char connector_directon; + char product_name[31]; + char product_licence[61]; + unsigned short standby_power; + unsigned short max_power; }; struct maple_device { - struct maple_driver *driver; - struct mapleq *mq; - void *private_data; - void (*callback) (struct mapleq * mq); - unsigned long when, interval, function; - struct maple_devinfo devinfo; - unsigned char port, unit; - char product_name[32]; - char product_licence[64]; - struct device dev; + struct maple_driver *driver; + struct mapleq *mq; + void *private_data; + void (*callback) (struct mapleq * mq); + unsigned long when, interval, function; + struct maple_devinfo devinfo; + unsigned char port, unit; + char product_name[32]; + char product_licence[64]; + int registered; + struct device dev; }; struct maple_driver { - unsigned long function; - int (*connect) (struct maple_device * dev); - void (*disconnect) (struct maple_device * dev); - struct device_driver drv; - int registered; + unsigned long function; + int (*connect) (struct maple_device * dev); + void (*disconnect) (struct maple_device * dev); + struct device_driver drv; }; void maple_getcond_callback(struct maple_device *dev, - void (*callback) (struct mapleq * mq), - unsigned long interval, - unsigned long function); + void (*callback) (struct mapleq * mq), + unsigned long interval, + unsigned long function); int maple_driver_register(struct device_driver *drv); void maple_add_packet(struct mapleq *mq); #define to_maple_dev(n) container_of(n, struct maple_device, dev) #define to_maple_driver(n) container_of(n, struct maple_driver, drv) -#endif /* __LINUX_MAPLE_H */ +#endif /* __LINUX_MAPLE_H */ diff --git a/trunk/include/linux/module.h b/trunk/include/linux/module.h index 819c4e889bf1..330bec08c2c4 100644 --- a/trunk/include/linux/module.h +++ b/trunk/include/linux/module.h @@ -567,7 +567,8 @@ static inline void print_modules(void) { } -static inline void module_update_markers(void) +static inline void module_update_markers(struct module *probe_module, + int *refcount) { } diff --git a/trunk/include/linux/namei.h b/trunk/include/linux/namei.h index 24d88e98a626..c13e411491f4 100644 --- a/trunk/include/linux/namei.h +++ b/trunk/include/linux/namei.h @@ -3,7 +3,6 @@ #include #include -#include struct vfsmount; @@ -16,7 +15,8 @@ struct open_intent { enum { MAX_NESTED_LINKS = 8 }; struct nameidata { - struct path path; + struct dentry *dentry; + struct vfsmount *mnt; struct qstr last; unsigned int flags; int last_type; @@ -29,6 +29,11 @@ struct nameidata { } intent; }; +struct path { + struct vfsmount *mnt; + struct dentry *dentry; +}; + /* * Type of the last component on LOOKUP_PARENT */ @@ -66,6 +71,8 @@ extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameida extern int path_lookup(const char *, unsigned, struct nameidata *); extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct nameidata *); +extern void path_release(struct nameidata *); +extern void path_release_on_umount(struct nameidata *); extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags); extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags); diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index a2f003239c85..7128a02f1d37 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -604,10 +604,6 @@ struct net_device unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ - /* ingress path synchronizer */ - spinlock_t ingress_lock; - struct Qdisc *qdisc_ingress; - /* * Cache line mostly used on queue transmit path (qdisc) */ @@ -621,6 +617,10 @@ struct net_device /* Partially transmitted GSO packet. */ struct sk_buff *gso_skb; + /* ingress path synchronizer */ + spinlock_t ingress_lock; + struct Qdisc *qdisc_ingress; + /* * One part is mostly used on xmit path (device) */ diff --git a/trunk/include/linux/nfsd/export.h b/trunk/include/linux/nfsd/export.h index 5431512b2757..3a1687251367 100644 --- a/trunk/include/linux/nfsd/export.h +++ b/trunk/include/linux/nfsd/export.h @@ -84,8 +84,9 @@ struct svc_export { struct cache_head h; struct auth_domain * ex_client; int ex_flags; - struct path ex_path; - char *ex_pathname; + struct vfsmount * ex_mnt; + struct dentry * ex_dentry; + char * ex_path; uid_t ex_anon_uid; gid_t ex_anon_gid; int ex_fsid; @@ -106,7 +107,8 @@ struct svc_expkey { int ek_fsidtype; u32 ek_fsid[6]; - struct path ek_path; + struct vfsmount * ek_mnt; + struct dentry * ek_dentry; }; #define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT)) diff --git a/trunk/include/linux/path.h b/trunk/include/linux/path.h deleted file mode 100644 index 915e0c382a51..000000000000 --- a/trunk/include/linux/path.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _LINUX_PATH_H -#define _LINUX_PATH_H - -struct dentry; -struct vfsmount; - -struct path { - struct vfsmount *mnt; - struct dentry *dentry; -}; - -extern void path_get(struct path *); -extern void path_put(struct path *); - -#endif /* _LINUX_PATH_H */ diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index d9a9e718ad19..d6a4f69bdc92 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -269,7 +269,7 @@ extern void kclist_add(struct kcore_list *, void *, size_t); #endif union proc_op { - int (*proc_get_link)(struct inode *, struct path *); + int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); int (*proc_read)(struct task_struct *task, char *page); int (*proc_show)(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, diff --git a/trunk/include/linux/seq_file.h b/trunk/include/linux/seq_file.h index 67c2563961f3..648dfeb444db 100644 --- a/trunk/include/linux/seq_file.h +++ b/trunk/include/linux/seq_file.h @@ -8,7 +8,8 @@ struct seq_operations; struct file; -struct path; +struct vfsmount; +struct dentry; struct inode; struct seq_file { @@ -41,7 +42,7 @@ int seq_puts(struct seq_file *m, const char *s); int seq_printf(struct seq_file *, const char *, ...) __attribute__ ((format (printf,2,3))); -int seq_path(struct seq_file *, struct path *, char *); +int seq_path(struct seq_file *, struct vfsmount *, struct dentry *, char *); int single_open(struct file *, int (*)(struct seq_file *, void *), void *); int single_release(struct inode *, struct file *); diff --git a/trunk/include/linux/slub_def.h b/trunk/include/linux/slub_def.h index 57deecc79d52..5e6d3d634d5b 100644 --- a/trunk/include/linux/slub_def.h +++ b/trunk/include/linux/slub_def.h @@ -71,7 +71,6 @@ struct kmem_cache { /* Allocation and freeing of slabs */ int objects; /* Number of objects in slab */ - gfp_t allocflags; /* gfp flags to use on each alloc */ int refcount; /* Refcount for slab cache destroy */ void (*ctor)(struct kmem_cache *, void *); int inuse; /* Offset to metadata */ @@ -111,7 +110,7 @@ struct kmem_cache { * We keep the general caches in an array of slab caches that are used for * 2^x bytes of allocations. */ -extern struct kmem_cache kmalloc_caches[PAGE_SHIFT + 1]; +extern struct kmem_cache kmalloc_caches[PAGE_SHIFT]; /* * Sorry that the following has to be that ugly but some versions of GCC @@ -189,16 +188,12 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size) void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); -static __always_inline void *kmalloc_large(size_t size, gfp_t flags) -{ - return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size)); -} - static __always_inline void *kmalloc(size_t size, gfp_t flags) { if (__builtin_constant_p(size)) { - if (size > PAGE_SIZE) - return kmalloc_large(size, flags); + if (size > PAGE_SIZE / 2) + return (void *)__get_free_pages(flags | __GFP_COMP, + get_order(size)); if (!(flags & SLUB_DMA)) { struct kmem_cache *s = kmalloc_slab(size); @@ -219,7 +214,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) { if (__builtin_constant_p(size) && - size <= PAGE_SIZE && !(flags & SLUB_DMA)) { + size <= PAGE_SIZE / 2 && !(flags & SLUB_DMA)) { struct kmem_cache *s = kmalloc_slab(size); if (!s) diff --git a/trunk/include/net/ax25.h b/trunk/include/net/ax25.h index 717e2192d521..32a57e1dee3a 100644 --- a/trunk/include/net/ax25.h +++ b/trunk/include/net/ax25.h @@ -324,7 +324,6 @@ extern void ax25_dama_on(ax25_cb *); extern void ax25_dama_off(ax25_cb *); /* ax25_ds_timer.c */ -extern void ax25_ds_setup_timer(ax25_dev *); extern void ax25_ds_set_timer(ax25_dev *); extern void ax25_ds_del_timer(ax25_dev *); extern void ax25_ds_timer(ax25_cb *); @@ -417,7 +416,6 @@ extern void ax25_calculate_rtt(ax25_cb *); extern void ax25_disconnect(ax25_cb *, int); /* ax25_timer.c */ -extern void ax25_setup_timers(ax25_cb *); extern void ax25_start_heartbeat(ax25_cb *); extern void ax25_start_t1timer(ax25_cb *); extern void ax25_start_t2timer(ax25_cb *); diff --git a/trunk/include/net/ndisc.h b/trunk/include/net/ndisc.h index 59b70624b056..6684f7efbeeb 100644 --- a/trunk/include/net/ndisc.h +++ b/trunk/include/net/ndisc.h @@ -103,6 +103,7 @@ extern void ndisc_send_redirect(struct sk_buff *skb, extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir); +struct rt6_info * dflt_rt_lookup(void); /* * IGMP diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index eea7785cc757..ac72116636ca 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -508,10 +508,7 @@ struct xfrm_skb_cb { } header; /* Sequence number for replay protection. */ - union { - u64 output; - __be32 input; - } seq; + u64 seq; }; #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0])) diff --git a/trunk/init/do_mounts.c b/trunk/init/do_mounts.c index 3885e70e7759..f86573126f83 100644 --- a/trunk/init/do_mounts.c +++ b/trunk/init/do_mounts.c @@ -193,10 +193,10 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) return err; sys_chdir("/root"); - ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev; + ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; printk("VFS: Mounted root (%s filesystem)%s.\n", - current->fs->pwd.mnt->mnt_sb->s_type->name, - current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ? + current->fs->pwdmnt->mnt_sb->s_type->name, + current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? " readonly" : ""); return 0; } diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index 2eeea9a14240..c8555b180213 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -1312,26 +1312,26 @@ void audit_log_untrustedstring(struct audit_buffer *ab, const char *string) /* This is a helper-function to print the escaped d_path */ void audit_log_d_path(struct audit_buffer *ab, const char *prefix, - struct path *path) + struct dentry *dentry, struct vfsmount *vfsmnt) { - char *p, *pathname; + char *p, *path; if (prefix) audit_log_format(ab, " %s", prefix); /* We will allow 11 spaces for ' (deleted)' to be appended */ - pathname = kmalloc(PATH_MAX+11, ab->gfp_mask); - if (!pathname) { + path = kmalloc(PATH_MAX+11, ab->gfp_mask); + if (!path) { audit_log_format(ab, ""); return; } - p = d_path(path, pathname, PATH_MAX+11); + p = d_path(dentry, vfsmnt, path, PATH_MAX+11); if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ /* FIXME: can we save some information here? */ audit_log_format(ab, ""); } else audit_log_untrustedstring(ab, p); - kfree(pathname); + kfree(path); } /** diff --git a/trunk/kernel/audit_tree.c b/trunk/kernel/audit_tree.c index 9ef5e0aacc3c..f4fcf58f20f8 100644 --- a/trunk/kernel/audit_tree.c +++ b/trunk/kernel/audit_tree.c @@ -549,8 +549,8 @@ void audit_trim_trees(void) if (err) goto skip_it; - root_mnt = collect_mounts(nd.path.mnt, nd.path.dentry); - path_put(&nd.path); + root_mnt = collect_mounts(nd.mnt, nd.dentry); + path_release(&nd); if (!root_mnt) goto skip_it; @@ -583,17 +583,17 @@ void audit_trim_trees(void) static int is_under(struct vfsmount *mnt, struct dentry *dentry, struct nameidata *nd) { - if (mnt != nd->path.mnt) { + if (mnt != nd->mnt) { for (;;) { if (mnt->mnt_parent == mnt) return 0; - if (mnt->mnt_parent == nd->path.mnt) + if (mnt->mnt_parent == nd->mnt) break; mnt = mnt->mnt_parent; } dentry = mnt->mnt_mountpoint; } - return is_subdir(dentry, nd->path.dentry); + return is_subdir(dentry, nd->dentry); } int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op) @@ -641,8 +641,8 @@ int audit_add_tree_rule(struct audit_krule *rule) err = path_lookup(tree->pathname, 0, &nd); if (err) goto Err; - mnt = collect_mounts(nd.path.mnt, nd.path.dentry); - path_put(&nd.path); + mnt = collect_mounts(nd.mnt, nd.dentry); + path_release(&nd); if (!mnt) { err = -ENOMEM; goto Err; @@ -701,8 +701,8 @@ int audit_tag_tree(char *old, char *new) err = path_lookup(new, 0, &nd); if (err) return err; - tagged = collect_mounts(nd.path.mnt, nd.path.dentry); - path_put(&nd.path); + tagged = collect_mounts(nd.mnt, nd.dentry); + path_release(&nd); if (!tagged) return -ENOMEM; @@ -711,9 +711,9 @@ int audit_tag_tree(char *old, char *new) drop_collected_mounts(tagged); return err; } - mnt = mntget(nd.path.mnt); - dentry = dget(nd.path.dentry); - path_put(&nd.path); + mnt = mntget(nd.mnt); + dentry = dget(nd.dentry); + path_release(&nd); if (dentry == tagged->mnt_root && dentry == mnt->mnt_root) follow_up(&mnt, &dentry); @@ -744,13 +744,13 @@ int audit_tag_tree(char *old, char *new) spin_lock(&vfsmount_lock); if (!is_under(mnt, dentry, &nd)) { spin_unlock(&vfsmount_lock); - path_put(&nd.path); + path_release(&nd); put_tree(tree); mutex_lock(&audit_filter_mutex); continue; } spin_unlock(&vfsmount_lock); - path_put(&nd.path); + path_release(&nd); list_for_each_entry(p, &list, mnt_list) { failed = tag_chunk(p->mnt_root->d_inode, tree); diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index 2f2914b7cc30..6f19fd477aac 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -169,8 +169,8 @@ static struct audit_parent *audit_init_parent(struct nameidata *ndp) inotify_init_watch(&parent->wdata); /* grab a ref so inotify watch hangs around until we take audit_filter_mutex */ get_inotify_watch(&parent->wdata); - wd = inotify_add_watch(audit_ih, &parent->wdata, - ndp->path.dentry->d_inode, AUDIT_IN_WATCH); + wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->dentry->d_inode, + AUDIT_IN_WATCH); if (wd < 0) { audit_free_parent(&parent->wdata); return ERR_PTR(wd); @@ -1161,11 +1161,11 @@ static int audit_get_nd(char *path, struct nameidata **ndp, static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw) { if (ndp) { - path_put(&ndp->path); + path_release(ndp); kfree(ndp); } if (ndw) { - path_put(&ndw->path); + path_release(ndw); kfree(ndw); } } @@ -1214,8 +1214,8 @@ static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, /* update watch filter fields */ if (ndw) { - watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev; - watch->ino = ndw->path.dentry->d_inode->i_ino; + watch->dev = ndw->dentry->d_inode->i_sb->s_dev; + watch->ino = ndw->dentry->d_inode->i_ino; } /* The audit_filter_mutex must not be held during inotify calls because @@ -1225,8 +1225,7 @@ static int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp, */ mutex_unlock(&audit_filter_mutex); - if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode, - &i_watch) < 0) { + if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) { parent = audit_init_parent(ndp); if (IS_ERR(parent)) { /* caller expects mutex locked */ diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index ac6d9b23b018..1c06ecf38d7b 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -208,7 +208,8 @@ struct audit_context { int name_count; struct audit_names names[AUDIT_NAMES]; char * filterkey; /* key for rule that triggered record */ - struct path pwd; + struct dentry * pwd; + struct vfsmount * pwdmnt; struct audit_context *previous; /* For nested syscalls */ struct audit_aux_data *aux; struct audit_aux_data *aux_pids; @@ -785,9 +786,12 @@ static inline void audit_free_names(struct audit_context *context) __putname(context->names[i].name); } context->name_count = 0; - path_put(&context->pwd); - context->pwd.dentry = NULL; - context->pwd.mnt = NULL; + if (context->pwd) + dput(context->pwd); + if (context->pwdmnt) + mntput(context->pwdmnt); + context->pwd = NULL; + context->pwdmnt = NULL; } static inline void audit_free_aux(struct audit_context *context) @@ -926,7 +930,8 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { audit_log_d_path(ab, "exe=", - &vma->vm_file->f_path); + vma->vm_file->f_path.dentry, + vma->vm_file->f_path.mnt); break; } vma = vma->vm_next; @@ -1336,10 +1341,10 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts context->target_sid, context->target_comm)) call_panic = 1; - if (context->pwd.dentry && context->pwd.mnt) { + if (context->pwd && context->pwdmnt) { ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); if (ab) { - audit_log_d_path(ab, "cwd=", &context->pwd); + audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt); audit_log_end(ab); } } @@ -1362,7 +1367,8 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts case 0: /* name was specified as a relative path and the * directory component is the cwd */ - audit_log_d_path(ab, " name=", &context->pwd); + audit_log_d_path(ab, " name=", context->pwd, + context->pwdmnt); break; default: /* log the name's directory component */ @@ -1689,10 +1695,10 @@ void __audit_getname(const char *name) context->names[context->name_count].ino = (unsigned long)-1; context->names[context->name_count].osid = 0; ++context->name_count; - if (!context->pwd.dentry) { + if (!context->pwd) { read_lock(¤t->fs->lock); - context->pwd = current->fs->pwd; - path_get(¤t->fs->pwd); + context->pwd = dget(current->fs->pwd); + context->pwdmnt = mntget(current->fs->pwdmnt); read_unlock(¤t->fs->lock); } diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 506a957b665a..3b893e78ce61 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -512,10 +512,14 @@ static void __put_fs_struct(struct fs_struct *fs) { /* No need to hold fs->lock if we are killing it */ if (atomic_dec_and_test(&fs->count)) { - path_put(&fs->root); - path_put(&fs->pwd); - if (fs->altroot.dentry) - path_put(&fs->altroot); + dput(fs->root); + mntput(fs->rootmnt); + dput(fs->pwd); + mntput(fs->pwdmnt); + if (fs->altroot) { + dput(fs->altroot); + mntput(fs->altrootmnt); + } kmem_cache_free(fs_cachep, fs); } } diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index dd249c37b3a3..4363a4eb84e3 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -600,16 +600,16 @@ static struct fs_struct *__copy_fs_struct(struct fs_struct *old) rwlock_init(&fs->lock); fs->umask = old->umask; read_lock(&old->lock); - fs->root = old->root; - path_get(&old->root); - fs->pwd = old->pwd; - path_get(&old->pwd); - if (old->altroot.dentry) { - fs->altroot = old->altroot; - path_get(&old->altroot); + fs->rootmnt = mntget(old->rootmnt); + fs->root = dget(old->root); + fs->pwdmnt = mntget(old->pwdmnt); + fs->pwd = dget(old->pwd); + if (old->altroot) { + fs->altrootmnt = mntget(old->altrootmnt); + fs->altroot = dget(old->altroot); } else { - fs->altroot.mnt = NULL; - fs->altroot.dentry = NULL; + fs->altrootmnt = NULL; + fs->altroot = NULL; } read_unlock(&old->lock); } diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 221f2128a437..a6baaec44b8f 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -2116,7 +2116,7 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, t = timespec_to_ktime(ts); if (cmd == FUTEX_WAIT) - t = ktime_add_safe(ktime_get(), t); + t = ktime_add(ktime_get(), t); tp = &t; } /* diff --git a/trunk/kernel/futex_compat.c b/trunk/kernel/futex_compat.c index 7d5e4b016f39..133d558db452 100644 --- a/trunk/kernel/futex_compat.c +++ b/trunk/kernel/futex_compat.c @@ -176,7 +176,7 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, t = timespec_to_ktime(ts); if (cmd == FUTEX_WAIT) - t = ktime_add_safe(ktime_get(), t); + t = ktime_add(ktime_get(), t); tp = &t; } if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 98bee013f71f..3f4a57c7895d 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -325,23 +325,6 @@ u64 ktime_divns(const ktime_t kt, s64 div) } #endif /* BITS_PER_LONG >= 64 */ -/* - * Add two ktime values and do a safety check for overflow: - */ -ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) -{ - ktime_t res = ktime_add(lhs, rhs); - - /* - * We use KTIME_SEC_MAX here, the maximum timeout which we can - * return to user space in a timespec: - */ - if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64) - res = ktime_set(KTIME_SEC_MAX, 0); - - return res; -} - /* * Check, whether the timer is on the callback pending list */ @@ -442,8 +425,6 @@ static int hrtimer_reprogram(struct hrtimer *timer, ktime_t expires = ktime_sub(timer->expires, base->offset); int res; - WARN_ON_ONCE(timer->expires.tv64 < 0); - /* * When the callback is running, we do not reprogram the clock event * device. The timer callback is either running on a different CPU or @@ -454,15 +435,6 @@ static int hrtimer_reprogram(struct hrtimer *timer, if (hrtimer_callback_running(timer)) return 0; - /* - * CLOCK_REALTIME timer might be requested with an absolute - * expiry time which is less than base->offset. Nothing wrong - * about that, just avoid to call into the tick code, which - * has now objections against negative expiry values. - */ - if (expires.tv64 < 0) - return -ETIME; - if (expires.tv64 >= expires_next->tv64) return 0; @@ -710,7 +682,13 @@ u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval) */ orun++; } - timer->expires = ktime_add_safe(timer->expires, interval); + timer->expires = ktime_add(timer->expires, interval); + /* + * Make sure, that the result did not wrap with a very large + * interval. + */ + if (timer->expires.tv64 < 0) + timer->expires = ktime_set(KTIME_SEC_MAX, 0); return orun; } @@ -861,7 +839,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) new_base = switch_hrtimer_base(timer, base); if (mode == HRTIMER_MODE_REL) { - tim = ktime_add_safe(tim, new_base->get_time()); + tim = ktime_add(tim, new_base->get_time()); /* * CONFIG_TIME_LOW_RES is a temporary way for architectures * to signal that they simply return xtime in @@ -870,8 +848,16 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) * timeouts. This will go away with the GTOD framework. */ #ifdef CONFIG_TIME_LOW_RES - tim = ktime_add_safe(tim, base->resolution); + tim = ktime_add(tim, base->resolution); #endif + /* + * Careful here: User space might have asked for a + * very long sleep, so the add above might result in a + * negative number, which enqueues the timer in front + * of the queue. + */ + if (tim.tv64 < 0) + tim.tv64 = KTIME_MAX; } timer->expires = tim; diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 22be3ff3f363..bb7df2a28bd7 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -173,7 +173,10 @@ static int ____call_usermodehelper(void *data) */ set_user_nice(current, 0); - retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); + retval = -EPERM; + if (current->fs->root) + retval = kernel_execve(sub_info->path, + sub_info->argv, sub_info->envp); /* Exec failed? */ sub_info->retval = retval; diff --git a/trunk/kernel/posix-timers.c b/trunk/kernel/posix-timers.c index a9b04203a66d..022c9c3cee6f 100644 --- a/trunk/kernel/posix-timers.c +++ b/trunk/kernel/posix-timers.c @@ -767,11 +767,9 @@ common_timer_set(struct k_itimer *timr, int flags, /* SIGEV_NONE timers are not queued ! See common_timer_get */ if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { /* Setup correct expiry time for relative timers */ - if (mode == HRTIMER_MODE_REL) { - timer->expires = - ktime_add_safe(timer->expires, - timer->base->get_time()); - } + if (mode == HRTIMER_MODE_REL) + timer->expires = ktime_add(timer->expires, + timer->base->get_time()); return 0; } diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index ce3c9e4492d8..717aa0e3be2d 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -2711,13 +2711,6 @@ void print_vma_addr(char *prefix, unsigned long ip) struct mm_struct *mm = current->mm; struct vm_area_struct *vma; - /* - * Do not print if we are in atomic - * contexts (in exception stacks, etc.): - */ - if (preempt_count()) - return; - down_read(&mm->mmap_sem); vma = find_vma(mm, ip); if (vma && vma->vm_file) { @@ -2726,7 +2719,7 @@ void print_vma_addr(char *prefix, unsigned long ip) if (buf) { char *p, *s; - p = d_path(&f->f_path, buf, PAGE_SIZE); + p = d_path(f->f_dentry, f->f_vfsmnt, buf, PAGE_SIZE); if (IS_ERR(p)) p = "?"; s = strrchr(p, '/'); diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index 6c7ba1a63d23..8d246c3b340f 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -1996,7 +1996,7 @@ int show_numa_map(struct seq_file *m, void *v) if (file) { seq_printf(m, " file="); - seq_path(m, &file->f_path, "\n\t= "); + seq_path(m, file->f_path.mnt, file->f_path.dentry, "\n\t= "); } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { seq_printf(m, " heap"); } else if (vma->vm_start <= mm->start_stack && diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 473e6c2eaefb..40c00dacbe4b 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -2630,7 +2630,6 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, slabp->colouroff = colour_off; slabp->s_mem = objp + colour_off; slabp->nodeid = nodeid; - slabp->free = 0; return slabp; } @@ -2684,6 +2683,7 @@ static void cache_init_objs(struct kmem_cache *cachep, slab_bufctl(slabp)[i] = i + 1; } slab_bufctl(slabp)[i - 1] = BUFCTL_END; + slabp->free = 0; } static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags) @@ -2816,6 +2816,7 @@ static int cache_grow(struct kmem_cache *cachep, if (!slabp) goto opps1; + slabp->nodeid = nodeid; slab_map_pages(cachep, slabp, objp); cache_init_objs(cachep, slabp); diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 4b3895cb90ee..e2989ae243b5 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -211,8 +211,6 @@ static inline void ClearSlabDebug(struct page *page) /* Internal SLUB flags */ #define __OBJECT_POISON 0x80000000 /* Poison object */ #define __SYSFS_ADD_DEFERRED 0x40000000 /* Not yet visible via sysfs */ -#define __KMALLOC_CACHE 0x20000000 /* objects freed using kfree */ -#define __PAGE_ALLOC_FALLBACK 0x10000000 /* Allow fallback to page alloc */ /* Not all arches define cache_line_size */ #ifndef cache_line_size @@ -310,7 +308,7 @@ static inline int is_end(void *addr) return (unsigned long)addr & PAGE_MAPPING_ANON; } -static void *slab_address(struct page *page) +void *slab_address(struct page *page) { return page->end - PAGE_MAPPING_ANON; } @@ -1080,7 +1078,14 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) struct page *page; int pages = 1 << s->order; - flags |= s->allocflags; + if (s->order) + flags |= __GFP_COMP; + + if (s->flags & SLAB_CACHE_DMA) + flags |= SLUB_DMA; + + if (s->flags & SLAB_RECLAIM_ACCOUNT) + flags |= __GFP_RECLAIMABLE; if (node == -1) page = alloc_pages(flags, s->order); @@ -1541,6 +1546,7 @@ static void *__slab_alloc(struct kmem_cache *s, unlock_out: slab_unlock(c->page); stat(c, ALLOC_SLOWPATH); +out: #ifdef SLUB_FASTPATH local_irq_restore(flags); #endif @@ -1575,24 +1581,8 @@ static void *__slab_alloc(struct kmem_cache *s, c->page = new; goto load_freelist; } -#ifdef SLUB_FASTPATH - local_irq_restore(flags); -#endif - /* - * No memory available. - * - * If the slab uses higher order allocs but the object is - * smaller than a page size then we can fallback in emergencies - * to the page allocator via kmalloc_large. The page allocator may - * have failed to obtain a higher order page and we can try to - * allocate a single page if the object fits into a single page. - * That is only possible if certain conditions are met that are being - * checked when a slab is created. - */ - if (!(gfpflags & __GFP_NORETRY) && (s->flags & __PAGE_ALLOC_FALLBACK)) - return kmalloc_large(s->objsize, gfpflags); - - return NULL; + object = NULL; + goto out; debug: object = c->page->freelist; if (!alloc_debug_processing(s, c->page, object, addr)) @@ -2339,33 +2329,10 @@ static int calculate_sizes(struct kmem_cache *s) size = ALIGN(size, align); s->size = size; - if ((flags & __KMALLOC_CACHE) && - PAGE_SIZE / size < slub_min_objects) { - /* - * Kmalloc cache that would not have enough objects in - * an order 0 page. Kmalloc slabs can fallback to - * page allocator order 0 allocs so take a reasonably large - * order that will allows us a good number of objects. - */ - s->order = max(slub_max_order, PAGE_ALLOC_COSTLY_ORDER); - s->flags |= __PAGE_ALLOC_FALLBACK; - s->allocflags |= __GFP_NOWARN; - } else - s->order = calculate_order(size); - + s->order = calculate_order(size); if (s->order < 0) return 0; - s->allocflags = 0; - if (s->order) - s->allocflags |= __GFP_COMP; - - if (s->flags & SLAB_CACHE_DMA) - s->allocflags |= SLUB_DMA; - - if (s->flags & SLAB_RECLAIM_ACCOUNT) - s->allocflags |= __GFP_RECLAIMABLE; - /* * Determine the number of objects per slab */ @@ -2517,11 +2484,11 @@ EXPORT_SYMBOL(kmem_cache_destroy); * Kmalloc subsystem *******************************************************************/ -struct kmem_cache kmalloc_caches[PAGE_SHIFT + 1] __cacheline_aligned; +struct kmem_cache kmalloc_caches[PAGE_SHIFT] __cacheline_aligned; EXPORT_SYMBOL(kmalloc_caches); #ifdef CONFIG_ZONE_DMA -static struct kmem_cache *kmalloc_caches_dma[PAGE_SHIFT + 1]; +static struct kmem_cache *kmalloc_caches_dma[PAGE_SHIFT]; #endif static int __init setup_slub_min_order(char *str) @@ -2569,7 +2536,7 @@ static struct kmem_cache *create_kmalloc_cache(struct kmem_cache *s, down_write(&slub_lock); if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN, - flags | __KMALLOC_CACHE, NULL)) + flags, NULL)) goto panic; list_add(&s->list, &slab_caches); @@ -2703,8 +2670,9 @@ void *__kmalloc(size_t size, gfp_t flags) { struct kmem_cache *s; - if (unlikely(size > PAGE_SIZE)) - return kmalloc_large(size, flags); + if (unlikely(size > PAGE_SIZE / 2)) + return (void *)__get_free_pages(flags | __GFP_COMP, + get_order(size)); s = get_slab(size, flags); @@ -2720,8 +2688,9 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node) { struct kmem_cache *s; - if (unlikely(size > PAGE_SIZE)) - return kmalloc_large(size, flags); + if (unlikely(size > PAGE_SIZE / 2)) + return (void *)__get_free_pages(flags | __GFP_COMP, + get_order(size)); s = get_slab(size, flags); @@ -3032,7 +3001,7 @@ void __init kmem_cache_init(void) caches++; } - for (i = KMALLOC_SHIFT_LOW; i <= PAGE_SHIFT; i++) { + for (i = KMALLOC_SHIFT_LOW; i < PAGE_SHIFT; i++) { create_kmalloc_cache(&kmalloc_caches[i], "kmalloc", 1 << i, GFP_KERNEL); caches++; @@ -3059,7 +3028,7 @@ void __init kmem_cache_init(void) slab_state = UP; /* Provide the correct kmalloc names now that the caches are up */ - for (i = KMALLOC_SHIFT_LOW; i <= PAGE_SHIFT; i++) + for (i = KMALLOC_SHIFT_LOW; i < PAGE_SHIFT; i++) kmalloc_caches[i]. name = kasprintf(GFP_KERNEL, "kmalloc-%d", 1 << i); @@ -3088,9 +3057,6 @@ static int slab_unmergeable(struct kmem_cache *s) if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE)) return 1; - if ((s->flags & __PAGE_ALLOC_FALLBACK)) - return 1; - if (s->ctor) return 1; @@ -3252,9 +3218,9 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller) { struct kmem_cache *s; - if (unlikely(size > PAGE_SIZE)) - return kmalloc_large(size, gfpflags); - + if (unlikely(size > PAGE_SIZE / 2)) + return (void *)__get_free_pages(gfpflags | __GFP_COMP, + get_order(size)); s = get_slab(size, gfpflags); if (unlikely(ZERO_OR_NULL_PTR(s))) @@ -3268,9 +3234,9 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, { struct kmem_cache *s; - if (unlikely(size > PAGE_SIZE)) - return kmalloc_large(size, gfpflags); - + if (unlikely(size > PAGE_SIZE / 2)) + return (void *)__get_free_pages(gfpflags | __GFP_COMP, + get_order(size)); s = get_slab(size, gfpflags); if (unlikely(ZERO_OR_NULL_PTR(s))) diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index 2da149cfc9ac..02ccab5ad9d9 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -1394,7 +1394,7 @@ static int swap_show(struct seq_file *swap, void *v) } file = ptr->swap_file; - len = seq_path(swap, &file->f_path, " \t\n\\"); + len = seq_path(swap, file->f_path.mnt, file->f_path.dentry, " \t\n\\"); seq_printf(swap, "%*s%s\t%u\t%u\t%d\n", len < 40 ? 40 - len : 1, " ", S_ISBLK(file->f_path.dentry->d_inode->i_mode) ? diff --git a/trunk/net/ax25/af_ax25.c b/trunk/net/ax25/af_ax25.c index 48bfcc741f25..8fc64e3150a2 100644 --- a/trunk/net/ax25/af_ax25.c +++ b/trunk/net/ax25/af_ax25.c @@ -510,7 +510,11 @@ ax25_cb *ax25_create_cb(void) skb_queue_head_init(&ax25->ack_queue); skb_queue_head_init(&ax25->reseq_queue); - ax25_setup_timers(ax25); + init_timer(&ax25->timer); + init_timer(&ax25->t1timer); + init_timer(&ax25->t2timer); + init_timer(&ax25->t3timer); + init_timer(&ax25->idletimer); ax25_fillin_cb(ax25, NULL); @@ -1924,10 +1928,12 @@ static int ax25_info_show(struct seq_file *seq, void *v) ax25->paclen); if (ax25->sk != NULL) { - seq_printf(seq, " %d %d %lu\n", + bh_lock_sock(ax25->sk); + seq_printf(seq," %d %d %ld\n", atomic_read(&ax25->sk->sk_wmem_alloc), atomic_read(&ax25->sk->sk_rmem_alloc), - sock_i_ino(ax25->sk)); + ax25->sk->sk_socket != NULL ? SOCK_INODE(ax25->sk->sk_socket)->i_ino : 0L); + bh_unlock_sock(ax25->sk); } else { seq_puts(seq, " * * *\n"); } diff --git a/trunk/net/ax25/ax25_dev.c b/trunk/net/ax25/ax25_dev.c index a7a0e0c9698b..528c874d9828 100644 --- a/trunk/net/ax25/ax25_dev.c +++ b/trunk/net/ax25/ax25_dev.c @@ -82,7 +82,7 @@ void ax25_dev_device_up(struct net_device *dev) ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT; #if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER) - ax25_ds_setup_timer(ax25_dev); + init_timer(&ax25_dev->dama.slave_timer); #endif spin_lock_bh(&ax25_dev_lock); diff --git a/trunk/net/ax25/ax25_ds_timer.c b/trunk/net/ax25/ax25_ds_timer.c index 2ce79df00680..c4e3b025d21c 100644 --- a/trunk/net/ax25/ax25_ds_timer.c +++ b/trunk/net/ax25/ax25_ds_timer.c @@ -40,10 +40,13 @@ static void ax25_ds_timeout(unsigned long); * 1/10th of a second. */ -void ax25_ds_setup_timer(ax25_dev *ax25_dev) +static void ax25_ds_add_timer(ax25_dev *ax25_dev) { - setup_timer(&ax25_dev->dama.slave_timer, ax25_ds_timeout, - (unsigned long)ax25_dev); + struct timer_list *t = &ax25_dev->dama.slave_timer; + t->data = (unsigned long) ax25_dev; + t->function = &ax25_ds_timeout; + t->expires = jiffies + HZ; + add_timer(t); } void ax25_ds_del_timer(ax25_dev *ax25_dev) @@ -57,9 +60,10 @@ void ax25_ds_set_timer(ax25_dev *ax25_dev) if (ax25_dev == NULL) /* paranoia */ return; + del_timer(&ax25_dev->dama.slave_timer); ax25_dev->dama.slave_timeout = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10; - mod_timer(&ax25_dev->dama.slave_timer, jiffies + HZ); + ax25_ds_add_timer(ax25_dev); } /* diff --git a/trunk/net/ax25/ax25_route.c b/trunk/net/ax25/ax25_route.c index 8672cd84fdf9..38c7f3087ec3 100644 --- a/trunk/net/ax25/ax25_route.c +++ b/trunk/net/ax25/ax25_route.c @@ -45,7 +45,7 @@ void ax25_rt_device_down(struct net_device *dev) { ax25_route *s, *t, *ax25_rt; - write_lock_bh(&ax25_route_lock); + write_lock(&ax25_route_lock); ax25_rt = ax25_route_list; while (ax25_rt != NULL) { s = ax25_rt; @@ -68,7 +68,7 @@ void ax25_rt_device_down(struct net_device *dev) } } } - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); } static int __must_check ax25_rt_add(struct ax25_routes_struct *route) @@ -82,7 +82,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) if (route->digi_count > AX25_MAX_DIGIS) return -EINVAL; - write_lock_bh(&ax25_route_lock); + write_lock(&ax25_route_lock); ax25_rt = ax25_route_list; while (ax25_rt != NULL) { @@ -92,7 +92,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) ax25_rt->digipeat = NULL; if (route->digi_count != 0) { if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); return -ENOMEM; } ax25_rt->digipeat->lastrepeat = -1; @@ -102,14 +102,14 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) ax25_rt->digipeat->calls[i] = route->digi_addr[i]; } } - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); return 0; } ax25_rt = ax25_rt->next; } if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) { - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); return -ENOMEM; } @@ -120,7 +120,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) ax25_rt->ip_mode = ' '; if (route->digi_count != 0) { if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); kfree(ax25_rt); return -ENOMEM; } @@ -133,7 +133,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) } ax25_rt->next = ax25_route_list; ax25_route_list = ax25_rt; - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); return 0; } @@ -152,7 +152,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route) if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL) return -EINVAL; - write_lock_bh(&ax25_route_lock); + write_lock(&ax25_route_lock); ax25_rt = ax25_route_list; while (ax25_rt != NULL) { @@ -174,7 +174,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route) } } } - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); return 0; } @@ -188,7 +188,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option) if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL) return -EINVAL; - write_lock_bh(&ax25_route_lock); + write_lock(&ax25_route_lock); ax25_rt = ax25_route_list; while (ax25_rt != NULL) { @@ -216,7 +216,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option) } out: - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); return err; } @@ -492,7 +492,7 @@ void __exit ax25_rt_free(void) { ax25_route *s, *ax25_rt = ax25_route_list; - write_lock_bh(&ax25_route_lock); + write_lock(&ax25_route_lock); while (ax25_rt != NULL) { s = ax25_rt; ax25_rt = ax25_rt->next; @@ -500,5 +500,5 @@ void __exit ax25_rt_free(void) kfree(s->digipeat); kfree(s); } - write_unlock_bh(&ax25_route_lock); + write_unlock(&ax25_route_lock); } diff --git a/trunk/net/ax25/ax25_timer.c b/trunk/net/ax25/ax25_timer.c index db29ea71e80a..72594867fab6 100644 --- a/trunk/net/ax25/ax25_timer.c +++ b/trunk/net/ax25/ax25_timer.c @@ -40,45 +40,63 @@ static void ax25_t2timer_expiry(unsigned long); static void ax25_t3timer_expiry(unsigned long); static void ax25_idletimer_expiry(unsigned long); -void ax25_setup_timers(ax25_cb *ax25) -{ - setup_timer(&ax25->timer, ax25_heartbeat_expiry, (unsigned long)ax25); - setup_timer(&ax25->t1timer, ax25_t1timer_expiry, (unsigned long)ax25); - setup_timer(&ax25->t2timer, ax25_t2timer_expiry, (unsigned long)ax25); - setup_timer(&ax25->t3timer, ax25_t3timer_expiry, (unsigned long)ax25); - setup_timer(&ax25->idletimer, ax25_idletimer_expiry, - (unsigned long)ax25); -} - void ax25_start_heartbeat(ax25_cb *ax25) { - mod_timer(&ax25->timer, jiffies + 5 * HZ); + del_timer(&ax25->timer); + + ax25->timer.data = (unsigned long)ax25; + ax25->timer.function = &ax25_heartbeat_expiry; + ax25->timer.expires = jiffies + 5 * HZ; + + add_timer(&ax25->timer); } void ax25_start_t1timer(ax25_cb *ax25) { - mod_timer(&ax25->t1timer, jiffies + ax25->t1); + del_timer(&ax25->t1timer); + + ax25->t1timer.data = (unsigned long)ax25; + ax25->t1timer.function = &ax25_t1timer_expiry; + ax25->t1timer.expires = jiffies + ax25->t1; + + add_timer(&ax25->t1timer); } void ax25_start_t2timer(ax25_cb *ax25) { - mod_timer(&ax25->t2timer, jiffies + ax25->t2); + del_timer(&ax25->t2timer); + + ax25->t2timer.data = (unsigned long)ax25; + ax25->t2timer.function = &ax25_t2timer_expiry; + ax25->t2timer.expires = jiffies + ax25->t2; + + add_timer(&ax25->t2timer); } void ax25_start_t3timer(ax25_cb *ax25) { - if (ax25->t3 > 0) - mod_timer(&ax25->t3timer, jiffies + ax25->t3); - else - del_timer(&ax25->t3timer); + del_timer(&ax25->t3timer); + + if (ax25->t3 > 0) { + ax25->t3timer.data = (unsigned long)ax25; + ax25->t3timer.function = &ax25_t3timer_expiry; + ax25->t3timer.expires = jiffies + ax25->t3; + + add_timer(&ax25->t3timer); + } } void ax25_start_idletimer(ax25_cb *ax25) { - if (ax25->idle > 0) - mod_timer(&ax25->idletimer, jiffies + ax25->idle); - else - del_timer(&ax25->idletimer); + del_timer(&ax25->idletimer); + + if (ax25->idle > 0) { + ax25->idletimer.data = (unsigned long)ax25; + ax25->idletimer.function = &ax25_idletimer_expiry; + ax25->idletimer.expires = jiffies + ax25->idle; + + add_timer(&ax25->idletimer); + } } void ax25_stop_heartbeat(ax25_cb *ax25) diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 908f07c3bd7d..b3e19ae57f95 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1071,6 +1071,8 @@ int dev_close(struct net_device *dev) */ call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); + dev_deactivate(dev); + clear_bit(__LINK_STATE_START, &dev->state); /* Synchronize to scheduled poll. We cannot touch poll list, @@ -1081,8 +1083,6 @@ int dev_close(struct net_device *dev) */ smp_mb__after_clear_bit(); /* Commit netif_running(). */ - dev_deactivate(dev); - /* * Call the device specific close. This cannot fail. * Only if device is UP diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 7bb6a9a1256d..a16cf1ec5e5e 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -834,12 +834,18 @@ static void neigh_timer_handler(unsigned long arg) } if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { struct sk_buff *skb = skb_peek(&neigh->arp_queue); - + /* keep skb alive even if arp_queue overflows */ + if (skb) + skb_get(skb); + write_unlock(&neigh->lock); neigh->ops->solicit(neigh, skb); atomic_inc(&neigh->probes); - } + if (skb) + kfree_skb(skb); + } else { out: - write_unlock(&neigh->lock); + write_unlock(&neigh->lock); + } if (notify) neigh_update_notify(neigh); diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index ecb02afd52dc..61ac8d06292c 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -504,7 +504,7 @@ int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id, EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo); -static int set_operstate(struct net_device *dev, unsigned char transition, bool send_notification) +static void set_operstate(struct net_device *dev, unsigned char transition) { unsigned char operstate = dev->operstate; @@ -527,12 +527,8 @@ static int set_operstate(struct net_device *dev, unsigned char transition, bool write_lock_bh(&dev_base_lock); dev->operstate = operstate; write_unlock_bh(&dev_base_lock); - - if (send_notification) - netdev_state_change(dev); - return 1; - } else - return 0; + netdev_state_change(dev); + } } static void copy_rtnl_link_stats(struct rtnl_link_stats *a, @@ -826,7 +822,6 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, if (tb[IFLA_BROADCAST]) { nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); send_addr_notify = 1; - modified = 1; } if (ifm->ifi_flags || ifm->ifi_change) { @@ -839,23 +834,16 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, dev_change_flags(dev, flags); } - if (tb[IFLA_TXQLEN]) { - if (dev->tx_queue_len != nla_get_u32(tb[IFLA_TXQLEN])) { - dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); - modified = 1; - } - } + if (tb[IFLA_TXQLEN]) + dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); if (tb[IFLA_OPERSTATE]) - modified |= set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), false); + set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); if (tb[IFLA_LINKMODE]) { - if (dev->link_mode != nla_get_u8(tb[IFLA_LINKMODE])) { - write_lock_bh(&dev_base_lock); - dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); - write_lock_bh(&dev_base_lock); - modified = 1; - } + write_lock_bh(&dev_base_lock); + dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); + write_unlock_bh(&dev_base_lock); } err = 0; @@ -869,10 +857,6 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, if (send_addr_notify) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - - if (modified) - netdev_state_change(dev); - return err; } @@ -990,7 +974,7 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname, if (tb[IFLA_TXQLEN]) dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); if (tb[IFLA_OPERSTATE]) - set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]), true); + set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); if (tb[IFLA_LINKMODE]) dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 0d0fd28a9041..cfc07dac636c 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -2106,10 +2106,11 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, /** * skb_pull_rcsum - pull skb and update receive checksum * @skb: buffer to update + * @start: start of data before pull * @len: length of data pulled * * This function performs an skb_pull on the packet and updates - * the CHECKSUM_COMPLETE checksum. It should be used on + * update the CHECKSUM_COMPLETE checksum. It should be used on * receive path processing instead of skb_pull unless you know * that the checksum difference is zero (e.g., a valid IP header) * or you are setting ip_summed to CHECKSUM_NONE. diff --git a/trunk/net/ipv4/ah4.c b/trunk/net/ipv4/ah4.c index 8219b7e0968d..9d4555ec0b59 100644 --- a/trunk/net/ipv4/ah4.c +++ b/trunk/net/ipv4/ah4.c @@ -96,7 +96,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) ah->reserved = 0; ah->spi = x->id.spi; - ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); + ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq); spin_lock_bh(&x->lock); err = ah_mac_digest(ahp, skb, ah->auth_data); diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index c663fa5339ee..8e17f65f4002 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -368,6 +368,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) if (!(neigh->nud_state&NUD_VALID)) printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n"); dst_ha = neigh->ha; + read_lock_bh(&neigh->lock); } else if ((probes -= neigh->parms->app_probes) < 0) { #ifdef CONFIG_ARPD neigh_app_ns(neigh); @@ -377,6 +378,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, dst_ha, dev->dev_addr, NULL); + if (dst_ha) + read_unlock_bh(&neigh->lock); } static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) diff --git a/trunk/net/ipv4/esp4.c b/trunk/net/ipv4/esp4.c index 091e6709f831..258d17631b4b 100644 --- a/trunk/net/ipv4/esp4.c +++ b/trunk/net/ipv4/esp4.c @@ -199,7 +199,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) } esph->spi = x->id.spi; - esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); + esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); sg_init_table(sg, nfrags); skb_to_sgvec(skb, sg, @@ -210,8 +210,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) aead_givcrypt_set_callback(req, 0, esp_output_done, skb); aead_givcrypt_set_crypt(req, sg, sg, clen, iv); aead_givcrypt_set_assoc(req, asg, sizeof(*esph)); - aead_givcrypt_set_giv(req, esph->enc_data, - XFRM_SKB_CB(skb)->seq.output); + aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq); ESP_SKB_CB(skb)->tmp = tmp; err = crypto_aead_givencrypt(req); diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index 1ff446d0fa8b..f5fba3f71c06 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -1762,9 +1762,11 @@ static struct leaf *trie_leafindex(struct trie *t, int index) { struct leaf *l = trie_firstleaf(t); - while (l && index-- > 0) + while (index-- > 0) { l = trie_nextleaf(l); - + if (!l) + break; + } return l; } @@ -2459,84 +2461,6 @@ static const struct file_operations fib_trie_fops = { .release = seq_release_net, }; -struct fib_route_iter { - struct seq_net_private p; - struct trie *main_trie; - loff_t pos; - t_key key; -}; - -static struct leaf *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) -{ - struct leaf *l = NULL; - struct trie *t = iter->main_trie; - - /* use cache location of last found key */ - if (iter->pos > 0 && pos >= iter->pos && (l = fib_find_node(t, iter->key))) - pos -= iter->pos; - else { - iter->pos = 0; - l = trie_firstleaf(t); - } - - while (l && pos-- > 0) { - iter->pos++; - l = trie_nextleaf(l); - } - - if (l) - iter->key = pos; /* remember it */ - else - iter->pos = 0; /* forget it */ - - return l; -} - -static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(RCU) -{ - struct fib_route_iter *iter = seq->private; - struct fib_table *tb; - - rcu_read_lock(); - tb = fib_get_table(iter->p.net, RT_TABLE_MAIN); - if (!tb) - return NULL; - - iter->main_trie = (struct trie *) tb->tb_data; - if (*pos == 0) - return SEQ_START_TOKEN; - else - return fib_route_get_idx(iter, *pos - 1); -} - -static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct fib_route_iter *iter = seq->private; - struct leaf *l = v; - - ++*pos; - if (v == SEQ_START_TOKEN) { - iter->pos = 0; - l = trie_firstleaf(iter->main_trie); - } else { - iter->pos++; - l = trie_nextleaf(l); - } - - if (l) - iter->key = l->key; - else - iter->pos = 0; - return l; -} - -static void fib_route_seq_stop(struct seq_file *seq, void *v) - __releases(RCU) -{ - rcu_read_unlock(); -} - static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) { static unsigned type2flags[RTN_MAX + 1] = { @@ -2560,6 +2484,7 @@ static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) */ static int fib_route_seq_show(struct seq_file *seq, void *v) { + const struct fib_trie_iter *iter = seq->private; struct leaf *l = v; struct leaf_info *li; struct hlist_node *node; @@ -2571,6 +2496,12 @@ static int fib_route_seq_show(struct seq_file *seq, void *v) return 0; } + if (iter->trie == iter->trie_local) + return 0; + + if (IS_TNODE(l)) + return 0; + hlist_for_each_entry_rcu(li, node, &l->list, hlist) { struct fib_alias *fa; __be32 mask, prefix; @@ -2613,16 +2544,16 @@ static int fib_route_seq_show(struct seq_file *seq, void *v) } static const struct seq_operations fib_route_seq_ops = { - .start = fib_route_seq_start, - .next = fib_route_seq_next, - .stop = fib_route_seq_stop, + .start = fib_trie_seq_start, + .next = fib_trie_seq_next, + .stop = fib_trie_seq_stop, .show = fib_route_seq_show, }; static int fib_route_seq_open(struct inode *inode, struct file *file) { return seq_open_net(inode, file, &fib_route_seq_ops, - sizeof(struct fib_route_iter)); + sizeof(struct fib_trie_iter)); } static const struct file_operations fib_route_fops = { diff --git a/trunk/net/ipv4/inet_hashtables.c b/trunk/net/ipv4/inet_hashtables.c index 1aba606f6bbb..9cac6c034abd 100644 --- a/trunk/net/ipv4/inet_hashtables.c +++ b/trunk/net/ipv4/inet_hashtables.c @@ -120,6 +120,8 @@ void inet_listen_wlock(struct inet_hashinfo *hashinfo) } } +EXPORT_SYMBOL(inet_listen_wlock); + /* * Don't inline this cruft. Here are some nice properties to exploit here. The * BSD API does not allow a listening sock to specify the remote port nor the @@ -492,6 +494,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, return ret; } } +EXPORT_SYMBOL_GPL(__inet_hash_connect); /* * Bind a port for a connect operation and hash it. diff --git a/trunk/net/ipv4/ip_sockglue.c b/trunk/net/ipv4/ip_sockglue.c index de0572c88859..754b0a5bbfe9 100644 --- a/trunk/net/ipv4/ip_sockglue.c +++ b/trunk/net/ipv4/ip_sockglue.c @@ -514,6 +514,11 @@ static int do_ip_setsockopt(struct sock *sk, int level, val &= ~3; val |= inet->tos & 3; } + if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP && + !capable(CAP_NET_ADMIN)) { + err = -EPERM; + break; + } if (inet->tos != val) { inet->tos = val; sk->sk_priority = rt_tos2priority(val); diff --git a/trunk/net/ipv6/ah6.c b/trunk/net/ipv6/ah6.c index 2ff0c8233e47..379c8e04c36c 100644 --- a/trunk/net/ipv6/ah6.c +++ b/trunk/net/ipv6/ah6.c @@ -283,7 +283,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) ah->reserved = 0; ah->spi = x->id.spi; - ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); + ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq); spin_lock_bh(&x->lock); err = ah_mac_digest(ahp, skb, ah->auth_data); diff --git a/trunk/net/ipv6/esp6.c b/trunk/net/ipv6/esp6.c index 0ec1402320ea..8e0f1428c716 100644 --- a/trunk/net/ipv6/esp6.c +++ b/trunk/net/ipv6/esp6.c @@ -188,7 +188,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) *skb_mac_header(skb) = IPPROTO_ESP; esph->spi = x->id.spi; - esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); + esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); sg_init_table(sg, nfrags); skb_to_sgvec(skb, sg, @@ -199,8 +199,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) aead_givcrypt_set_callback(req, 0, esp_output_done, skb); aead_givcrypt_set_crypt(req, sg, sg, clen, iv); aead_givcrypt_set_assoc(req, asg, sizeof(*esph)); - aead_givcrypt_set_giv(req, esph->enc_data, - XFRM_SKB_CB(skb)->seq.output); + aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq); ESP_SKB_CB(skb)->tmp = tmp; err = crypto_aead_givencrypt(req); diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 8b67ca07467d..9ac6ca2521c3 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -621,7 +621,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) * or if the skb it not generated by a local socket. (This last * check should be redundant, but it's free.) */ - if (!skb->local_df) { + if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) { skb->dev = skb->dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); @@ -1420,10 +1420,6 @@ int ip6_push_pending_frames(struct sock *sk) tmp_skb->sk = NULL; } - /* Allow local fragmentation. */ - if (np->pmtudisc < IPV6_PMTUDISC_DO) - skb->local_df = 1; - ipv6_addr_copy(final_dst, &fl->fl6_dst); __skb_pull(skb, skb_network_header_len(skb)); if (opt && opt->opt_flen) diff --git a/trunk/net/ipv6/xfrm6_output.c b/trunk/net/ipv6/xfrm6_output.c index 79ccfb080733..b34c58c65656 100644 --- a/trunk/net/ipv6/xfrm6_output.c +++ b/trunk/net/ipv6/xfrm6_output.c @@ -36,7 +36,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb) if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; - if (!skb->local_df && skb->len > mtu) { + if (skb->len > mtu) { skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); ret = -EMSGSIZE; diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index 1c853927810a..b3ac85e808ac 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -2291,7 +2291,6 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h return 0; out: - xp->dead = 1; xfrm_policy_destroy(xp); return err; } diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 62567959b66e..202d7fa09483 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -945,7 +945,7 @@ static int tcp_packet(struct nf_conn *ct, ct->proto.tcp.state = new_state; if (old_state != new_state - && new_state == TCP_CONNTRACK_FIN_WAIT) + && new_state == TCP_CONNTRACK_CLOSE) ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; timeout = ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans && tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans diff --git a/trunk/net/netfilter/xt_SECMARK.c b/trunk/net/netfilter/xt_SECMARK.c index c0284856ccd4..7708e2084ce2 100644 --- a/trunk/net/netfilter/xt_SECMARK.c +++ b/trunk/net/netfilter/xt_SECMARK.c @@ -111,7 +111,7 @@ secmark_tg_check(const char *tablename, const void *entry, return true; } -static void secmark_tg_destroy(const struct xt_target *target, void *targinfo) +void secmark_tg_destroy(const struct xt_target *target, void *targinfo) { switch (mode) { case SECMARK_MODE_SEL: diff --git a/trunk/net/netlabel/netlabel_domainhash.c b/trunk/net/netlabel/netlabel_domainhash.c index fd462313471c..9a8ea0195c4f 100644 --- a/trunk/net/netlabel/netlabel_domainhash.c +++ b/trunk/net/netlabel/netlabel_domainhash.c @@ -150,11 +150,11 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) entry = netlbl_domhsh_search(domain); if (entry == NULL) { entry = rcu_dereference(netlbl_domhsh_def); - if (entry != NULL && !entry->valid) - entry = NULL; + if (entry != NULL && entry->valid) + return entry; } - return entry; + return NULL; } /* diff --git a/trunk/net/netlabel/netlabel_unlabeled.c b/trunk/net/netlabel/netlabel_unlabeled.c index 3e745b72fded..42e81fd8cc49 100644 --- a/trunk/net/netlabel/netlabel_unlabeled.c +++ b/trunk/net/netlabel/netlabel_unlabeled.c @@ -180,7 +180,6 @@ static void netlbl_unlabel_audit_addr4(struct audit_buffer *audit_buf, } } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) /** * netlbl_unlabel_audit_addr6 - Audit an IPv6 address * @audit_buf: audit buffer @@ -214,7 +213,6 @@ static void netlbl_unlabel_audit_addr6(struct audit_buffer *audit_buf, audit_log_format(audit_buf, " src_prefixlen=%d", mask_len); } } -#endif /* IPv6 */ /* * Unlabeled Connection Hash Table Functions @@ -619,6 +617,8 @@ static int netlbl_unlhsh_add(struct net *net, int ifindex; struct net_device *dev; struct netlbl_unlhsh_iface *iface; + struct in_addr *addr4, *mask4; + struct in6_addr *addr6, *mask6; struct audit_buffer *audit_buf = NULL; char *secctx = NULL; u32 secctx_len; @@ -651,9 +651,7 @@ static int netlbl_unlhsh_add(struct net *net, audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD, audit_info); switch (addr_len) { - case sizeof(struct in_addr): { - struct in_addr *addr4, *mask4; - + case sizeof(struct in_addr): addr4 = (struct in_addr *)addr; mask4 = (struct in_addr *)mask; ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); @@ -663,11 +661,8 @@ static int netlbl_unlhsh_add(struct net *net, addr4->s_addr, mask4->s_addr); break; - } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case sizeof(struct in6_addr): { - struct in6_addr *addr6, *mask6; - + case sizeof(struct in6_addr): addr6 = (struct in6_addr *)addr; mask6 = (struct in6_addr *)mask; ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); @@ -676,7 +671,6 @@ static int netlbl_unlhsh_add(struct net *net, dev_name, addr6, mask6); break; - } #endif /* IPv6 */ default: ret_val = -EINVAL; @@ -1747,6 +1741,10 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, u16 family, struct netlbl_lsm_secattr *secattr) { + struct iphdr *hdr4; + struct ipv6hdr *hdr6; + struct netlbl_unlhsh_addr4 *addr4; + struct netlbl_unlhsh_addr6 *addr6; struct netlbl_unlhsh_iface *iface; rcu_read_lock(); @@ -1754,29 +1752,21 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, if (iface == NULL) goto unlabel_getattr_nolabel; switch (family) { - case PF_INET: { - struct iphdr *hdr4; - struct netlbl_unlhsh_addr4 *addr4; - + case PF_INET: hdr4 = ip_hdr(skb); addr4 = netlbl_unlhsh_search_addr4(hdr4->saddr, iface); if (addr4 == NULL) goto unlabel_getattr_nolabel; secattr->attr.secid = addr4->secid; break; - } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case PF_INET6: { - struct ipv6hdr *hdr6; - struct netlbl_unlhsh_addr6 *addr6; - + case PF_INET6: hdr6 = ipv6_hdr(skb); addr6 = netlbl_unlhsh_search_addr6(&hdr6->saddr, iface); if (addr6 == NULL) goto unlabel_getattr_nolabel; secattr->attr.secid = addr6->secid; break; - } #endif /* IPv6 */ default: goto unlabel_getattr_nolabel; diff --git a/trunk/net/netlabel/netlabel_user.c b/trunk/net/netlabel/netlabel_user.c index 023fc8fe840d..85a96a3fddaa 100644 --- a/trunk/net/netlabel/netlabel_user.c +++ b/trunk/net/netlabel/netlabel_user.c @@ -96,6 +96,7 @@ int netlbl_netlink_init(void) struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { + struct audit_context *audit_ctx = current->audit_context; struct audit_buffer *audit_buf; char *secctx; u32 secctx_len; @@ -103,7 +104,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, if (audit_enabled == 0) return NULL; - audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type); + audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type); if (audit_buf == NULL) return NULL; diff --git a/trunk/net/netlink/genetlink.c b/trunk/net/netlink/genetlink.c index d16929c9b4bc..150579a21469 100644 --- a/trunk/net/netlink/genetlink.c +++ b/trunk/net/netlink/genetlink.c @@ -230,8 +230,10 @@ static void genl_unregister_mc_groups(struct genl_family *family) { struct genl_multicast_group *grp, *tmp; + genl_lock(); list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list) __genl_unregister_mc_group(family, grp); + genl_unlock(); } /** @@ -394,10 +396,10 @@ int genl_unregister_family(struct genl_family *family) { struct genl_family *rc; - genl_lock(); - genl_unregister_mc_groups(family); + genl_lock(); + list_for_each_entry(rc, genl_family_chain(family->id), family_list) { if (family->id != rc->id || strcmp(rc->name, family->name)) continue; diff --git a/trunk/net/socket.c b/trunk/net/socket.c index b6d35cd72a50..7651de008502 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -701,9 +701,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, { struct socket *sock = file->private_data; - if (unlikely(!sock->ops->splice_read)) - return -EINVAL; - return sock->ops->splice_read(sock, ppos, pipe, len, flags); } diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 1b395a41a8b2..0e3ead7e11b9 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -495,7 +495,7 @@ rpc_lookup_parent(char *path, struct nameidata *nd) static void rpc_release_path(struct nameidata *nd) { - path_put(&nd->path); + path_release(nd); rpc_put_mount(); } @@ -668,8 +668,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd) if ((error = rpc_lookup_parent(path, nd)) != 0) return ERR_PTR(error); - dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, nd->last.len, - 1); + dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len, 1); if (IS_ERR(dentry)) rpc_release_path(nd); return dentry; @@ -696,7 +695,7 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) dentry = rpc_lookup_negative(path, &nd); if (IS_ERR(dentry)) return dentry; - dir = nd.path.dentry->d_inode; + dir = nd.dentry->d_inode; if ((error = __rpc_mkdir(dir, dentry)) != 0) goto err_dput; RPC_I(dentry->d_inode)->private = rpc_client; diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index b8788fd5e3c6..eea75888805e 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -718,16 +718,16 @@ static struct sock *unix_find_other(struct net *net, goto put_fail; err = -ECONNREFUSED; - if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode)) + if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) goto put_fail; - u = unix_find_socket_byinode(net, nd.path.dentry->d_inode); + u=unix_find_socket_byinode(net, nd.dentry->d_inode); if (!u) goto put_fail; if (u->sk_type == type) - touch_atime(nd.path.mnt, nd.path.dentry); + touch_atime(nd.mnt, nd.dentry); - path_put(&nd.path); + path_release(&nd); err=-EPROTOTYPE; if (u->sk_type != type) { @@ -748,7 +748,7 @@ static struct sock *unix_find_other(struct net *net, return u; put_fail: - path_put(&nd.path); + path_release(&nd); fail: *error=err; return NULL; @@ -819,12 +819,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) */ mode = S_IFSOCK | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); - err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); + err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); if (err) goto out_mknod_dput; - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - dput(nd.path.dentry); - nd.path.dentry = dentry; + mutex_unlock(&nd.dentry->d_inode->i_mutex); + dput(nd.dentry); + nd.dentry = dentry; addr->hash = UNIX_HASH_SIZE; } @@ -842,8 +842,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) list = &unix_socket_table[addr->hash]; } else { list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; - u->dentry = nd.path.dentry; - u->mnt = nd.path.mnt; + u->dentry = nd.dentry; + u->mnt = nd.mnt; } err = 0; @@ -861,8 +861,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) out_mknod_dput: dput(dentry); out_mknod_unlock: - mutex_unlock(&nd.path.dentry->d_inode->i_mutex); - path_put(&nd.path); + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out_mknod_parent: if (err==-EEXIST) err=-EADDRINUSE; diff --git a/trunk/net/xfrm/Kconfig b/trunk/net/xfrm/Kconfig index 9201ef8ad90e..8f9dbec319be 100644 --- a/trunk/net/xfrm/Kconfig +++ b/trunk/net/xfrm/Kconfig @@ -38,7 +38,7 @@ config XFRM_MIGRATE config XFRM_STATISTICS bool "Transformation statistics (EXPERIMENTAL)" - depends on INET && XFRM && PROC_FS && EXPERIMENTAL + depends on XFRM && PROC_FS && EXPERIMENTAL ---help--- This statistics is not a SNMP/MIB specification but shows statistics about transformation error (or almost error) factor diff --git a/trunk/net/xfrm/xfrm_input.c b/trunk/net/xfrm/xfrm_input.c index 62188c6a06dd..4d6ebc633a94 100644 --- a/trunk/net/xfrm/xfrm_input.c +++ b/trunk/net/xfrm/xfrm_input.c @@ -109,7 +109,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) if (encap_type < 0) { async = 1; x = xfrm_input_state(skb); - seq = XFRM_SKB_CB(skb)->seq.input; + seq = XFRM_SKB_CB(skb)->seq; goto resume; } @@ -175,7 +175,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) spin_unlock(&x->lock); - XFRM_SKB_CB(skb)->seq.input = seq; + XFRM_SKB_CB(skb)->seq = seq; nexthdr = x->type->input(x, skb); diff --git a/trunk/net/xfrm/xfrm_output.c b/trunk/net/xfrm/xfrm_output.c index 569d377932c4..fc690368325f 100644 --- a/trunk/net/xfrm/xfrm_output.c +++ b/trunk/net/xfrm/xfrm_output.c @@ -62,7 +62,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) } if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { - XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq; + XFRM_SKB_CB(skb)->seq = ++x->replay.oseq; if (unlikely(x->replay.oseq == 0)) { XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR); x->replay.oseq--; diff --git a/trunk/net/xfrm/xfrm_user.c b/trunk/net/xfrm/xfrm_user.c index f971ca5645f8..78338079b7f5 100644 --- a/trunk/net/xfrm/xfrm_user.c +++ b/trunk/net/xfrm/xfrm_user.c @@ -1105,7 +1105,6 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, return xp; error: *errp = err; - xp->dead = 1; xfrm_policy_destroy(xp); return NULL; } diff --git a/trunk/scripts/kernel-doc b/trunk/scripts/kernel-doc index 26146cbaa504..6c18a14386a4 100755 --- a/trunk/scripts/kernel-doc +++ b/trunk/scripts/kernel-doc @@ -1624,6 +1624,7 @@ sub dump_function($$) { $prototype =~ s/^static +//; $prototype =~ s/^extern +//; + $prototype =~ s/^fastcall +//; $prototype =~ s/^asmlinkage +//; $prototype =~ s/^inline +//; $prototype =~ s/^__inline__ +//; diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index 187964e88af1..e8529e2f51e5 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -568,11 +568,10 @@ void avc_audit(u32 ssid, u32 tsid, audit_log_format(ab, " capability=%d", a->u.cap); break; case AVC_AUDIT_DATA_FS: - if (a->u.fs.path.dentry) { - struct dentry *dentry = a->u.fs.path.dentry; - if (a->u.fs.path.mnt) { - audit_log_d_path(ab, "path=", - &a->u.fs.path); + if (a->u.fs.dentry) { + struct dentry *dentry = a->u.fs.dentry; + if (a->u.fs.mnt) { + audit_log_d_path(ab, "path=", dentry, a->u.fs.mnt); } else { audit_log_format(ab, " name="); audit_log_untrustedstring(ab, dentry->d_name.name); @@ -627,12 +626,8 @@ void avc_audit(u32 ssid, u32 tsid, case AF_UNIX: u = unix_sk(sk); if (u->dentry) { - struct path path = { - .dentry = u->dentry, - .mnt = u->mnt - }; audit_log_d_path(ab, "path=", - &path); + u->dentry, u->mnt); break; } if (!u->addr) diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 75c2e99bfb81..44f16d9041e3 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -1356,8 +1356,8 @@ static inline int dentry_has_perm(struct task_struct *tsk, struct inode *inode = dentry->d_inode; struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.path.mnt = mnt; - ad.u.fs.path.dentry = dentry; + ad.u.fs.mnt = mnt; + ad.u.fs.dentry = dentry; return inode_has_perm(tsk, inode, av, &ad); } @@ -1375,12 +1375,15 @@ static int file_has_perm(struct task_struct *tsk, { struct task_security_struct *tsec = tsk->security; struct file_security_struct *fsec = file->f_security; - struct inode *inode = file->f_path.dentry->d_inode; + struct vfsmount *mnt = file->f_path.mnt; + struct dentry *dentry = file->f_path.dentry; + struct inode *inode = dentry->d_inode; struct avc_audit_data ad; int rc; AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path = file->f_path; + ad.u.fs.mnt = mnt; + ad.u.fs.dentry = dentry; if (tsec->sid != fsec->sid) { rc = avc_has_perm(tsec->sid, fsec->sid, @@ -1415,7 +1418,7 @@ static int may_create(struct inode *dir, sbsec = dir->i_sb->s_security; AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = dentry; + ad.u.fs.dentry = dentry; rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR, DIR__ADD_NAME | DIR__SEARCH, @@ -1473,7 +1476,7 @@ static int may_link(struct inode *dir, isec = dentry->d_inode->i_security; AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = dentry; + ad.u.fs.dentry = dentry; av = DIR__SEARCH; av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); @@ -1520,7 +1523,7 @@ static inline int may_rename(struct inode *old_dir, AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path.dentry = old_dentry; + ad.u.fs.dentry = old_dentry; rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR, DIR__REMOVE_NAME | DIR__SEARCH, &ad); if (rc) @@ -1536,7 +1539,7 @@ static inline int may_rename(struct inode *old_dir, return rc; } - ad.u.fs.path.dentry = new_dentry; + ad.u.fs.dentry = new_dentry; av = DIR__ADD_NAME | DIR__SEARCH; if (new_dentry->d_inode) av |= DIR__REMOVE_NAME; @@ -1915,7 +1918,8 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) } AVC_AUDIT_DATA_INIT(&ad, FS); - ad.u.fs.path = bprm->file->f_path; + ad.u.fs.mnt = bprm->file->f_path.mnt; + ad.u.fs.dentry = bprm->file->f_path.dentry; if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) newsid = tsec->sid; @@ -2311,7 +2315,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data) return rc; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.path.dentry = sb->s_root; + ad.u.fs.dentry = sb->s_root; return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); } @@ -2320,7 +2324,7 @@ static int selinux_sb_statfs(struct dentry *dentry) struct avc_audit_data ad; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.path.dentry = dentry->d_sb->s_root; + ad.u.fs.dentry = dentry->d_sb->s_root; return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad); } @@ -2337,10 +2341,10 @@ static int selinux_mount(char * dev_name, return rc; if (flags & MS_REMOUNT) - return superblock_has_perm(current, nd->path.mnt->mnt_sb, + return superblock_has_perm(current, nd->mnt->mnt_sb, FILESYSTEM__REMOUNT, NULL); else - return dentry_has_perm(current, nd->path.mnt, nd->path.dentry, + return dentry_has_perm(current, nd->mnt, nd->dentry, FILE__MOUNTON); } @@ -2583,7 +2587,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value return -EPERM; AVC_AUDIT_DATA_INIT(&ad,FS); - ad.u.fs.path.dentry = dentry; + ad.u.fs.dentry = dentry; rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, FILE__RELABELFROM, &ad); diff --git a/trunk/security/selinux/include/avc.h b/trunk/security/selinux/include/avc.h index 8e23d7a873a4..80c28fa6621c 100644 --- a/trunk/security/selinux/include/avc.h +++ b/trunk/security/selinux/include/avc.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "flask.h" #include "av_permissions.h" @@ -31,6 +30,8 @@ extern int selinux_enforcing; struct avc_entry; struct task_struct; +struct vfsmount; +struct dentry; struct inode; struct sock; struct sk_buff; @@ -45,7 +46,8 @@ struct avc_audit_data { struct task_struct *tsk; union { struct { - struct path path; + struct vfsmount *mnt; + struct dentry *dentry; struct inode *inode; } fs; struct { diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 2b5d6f72f678..5b690482f8cb 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -325,7 +325,7 @@ static int smack_sb_statfs(struct dentry *dentry) static int smack_sb_mount(char *dev_name, struct nameidata *nd, char *type, unsigned long flags, void *data) { - struct superblock_smack *sbp = nd->path.mnt->mnt_sb->s_security; + struct superblock_smack *sbp = nd->mnt->mnt_sb->s_security; return smk_curacc(sbp->smk_floor, MAY_WRITE); } diff --git a/trunk/sound/core/seq/seq_clientmgr.c b/trunk/sound/core/seq/seq_clientmgr.c index 47cfa5186e34..f97c1ba43a28 100644 --- a/trunk/sound/core/seq/seq_clientmgr.c +++ b/trunk/sound/core/seq/seq_clientmgr.c @@ -149,13 +149,13 @@ struct snd_seq_client *snd_seq_client_use_ptr(int clientid) } spin_unlock_irqrestore(&clients_lock, flags); #ifdef CONFIG_KMOD - if (!in_interrupt()) { + if (!in_interrupt() && current->fs->root) { static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS]; static char card_requested[SNDRV_CARDS]; if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) { int idx; - if (!client_requested[clientid]) { + if (! client_requested[clientid] && current->fs->root) { client_requested[clientid] = 1; for (idx = 0; idx < 15; idx++) { if (seq_client_load[idx] < 0) diff --git a/trunk/sound/core/seq/seq_device.c b/trunk/sound/core/seq/seq_device.c index 2f00ad28a2b7..155dc7da4722 100644 --- a/trunk/sound/core/seq/seq_device.c +++ b/trunk/sound/core/seq/seq_device.c @@ -149,6 +149,9 @@ void snd_seq_device_load_drivers(void) if (snd_seq_in_init) return; + if (! current->fs->root) + return; + mutex_lock(&ops_mutex); list_for_each_entry(ops, &opslist, list) { if (! (ops->driver & DRIVER_LOADED) && diff --git a/trunk/sound/core/sound.c b/trunk/sound/core/sound.c index 812f91b3de5b..00cca4d6e562 100644 --- a/trunk/sound/core/sound.c +++ b/trunk/sound/core/sound.c @@ -71,6 +71,8 @@ static DEFINE_MUTEX(sound_mutex); */ void snd_request_card(int card) { + if (! current->fs->root) + return; if (snd_card_locked(card)) return; if (card < 0 || card >= cards_limit) @@ -84,6 +86,8 @@ static void snd_request_other(int minor) { char *str; + if (! current->fs->root) + return; switch (minor) { case SNDRV_MINOR_SEQUENCER: str = "snd-seq"; break; case SNDRV_MINOR_TIMER: str = "snd-timer"; break; diff --git a/trunk/sound/core/timer.c b/trunk/sound/core/timer.c index 9d8184a2c2d0..aece465934b8 100644 --- a/trunk/sound/core/timer.c +++ b/trunk/sound/core/timer.c @@ -150,6 +150,8 @@ static struct snd_timer *snd_timer_find(struct snd_timer_id *tid) static void snd_timer_request(struct snd_timer_id *tid) { + if (! current->fs->root) + return; switch (tid->dev_class) { case SNDRV_TIMER_CLASS_GLOBAL: if (tid->device < timer_limit) diff --git a/trunk/sound/ppc/daca.c b/trunk/sound/ppc/daca.c index ca9452901a50..8432c16cd6ff 100644 --- a/trunk/sound/ppc/daca.c +++ b/trunk/sound/ppc/daca.c @@ -250,8 +250,9 @@ int __init snd_pmac_daca_init(struct snd_pmac *chip) struct pmac_daca *mix; #ifdef CONFIG_KMOD - request_module("i2c-powermac"); -#endif /* CONFIG_KMOD */ + if (current->fs->root) + request_module("i2c-powermac"); +#endif /* CONFIG_KMOD */ mix = kzalloc(sizeof(*mix), GFP_KERNEL); if (! mix) diff --git a/trunk/sound/ppc/tumbler.c b/trunk/sound/ppc/tumbler.c index 3f8d7164cef9..71a7a9765429 100644 --- a/trunk/sound/ppc/tumbler.c +++ b/trunk/sound/ppc/tumbler.c @@ -1351,8 +1351,9 @@ int __init snd_pmac_tumbler_init(struct snd_pmac *chip) char *chipname; #ifdef CONFIG_KMOD - request_module("i2c-powermac"); -#endif /* CONFIG_KMOD */ + if (current->fs->root) + request_module("i2c-powermac"); +#endif /* CONFIG_KMOD */ mix = kzalloc(sizeof(*mix), GFP_KERNEL); if (! mix)