aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/lguest/lguest.c17
-rw-r--r--Documentation/networking/00-INDEX10
-rw-r--r--Documentation/networking/Configurable34
-rw-r--r--Documentation/networking/comx.txt248
-rw-r--r--Documentation/networking/ncsa-telnet16
-rw-r--r--Documentation/networking/pt.txt58
-rw-r--r--Documentation/networking/routing.txt46
-rw-r--r--Documentation/networking/slicecom.hun371
-rw-r--r--Documentation/networking/slicecom.txt369
-rw-r--r--Documentation/powerpc/booting-without-of.txt275
-rw-r--r--MAINTAINERS17
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/mach-netx/xc.c6
-rw-r--r--arch/arm/mach-pxa/time.c23
-rw-r--r--arch/arm/plat-omap/fb.c2
-rw-r--r--arch/frv/mm/init.c2
-rw-r--r--arch/ia64/hp/sim/boot/fw-emu.c2
-rw-r--r--arch/ia64/ia32/ia32priv.h1
-rw-r--r--arch/ia64/kernel/.gitignore1
-rw-r--r--arch/ia64/kernel/acpi.c8
-rw-r--r--arch/ia64/kernel/efi.c5
-rw-r--r--arch/ia64/kernel/iosapic.c18
-rw-r--r--arch/ia64/kernel/irq.c6
-rw-r--r--arch/ia64/kernel/mca.c2
-rw-r--r--arch/ia64/kernel/palinfo.c91
-rw-r--r--arch/ia64/kernel/patch.c3
-rw-r--r--arch/ia64/kernel/perfmon.c4
-rw-r--r--arch/ia64/mm/contig.c74
-rw-r--r--arch/ia64/sn/kernel/irq.c8
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c12
-rw-r--r--arch/powerpc/boot/dts/walnut.dts4
-rwxr-xr-xarch/powerpc/boot/wrapper43
-rw-r--r--arch/powerpc/configs/pasemi_defconfig308
-rw-r--r--arch/powerpc/configs/ppc64_defconfig247
-rw-r--r--arch/powerpc/kernel/cputable.c36
-rw-r--r--arch/powerpc/kernel/entry_32.S23
-rw-r--r--arch/powerpc/kernel/head_64.S2
-rw-r--r--arch/powerpc/kernel/idle.c2
-rw-r--r--arch/powerpc/kernel/misc_32.S32
-rw-r--r--arch/powerpc/kernel/process.c2
-rw-r--r--arch/powerpc/kernel/prom.c12
-rw-r--r--arch/powerpc/kernel/prom_init.c2
-rw-r--r--arch/powerpc/kernel/setup_64.c19
-rw-r--r--arch/powerpc/kernel/swsusp_32.S2
-rw-r--r--arch/powerpc/kernel/time.c35
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S3
-rw-r--r--arch/powerpc/mm/40x_mmu.c17
-rw-r--r--arch/powerpc/mm/44x_mmu.c1
-rw-r--r--arch/powerpc/mm/fault.c2
-rw-r--r--arch/powerpc/mm/hash_low_64.S5
-rw-r--r--arch/powerpc/mm/hash_utils_64.c7
-rw-r--r--arch/powerpc/mm/mmu_decl.h4
-rw-r--r--arch/powerpc/mm/slb.c35
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c24
-rw-r--r--arch/powerpc/platforms/cell/smp.c1
-rw-r--r--arch/powerpc/platforms/celleb/setup.c1
-rw-r--r--arch/powerpc/platforms/iseries/irq.h4
-rw-r--r--arch/powerpc/platforms/iseries/setup.c4
-rw-r--r--arch/powerpc/platforms/iseries/vio.c10
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c13
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c18
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c1
-rw-r--r--arch/powerpc/platforms/pseries/msi.c6
-rw-r--r--arch/powerpc/sysdev/i8259.c1
-rw-r--r--arch/powerpc/sysdev/mv64x60_pci.c10
-rw-r--r--arch/ppc/kernel/entry.S23
-rw-r--r--arch/ppc/kernel/misc.S31
-rw-r--r--arch/ppc/mm/44x_mmu.c1
-rw-r--r--arch/ppc/mm/4xx_mmu.c17
-rw-r--r--arch/ppc/mm/fault.c2
-rw-r--r--arch/ppc/mm/mmu_decl.h4
-rw-r--r--arch/ppc/platforms/4xx/ebony.c2
-rw-r--r--arch/ppc/platforms/4xx/luan.c7
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c2
-rw-r--r--arch/ppc/platforms/4xx/taishan.c2
-rw-r--r--arch/ppc/syslib/i8259.c1
-rw-r--r--arch/ppc/syslib/m8260_setup.c13
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/vtime.c8
-rw-r--r--arch/sh/Kconfig10
-rw-r--r--arch/sh/Kconfig.debug3
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/irq.c1
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/setup.c19
-rw-r--r--arch/sh/boards/renesas/sh7710voipgw/setup.c1
-rw-r--r--arch/sh/boards/se/7206/irq.c1
-rw-r--r--arch/sh/boards/se/770x/setup.c1
-rw-r--r--arch/sh/boards/se/7722/setup.c8
-rw-r--r--arch/sh/boards/se/7780/setup.c8
-rw-r--r--arch/sh/boards/snapgear/Makefile3
-rw-r--r--arch/sh/boards/snapgear/rtc.c309
-rw-r--r--arch/sh/boards/snapgear/setup.c16
-rw-r--r--arch/sh/boot/Makefile2
-rw-r--r--arch/sh/cchips/hd6446x/Makefile2
-rw-r--r--arch/sh/cchips/voyagergx/Makefile1
-rw-r--r--arch/sh/drivers/pci/Makefile1
-rw-r--r--arch/sh/drivers/pci/pci-st40.c488
-rw-r--r--arch/sh/drivers/pci/pci-st40.h136
-rw-r--r--arch/sh/kernel/Makefile3
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S2
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c8
-rw-r--r--arch/sh/kernel/irq.c1
-rw-r--r--arch/sh/kernel/kgdb_stub.c9
-rw-r--r--arch/sh/kernel/setup.c1
-rw-r--r--arch/sh/kernel/sh_ksyms.c2
-rw-r--r--arch/sh/lib/Makefile2
-rw-r--r--arch/sh/mm/Kconfig21
-rw-r--r--arch/sh/mm/Makefile2
-rw-r--r--arch/sh/mm/clear_page.S45
-rw-r--r--arch/sh/mm/copy_page.S61
-rw-r--r--arch/sh/mm/pg-sh4.c75
-rw-r--r--arch/sh/oprofile/Makefile1
-rw-r--r--arch/sh64/kernel/process.c10
-rw-r--r--arch/sh64/kernel/traps.c5
-rw-r--r--arch/sparc/kernel/irq.c1
-rw-r--r--arch/sparc64/kernel/ds.c1
-rw-r--r--arch/sparc64/kernel/module.c1
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c1
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c1
-rw-r--r--arch/sparc64/kernel/time.c2
-rw-r--r--arch/x86/ia32/ia32entry.S19
-rw-r--r--arch/x86/ia32/ptrace32.c10
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c6
-rw-r--r--arch/x86/kernel/i387_64.c9
-rw-r--r--arch/x86/kernel/nmi_32.c4
-rw-r--r--block/cfq-iosched.c34
-rw-r--r--block/ll_rw_blk.c41
-rw-r--r--drivers/acpi/Kconfig1
-rw-r--r--drivers/ata/ata_piix.c7
-rw-r--r--drivers/ata/libata-acpi.c10
-rw-r--r--drivers/ata/libata-core.c78
-rw-r--r--drivers/ata/pata_platform.c35
-rw-r--r--drivers/ata/sata_nv.c2
-rw-r--r--drivers/ata/sata_qstor.c114
-rw-r--r--drivers/block/pktcdvd.c9
-rw-r--r--drivers/char/tty_ioctl.c170
-rw-r--r--drivers/firewire/fw-sbp2.c11
-rw-r--r--drivers/lguest/lguest_device.c3
-rw-r--r--drivers/macintosh/windfarm_core.c10
-rw-r--r--drivers/md/bitmap.c3
-rw-r--r--drivers/md/dm-table.c3
-rw-r--r--drivers/md/linear.c3
-rw-r--r--drivers/md/md.c4
-rw-r--r--drivers/md/multipath.c3
-rw-r--r--drivers/md/raid0.c3
-rw-r--r--drivers/md/raid1.c3
-rw-r--r--drivers/md/raid10.c3
-rw-r--r--drivers/md/raid5.c3
-rw-r--r--drivers/mmc/card/queue.c2
-rw-r--r--drivers/mmc/host/sdhci.c2
-rw-r--r--drivers/net/Kconfig9
-rw-r--r--drivers/net/bonding/bond_main.c1
-rw-r--r--drivers/net/bonding/bond_sysfs.c4
-rw-r--r--drivers/net/hamradio/6pack.c26
-rw-r--r--drivers/net/irda/irtty-sir.c7
-rw-r--r--drivers/net/pasemi_mac.c18
-rw-r--r--drivers/net/ppp_async.c10
-rw-r--r--drivers/net/ppp_synctty.c10
-rw-r--r--drivers/net/pppol2tp.c25
-rw-r--r--drivers/net/qla3xxx.c42
-rw-r--r--drivers/net/qla3xxx.h1
-rw-r--r--drivers/net/r8169.c26
-rw-r--r--drivers/net/rrunner.c18
-rw-r--r--drivers/net/sky2.c116
-rw-r--r--drivers/net/sky2.h3
-rw-r--r--drivers/net/slip.c8
-rw-r--r--drivers/net/smc91x.h15
-rw-r--r--drivers/net/usb/Kconfig9
-rw-r--r--drivers/net/usb/usbnet.c7
-rw-r--r--drivers/net/virtio_net.c3
-rw-r--r--drivers/net/wan/x25_asy.c6
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/b43/Kconfig10
-rw-r--r--drivers/net/wireless/b43/debugfs.c2
-rw-r--r--drivers/net/wireless/b43/main.c19
-rw-r--r--drivers/net/wireless/b43/pcmcia.c52
-rw-r--r--drivers/net/wireless/b43/rfkill.c115
-rw-r--r--drivers/net/wireless/b43/rfkill.h14
-rw-r--r--drivers/net/wireless/b43legacy/debugfs.c2
-rw-r--r--drivers/net/wireless/b43legacy/main.c21
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c6
-rw-r--r--drivers/net/wireless/ipw2100.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c2
-rw-r--r--drivers/net/wireless/libertas/cmd.c10
-rw-r--r--drivers/net/wireless/libertas/if_cs.c7
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c8
-rw-r--r--drivers/net/wireless/strip.c10
-rw-r--r--drivers/rtc/rtc-sh.c6
-rw-r--r--drivers/serial/sh-sci.h19
-rw-r--r--drivers/serial/uartlite.c10
-rw-r--r--drivers/sh/superhyway/superhyway.c7
-rw-r--r--drivers/ssb/main.c6
-rw-r--r--drivers/ssb/pcmcia.c56
-rw-r--r--drivers/video/cyber2000fb.c2
-rw-r--r--drivers/virtio/virtio_ring.c10
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/cifs/CHANGES11
-rw-r--r--fs/cifs/Makefile7
-rw-r--r--fs/cifs/asn1.c35
-rw-r--r--fs/cifs/cifs_spnego.c128
-rw-r--r--fs/cifs/cifs_spnego.h46
-rw-r--r--fs/cifs/cifsacl.c346
-rw-r--r--fs/cifs/cifsacl.h17
-rw-r--r--fs/cifs/cifsencrypt.c9
-rw-r--r--fs/cifs/cifsfs.c17
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifspdu.h40
-rw-r--r--fs/cifs/cifsproto.h11
-rw-r--r--fs/cifs/cifssmb.c64
-rw-r--r--fs/cifs/connect.c4
-rw-r--r--fs/cifs/dir.c2
-rw-r--r--fs/cifs/file.c31
-rw-r--r--fs/cifs/inode.c15
-rw-r--r--fs/cifs/md5.c8
-rw-r--r--fs/cifs/misc.c10
-rw-r--r--fs/cifs/netmisc.c54
-rw-r--r--fs/cifs/readdir.c10
-rw-r--r--fs/cifs/smbencrypt.c18
-rw-r--r--fs/cifs/xattr.c11
-rw-r--r--fs/dlm/lowcomms.c6
-rw-r--r--fs/exec.c6
-rw-r--r--fs/ioprio.c4
-rw-r--r--fs/ocfs2/alloc.c2
-rw-r--r--fs/ocfs2/aops.c22
-rw-r--r--fs/ocfs2/cluster/heartbeat.c2
-rw-r--r--fs/ocfs2/dcache.c2
-rw-r--r--fs/ocfs2/dir.c6
-rw-r--r--fs/ocfs2/dlmglue.c25
-rw-r--r--fs/ocfs2/file.c26
-rw-r--r--fs/ocfs2/namei.c13
-rw-r--r--fs/proc/proc_net.c7
-rw-r--r--include/asm-arm/hardware/iop3xx.h2
-rw-r--r--include/asm-arm/pgtable.h2
-rw-r--r--include/asm-frv/irq.h3
-rw-r--r--include/asm-ia64/pal.h5
-rw-r--r--include/asm-powerpc/pgtable-ppc32.h13
-rw-r--r--include/asm-powerpc/systbl.h2
-rw-r--r--include/asm-powerpc/time.h20
-rw-r--r--include/asm-powerpc/tlbflush.h12
-rw-r--r--include/asm-sh/cacheflush.h18
-rw-r--r--include/asm-sh/cpu-sh3/timer.h6
-rw-r--r--include/asm-sh/page.h11
-rw-r--r--include/asm-sh/pgtable.h4
-rw-r--r--include/asm-sh/processor.h2
-rw-r--r--include/asm-sh/ptrace.h3
-rw-r--r--include/asm-sh/vga.h6
-rw-r--r--include/asm-sh64/ptrace.h2
-rw-r--r--include/asm-sparc64/vio.h4
-rw-r--r--include/asm-x86/i387_64.h5
-rw-r--r--include/asm-x86/mach-voyager/setup_arch.h4
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/mroute.h12
-rw-r--r--include/linux/netfilter/Kbuild18
-rw-r--r--include/linux/netfilter_ipv4/Kbuild28
-rw-r--r--include/linux/netfilter_ipv6/Kbuild2
-rw-r--r--include/linux/netlink.h2
-rw-r--r--include/linux/proc_fs.h3
-rw-r--r--include/linux/sched.h17
-rw-r--r--include/linux/skbuff.h4
-rw-r--r--include/linux/smp.h7
-rw-r--r--include/linux/tty.h4
-rw-r--r--include/linux/virtio_ring.h21
-rw-r--r--include/net/af_unix.h2
-rw-r--r--include/net/dst.h7
-rw-r--r--include/net/fib_rules.h3
-rw-r--r--include/net/inet_hashtables.h72
-rw-r--r--include/net/ip_fib.h15
-rw-r--r--include/net/ip_vs.h8
-rw-r--r--include/net/mac80211.h26
-rw-r--r--include/net/sock.h63
-rw-r--r--init/main.c4
-rw-r--r--ipc/mqueue.c6
-rw-r--r--kernel/fork.c6
-rw-r--r--kernel/futex_compat.c26
-rw-r--r--kernel/sched.c59
-rw-r--r--kernel/sched_debug.c2
-rw-r--r--kernel/sched_fair.c96
-rw-r--r--kernel/sched_stats.h11
-rw-r--r--kernel/sysctl.c23
-rw-r--r--kernel/timer.c21
-rw-r--r--lib/libcrc32c.c7
-rw-r--r--mm/slub.c2
-rw-r--r--net/8021q/vlan.c6
-rw-r--r--net/8021q/vlan.h1
-rw-r--r--net/8021q/vlan_dev.c26
-rw-r--r--net/bridge/netfilter/ebt_arp.c2
-rw-r--r--net/core/dev.c1
-rw-r--r--net/core/dev_mcast.c14
-rw-r--r--net/core/dst.c1
-rw-r--r--net/core/fib_rules.c22
-rw-r--r--net/core/neighbour.c2
-rw-r--r--net/core/net_namespace.c28
-rw-r--r--net/core/sock.c69
-rw-r--r--net/dccp/ipv4.c3
-rw-r--r--net/dccp/ipv6.c3
-rw-r--r--net/dccp/proto.c9
-rw-r--r--net/decnet/dn_dev.c2
-rw-r--r--net/decnet/dn_route.c16
-rw-r--r--net/decnet/dn_rules.c13
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c1
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c1
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c2
-rw-r--r--net/ipv4/fib_frontend.c15
-rw-r--r--net/ipv4/fib_rules.c51
-rw-r--r--net/ipv4/inet_diag.c9
-rw-r--r--net/ipv4/inet_hashtables.c7
-rw-r--r--net/ipv4/inet_timewait_sock.c13
-rw-r--r--net/ipv4/ip_output.c28
-rw-r--r--net/ipv4/ip_sockglue.c39
-rw-r--r--net/ipv4/ipcomp.c3
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c19
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c20
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c26
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c24
-rw-r--r--net/ipv4/netfilter/Makefile20
-rw-r--r--net/ipv4/netfilter/ip_queue.c37
-rw-r--r--net/ipv4/netfilter/nf_nat_amanda.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_ftp.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_h323.c18
-rw-r--r--net/ipv4/netfilter/nf_nat_irc.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c8
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_tftp.c2
-rw-r--r--net/ipv4/proc.c19
-rw-r--r--net/ipv4/raw.c3
-rw-r--r--net/ipv4/route.c17
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_input.c99
-rw-r--r--net/ipv4/tcp_ipv4.c14
-rw-r--r--net/ipv4/tunnel4.c24
-rw-r--r--net/ipv4/udp.c3
-rw-r--r--net/ipv4/udplite.c3
-rw-r--r--net/ipv6/fib6_rules.c37
-rw-r--r--net/ipv6/inet6_hashtables.c19
-rw-r--r--net/ipv6/ip6_output.c36
-rw-r--r--net/ipv6/ipcomp6.c3
-rw-r--r--net/ipv6/netfilter/Makefile28
-rw-r--r--net/ipv6/netfilter/ip6_queue.c37
-rw-r--r--net/ipv6/proc.c19
-rw-r--r--net/ipv6/raw.c3
-rw-r--r--net/ipv6/route.c97
-rw-r--r--net/ipv6/tcp_ipv6.c3
-rw-r--r--net/ipv6/udp.c8
-rw-r--r--net/ipv6/udplite.c3
-rw-r--r--net/ipx/af_ipx.c22
-rw-r--r--net/mac80211/Kconfig12
-rw-r--r--net/mac80211/Makefile3
-rw-r--r--net/mac80211/ieee80211.c16
-rw-r--r--net/mac80211/ieee80211_common.h91
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/ieee80211_ioctl.c21
-rw-r--r--net/mac80211/ieee80211_rate.c24
-rw-r--r--net/mac80211/ieee80211_rate.h3
-rw-r--r--net/mac80211/ieee80211_sta.c18
-rw-r--r--net/mac80211/rc80211_simple.c25
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/wep.c2
-rw-r--r--net/mac80211/wpa.c18
-rw-r--r--net/netfilter/Makefile14
-rw-r--r--net/netfilter/nf_sockopt.c13
-rw-r--r--net/netfilter/xt_connlimit.c5
-rw-r--r--net/netfilter/xt_time.c3
-rw-r--r--net/netfilter/xt_u32.c5
-rw-r--r--net/netlink/af_netlink.c10
-rw-r--r--net/packet/af_packet.c15
-rw-r--r--net/rfkill/rfkill.c37
-rw-r--r--net/sched/cls_u32.c14
-rw-r--r--net/sched/sch_teql.c3
-rw-r--r--net/sctp/socket.c6
-rw-r--r--net/unix/af_unix.c9
-rw-r--r--net/unix/garbage.c26
-rw-r--r--security/selinux/ss/avtab.c32
-rw-r--r--security/selinux/ss/avtab.h5
-rw-r--r--security/selinux/ss/conditional.c3
-rw-r--r--security/selinux/ss/ebitmap.c2
-rw-r--r--security/selinux/ss/mls.c66
-rw-r--r--security/selinux/ss/mls.h2
-rw-r--r--security/selinux/ss/policydb.c45
-rw-r--r--security/selinux/ss/policydb.h3
-rw-r--r--security/selinux/xfrm.c13
381 files changed, 4193 insertions, 4592 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index f2668390e8f..42008395534 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -62,8 +62,8 @@ typedef uint8_t u8;
#endif
/* We can have up to 256 pages for devices. */
#define DEVICE_PAGES 256
-/* This fits nicely in a single 4096-byte page. */
-#define VIRTQUEUE_NUM 127
+/* This will occupy 2 pages: it must be a power of 2. */
+#define VIRTQUEUE_NUM 128
/*L:120 verbose is both a global flag and a macro. The C preprocessor allows
* this, and although I wouldn't recommend it, it works quite nicely here. */
@@ -1036,7 +1036,8 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
void *p;
/* First we need some pages for this virtqueue. */
- pages = (vring_size(num_descs) + getpagesize() - 1) / getpagesize();
+ pages = (vring_size(num_descs, getpagesize()) + getpagesize() - 1)
+ / getpagesize();
p = get_pages(pages);
/* Initialize the configuration. */
@@ -1045,7 +1046,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
vq->config.pfn = to_guest_phys(p) / getpagesize();
/* Initialize the vring. */
- vring_init(&vq->vring, num_descs, p);
+ vring_init(&vq->vring, num_descs, p, getpagesize());
/* Add the configuration information to this device's descriptor. */
add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE,
@@ -1342,7 +1343,7 @@ static bool service_io(struct device *dev)
if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
fprintf(stderr, "Scsi commands unsupported\n");
in->status = VIRTIO_BLK_S_UNSUPP;
- wlen = sizeof(in);
+ wlen = sizeof(*in);
} else if (out->type & VIRTIO_BLK_T_OUT) {
/* Write */
@@ -1363,7 +1364,7 @@ static bool service_io(struct device *dev)
/* Die, bad Guest, die. */
errx(1, "Write past end %llu+%u", off, ret);
}
- wlen = sizeof(in);
+ wlen = sizeof(*in);
in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
} else {
/* Read */
@@ -1376,10 +1377,10 @@ static bool service_io(struct device *dev)
ret = readv(vblk->fd, iov+1, in_num-1);
verbose("READ from sector %llu: %i\n", out->sector, ret);
if (ret >= 0) {
- wlen = sizeof(in) + ret;
+ wlen = sizeof(*in) + ret;
in->status = VIRTIO_BLK_S_OK;
} else {
- wlen = sizeof(in);
+ wlen = sizeof(*in);
in->status = VIRTIO_BLK_S_IOERR;
}
}
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
index f5a5e6d3d54..563e442f2d4 100644
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -4,8 +4,6 @@
- information on the 3Com EtherLink Plus (3c505) driver.
6pack.txt
- info on the 6pack protocol, an alternative to KISS for AX.25
-Configurable
- - info on some of the configurable network parameters
DLINK.txt
- info on the D-Link DE-600/DE-620 parallel port pocket adapters
PLIP.txt
@@ -26,8 +24,6 @@ baycom.txt
- info on the driver for Baycom style amateur radio modems
bridge.txt
- where to get user space programs for ethernet bridging with Linux.
-comx.txt
- - info on drivers for COMX line of synchronous serial adapters.
cops.txt
- info on the COPS LocalTalk Linux driver
cs89x0.txt
@@ -78,20 +74,14 @@ ltpc.txt
- the Apple or Farallon LocalTalk PC card driver
multicast.txt
- Behaviour of cards under Multicast
-ncsa-telnet
- - notes on how NCSA telnet (DOS) breaks with MTU discovery enabled.
netdevices.txt
- info on network device driver functions exported to the kernel.
olympic.txt
- IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info.
policy-routing.txt
- IP policy-based routing
-pt.txt
- - the Gracilis Packetwin AX.25 device driver
ray_cs.txt
- Raylink Wireless LAN card driver info.
-routing.txt
- - the new routing mechanism
shaper.txt
- info on the module that can shape/limit transmitted traffic.
sk98lin.txt
diff --git a/Documentation/networking/Configurable b/Documentation/networking/Configurable
deleted file mode 100644
index 69c0dd466ea..00000000000
--- a/Documentation/networking/Configurable
+++ /dev/null
@@ -1,34 +0,0 @@
-
-There are a few network parameters that can be tuned to better match
-the kernel to your system hardware and intended usage. The defaults
-are usually a good choice for 99% of the people 99% of the time, but
-you should be aware they do exist and can be changed.
-
-The current list of parameters can be found in the files:
-
- linux/net/TUNABLE
- Documentation/networking/ip-sysctl.txt
-
-Some of these are accessible via the sysctl interface, and many more are
-scheduled to be added in this way. For example, some parameters related
-to Address Resolution Protocol (ARP) are very easily viewed and altered.
-
- # cat /proc/sys/net/ipv4/arp_timeout
- 6000
- # echo 7000 > /proc/sys/net/ipv4/arp_timeout
- # cat /proc/sys/net/ipv4/arp_timeout
- 7000
-
-Others are already accessible via the related user space programs.
-For example, MAX_WINDOW has a default of 32 k which is a good choice for
-modern hardware, but if you have a slow (8 bit) Ethernet card and/or a slow
-machine, then this will be far too big for the card to keep up with fast
-machines transmitting on the same net, resulting in overruns and receive errors.
-A value of about 4 k would be more appropriate, which can be set via:
-
- # route add -net 192.168.3.0 window 4096
-
-The remainder of these can only be presently changed by altering a #define
-in the related header file. This means an edit and recompile cycle.
-
- Paul Gortmaker 06/96
diff --git a/Documentation/networking/comx.txt b/Documentation/networking/comx.txt
deleted file mode 100644
index d1526eba264..00000000000
--- a/Documentation/networking/comx.txt
+++ /dev/null
@@ -1,248 +0,0 @@
-
- COMX drivers for the 2.2 kernel
-
-Originally written by: Tivadar Szemethy, <tiv@itc.hu>
-Currently maintained by: Gergely Madarasz <gorgo@itc.hu>
-
-Last change: 21/06/1999.
-
-INTRODUCTION
-
-This document describes the software drivers and their use for the
-COMX line of synchronous serial adapters for Linux version 2.2.0 and
-above.
-The cards are produced and sold by ITC-Pro Ltd. Budapest, Hungary
-For further info contact <info@itc.hu>
-or http://www.itc.hu (mostly in Hungarian).
-The firmware files and software are available from ftp://ftp.itc.hu
-
-Currently, the drivers support the following cards and protocols:
-
-COMX (2x64 kbps intelligent board)
-CMX (1x256 + 1x128 kbps intelligent board)
-HiCOMX (2x2Mbps intelligent board)
-LoCOMX (1x512 kbps passive board)
-MixCOM (1x512 or 2x512kbps passive board with a hardware watchdog an
- optional BRI interface and optional flashROM (1-32M))
-SliceCOM (1x2Mbps channelized E1 board)
-PciCOM (X21)
-
-At the moment of writing this document, the (Cisco)-HDLC, LAPB, SyncPPP and
-Frame Relay (DTE, rfc1294 IP encapsulation with partially implemented Q933a
-LMI) protocols are available as link-level protocol.
-X.25 support is being worked on.
-
-USAGE
-
-Load the comx.o module and the hardware-specific and protocol-specific
-modules you'll need into the running kernel using the insmod utility.
-This creates the /proc/comx directory.
-See the example scripts in the 'etc' directory.
-
-/proc INTERFACE INTRO
-
-The COMX driver set has a new type of user interface based on the /proc
-filesystem which eliminates the need for external user-land software doing
-IOCTL calls.
-Each network interface or device (i.e. those ones you configure with 'ifconfig'
-and 'route' etc.) has a corresponding directory under /proc/comx. You can
-dynamically create a new interface by saying 'mkdir /proc/comx/comx0' (or you
-can name it whatever you want up to 8 characters long, comx[n] is just a
-convention).
-Generally the files contained in these directories are text files, which can
-be viewed by 'cat filename' and you can write a string to such a file by
-saying 'echo _string_ >filename'. This is very similar to the sysctl interface.
-Don't use a text editor to edit these files, always use 'echo' (or 'cat'
-where appropriate).
-When you've created the comx[n] directory, two files are created automagically
-in it: 'boardtype' and 'protocol'. You have to fill in these files correctly
-for your board and protocol you intend to use (see the board and protocol
-descriptions in this file below or the example scripts in the 'etc' directory).
-After filling in these files, other files will appear in the directory for
-setting the various hardware- and protocol-related informations (for example
-irq and io addresses, keepalive values etc.) These files are set to default
-values upon creation, so you don't necessarily have to change all of them.
-
-When you're ready with filling in the files in the comx[n] directory, you can
-configure the corresponding network interface with the standard network
-configuration utilities. If you're unable to bring the interfaces up, look up
-the various kernel log files on your system, and consult the messages for
-a probable reason.
-
-EXAMPLE
-
-To create the interface 'comx0' which is the first channel of a COMX card:
-
-insmod comx
-# insmod comx-hw-comx ; insmod comx-proto-ppp (these are usually
-autoloaded if you use the kernel module loader)
-
-mkdir /proc/comx/comx0
-echo comx >/proc/comx/comx0/boardtype
-echo 0x360 >/proc/comx/comx0/io <- jumper-selectable I/O port
-echo 0x0a >/proc/comx/comx0/irq <- jumper-selectable IRQ line
-echo 0xd000 >/proc/comx/comx0/memaddr <- software-configurable memory
- address. COMX uses 64 KB, and this
- can be: 0xa000, 0xb000, 0xc000,
- 0xd000, 0xe000. Avoid conflicts
- with other hardware.
-cat </etc/siol1.rom >/proc/comx/comx0/firmware <- the firmware for the card
-echo HDLC >/proc/comx/comx0/protocol <- the data-link protocol
-echo 10 >/proc/comx/comx0/keepalive <- the keepalive for the protocol
-ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255 <-
- finally configure it with ifconfig
-Check its status:
-cat /proc/comx/comx0/status
-
-If you want to use the second channel of this board:
-
-mkdir /proc/comx/comx1
-echo comx >/proc/comx/comx1/boardtype
-echo 0x360 >/proc/comx/comx1/io
-echo 10 >/proc/comx/comx1/irq
-echo 0xd000 >/proc/comx/comx1/memaddr
-echo 1 >/proc/comx/comx1/channel <- channels are numbered
- as 0 (default) and 1
-
-Now, check if the driver recognized that you're going to use the other
-channel of the same adapter:
-
-cat /proc/comx/comx0/twin
-comx1
-cat /proc/comx/comx1/twin
-comx0
-
-You don't have to load the firmware twice, if you use both channels of
-an adapter, just write it into the channel 0's /proc firmware file.
-
-Default values: io 0x360 for COMX, 0x320 (HICOMX), irq 10, memaddr 0xd0000
-
-THE LOCOMX HARDWARE DRIVER
-
-The LoCOMX driver doesn't require firmware, and it doesn't use memory either,
-but it uses DMA channels 1 and 3. You can set the clock rate (if enabled by
-jumpers on the board) by writing the kbps value into the file named 'clock'.
-Set it to 'external' (it is the default) if you have external clock source.
-
-(Note: currently the LoCOMX driver does not support the internal clock)
-
-THE COMX, CMX AND HICOMX DRIVERS
-
-On the HICOMX, COMX and CMX, you have to load the firmware (it is different for
-the three cards!). All these adapters can share the same memory
-address (we usually use 0xd0000). On the CMX you can set the internal
-clock rate (if enabled by jumpers on the small adapter boards) by writing
-the kbps value into the 'clock' file. You have to do this before initializing
-the card. If you use both HICOMX and CMX/COMX cards, initialize the HICOMX
-first. The I/O address of the HICOMX board is not configurable by any
-method available to the user: it is hardwired to 0x320, and if you have to
-change it, consult ITC-Pro Ltd.
-
-THE MIXCOM DRIVER
-
-The MixCOM board doesn't require firmware, the driver communicates with
-it through I/O ports. You can have three of these cards in one machine.
-
-THE SLICECOM DRIVER
-
-The SliceCOM board doesn't require firmware. You can have 4 of these cards
-in one machine. The driver doesn't (yet) support shared interrupts, so
-you will need a separate IRQ line for every board.
-Read Documentation/networking/slicecom.txt for help on configuring
-this adapter.
-
-THE HDLC/PPP LINE PROTOCOL DRIVER
-
-The HDLC/SyncPPP line protocol driver uses the kernel's built-in syncppp
-driver (syncppp.o). You don't have to manually select syncppp.o when building
-the kernel, the dependencies compile it in automatically.
-
-
-
-
-EXAMPLE
-(setting up hw parameters, see above)
-
-# using HDLC:
-echo hdlc >/proc/comx/comx0/protocol
-echo 10 >/proc/comx/comx0/keepalive <- not necessary, 10 is the default
-ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255
-
-(setting up hw parameters, see above)
-
-# using PPP:
-echo ppp >/proc/comx/comx0/protocol
-ifconfig comx0 up
-ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255
-
-
-THE LAPB LINE PROTOCOL DRIVER
-
-For this, you'll need to configure LAPB support (See 'LAPB Data Link Driver' in
-'Network options' section) into your kernel (thanks to Jonathan Naylor for his
-excellent implementation).
-comx-proto-lapb.o provides the following files in the appropriate directory
-(the default values in parens): t1 (5), t2 (1), n2 (20), mode (DTE, STD) and
-window (7). Agree with the administrator of your peer router on these
-settings (most people use defaults, but you have to know if you are DTE or
-DCE).
-
-EXAMPLE
-
-(setting up hw parameters, see above)
-echo lapb >/proc/comx/comx0/protocol
-echo dce >/proc/comx/comx0/mode <- DCE interface in this example
-ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255
-
-
-THE FRAME RELAY PROTOCOL DRIVER
-
-You DON'T need any other frame relay related modules from the kernel to use
-COMX-Frame Relay. This protocol is a bit more complicated than the others,
-because it allows to use 'subinterfaces' or DLCIs within one physical device.
-First you have to create the 'master' device (the actual physical interface)
-as you would do for other protocols. Specify 'frad' as protocol type.
-Now you can bring this interface up by saying 'ifconfig comx0 up' (or whatever
-you've named the interface). Do not assign any IP address to this interface
-and do not set any routes through it.
-Then, set up your DLCIs the following way: create a comx interface for each
-DLCI you intend to use (with mkdir), and write 'dlci' to the 'boardtype' file,
-and 'ietf-ip' to the 'protocol' file. Currently, the only supported
-encapsulation type is this (also called as RFC1294/1490 IP encapsulation).
-Write the DLCI number to the 'dlci' file, and write the name of the physical
-COMX device to the file called 'master'.
-Now you can assign an IP address to this interface and set routes using it.
-See the example file for further info and example config script.
-Notes: this driver implements a DTE interface with partially implemented
-Q933a LMI.
-You can find an extensively commented example in the 'etc' directory.
-
-FURTHER /proc FILES
-
-boardtype:
-Type of the hardware. Valid values are:
- 'comx', 'hicomx', 'locomx', 'cmx', 'slicecom'.
-
-protocol:
-Data-link protocol on this channel. Can be: HDLC, LAPB, PPP, FRAD
-
-status:
-You can read the channel's actual status from the 'status' file, for example
-'cat /proc/comx/comx3/status'.
-
-lineup_delay:
-Interpreted in seconds (default is 1). Used to avoid line jitter: the system
-will consider the line status 'UP' only if it is up for at least this number
-of seconds.
-
-debug:
-You can set various debug options through this file. Valid options are:
-'comx_events', 'comx_tx', 'comx_rx', 'hw_events', 'hw_tx', 'hw_rx'.
-You can enable a debug options by writing its name prepended by a '+' into
-the debug file, for example 'echo +comx_rx >comx0/debug'.
-Disabling an option happens similarly, use the '-' prefix
-(e.g. 'echo -hw_rx >debug').
-Debug results can be read from the debug file, for example:
-tail -f /proc/comx/comx2/debug
-
-
diff --git a/Documentation/networking/ncsa-telnet b/Documentation/networking/ncsa-telnet
deleted file mode 100644
index d77d28b0909..00000000000
--- a/Documentation/networking/ncsa-telnet
+++ /dev/null
@@ -1,16 +0,0 @@
-NCSA telnet doesn't work with path MTU discovery enabled. This is due to a
-bug in NCSA that also stops it working with other modern networking code
-such as Solaris.
-
-The following information is courtesy of
-Marek <marekm@i17linuxb.ists.pwr.wroc.pl>
-
-There is a fixed version somewhere on ftp.upe.ac.za (sorry, I don't
-remember the exact pathname, and this site is very slow from here).
-It may or may not be faster for you to get it from
-ftp://ftp.ists.pwr.wroc.pl/pub/msdos/telnet/ncsa_upe/tel23074.zip
-(source is in v230704s.zip). I have tested it with 1.3.79 (with
-path mtu discovery enabled - ncsa 2.3.08 didn't work) and it seems
-to work. I don't know if anyone is working on this code - this
-version is over a year old. Too bad - it's faster and often more
-stable than these windoze telnets, and runs on almost anything...
diff --git a/Documentation/networking/pt.txt b/Documentation/networking/pt.txt
deleted file mode 100644
index 72e888c1d98..00000000000
--- a/Documentation/networking/pt.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-This is the README for the Gracilis Packetwin device driver, version 0.5
-ALPHA for Linux 1.3.43.
-
-These files will allow you to talk to the PackeTwin (now know as PT) and
-connect through it just like a pair of TNCs. To do this you will also
-require the AX.25 code in the kernel enabled.
-
-There are four files in this archive; this readme, a patch file, a .c file
-and finally a .h file. The two program files need to be put into the
-drivers/net directory in the Linux source tree, for me this is the
-directory /usr/src/linux/drivers/net. The patch file needs to be patched in
-at the top of the Linux source tree (/usr/src/linux in my case).
-
-You will most probably have to edit the pt.c file to suit your own setup,
-this should just involve changing some of the defines at the top of the file.
-Please note that if you run an external modem you must specify a speed of 0.
-
-The program is currently setup to run a 4800 baud external modem on port A
-and a Kantronics DE-9600 daughter board on port B so if you have this (or
-something similar) then you're right.
-
-To compile in the driver, put the files in the correct place and patch in
-the diff. You will have to re-configure the kernel again before you
-recompile it.
-
-The driver is not real good at the moment for finding the card. You can
-'help' it by changing the order of the potential addresses in the structure
-found in the pt_init() function so the address of where the card is is put
-first.
-
-After compiling, you have to get them going, they are pretty well like any
-other net device and just need ifconfig to get them going.
-As an example, here is my /etc/rc.net
---------------------------
-
-#
-# Configure the PackeTwin, port A.
-/sbin/ifconfig pt0a 44.136.8.87 hw ax25 vk2xlz mtu 512
-/sbin/ifconfig pt0a 44.136.8.87 broadcast 44.136.8.255 netmask 255.255.255.0
-/sbin/route add -net 44.136.8.0 netmask 255.255.255.0 dev pt0a
-/sbin/route add -net 44.0.0.0 netmask 255.0.0.0 gw 44.136.8.68 dev pt0a
-/sbin/route add -net 138.25.16.0 netmask 255.255.240.0 dev pt0a
-/sbin/route add -host 44.136.8.255 dev pt0a
-#
-# Configure the PackeTwin, port B.
-/sbin/ifconfig pt0b 44.136.8.87 hw ax25 vk2xlz-1 mtu 512
-/sbin/ifconfig pt0b 44.136.8.87 broadcast 44.255.255.255 netmask 255.0.0.0
-/sbin/route add -host 44.136.8.216 dev pt0b
-/sbin/route add -host 44.136.8.95 dev pt0b
-/sbin/route add -host 44.255.255.255 dev pt0b
-
-This version of the driver comes under the GNU GPL. If you have one of my
-previous (non-GPL) versions of the driver, please update to this one.
-
-I hope that this all works well for you. I would be pleased to hear how
-many people use the driver and if it does its job.
-
- - Craig vk2xlz <csmall@small.dropbear.id.au>
diff --git a/Documentation/networking/routing.txt b/Documentation/networking/routing.txt
deleted file mode 100644
index a26838b930f..00000000000
--- a/Documentation/networking/routing.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-The directory ftp.inr.ac.ru:/ip-routing contains:
-
-- iproute.c - "professional" routing table maintenance utility.
-
-- rdisc.tar.gz - rdisc daemon, ported from Sun.
- STRONGLY RECOMMENDED FOR ALL HOSTS.
-
-- routing.tgz - original Mike McLagan's route by source patch.
- Currently it is obsolete.
-
-- gated.dif-ss<NEWEST>.gz - gated-R3_6Alpha_2 fixes.
- Look at README.gated
-
-- mrouted-3.8.dif.gz - mrouted-3.8 fixes.
-
-- rtmon.c - trivial debugging utility: reads and stores netlink.
-
-
-NEWS for user.
-
-- Policy based routing. Routing decisions are made on the basis
- not only of destination address, but also source address,
- TOS and incoming interface.
-- Complete set of IP level control messages.
- Now Linux is the only OS in the world complying to RFC requirements.
- Great win 8)
-- New interface addressing paradigm.
- Assignment of address ranges to interface,
- multiple prefixes etc. etc.
- Do not bother, it is compatible with the old one. Moreover:
-- You don't need to do "route add aaa.bbb.ccc... eth0" anymore,
- it is done automatically.
-- "Abstract" UNIX sockets and security enhancements.
- This is necessary to use TIRPC and TLI emulation library.
-
-NEWS for hacker.
-
-- New destination cache. Flexible, robust and just beautiful.
-- Network stack is reordered, simplified, optimized, a lot of bugs fixed.
- (well, and new bugs were introduced, but I haven't seen them yet 8))
- It is difficult to describe all the changes, look into source.
-
-If you see this file, then this patch works 8)
-
-Alexey Kuznetsov.
-kuznet@ms2.inr.ac.ru
diff --git a/Documentation/networking/slicecom.hun b/Documentation/networking/slicecom.hun
deleted file mode 100644
index bed2f045e55..00000000000
--- a/Documentation/networking/slicecom.hun
+++ /dev/null
@@ -1,371 +0,0 @@
-
-SliceCOM adapter felhasznaloi dokumentacioja - 0.51 verziohoz
-
-Bartók István <bartoki@itc.hu>
-Utolso modositas: Wed Aug 29 17:26:58 CEST 2001
-
------------------------------------------------------------------
-
-Hasznalata:
-
-Forditas:
-
-Code maturity level options
- [*] Prompt for development and/or incomplete code/drivers
-
-Network device support
- Wan interfaces
- <M> MultiGate (COMX) synchronous
- <M> Support for MUNICH based boards: SliceCOM, PCICOM (NEW)
- <M> Support for HDLC and syncPPP...
-
-
-A modulok betoltese:
-
-modprobe comx
-
-modprobe comx-proto-ppp # a Cisco-HDLC es a SyncPPP protokollt is
- # ez a modul adja
-
-modprobe comx-hw-munich # a modul betoltodeskor azonnal jelent a
- # syslogba a detektalt kartyakrol
-
-
-Konfiguralas:
-
-# Ezen az interfeszen Cisco-HDLC vonali protokoll fog futni
-# Az interfeszhez rendelt idoszeletek: 1,2 (128 kbit/sec-es vonal)
-# (a G.703 keretben az elso adatot vivo idoszelet az 1-es)
-#
-mkdir /proc/comx/comx0.1/
-echo slicecom >/proc/comx/comx0.1/boardtype
-echo hdlc >/proc/comx/comx0.1/protocol
-echo 1 2 >/proc/comx/comx0.1/timeslots
-
-
-# Ezen az interfeszen SyncPPP vonali protokoll fog futni
-# Az interfeszhez rendelt idoszelet: 3 (64 kbit/sec-es vonal)
-#
-mkdir /proc/comx/comx0.2/
-echo slicecom >/proc/comx/comx0.2/boardtype
-echo ppp >/proc/comx/comx0.2/protocol
-echo 3 >/proc/comx/comx0.2/timeslots
-
-...
-
-ifconfig comx0.1 up
-ifconfig comx0.2 up
-
------------------------------------------------------------------
-
-A COMX driverek default 20 csomagnyi transmit queue-t rendelnek a halozati
-interfeszekhez. WAN halozatokban ennel hosszabbat is szokas hasznalni
-(20 es 100 kozott), hogy a vonal kihasznaltsaga nagy terheles eseten jobb
-legyen (bar ezzel megno a varhato kesleltetes a csomagok sorban allasa miatt):
-
-# ifconfig comx0 txqueuelen 50
-
-Ezt a beallitasi lehetoseget csak az ujabb disztribuciok ifconfig parancsa
-tamogatja (amik mar a 2.2 kernelekhez keszultek, mint a RedHat 6.1 vagy a
-Debian 2.2).
-
-A 2.1-es Debian disztribuciohoz a http://www.debian.org/~rcw/2.2/netbase/
-cimrol toltheto le ujabb netbase csomag, ami mar ilyet tamogato ifconfig
-parancsot tartalmaz. Bovebben a 2.2 kernel hasznalatarol Debian 2.1 alatt:
-http://www.debian.org/releases/stable/running-kernel-2.2
-
------------------------------------------------------------------
-
-A kartya LED-jeinek jelentese:
-
-piros - eg, ha Remote Alarm-ot kuld a tuloldal
-zold - eg, ha a vett jelben megtalalja a keretszinkront
-
-Reszletesebben:
-
-piros: zold: jelentes:
-
-- - nincs keretszinkron (nincs jel, vagy rossz a jel)
-- eg "minden rendben"
-eg eg a vetel OK, de a tuloldal Remote Alarm-ot kuld
-eg - ez nincs ertelmezve, egyelore funkcio nelkul
-
------------------------------------------------------------------
-
-Reszletesebb leiras a hardver beallitasi lehetosegeirol:
-
-Az altalanos,- es a protokoll-retegek beallitasi lehetosegeirol a 'comx.txt'
-fajlban leirtak SliceCOM kartyanal is ervenyesek, itt csak a hardver-specifikus
-beallitasi lehetosegek vannak osszefoglalva:
-
-Konfiguralasi interfesz a /proc/comx/ alatt:
-
-Minden timeslot-csoportnak kulon comx* interfeszt kell letrehozni mkdir-rel:
-comx0, comx1, .. stb. Itt beallithato, hogy az adott interfesz hanyadik kartya
-melyik timeslotja(i)bol alljon ossze. A Cisco-fele serial3:1 elnevezesek
-(serial3:1 = a 3. kartyaban az 1-es idoszelet-csoport) Linuxon aliasing-ot
-jelentenenek, ezert mi nem tudunk ilyen elnevezest hasznalni.
-
-Tobb kartya eseten a comx0.1, comx0.2, ... vagy slice0.1, slice0.2 nevek
-hasznalhatoak.
-
-Tobb SliceCOM kartya is lehet egy gepben, de sajat interrupt kell mindegyiknek,
-nem tud meg megosztott interruptot kezelni.
-
-Az egesz kartyat erinto beallitasok:
-
-Az ioport es irq beallitas nincs: amit a PCI BIOS kioszt a rendszernek,
-azt hasznalja a driver.
-
-
-comx0/boardnum - hanyadik SliceCOM kartya a gepben (a 'termeszetes' PCI
- sorrendben ertve: ahogyan a /proc/pci-ban vagy az 'lspci'
- kimeneteben megjelenik, altalaban az alaplapi PCI meghajto
- aramkorokhoz kozelebb eso kartyak a kisebb sorszamuak)
-
- Default: 0 (0-tol kezdodik a szamolas)
-
-
-Bar a kovetkezoket csak egy-egy interfeszen allitjuk at, megis az egesz kartya
-mukodeset egyszerre allitjak. A megkotes hogy csak UP-ban levo interfeszen
-hasznalhatoak, azert van, mert kulonben nem vart eredmenyekre vezetne egy ilyen
-paranccsorozat:
-
- echo 0 >boardnum
- echo internal >clock_source
- echo 1 >boardnum
-
-- Ez a 0-s board clock_source-at allitana at.
-
-Ezek a beallitasok megmaradnak az osszes interfesz torlesekor, de torlodnek
-a driver modul ki/betoltesekor.
-
-
-comx0/clock_source - A Tx orajelforrasa, a Cisco-val hasonlatosra keszult.
- Hasznalata:
-
- papaya:# echo line >/proc/comx/comx0/clock_source
- papaya:# echo internal >/proc/comx/comx0/clock_source
-
- line - A Tx orajelet a vett adatfolyambol dekodolja, igyekszik
- igazodni hozza. Ha nem lat orajelet az inputon, akkor
- atall a sajat orajelgeneratorara.
- internal - A Tx orajelet a sajat orajelgeneratora szolgaltatja.
-
- Default: line
-
- Normal osszeallitas eseten a tavkozlesi szolgaltato eszkoze
- (pl. HDSL modem) adja az orajelet, ezert ez a default.
-
-
-comx0/framing - A CRC4 ki/be kapcsolasa
-
- A CRC4: 16 PCM keretet (A PCM keret az, amibe a 32 darab 64
- kilobites csatorna van bemultiplexalva. Nem osszetevesztendo a HDLC
- kerettel.) 2x8 -as csoportokra osztanak, es azokhoz 4-4 bites CRC-t
- szamolnak. Elsosorban a vonal minosegenek a monitorozasara szolgal.
-
- papaya:~# echo crc4 >/proc/comx/comx0/framing
- papaya:~# echo no-crc4 >/proc/comx/comx0/framing
-
- Default a 'crc4', a MATAV vonalak altalaban igy futnak. De ha nem
- egyforma is a beallitas a vonal ket vegen, attol a forgalom altalaban
- at tud menni.
-
-
-comx0/linecode - A vonali kodolas beallitasa
-
- papaya:~# echo hdb3 >/proc/comx/comx0/linecode
- papaya:~# echo ami >/proc/comx/comx0/linecode
-
- Default a 'hdb3', a MATAV vonalak igy futnak.
-
- (az AMI kodolas igen ritka E1-es vonalaknal). Ha ez a beallitas nem
- egyezik a vonal ket vegen, akkor elofordulhat hogy a keretszinkron
- osszejon, de CRC4-hibak es a vonalakon atvitt adatokban is hibak
- keletkeznek (amit a HDLC/SyncPPP szinten CRC-hibaval jelez)
-
-
-comx0/reg - a kartya aramkoreinek, a MUNICH (reg) es a FALC (lbireg)
-comx0/lbireg regisztereinek kozvetlen elerese. Hasznalata:
-
- echo >reg 0x04 0x0 - a 4-es regiszterbe 0-t ir
- echo >reg 0x104 - printk()-val kiirja a 4-es regiszter
- tartalmat a syslogba.
-
- WARNING: ezek csak a fejleszteshez keszultek, sok galibat
- lehet veluk okozni!
-
-
-comx0/loopback - A kartya G.703 jelenek a visszahurkolasara is van lehetoseg:
-
- papaya:# echo none >/proc/comx/comx0/loopback
- papaya:# echo local >/proc/comx/comx0/loopback
- papaya:# echo remote >/proc/comx/comx0/loopback
-
- none - nincs visszahurkolas, normal mukodes
- local - a kartya a sajat maga altal adott jelet kapja vissza
- remote - a kartya a kivulrol vett jelet adja kifele
-
- Default: none
-
------------------------------------------------------------------
-
-Az interfeszhez (Cisco terminologiaban 'channel-group') kapcsolodo beallitasok:
-
-comx0/timeslots - mely timeslotok (idoszeletek) tartoznak az adott interfeszhez.
-
- papaya:~# cat /proc/comx/comx0/timeslots
- 1 3 4 5 6
- papaya:~#
-
- Egy timeslot megkeresese (hanyas interfeszbe tartozik nalunk):
-
- papaya:~# grep ' 4' /proc/comx/comx*/timeslots
- /proc/comx/comx0/timeslots:1 3 4 5 6
- papaya:~#
-
- Beallitasa:
- papaya:~# echo '1 5 2 6 7 8' >/proc/comx/comx0/timeslots
-
- A timeslotok sorrendje nem szamit, '1 3 2' ugyanaz mint az '1 2 3'.
-
- Beallitashoz az adott interfesznek DOWN-ban kell lennie
- (ifconfig comx0 down), de ugyanannak a kartyanak a tobbi interfesze
- uzemelhet kozben.
-
- Beallitaskor leellenorzi, hogy az uj timeslotok nem utkoznek-e egy
- masik interfesz timeslotjaival. Ha utkoznek, akkor nem allitja at.
-
- Mindig 10-es szamrendszerben tortenik a timeslotok ertelmezese, nehogy
- a 08, 09 alaku felirast rosszul ertelmezze.
-
------------------------------------------------------------------
-
-Az interfeszek es a kartya allapotanak lekerdezese:
-
-- A ' '-szel kezdodo sorok az eredeti kimenetet, a //-rel kezdodo sorok a
-magyarazatot jelzik.
-
- papaya:~$ cat /proc/comx/comx1/status
- Interface administrative status is UP, modem status is UP, protocol is UP
- Modem status changes: 0, Transmitter status is IDLE, tbusy: 0
- Interface load (input): 978376 / 947808 / 951024 bits/s (5s/5m/15m)
- (output): 978376 / 947848 / 951024 bits/s (5s/5m/15m)
- Debug flags: none
- RX errors: len: 22, overrun: 1, crc: 0, aborts: 0
- buffer overrun: 0, pbuffer overrun: 0
- TX errors: underrun: 0
- Line keepalive (value: 10) status UP [0]
-
-// Itt kezdodik a hardver-specifikus resz:
- Controller status:
- No alarms
-
-// Alarm: hibajelzes:
-//
-// No alarms - minden rendben
-//
-// LOS - Loss Of Signal - nem erzekel jelet a bemeneten.
-// AIS - Alarm Indication Signal - csak egymas utani 1-esek jonnek
-// a bemeneten, a tuloldal igy is jelezheti hogy meghibasodott vagy
-// nincs inicializalva.
-// AUXP - Auxiliary Pattern Indication - 01010101.. sorozat jon a bemeneten.
-// LFA - Loss of Frame Alignment - nincs keretszinkron
-// RRA - Receive Remote Alarm - a tuloldal el, de hibat jelez.
-// LMFA - Loss of CRC4 Multiframe Alignment - nincs CRC4-multikeret-szinkron
-// NMF - No Multiframe alignment Found after 400 msec - ilyen alarm a no-crc4
-// es crc4 keretezesek eseten nincs, lasd lentebb
-//
-// Egyeb lehetseges hibajelzesek:
-//
-// Transmit Line Short - a kartya ugy erzi hogy az adasi kimenete rovidre
-// van zarva, ezert kikapcsolta az adast. (nem feltetlenul veszi eszre
-// a kulso rovidzarat)
-
-// A veteli oldal csomagjainak lancolt listai, debug celokra:
-
- Rx ring:
- rafutott: 0
- lastcheck: 50845731, jiffies: 51314281
- base: 017b1858
- rx_desc_ptr: 0
- rx_desc_ptr: 017b1858
- hw_curr_ptr: 017b1858
- 06040000 017b1868 017b1898 c016ff00
- 06040000 017b1878 017b1e9c c016ff00
- 46040000 017b1888 017b24a0 c016ff00
- 06040000 017b1858 017b2aa4 c016ff00
-
-// A kartyat hasznalo tobbi interfesz: a 0-s channel-group a comx1 interfesz,
-// es az 1,2,...,16 timeslotok tartoznak hozza:
-
- Interfaces using this board: (channel-group, interface, timeslots)
- 0 comx1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- 1 comx2: 17
- 2 comx3: 18
- 3 comx4: 19
- 4 comx5: 20
- 5 comx6: 21
- 6 comx7: 22
- 7 comx8: 23
- 8 comx9: 24
- 9 comx10: 25
- 10 comx11: 26
- 11 comx12: 27
- 12 comx13: 28
- 13 comx14: 29
- 14 comx15: 30
- 15 comx16: 31
-
-// Hany esemenyt kezelt le a driver egy-egy hardver-interrupt kiszolgalasanal:
-
- Interrupt work histogram:
- hist[ 0]: 0 hist[ 1]: 2 hist[ 2]: 18574 hist[ 3]: 79
- hist[ 4]: 14 hist[ 5]: 1 hist[ 6]: 0 hist[ 7]: 1
- hist[ 8]: 0 hist[ 9]: 7
-
-// Hany kikuldendo csomag volt mar a Tx-ringben amikor ujabb lett irva bele:
-
- Tx ring histogram:
- hist[ 0]: 2329 hist[ 1]: 0 hist[ 2]: 0 hist[ 3]: 0
-
-// Az E1-interfesz hiba-szamlaloi, az rfc2495-nek megfeleloen:
-// (kb. a Cisco routerek "show controllers e1" formatumaban: http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/rbook/rinterfc.htm#xtocid25669126)
-
-Data in current interval (91 seconds elapsed):
- 9516 Line Code Violations, 65 Path Code Violations, 2 E-Bit Errors
- 0 Slip Secs, 2 Fr Loss Secs, 2 Line Err Secs, 0 Degraded Mins
- 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 11 Unavail Secs
-Data in Interval 1 (15 minutes):
- 0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
- 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
- 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-Data in last 4 intervals (1 hour):
- 0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
- 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
- 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-Data in last 96 intervals (24 hours):
- 0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
- 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
- 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-
------------------------------------------------------------------
-
-Nehany kulonlegesebb beallitasi lehetoseg (idovel beepulhetnek majd a driverbe):
-Ezekkel sok galibat lehet okozni, nagyon ovatosan kell oket hasznalni!
-
- modified CRC-4, for improved interworking of CRC-4 and non-CRC-4
- devices: (lasd page 107 es g706 Annex B)
- lbireg[ 0x1b ] |= 0x08
- lbireg[ 0x1c ] |= 0xc0
- - ilyenkor ertelmezett az NMF - 'No Multiframe alignment Found after
- 400 msec' alarm.
-
- FALC - a vonali meghajto IC
- local loop - a sajat adasomat halljam vissza
- remote loop - a kivulrol jovo adast adom vissza
-
- Egy hibakeresesre hasznalhato dolog:
- - 1-es timeslot local loop a FALC-ban: echo >lbireg 0x1d 0x21
- - local loop kikapcsolasa: echo >lbireg 0x1d 0x00
diff --git a/Documentation/networking/slicecom.txt b/Documentation/networking/slicecom.txt
deleted file mode 100644
index c82c0cf981b..00000000000
--- a/Documentation/networking/slicecom.txt
+++ /dev/null
@@ -1,369 +0,0 @@
-
-SliceCOM adapter user's documentation - for the 0.51 driver version
-
-Written by Bartók István <bartoki@itc.hu>
-
-English translation: Lakatos György <gyuri@itc.hu>
-Mon Dec 11 15:28:42 CET 2000
-
-Last modified: Wed Aug 29 17:25:37 CEST 2001
-
------------------------------------------------------------------
-
-Usage:
-
-Compiling the kernel:
-
-Code maturity level options
- [*] Prompt for development and/or incomplete code/drivers
-
-Network device support
- Wan interfaces
- <M> MultiGate (COMX) synchronous
- <M> Support for MUNICH based boards: SliceCOM, PCICOM (NEW)
- <M> Support for HDLC and syncPPP...
-
-
-Loading the modules:
-
-modprobe comx
-
-modprobe comx-proto-ppp # module for Cisco-HDLC and SyncPPP protocols
-
-modprobe comx-hw-munich # the module logs information by the kernel
- # about the detected boards
-
-
-Configuring the board:
-
-# This interface will use the Cisco-HDLC line protocol,
-# the timeslices assigned are 1,2 (128 KiBit line speed)
-# (the first data timeslice in the G.703 frame is no. 1)
-#
-mkdir /proc/comx/comx0.1/
-echo slicecom >/proc/comx/comx0.1/boardtype
-echo hdlc >/proc/comx/comx0.1/protocol
-echo 1 2 >/proc/comx/comx0.1/timeslots
-
-
-# This interface uses SyncPPP line protocol, the assigned
-# is no. 3 (64 KiBit line speed)
-#
-mkdir /proc/comx/comx0.2/
-echo slicecom >/proc/comx/comx0.2/boardtype
-echo ppp >/proc/comx/comx0.2/protocol
-echo 3 >/proc/comx/comx0.2/timeslots
-
-...
-
-ifconfig comx0.1 up
-ifconfig comx0.2 up
-
------------------------------------------------------------------
-
-The COMX interfaces use a 10 packet transmit queue by default, however WAN
-networks sometimes use bigger values (20 to 100), to utilize the line better
-by large traffic (though the line delay increases because of more packets
-join the queue).
-
-# ifconfig comx0 txqueuelen 50
-
-This option is only supported by the ifconfig command of the later
-distributions, which came with 2.2 kernels, such as RedHat 6.1 or Debian 2.2.
-
-You can download a newer netbase packet from
-http://www.debian.org/~rcw/2.2/netbase/ for Debian 2.1, which has a new
-ifconfig. You can get further information about using 2.2 kernel with
-Debian 2.1 from http://www.debian.org/releases/stable/running-kernel-2.2
-
------------------------------------------------------------------
-
-The SliceCom LEDs:
-
-red - on, if the interface is unconfigured, or it gets Remote Alarm-s
-green - on, if the board finds frame-sync in the received signal
-
-A bit more detailed:
-
-red: green: meaning:
-
-- - no frame-sync, no signal received, or signal SNAFU.
-- on "Everything is OK"
-on on Reception is ok, but the remote end sends Remote Alarm
-on - The interface is unconfigured
-
------------------------------------------------------------------
-
-A more detailed description of the hardware setting options:
-
-The general and the protocol layer options described in the 'comx.txt' file
-apply to the SliceCom as well, I only summarize the SliceCom hardware specific
-settings below.
-
-The '/proc/comx' configuring interface:
-
-An interface directory should be created for every timeslot group with
-'mkdir', e,g: 'comx0', 'comx1' etc. The timeslots can be assigned here to the
-specific interface. The Cisco-like naming convention (serial3:1 - first
-timeslot group of the 3rd. board) can't be used here, because these mean IP
-aliasing in Linux.
-
-You can give any meaningful name to keep the configuration clear;
-e.g: 'comx0.1', 'comx0.2', 'comx1.1', comx1.2', if you have two boards
-with two interfaces each.
-
-Settings, which apply to the board:
-
-Neither 'io' nor 'irq' settings required, the driver uses the resources
-given by the PCI BIOS.
-
-comx0/boardnum - board number of the SliceCom in the PC (using the 'natural'
- PCI order) as listed in '/proc/pci' or the output of the
- 'lspci' command, generally the slots nearer to the motherboard
- PCI driver chips have the lower numbers.
-
- Default: 0 (the counting starts with 0)
-
-Though the options below are to be set on a single interface, they apply to the
-whole board. The restriction, to use them on 'UP' interfaces, is because the
-command sequence below could lead to unpredictable results.
-
- # echo 0 >boardnum
- # echo internal >clock_source
- # echo 1 >boardnum
-
-The sequence would set the clock source of board 0.
-
-These settings will persist after all the interfaces are cleared, but are
-cleared when the driver module is unloaded and loaded again.
-
-comx0/clock_source - source of the transmit clock
- Usage:
-
- # echo line >/proc/comx/comx0/clock_source
- # echo internal >/proc/comx/comx0/clock_source
-
- line - The Tx clock is being decoded if the input data stream,
- if no clock seen on the input, then the board will use it's
- own clock generator.
-
- internal - The Tx clock is supplied by the builtin clock generator.
-
- Default: line
-
- Normally, the telecommunication company's end device (the HDSL
- modem) provides the Tx clock, that's why 'line' is the default.
-
-comx0/framing - Switching CRC4 off/on
-
- CRC4: 16 PCM frames (The 32 64Kibit channels are multiplexed into a
- PCM frame, nothing to do with HDLC frames) are divided into 2x8
- groups, each group has a 4 bit CRC.
-
- # echo crc4 >/proc/comx/comx0/framing
- # echo no-crc4 >/proc/comx/comx0/framing
-
- Default is 'crc4', the Hungarian MATAV lines behave like this.
- The traffic generally passes if this setting on both ends don't match.
-
-comx0/linecode - Setting the line coding
-
- # echo hdb3 >/proc/comx/comx0/linecode
- # echo ami >/proc/comx/comx0/linecode
-
- Default a 'hdb3', MATAV lines use this.
-
- (AMI coding is rarely used with E1 lines). Frame sync may occur, if
- this setting doesn't match the other end's, but CRC4 and data errors
- will come, which will result in CRC errors on HDLC/SyncPPP level.
-
-comx0/reg - direct access to the board's MUNICH (reg) and FALC (lbireg)
-comx0/lbireg circuit's registers
-
- # echo >reg 0x04 0x0 - write 0 to register 4
- # echo >reg 0x104 - write the contents of register 4 with
- printk() to syslog
-
-WARNING! These are only for development purposes, messing with this will
- result much trouble!
-
-comx0/loopback - Places a loop to the board's G.703 signals
-
- # echo none >/proc/comx/comx0/loopback
- # echo local >/proc/comx/comx0/loopback
- # echo remote >/proc/comx/comx0/loopback
-
- none - normal operation, no loop
- local - the board receives it's own output
- remote - the board sends the received data to the remote side
-
- Default: none
-
------------------------------------------------------------------
-
-Interface (channel group in Cisco terms) settings:
-
-comx0/timeslots - which timeslots belong to the given interface
-
- Setting:
-
- # echo '1 5 2 6 7 8' >/proc/comx/comx0/timeslots
-
- # cat /proc/comx/comx0/timeslots
- 1 2 5 6 7 8
- #
-
- Finding a timeslot:
-
- # grep ' 4' /proc/comx/comx*/timeslots
- /proc/comx/comx0/timeslots:1 3 4 5 6
- #
-
- The timeslots can be in any order, '1 2 3' is the same as '1 3 2'.
-
- The interface has to be DOWN during the setting ('ifconfig comx0
- down'), but the other interfaces could operate normally.
-
- The driver checks if the assigned timeslots are vacant, if not, then
- the setting won't be applied.
-
- The timeslot values are treated as decimal numbers, not to misunderstand
- values of 08, 09 form.
-
------------------------------------------------------------------
-
-Checking the interface and board status:
-
-- Lines beginning with ' ' (space) belong to the original output, the lines
-which begin with '//' are the comments.
-
- papaya:~$ cat /proc/comx/comx1/status
- Interface administrative status is UP, modem status is UP, protocol is UP
- Modem status changes: 0, Transmitter status is IDLE, tbusy: 0
- Interface load (input): 978376 / 947808 / 951024 bits/s (5s/5m/15m)
- (output): 978376 / 947848 / 951024 bits/s (5s/5m/15m)
- Debug flags: none
- RX errors: len: 22, overrun: 1, crc: 0, aborts: 0
- buffer overrun: 0, pbuffer overrun: 0
- TX errors: underrun: 0
- Line keepalive (value: 10) status UP [0]
-
-// The hardware specific part starts here:
- Controller status:
- No alarms
-
-// Alarm:
-//
-// No alarms - Everything OK
-//
-// LOS - Loss Of Signal - No signal sensed on the input
-// AIS - Alarm Indication Signal - The remote side sends '11111111'-s,
-// it tells, that there's an error condition, or it's not
-// initialised.
-// AUXP - Auxiliary Pattern Indication - 01010101.. received.
-// LFA - Loss of Frame Alignment - no frame sync received.
-// RRA - Receive Remote Alarm - the remote end's OK, but signals error cond.
-// LMFA - Loss of CRC4 Multiframe Alignment - no CRC4 multiframe sync.
-// NMF - No Multiframe alignment Found after 400 msec - no such alarm using
-// no-crc4 or crc4 framing, see below.
-//
-// Other possible error messages:
-//
-// Transmit Line Short - the board felt, that it's output is short-circuited,
-// so it switched the transmission off. (The board can't definitely tell,
-// that it's output is short-circuited.)
-
-// Chained list of the received packets, for debug purposes:
-
- Rx ring:
- rafutott: 0
- lastcheck: 50845731, jiffies: 51314281
- base: 017b1858
- rx_desc_ptr: 0
- rx_desc_ptr: 017b1858
- hw_curr_ptr: 017b1858
- 06040000 017b1868 017b1898 c016ff00
- 06040000 017b1878 017b1e9c c016ff00
- 46040000 017b1888 017b24a0 c016ff00
- 06040000 017b1858 017b2aa4 c016ff00
-
-// All the interfaces using the board: comx1, using the 1,2,...16 timeslots,
-// comx2, using timeslot 17, etc.
-
- Interfaces using this board: (channel-group, interface, timeslots)
- 0 comx1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- 1 comx2: 17
- 2 comx3: 18
- 3 comx4: 19
- 4 comx5: 20
- 5 comx6: 21
- 6 comx7: 22
- 7 comx8: 23
- 8 comx9: 24
- 9 comx10: 25
- 10 comx11: 26
- 11 comx12: 27
- 12 comx13: 28
- 13 comx14: 29
- 14 comx15: 30
- 15 comx16: 31
-
-// The number of events handled by the driver during an interrupt cycle:
-
- Interrupt work histogram:
- hist[ 0]: 0 hist[ 1]: 2 hist[ 2]: 18574 hist[ 3]: 79
- hist[ 4]: 14 hist[ 5]: 1 hist[ 6]: 0 hist[ 7]: 1
- hist[ 8]: 0 hist[ 9]: 7
-
-// The number of packets to send in the Tx ring, when a new one arrived:
-
- Tx ring histogram:
- hist[ 0]: 2329 hist[ 1]: 0 hist[ 2]: 0 hist[ 3]: 0
-
-// The error counters of the E1 interface, according to the RFC2495,
-// (similar to the Cisco "show controllers e1" command's output:
-// http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/rbook/rinterfc.htm#xtocid25669126)
-
-Data in current interval (91 seconds elapsed):
- 9516 Line Code Violations, 65 Path Code Violations, 2 E-Bit Errors
- 0 Slip Secs, 2 Fr Loss Secs, 2 Line Err Secs, 0 Degraded Mins
- 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 11 Unavail Secs
-Data in Interval 1 (15 minutes):
- 0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
- 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
- 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-Data in last 4 intervals (1 hour):
- 0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
- 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
- 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-Data in last 96 intervals (24 hours):
- 0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
- 0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
- 0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
-
------------------------------------------------------------------
-
-Some unique options, (may get into the driver later):
-Treat them very carefully, these can cause much trouble!
-
- modified CRC-4, for improved interworking of CRC-4 and non-CRC-4
- devices: (see page 107 and g706 Annex B)
- lbireg[ 0x1b ] |= 0x08
- lbireg[ 0x1c ] |= 0xc0
-
- - The NMF - 'No Multiframe alignment Found after 400 msec' alarm
- comes into account.
-
- FALC - the line driver chip.
- local loop - I hear my transmission back.
- remote loop - I echo the remote transmission back.
-
- Something useful for finding errors:
-
- - local loop for timeslot 1 in the FALC chip:
-
- # echo >lbireg 0x1d 0x21
-
- - Switching the loop off:
-
- # echo >lbireg 0x1d 0x00
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index a96e85397eb..ac1be25c1e2 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -52,6 +52,7 @@ Table of Contents
i) Freescale QUICC Engine module (QE)
j) CFI or JEDEC memory-mapped NOR flash
k) Global Utilities Block
+ l) Xilinx IP cores
VII - Specifying interrupt information for devices
1) interrupts property
@@ -851,12 +852,18 @@ address which can extend beyond that limit.
/cpus/PowerPC,970FX@0
/cpus/PowerPC,970FX@1
(unit addresses do not require leading zeroes)
- - d-cache-line-size : one cell, L1 data cache line size in bytes
- - i-cache-line-size : one cell, L1 instruction cache line size in
+ - d-cache-block-size : one cell, L1 data cache block size in bytes (*)
+ - i-cache-block-size : one cell, L1 instruction cache block size in
bytes
- d-cache-size : one cell, size of L1 data cache in bytes
- i-cache-size : one cell, size of L1 instruction cache in bytes
+(*) The cache "block" size is the size on which the cache management
+instructions operate. Historically, this document used the cache
+"line" size here which is incorrect. The kernel will prefer the cache
+block size and will fallback to cache line size for backward
+compatibility.
+
Recommended properties:
- timebase-frequency : a cell indicating the frequency of the
@@ -870,6 +877,10 @@ address which can extend beyond that limit.
for the above, the common code doesn't use that property, but
you are welcome to re-use the pSeries or Maple one. A future
kernel version might provide a common function for this.
+ - d-cache-line-size : one cell, L1 data cache line size in bytes
+ if different from the block size
+ - i-cache-line-size : one cell, L1 instruction cache line size in
+ bytes if different from the block size
You are welcome to add any property you find relevant to your board,
like some information about the mechanism used to soft-reset the
@@ -2242,6 +2253,266 @@ platforms are moved over to use the flattened-device-tree model.
available.
For Axon: 0x0000012a
+ l) Xilinx IP cores
+
+ The Xilinx EDK toolchain ships with a set of IP cores (devices) for use
+ in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range
+ of standard device types (network, serial, etc.) and miscellanious
+ devices (gpio, LCD, spi, etc). Also, since these devices are
+ implemented within the fpga fabric every instance of the device can be
+ synthesised with different options that change the behaviour.
+
+ Each IP-core has a set of parameters which the FPGA designer can use to
+ control how the core is synthesized. Historically, the EDK tool would
+ extract the device parameters relevant to device drivers and copy them
+ into an 'xparameters.h' in the form of #define symbols. This tells the
+ device drivers how the IP cores are configured, but it requres the kernel
+ to be recompiled every time the FPGA bitstream is resynthesized.
+
+ The new approach is to export the parameters into the device tree and
+ generate a new device tree each time the FPGA bitstream changes. The
+ parameters which used to be exported as #defines will now become
+ properties of the device node. In general, device nodes for IP-cores
+ will take the following form:
+
+ (name)@(base-address) {
+ compatible = "xlnx,(ip-core-name)-(HW_VER)"
+ [, (list of compatible devices), ...];
+ reg = <(baseaddr) (size)>;
+ interrupt-parent = <&interrupt-controller-phandle>;
+ interrupts = < ... >;
+ xlnx,(parameter1) = "(string-value)";
+ xlnx,(parameter2) = <(int-value)>;
+ };
+
+ (ip-core-name): the name of the ip block (given after the BEGIN
+ directive in system.mhs). Should be in lowercase
+ and all underscores '_' converted to dashes '-'.
+ (name): is derived from the "PARAMETER INSTANCE" value.
+ (parameter#): C_* parameters from system.mhs. The C_ prefix is
+ dropped from the parameter name, the name is converted
+ to lowercase and all underscore '_' characters are
+ converted to dashes '-'.
+ (baseaddr): the C_BASEADDR parameter.
+ (HW_VER): from the HW_VER parameter.
+ (size): equals C_HIGHADDR - C_BASEADDR + 1
+
+ Typically, the compatible list will include the exact IP core version
+ followed by an older IP core version which implements the same
+ interface or any other device with the same interface.
+
+ 'reg', 'interrupt-parent' and 'interrupts' are all optional properties.
+
+ For example, the following block from system.mhs:
+
+ BEGIN opb_uartlite
+ PARAMETER INSTANCE = opb_uartlite_0
+ PARAMETER HW_VER = 1.00.b
+ PARAMETER C_BAUDRATE = 115200
+ PARAMETER C_DATA_BITS = 8
+ PARAMETER C_ODD_PARITY = 0
+ PARAMETER C_USE_PARITY = 0
+ PARAMETER C_CLK_FREQ = 50000000
+ PARAMETER C_BASEADDR = 0xEC100000
+ PARAMETER C_HIGHADDR = 0xEC10FFFF
+ BUS_INTERFACE SOPB = opb_7
+ PORT OPB_Clk = CLK_50MHz
+ PORT Interrupt = opb_uartlite_0_Interrupt
+ PORT RX = opb_uartlite_0_RX
+ PORT TX = opb_uartlite_0_TX
+ PORT OPB_Rst = sys_bus_reset_0
+ END
+
+ becomes the following device tree node:
+
+ opb-uartlite-0@ec100000 {
+ device_type = "serial";
+ compatible = "xlnx,opb-uartlite-1.00.b";
+ reg = <ec100000 10000>;
+ interrupt-parent = <&opb-intc>;
+ interrupts = <1 0>; // got this from the opb_intc parameters
+ current-speed = <d#115200>; // standard serial device prop
+ clock-frequency = <d#50000000>; // standard serial device prop
+ xlnx,data-bits = <8>;
+ xlnx,odd-parity = <0>;
+ xlnx,use-parity = <0>;
+ };
+
+ Some IP cores actually implement 2 or more logical devices. In this case,
+ the device should still describe the whole IP core with a single node
+ and add a child node for each logical device. The ranges property can
+ be used to translate from parent IP-core to the registers of each device.
+ (Note: this makes the assumption that both logical devices have the same
+ bus binding. If this is not true, then separate nodes should be used for
+ each logical device). The 'cell-index' property can be used to enumerate
+ logical devices within an IP core. For example, the following is the
+ system.mhs entry for the dual ps2 controller found on the ml403 reference
+ design.
+
+ BEGIN opb_ps2_dual_ref
+ PARAMETER INSTANCE = opb_ps2_dual_ref_0
+ PARAMETER HW_VER = 1.00.a
+ PARAMETER C_BASEADDR = 0xA9000000
+ PARAMETER C_HIGHADDR = 0xA9001FFF
+ BUS_INTERFACE SOPB = opb_v20_0
+ PORT Sys_Intr1 = ps2_1_intr
+ PORT Sys_Intr2 = ps2_2_intr
+ PORT Clkin1 = ps2_clk_rx_1
+ PORT Clkin2 = ps2_clk_rx_2
+ PORT Clkpd1 = ps2_clk_tx_1
+ PORT Clkpd2 = ps2_clk_tx_2
+ PORT Rx1 = ps2_d_rx_1
+ PORT Rx2 = ps2_d_rx_2
+ PORT Txpd1 = ps2_d_tx_1
+ PORT Txpd2 = ps2_d_tx_2
+ END
+
+ It would result in the following device tree nodes:
+
+ opb_ps2_dual_ref_0@a9000000 {
+ ranges = <0 a9000000 2000>;
+ // If this device had extra parameters, then they would
+ // go here.
+ ps2@0 {
+ compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
+ reg = <0 40>;
+ interrupt-parent = <&opb-intc>;
+ interrupts = <3 0>;
+ cell-index = <0>;
+ };
+ ps2@1000 {
+ compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
+ reg = <1000 40>;
+ interrupt-parent = <&opb-intc>;
+ interrupts = <3 0>;
+ cell-index = <0>;
+ };
+ };
+
+ Also, the system.mhs file defines bus attachments from the processor
+ to the devices. The device tree structure should reflect the bus
+ attachments. Again an example; this system.mhs fragment:
+
+ BEGIN ppc405_virtex4
+ PARAMETER INSTANCE = ppc405_0
+ PARAMETER HW_VER = 1.01.a
+ BUS_INTERFACE DPLB = plb_v34_0
+ BUS_INTERFACE IPLB = plb_v34_0
+ END
+
+ BEGIN opb_intc
+ PARAMETER INSTANCE = opb_intc_0
+ PARAMETER HW_VER = 1.00.c
+ PARAMETER C_BASEADDR = 0xD1000FC0
+ PARAMETER C_HIGHADDR = 0xD1000FDF
+ BUS_INTERFACE SOPB = opb_v20_0
+ END
+
+ BEGIN opb_uart16550
+ PARAMETER INSTANCE = opb_uart16550_0
+ PARAMETER HW_VER = 1.00.d
+ PARAMETER C_BASEADDR = 0xa0000000
+ PARAMETER C_HIGHADDR = 0xa0001FFF
+ BUS_INTERFACE SOPB = opb_v20_0
+ END
+
+ BEGIN plb_v34
+ PARAMETER INSTANCE = plb_v34_0
+ PARAMETER HW_VER = 1.02.a
+ END
+
+ BEGIN plb_bram_if_cntlr
+ PARAMETER INSTANCE = plb_bram_if_cntlr_0
+ PARAMETER HW_VER = 1.00.b
+ PARAMETER C_BASEADDR = 0xFFFF0000
+ PARAMETER C_HIGHADDR = 0xFFFFFFFF
+ BUS_INTERFACE SPLB = plb_v34_0
+ END
+
+ BEGIN plb2opb_bridge
+ PARAMETER INSTANCE = plb2opb_bridge_0
+ PARAMETER HW_VER = 1.01.a
+ PARAMETER C_RNG0_BASEADDR = 0x20000000
+ PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF
+ PARAMETER C_RNG1_BASEADDR = 0x60000000
+ PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF
+ PARAMETER C_RNG2_BASEADDR = 0x80000000
+ PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF
+ PARAMETER C_RNG3_BASEADDR = 0xC0000000
+ PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF
+ BUS_INTERFACE SPLB = plb_v34_0
+ BUS_INTERFACE MOPB = opb_v20_0
+ END
+
+ Gives this device tree (some properties removed for clarity):
+
+ plb-v34-0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "ibm,plb";
+ ranges; // 1:1 translation
+
+ plb-bram-if-cntrl-0@ffff0000 {
+ reg = <ffff0000 10000>;
+ }
+
+ opb-v20-0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <20000000 20000000 20000000
+ 60000000 60000000 20000000
+ 80000000 80000000 40000000
+ c0000000 c0000000 20000000>;
+
+ opb-uart16550-0@a0000000 {
+ reg = <a00000000 2000>;
+ };
+
+ opb-intc-0@d1000fc0 {
+ reg = <d1000fc0 20>;
+ };
+ };
+ };
+
+ That covers the general approach to binding xilinx IP cores into the
+ device tree. The following are bindings for specific devices:
+
+ i) Xilinx ML300 Framebuffer
+
+ Simple framebuffer device from the ML300 reference design (also on the
+ ML403 reference design as well as others).
+
+ Optional properties:
+ - resolution = <xres yres> : pixel resolution of framebuffer. Some
+ implementations use a different resolution.
+ Default is <d#640 d#480>
+ - virt-resolution = <xvirt yvirt> : Size of framebuffer in memory.
+ Default is <d#1024 d#480>.
+ - rotate-display (empty) : rotate display 180 degrees.
+
+ ii) Xilinx SystemACE
+
+ The Xilinx SystemACE device is used to program FPGAs from an FPGA
+ bitstream stored on a CF card. It can also be used as a generic CF
+ interface device.
+
+ Optional properties:
+ - 8-bit (empty) : Set this property for SystemACE in 8 bit mode
+
+ iii) Xilinx EMAC and Xilinx TEMAC
+
+ Xilinx Ethernet devices. In addition to general xilinx properties
+ listed above, nodes for these devices should include a phy-handle
+ property, and may include other common network device properties
+ like local-mac-address.
+
+ iv) Xilinx Uartlite
+
+ Xilinx uartlite devices are simple fixed speed serial ports.
+
+ Requred properties:
+ - current-speed : Baud rate of uartlite
+
More devices will be defined as this spec matures.
VII - Specifying interrupt information for devices
diff --git a/MAINTAINERS b/MAINTAINERS
index 1c7c229a092..cad0882754a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -787,23 +787,25 @@ B43 WIRELESS DRIVER
P: Michael Buesch
M: mb@bu3sch.de
P: Stefano Brivio
-M: st3@riseup.net
+M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org
-W: http://bcm43xx.berlios.de/
+W: http://linuxwireless.org/en/users/Drivers/b43
S: Maintained
B43LEGACY WIRELESS DRIVER
P: Larry Finger
M: Larry.Finger@lwfinger.net
+P: Stefano Brivio
+M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org
-W: http://bcm43xx.berlios.de/
+W: http://linuxwireless.org/en/users/Drivers/b43
S: Maintained
BCM43XX WIRELESS DRIVER (SOFTMAC BASED VERSION)
P: Larry Finger
M: Larry.Finger@lwfinger.net
P: Stefano Brivio
-M: st3@riseup.net
+M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org
W: http://bcm43xx.berlios.de/
S: Maintained
@@ -3452,15 +3454,10 @@ L: lm-sensors@lm-sensors.org
S: Maintained
SOFTMAC LAYER (IEEE 802.11)
-P: Johannes Berg
-M: johannes@sipsolutions.net
-P: Joe Jezak
-M: josejx@gentoo.org
P: Daniel Drake
M: dsd@gentoo.org
-W: http://softmac.sipsolutions.net/
L: linux-wireless@vger.kernel.org
-S: Maintained
+S: Obsolete
SOFTWARE RAID (Multiple Disks) SUPPORT
P: Ingo Molnar
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a0cdaafa115..a7e9fea978a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1040,6 +1040,8 @@ source "drivers/power/Kconfig"
source "drivers/hwmon/Kconfig"
+source "drivers/watchdog/Kconfig"
+
source "drivers/ssb/Kconfig"
#source "drivers/l3/Kconfig"
diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c
index bd5184fe177..ca9c5b61283 100644
--- a/arch/arm/mach-netx/xc.c
+++ b/arch/arm/mach-netx/xc.c
@@ -190,15 +190,15 @@ struct xc *request_xc(int xcno, struct device *dev)
goto exit;
if (!request_mem_region
- (NETX_PA_XPEC(xcno), XPEC_MEM_SIZE, kobject_name(dev->kobj)))
+ (NETX_PA_XPEC(xcno), XPEC_MEM_SIZE, kobject_name(&dev->kobj)))
goto exit_free;
if (!request_mem_region
- (NETX_PA_XMAC(xcno), XMAC_MEM_SIZE, kobject_name(dev->kobj)))
+ (NETX_PA_XMAC(xcno), XMAC_MEM_SIZE, kobject_name(&dev->kobj)))
goto exit_release_1;
if (!request_mem_region
- (SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE, kobject_name(dev->kobj)))
+ (SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE, kobject_name(&dev->kobj)))
goto exit_release_2;
x->xpec_base = (void * __iomem)io_p2v(NETX_PA_XPEC(xcno));
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index a2d45d742ce..fbfa1920353 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -68,6 +68,7 @@ pxa_ost0_interrupt(int irq, void *dev_id)
if (c->mode == CLOCK_EVT_MODE_ONESHOT) {
/* Disarm the compare/match, signal the event. */
OIER &= ~OIER_E0;
+ OSSR = OSSR_M0;
c->event_handler(c);
} else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
/* Call the event handler as many times as necessary
@@ -100,9 +101,9 @@ pxa_ost0_interrupt(int irq, void *dev_id)
* anything that might put us "very close".
*/
#define MIN_OSCR_DELTA 16
- do {
+ do {
OSSR = OSSR_M0;
- next_match = (OSMR0 += LATCH);
+ next_match = (OSMR0 += LATCH);
c->event_handler(c);
} while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
&& (c->mode == CLOCK_EVT_MODE_PERIODIC));
@@ -114,14 +115,16 @@ pxa_ost0_interrupt(int irq, void *dev_id)
static int
pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
{
- unsigned long irqflags;
+ unsigned long flags, next, oscr;
- raw_local_irq_save(irqflags);
- OSMR0 = OSCR + delta;
- OSSR = OSSR_M0;
+ raw_local_irq_save(flags);
OIER |= OIER_E0;
- raw_local_irq_restore(irqflags);
- return 0;
+ next = OSCR + delta;
+ OSMR0 = next;
+ oscr = OSCR;
+ raw_local_irq_restore(flags);
+
+ return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
}
static void
@@ -132,15 +135,16 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
raw_local_irq_save(irqflags);
- OSMR0 = OSCR + LATCH;
OSSR = OSSR_M0;
OIER |= OIER_E0;
+ OSMR0 = OSCR + LATCH;
raw_local_irq_restore(irqflags);
break;
case CLOCK_EVT_MODE_ONESHOT:
raw_local_irq_save(irqflags);
OIER &= ~OIER_E0;
+ OSSR = OSSR_M0;
raw_local_irq_restore(irqflags);
break;
@@ -149,6 +153,7 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
/* initializing, released, or preparing for suspend */
raw_local_irq_save(irqflags);
OIER &= ~OIER_E0;
+ OSSR = OSSR_M0;
raw_local_irq_restore(irqflags);
break;
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index 4493bcff517..ee40c1a0b83 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -171,7 +171,7 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
* Called from map_io. We need to call to this early enough so that we
* can reserve the fixed SDRAM regions before VM could get hold of them.
*/
-void omapfb_reserve_sdram(void)
+void __init omapfb_reserve_sdram(void)
{
struct bootmem_data *bdata;
unsigned long sdram_start, sdram_size;
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c
index 4103c2c487f..b841ecfd5d5 100644
--- a/arch/frv/mm/init.c
+++ b/arch/frv/mm/init.c
@@ -197,7 +197,7 @@ void __init mem_init(void)
/*
* free the memory that was only required for initialisation
*/
-void __init free_initmem(void)
+void free_initmem(void)
{
#if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL)
unsigned long start, end, addr;
diff --git a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c
index 1189d035d31..bf6d9d8c802 100644
--- a/arch/ia64/hp/sim/boot/fw-emu.c
+++ b/arch/ia64/hp/sim/boot/fw-emu.c
@@ -285,7 +285,7 @@ sys_fw_init (const char *args, int arglen)
}
cmd_line[arglen] = '\0';
- memset(efi_systab, 0, sizeof(efi_systab));
+ memset(efi_systab, 0, sizeof(*efi_systab));
efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
efi_systab->hdr.revision = ((1 << 16) | 00);
efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
index 466bbcb138b..c5c872b250d 100644
--- a/arch/ia64/ia32/ia32priv.h
+++ b/arch/ia64/ia32/ia32priv.h
@@ -290,7 +290,6 @@ struct old_linux32_dirent {
#define _ASM_IA64_ELF_H /* Don't include elf.h */
#include <linux/sched.h>
-#include <asm/processor.h>
/*
* This is used to ensure we don't load something for the wrong architecture.
diff --git a/arch/ia64/kernel/.gitignore b/arch/ia64/kernel/.gitignore
new file mode 100644
index 00000000000..98307759a3b
--- /dev/null
+++ b/arch/ia64/kernel/.gitignore
@@ -0,0 +1 @@
+gate.lds
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 3d45d24a9d6..897e2083a3b 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -678,9 +678,11 @@ int __init acpi_boot_init(void)
/* I/O APIC */
if (acpi_table_parse_madt
- (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1)
- printk(KERN_ERR PREFIX
- "Error parsing MADT - no IOSAPIC entries\n");
+ (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) {
+ if (!ia64_platform_is("sn2"))
+ printk(KERN_ERR PREFIX
+ "Error parsing MADT - no IOSAPIC entries\n");
+ }
/* System-Level Interrupt Routing */
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 6216eba2e38..5181bf551f3 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -218,9 +218,10 @@ efi_gettimeofday (struct timespec *ts)
{
efi_time_t tm;
- memset(ts, 0, sizeof(ts));
- if ((*efi.get_time)(&tm, NULL) != EFI_SUCCESS)
+ if ((*efi.get_time)(&tm, NULL) != EFI_SUCCESS) {
+ memset(ts, 0, sizeof(*ts));
return;
+ }
ts->tv_sec = mktime(tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);
ts->tv_nsec = tm.nanosecond;
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index cfe4654838f..274a5938304 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -748,6 +748,15 @@ skip_numa_setup:
#endif
}
+static inline unsigned char choose_dmode(void)
+{
+#ifdef CONFIG_SMP
+ if (smp_int_redirect & SMP_IRQ_REDIRECTION)
+ return IOSAPIC_LOWEST_PRIORITY;
+#endif
+ return IOSAPIC_FIXED;
+}
+
/*
* ACPI can describe IOSAPIC interrupts via static tables and namespace
* methods. This provides an interface to register those interrupts and
@@ -762,6 +771,7 @@ iosapic_register_intr (unsigned int gsi,
unsigned long flags;
struct iosapic_rte_info *rte;
u32 low32;
+ unsigned char dmode;
/*
* If this GSI has already been registered (i.e., it's a
@@ -791,8 +801,8 @@ iosapic_register_intr (unsigned int gsi,
spin_lock(&irq_desc[irq].lock);
dest = get_target_cpu(gsi, irq);
- err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY,
- polarity, trigger);
+ dmode = choose_dmode();
+ err = register_intr(gsi, irq, dmode, polarity, trigger);
if (err < 0) {
spin_unlock(&irq_desc[irq].lock);
irq = err;
@@ -961,10 +971,12 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
{
int vector, irq;
unsigned int dest = cpu_physical_id(smp_processor_id());
+ unsigned char dmode;
irq = vector = isa_irq_to_vector(isa_irq);
BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL));
- register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
+ dmode = choose_dmode();
+ register_intr(gsi, irq, dmode, polarity, trigger);
DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 44be1c952b7..6dee579f205 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -61,9 +61,11 @@ int show_interrupts(struct seq_file *p, void *v)
unsigned long flags;
if (i == 0) {
- seq_printf(p, " ");
+ char cpuname[16];
+ seq_printf(p, " ");
for_each_online_cpu(j) {
- seq_printf(p, "CPU%d ",j);
+ snprintf(cpuname, 10, "CPU%d", j);
+ seq_printf(p, "%10s ", cpuname);
}
seq_putc(p, '\n');
}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index cc87025e8f5..10b48cd15a8 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -571,7 +571,7 @@ out:
* Outputs
* None
*/
-static void __init
+void
ia64_mca_register_cpev (int cpev)
{
/* Register the CPE interrupt vector with SAL */
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
index 6ef6ffb943a..396004e8cd1 100644
--- a/arch/ia64/kernel/palinfo.c
+++ b/arch/ia64/kernel/palinfo.c
@@ -470,7 +470,7 @@ register_info(char *page)
return p - page;
}
-static const char *proc_features[]={
+static char *proc_features_0[]={ /* Feature set 0 */
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
@@ -502,25 +502,92 @@ static const char *proc_features[]={
"Enable BERR promotion"
};
+static char *proc_features_16[]={ /* Feature set 16 */
+ "Disable ETM",
+ "Enable ETM",
+ "Enable MCA on half-way timer",
+ "Enable snoop WC",
+ NULL,
+ "Enable Fast Deferral",
+ "Disable MCA on memory aliasing",
+ "Enable RSB",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "DP system processor",
+ "Low Voltage",
+ "HT supported",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL
+};
+
+static char **proc_features[]={
+ proc_features_0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ proc_features_16,
+ NULL, NULL, NULL, NULL,
+};
+
+static char *
+feature_set_info(char *page, u64 avail, u64 status, u64 control, u64 set)
+{
+ char *p = page;
+ char **vf, **v;
+ int i;
+
+ vf = v = proc_features[set];
+ for(i=0; i < 64; i++, avail >>=1, status >>=1, control >>=1) {
+
+ if (!(control)) /* No remaining bits set */
+ break;
+ if (!(avail & 0x1)) /* Print only bits that are available */
+ continue;
+ if (vf)
+ v = vf + i;
+ if ( v && *v ) {
+ p += sprintf(p, "%-40s : %s %s\n", *v,
+ avail & 0x1 ? (status & 0x1 ?
+ "On " : "Off"): "",
+ avail & 0x1 ? (control & 0x1 ?
+ "Ctrl" : "NoCtrl"): "");
+ } else {
+ p += sprintf(p, "Feature set %2ld bit %2d\t\t\t"
+ " : %s %s\n",
+ set, i,
+ avail & 0x1 ? (status & 0x1 ?
+ "On " : "Off"): "",
+ avail & 0x1 ? (control & 0x1 ?
+ "Ctrl" : "NoCtrl"): "");
+ }
+ }
+ return p;
+}
static int
processor_info(char *page)
{
char *p = page;
- const char **v = proc_features;
- u64 avail=1, status=1, control=1;
- int i;
+ u64 avail=1, status=1, control=1, feature_set=0;
s64 ret;
- if ((ret=ia64_pal_proc_get_features(&avail, &status, &control)) != 0) return 0;
+ do {
+ ret = ia64_pal_proc_get_features(&avail, &status, &control,
+ feature_set);
+ if (ret < 0) {
+ return p - page;
+ }
+ if (ret == 1) {
+ feature_set++;
+ continue;
+ }
+
+ p = feature_set_info(p, avail, status, control, feature_set);
+
+ feature_set++;
+ } while(1);
- for(i=0; i < 64; i++, v++,avail >>=1, status >>=1, control >>=1) {
- if ( ! *v ) continue;
- p += sprintf(p, "%-40s : %s%s %s\n", *v,
- avail & 0x1 ? "" : "NotImpl",
- avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "",
- avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): "");
- }
return p - page;
}
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c
index e796e29f8e1..2cb9425e042 100644
--- a/arch/ia64/kernel/patch.c
+++ b/arch/ia64/kernel/patch.c
@@ -129,9 +129,6 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
first_time = 0;
if (need_workaround)
printk(KERN_INFO "Leaving McKinley Errata 9 workaround enabled\n");
- else
- printk(KERN_INFO "McKinley Errata 9 workaround not needed; "
- "disabling it\n");
}
if (need_workaround)
return;
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 59169bf7145..73e7c2e40b5 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -558,7 +558,7 @@ static ctl_table pfm_sysctl_dir[] = {
{
.ctl_name = CTL_UNNUMBERED,
.procname = "perfmon",
- .mode = 0755,
+ .mode = 0555,
.child = pfm_ctl_table,
},
{}
@@ -567,7 +567,7 @@ static ctl_table pfm_sysctl_root[] = {
{
.ctl_name = CTL_KERN,
.procname = "kernel",
- .mode = 0755,
+ .mode = 0555,
.child = pfm_sysctl_dir,
},
{}
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index d3c538be466..7e9c275ea14 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -146,6 +146,46 @@ find_bootmap_location (unsigned long start, unsigned long end, void *arg)
return 0;
}
+#ifdef CONFIG_SMP
+static void *cpu_data;
+/**
+ * per_cpu_init - setup per-cpu variables
+ *
+ * Allocate and setup per-cpu data areas.
+ */
+void * __cpuinit
+per_cpu_init (void)
+{
+ int cpu;
+ static int first_time=1;
+
+ /*
+ * get_free_pages() cannot be used before cpu_init() done. BSP
+ * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
+ * get_zeroed_page().
+ */
+ if (first_time) {
+ first_time=0;
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
+ __per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
+ cpu_data += PERCPU_PAGE_SIZE;
+ per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
+ }
+ }
+ return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+}
+
+static inline void
+alloc_per_cpu_data(void)
+{
+ cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
+ PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
+}
+#else
+#define alloc_per_cpu_data() do { } while (0)
+#endif /* CONFIG_SMP */
+
/**
* find_memory - setup memory map
*
@@ -182,41 +222,9 @@ find_memory (void)
find_initrd();
+ alloc_per_cpu_data();
}
-#ifdef CONFIG_SMP
-/**
- * per_cpu_init - setup per-cpu variables
- *
- * Allocate and setup per-cpu data areas.
- */
-void * __cpuinit
-per_cpu_init (void)
-{
- void *cpu_data;
- int cpu;
- static int first_time=1;
-
- /*
- * get_free_pages() cannot be used before cpu_init() done. BSP
- * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls
- * get_zeroed_page().
- */
- if (first_time) {
- first_time=0;
- cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS,
- PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start);
- __per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start;
- cpu_data += PERCPU_PAGE_SIZE;
- per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
- }
- }
- return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
-}
-#endif /* CONFIG_SMP */
-
static int
count_pages (u64 start, u64 end, void *arg)
{
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 0f9b12683bf..53351c3cd7b 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -5,7 +5,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2007 Silicon Graphics, Inc. All Rights Reserved.
*/
#include <linux/irq.h>
@@ -85,12 +85,18 @@ static void sn_shutdown_irq(unsigned int irq)
{
}
+extern void ia64_mca_register_cpev(int);
+
static void sn_disable_irq(unsigned int irq)
{
+ if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
+ ia64_mca_register_cpev(0);
}
static void sn_enable_irq(unsigned int irq)
{
+ if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
+ ia64_mca_register_cpev(irq);
}
static void sn_ack_irq(unsigned int irq)
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index e336e1692a7..81785b78bc1 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2004-2006 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004-2007 Silicon Graphics, Inc. All Rights Reserved.
*/
@@ -257,7 +257,9 @@ xpc_hb_checker(void *ignore)
set_cpus_allowed(current, cpumask_of_cpu(XPC_HB_CHECK_CPU));
+ /* set our heartbeating to other partitions into motion */
xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
+ xpc_hb_beater(0);
while (!(volatile int) xpc_exiting) {
@@ -1338,16 +1340,8 @@ xpc_init(void)
dev_warn(xpc_part, "can't register die notifier\n");
}
-
- /*
- * Set the beating to other partitions into motion. This is
- * the last requirement for other partitions' discovery to
- * initiate communications with us.
- */
init_timer(&xpc_hb_timer);
xpc_hb_timer.function = xpc_hb_beater;
- xpc_hb_beater(0);
-
/*
* The real work-horse behind xpc. This processes incoming
diff --git a/arch/powerpc/boot/dts/walnut.dts b/arch/powerpc/boot/dts/walnut.dts
index fa681f5343f..754fa3960f8 100644
--- a/arch/powerpc/boot/dts/walnut.dts
+++ b/arch/powerpc/boot/dts/walnut.dts
@@ -122,7 +122,9 @@
device_type = "network";
compatible = "ibm,emac-405gp", "ibm,emac";
interrupt-parent = <&UIC0>;
- interrupts = <9 4 f 4>;
+ interrupts = <
+ f 4 /* Ethernet */
+ 9 4 /* Ethernet Wake Up */>;
local-mac-address = [000000000000]; /* Filled in by zImage */
reg = <ef600800 70>;
mal-device = <&MAL>;
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 39b27e5ef6c..31147a03772 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -21,6 +21,14 @@
# (default ./arch/powerpc/boot)
# -W dir specify working directory for temporary files (default .)
+# Stop execution if any command fails
+set -e
+
+# Allow for verbose output
+if [ "$V" = 1 ]; then
+ set -x
+fi
+
# defaults
kernel=
ofile=zImage
@@ -111,7 +119,7 @@ if [ -n "$dts" ]; then
if [ -z "$dtb" ]; then
dtb="$platform.dtb"
fi
- dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1
+ dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts"
fi
if [ -z "$kernel" ]; then
@@ -149,7 +157,6 @@ cuboot*)
ps3)
platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
lds=$object/zImage.ps3.lds
- binary=y
gzip=
ext=bin
objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
@@ -233,7 +240,7 @@ entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3`
if [ -n "$binary" ]; then
mv "$ofile" "$ofile".elf
- ${CROSS}objcopy -O binary "$ofile".elf "$ofile".bin
+ ${CROSS}objcopy -O binary "$ofile".elf "$ofile"
fi
# post-processing needed for some platforms
@@ -246,9 +253,9 @@ coff)
$object/hack-coff "$ofile"
;;
cuboot*)
- gzip -f -9 "$ofile".bin
+ gzip -f -9 "$ofile"
mkimage -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
- $uboot_version -d "$ofile".bin.gz "$ofile"
+ $uboot_version -d "$ofile".gz "$ofile"
;;
treeboot*)
mv "$ofile" "$ofile.elf"
@@ -269,11 +276,11 @@ ps3)
# then copied to offset 0x100. At runtime the bootwrapper program
# copies the 0x100 bytes at __system_reset_kernel to addr 0x100.
- system_reset_overlay=0x`${CROSS}nm "$ofile".elf \
+ system_reset_overlay=0x`${CROSS}nm "$ofile" \
| grep ' __system_reset_overlay$' \
| cut -d' ' -f1`
system_reset_overlay=`printf "%d" $system_reset_overlay`
- system_reset_kernel=0x`${CROSS}nm "$ofile".elf \
+ system_reset_kernel=0x`${CROSS}nm "$ofile" \
| grep ' __system_reset_kernel$' \
| cut -d' ' -f1`
system_reset_kernel=`printf "%d" $system_reset_kernel`
@@ -282,23 +289,15 @@ ps3)
rm -f "$object/otheros.bld"
- msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
- skip=$overlay_dest seek=$system_reset_kernel \
- count=$overlay_size bs=1 2>&1)
+ ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
- if [ $? -ne "0" ]; then
- echo $msg
- exit 1
- fi
-
- msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
- skip=$system_reset_overlay seek=$overlay_dest \
- count=$overlay_size bs=1 2>&1)
+ dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
+ skip=$overlay_dest seek=$system_reset_kernel \
+ count=$overlay_size bs=1
- if [ $? -ne "0" ]; then
- echo $msg
- exit 2
- fi
+ dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
+ skip=$system_reset_overlay seek=$overlay_dest \
+ count=$overlay_size bs=1
gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
;;
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig
index 1ccf3ed7693..78c968aade4 100644
--- a/arch/powerpc/configs/pasemi_defconfig
+++ b/arch/powerpc/configs/pasemi_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc4
-# Thu Aug 30 16:40:47 2007
+# Linux kernel version: 2.6.24-rc2
+# Tue Nov 6 23:23:50 2007
#
CONFIG_PPC64=y
@@ -10,6 +10,7 @@ CONFIG_PPC64=y
#
CONFIG_POWER4_ONLY=y
CONFIG_POWER4=y
+# CONFIG_TUNE_CELL is not set
CONFIG_PPC_FPU=y
CONFIG_ALTIVEC=y
CONFIG_PPC_STD_MMU=y
@@ -18,8 +19,13 @@ CONFIG_PPC_MM_SLICES=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_64BIT=y
+CONFIG_WORD_SIZE=64
CONFIG_PPC_MERGE=y
CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -65,7 +71,10 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CPUSETS is not set
+# 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
@@ -86,7 +95,6 @@ CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
@@ -107,14 +115,15 @@ CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLOCK_COMPAT=y
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
@@ -125,7 +134,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# Platform support
#
CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_EMBEDDED6xx is not set
# CONFIG_PPC_82xx is not set
# CONFIG_PPC_83xx is not set
# CONFIG_PPC_86xx is not set
@@ -141,6 +149,7 @@ CONFIG_PPC_PASEMI=y
# PA Semi PWRficient options
#
CONFIG_PPC_PASEMI_IOMMU=y
+# CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set
CONFIG_PPC_PASEMI_MDIO=y
CONFIG_ELECTRA_IDE=y
# CONFIG_PPC_CELLEB is not set
@@ -156,29 +165,52 @@ CONFIG_MPIC=y
# CONFIG_U3_DART is not set
# CONFIG_PPC_RTAS is not set
# CONFIG_MMIO_NVRAM is not set
+CONFIG_MPIC_BROKEN_REGREAD=y
# CONFIG_PPC_MPC106 is not set
# CONFIG_PPC_970_NAP is not set
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
+# CPU Frequency drivers
+#
+CONFIG_PPC_PASEMI_CPUFREQ=y
# CONFIG_CPM2 is not set
# CONFIG_FSL_ULI1575 is not set
#
# Kernel options
#
-CONFIG_HZ_100=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=100
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
-CONFIG_PREEMPT_BKL=y
+# CONFIG_PREEMPT_BKL is not set
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
-CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_FORCE_MAX_ZONEORDER=9
CONFIG_IOMMU_VMERGE=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
# CONFIG_KEXEC is not set
@@ -196,12 +228,13 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
-# CONFIG_PPC_HAS_HASH_64K is not set
-# CONFIG_PPC_64K_PAGES is not set
+CONFIG_PPC_HAS_HASH_64K=y
+CONFIG_PPC_64K_PAGES=y
# CONFIG_SCHED_SMT is not set
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
@@ -222,11 +255,8 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
CONFIG_PCCARD=y
CONFIG_PCMCIA_DEBUG=y
CONFIG_PCMCIA=y
@@ -240,6 +270,7 @@ CONFIG_CARDBUS=y
# CONFIG_YENTA is not set
# CONFIG_PD6729 is not set
# CONFIG_I82092 is not set
+# CONFIG_ELECTRA_CF is not set
# CONFIG_HOTPLUG_PCI is not set
CONFIG_KERNEL_START=0xc000000000000000
@@ -255,7 +286,7 @@ CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
+CONFIG_XFRM_USER=y
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
CONFIG_NET_KEY=y
@@ -281,6 +312,7 @@ CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
@@ -306,10 +338,6 @@ 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
#
@@ -338,6 +366,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -361,6 +390,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
@@ -385,6 +415,7 @@ CONFIG_MTD_CFI_I2=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -402,7 +433,15 @@ CONFIG_MTD_PHRAM=y
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
# CONFIG_MTD_ONENAND is not set
#
@@ -455,10 +494,42 @@ CONFIG_IDE_PROC_FS=y
# IDE chipset support/bugfixes
#
# CONFIG_IDE_GENERIC is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
# CONFIG_BLK_DEV_HD is not set
#
@@ -498,10 +569,11 @@ 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=y
-CONFIG_SCSI_3W_9XXX=y
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
@@ -574,9 +646,10 @@ CONFIG_ATA_GENERIC=y
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL 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_PCMCIA is not set
+CONFIG_PATA_PCMCIA=y
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
@@ -589,41 +662,13 @@ CONFIG_ATA_GENERIC=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
#
# CONFIG_FIREWIRE is not set
-CONFIG_IEEE1394=y
-
-#
-# Subsystem Options
-#
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-
-#
-# Controllers
-#
-CONFIG_IEEE1394_PCILYNX=y
-CONFIG_IEEE1394_OHCI1394=y
-
-#
-# Protocols
-#
-# CONFIG_IEEE1394_VIDEO1394 is not set
-CONFIG_IEEE1394_SBP2=y
-# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set
-# CONFIG_IEEE1394_ETH1394 is not set
-# CONFIG_IEEE1394_DV1394 is not set
-CONFIG_IEEE1394_RAWIO=y
+# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
@@ -633,6 +678,8 @@ CONFIG_DUMMY=y
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
CONFIG_PHYLIB=y
@@ -649,6 +696,7 @@ CONFIG_MARVELL_PHY=y
# CONFIG_BROADCOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
@@ -657,13 +705,16 @@ CONFIG_MII=y
# CONFIG_NET_VENDOR_3COM 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
@@ -682,6 +733,7 @@ CONFIG_NETDEV_1000=y
CONFIG_E1000=y
CONFIG_E1000_NAPI=y
# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -689,6 +741,7 @@ CONFIG_E1000_NAPI=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=y
# CONFIG_BNX2 is not set
@@ -697,12 +750,15 @@ CONFIG_TIGON3=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_PASEMI_MAC=y
# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
# CONFIG_TR is not set
#
@@ -749,7 +805,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=y
-# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
@@ -810,15 +865,12 @@ CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=4
# CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_PASEMI=y
CONFIG_GEN_RTC=y
CONFIG_GEN_RTC_X=y
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
#
# PCMCIA character devices
@@ -896,8 +948,6 @@ CONFIG_SENSORS_EEPROM=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
@@ -905,12 +955,12 @@ CONFIG_HWMON_VID=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -946,6 +996,13 @@ CONFIG_SENSORS_LM90=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
@@ -963,14 +1020,14 @@ CONFIG_DAB=y
#
# Graphics support
#
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_AGP is not set
+CONFIG_DRM=y
+# CONFIG_DRM_TDFX is not set
+# CONFIG_DRM_R128 is not set
+CONFIG_DRM_RADEON=y
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
CONFIG_VGASTATE=y
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
@@ -979,6 +1036,7 @@ CONFIG_FB_DDC=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
@@ -1026,6 +1084,15 @@ CONFIG_FB_RADEON_BACKLIGHT=y
# CONFIG_FB_PM3 is not set
# CONFIG_FB_IBM_GXT4500 is not set
# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
@@ -1178,6 +1245,7 @@ CONFIG_SND_USB_USX2Y=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
#
# USB Input Devices
@@ -1328,6 +1396,7 @@ CONFIG_RTC_INTF_DEV=y
# I2C RTC drivers
#
CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_RS5C372 is not set
@@ -1357,19 +1426,6 @@ CONFIG_RTC_DRV_DS1307=y
#
#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
# Userspace I/O
#
# CONFIG_UIO is not set
@@ -1388,7 +1444,6 @@ CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
@@ -1436,7 +1491,6 @@ CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
CONFIG_CONFIGFS_FS=y
#
@@ -1449,30 +1503,43 @@ CONFIG_CONFIGFS_FS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN 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
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
# CONFIG_SUNRPC_BIND34 is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
@@ -1501,10 +1568,6 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
@@ -1545,10 +1608,6 @@ CONFIG_NLS_ISO8859_1=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
# CONFIG_UCC_SLOW is not set
@@ -1561,23 +1620,24 @@ CONFIG_CRC_CCITT=y
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-
-#
-# Instrumentation Support
-#
+CONFIG_INSTRUMENTATION=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
# CONFIG_KPROBES is not set
+# CONFIG_MARKERS is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
@@ -1586,7 +1646,7 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
-CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_SLUB_DEBUG_ON is not set
@@ -1601,9 +1661,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
# CONFIG_FORCED_INLINING is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -1620,6 +1683,7 @@ CONFIG_XMON_DISASSEMBLY=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
@@ -1628,34 +1692,38 @@ CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_ECB is not set
CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
+CONFIG_CRYPTO_BLOWFISH=y
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# 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_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_HW is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 05582af50c5..3e90c835fe1 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23-rc4
-# Thu Aug 30 16:47:09 2007
+# Linux kernel version: 2.6.24-rc2
+# Tue Nov 6 23:43:56 2007
#
CONFIG_PPC64=y
@@ -11,6 +11,7 @@ CONFIG_PPC64=y
# CONFIG_POWER4_ONLY is not set
CONFIG_POWER3=y
CONFIG_POWER4=y
+# CONFIG_TUNE_CELL is not set
CONFIG_PPC_FPU=y
CONFIG_ALTIVEC=y
CONFIG_PPC_STD_MMU=y
@@ -19,8 +20,13 @@ CONFIG_VIRT_CPU_ACCOUNTING=y
CONFIG_SMP=y
CONFIG_NR_CPUS=32
CONFIG_64BIT=y
+CONFIG_WORD_SIZE=64
CONFIG_PPC_MERGE=y
CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_IRQ_PER_CPU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -72,8 +78,15 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_CPUACCT is not set
CONFIG_CPUSETS=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
+CONFIG_PROC_PID_CPUSET=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
@@ -93,7 +106,6 @@ CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
@@ -114,6 +126,7 @@ CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_BLK_DEV_BSG=y
+CONFIG_BLOCK_COMPAT=y
#
# IO Schedulers
@@ -132,7 +145,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# Platform support
#
CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_EMBEDDED6xx is not set
# CONFIG_PPC_82xx is not set
# CONFIG_PPC_83xx is not set
# CONFIG_PPC_86xx is not set
@@ -155,7 +167,15 @@ CONFIG_VIOPATH=y
CONFIG_PPC_PMAC=y
CONFIG_PPC_PMAC64=y
CONFIG_PPC_MAPLE=y
-# CONFIG_PPC_PASEMI is not set
+CONFIG_PPC_PASEMI=y
+
+#
+# PA Semi PWRficient options
+#
+CONFIG_PPC_PASEMI_IOMMU=y
+# CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set
+CONFIG_PPC_PASEMI_MDIO=y
+CONFIG_ELECTRA_IDE=y
CONFIG_PPC_CELLEB=y
# CONFIG_PPC_PS3 is not set
CONFIG_PPC_CELL=y
@@ -188,6 +208,7 @@ CONFIG_RTAS_FLASH=m
CONFIG_PPC_PMI=m
CONFIG_MMIO_NVRAM=y
CONFIG_MPIC_U3_HT_IRQS=y
+CONFIG_MPIC_BROKEN_REGREAD=y
CONFIG_IBMVIO=y
# CONFIG_IBMEBUS is not set
# CONFIG_PPC_MPC106 is not set
@@ -201,6 +222,8 @@ CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -211,6 +234,7 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
# CPU Frequency drivers
#
CONFIG_CPU_FREQ_PMAC64=y
+CONFIG_PPC_PASEMI_CPUFREQ=y
# CONFIG_CPM2 is not set
CONFIG_AXON_RAM=m
# CONFIG_FSL_ULI1575 is not set
@@ -254,6 +278,8 @@ CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTPLUG_SPARSE=y
CONFIG_SPLIT_PTLOCK_CPUS=4
@@ -268,6 +294,7 @@ CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
CONFIG_SUSPEND_SMP_POSSIBLE=y
+CONFIG_HIBERNATION_SMP_POSSIBLE=y
CONFIG_SECCOMP=y
# CONFIG_WANT_DEVICE_TREE is not set
CONFIG_ISA_DMA_API=y
@@ -284,12 +311,22 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
+CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
#
-# PCCARD (PCMCIA/CardBus) support
+# PC-card bridges
#
-# CONFIG_PCCARD is not set
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_ELECTRA_CF=y
CONFIG_HOTPLUG_PCI=m
# CONFIG_HOTPLUG_PCI_FAKE is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
@@ -319,7 +356,10 @@ CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
CONFIG_NET_IPIP=y
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
@@ -333,6 +373,7 @@ CONFIG_INET_TUNNEL=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
@@ -404,6 +445,7 @@ CONFIG_NETFILTER_XT_MATCH_STATE=m
CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
CONFIG_NETFILTER_XT_MATCH_STRING=m
CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
CONFIG_NETFILTER_XT_MATCH_U32=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
@@ -465,10 +507,6 @@ CONFIG_LLC=y
# 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
CONFIG_NET_CLS_ROUTE=y
@@ -498,6 +536,7 @@ CONFIG_NET_CLS_ROUTE=y
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -539,6 +578,8 @@ CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -550,6 +591,11 @@ CONFIG_IDE_PROC_FS=y
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
CONFIG_IDEPCI_PCIBUS_ORDER=y
@@ -557,8 +603,6 @@ CONFIG_IDEPCI_PCIBUS_ORDER=y
CONFIG_BLK_DEV_GENERIC=y
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_ONLYDISK is not set
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
CONFIG_BLK_DEV_AMD74XX=y
@@ -590,7 +634,7 @@ CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
# CONFIG_BLK_DEV_HD is not set
#
@@ -631,6 +675,7 @@ CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_SRP_ATTRS=y
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
@@ -671,19 +716,20 @@ CONFIG_SCSI_LPFC=m
# CONFIG_SCSI_DC390T is not set
CONFIG_SCSI_DEBUG=m
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
CONFIG_ATA=y
CONFIG_ATA_NONSTANDARD=y
# CONFIG_SATA_AHCI is not set
CONFIG_SATA_SVW=y
# CONFIG_ATA_PIIX is not set
-# CONFIG_SATA_MV is not set
+CONFIG_SATA_MV=y
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIL24 is not set
+CONFIG_SATA_SIL24=y
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
@@ -713,8 +759,10 @@ CONFIG_SATA_SVW=y
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL 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_PCMCIA=y
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
@@ -725,6 +773,7 @@ CONFIG_SATA_SVW=y
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_VIA is not set
CONFIG_PATA_WINBOND=y
+CONFIG_PATA_PLATFORM=y
CONFIG_PATA_SCC=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
@@ -745,15 +794,10 @@ CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_EMC=m
# CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_MULTIPATH_HP is not set
# CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+# CONFIG_DM_UEVENT is not set
# 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
@@ -800,13 +844,15 @@ CONFIG_BONDING=m
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
-CONFIG_PHYLIB=m
+CONFIG_PHYLIB=y
#
# MII PHY device drivers
#
-CONFIG_MARVELL_PHY=m
+CONFIG_MARVELL_PHY=y
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
# CONFIG_LXT_PHY is not set
@@ -818,6 +864,9 @@ CONFIG_BROADCOM_PHY=m
CONFIG_FIXED_PHY=m
CONFIG_FIXED_MII_10_FDX=y
CONFIG_FIXED_MII_100_FDX=y
+# CONFIG_FIXED_MII_1000_FDX is not set
+CONFIG_FIXED_MII_AMNT=1
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_HAPPYMEAL is not set
@@ -829,6 +878,11 @@ CONFIG_VORTEX=y
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
CONFIG_IBMVETH=m
+# CONFIG_IBM_NEW_EMAC is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+CONFIG_IBM_NEW_EMAC_RGMII=y
+CONFIG_IBM_NEW_EMAC_TAH=y
+CONFIG_IBM_NEW_EMAC_EMAC4=y
CONFIG_NET_PCI=y
CONFIG_PCNET32=y
# CONFIG_PCNET32_NAPI is not set
@@ -836,7 +890,6 @@ CONFIG_PCNET32=y
# 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=y
# CONFIG_FEALNX is not set
@@ -856,6 +909,7 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
CONFIG_E1000=y
# CONFIG_E1000_NAPI is not set
# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -863,6 +917,7 @@ CONFIG_E1000=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=y
# CONFIG_BNX2 is not set
@@ -872,13 +927,16 @@ CONFIG_SPIDER_NET=m
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
CONFIG_IXGB=m
# CONFIG_IXGB_NAPI is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
-CONFIG_PASEMI_MAC=m
+# CONFIG_NIU is not set
+CONFIG_PASEMI_MAC=y
# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
CONFIG_TR=y
CONFIG_IBMOL=y
# CONFIG_3C359 is not set
@@ -899,6 +957,7 @@ CONFIG_IBMOL=y
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET_MII is not set
# CONFIG_USB_USBNET is not set
+# CONFIG_NET_PCMCIA is not set
# CONFIG_WAN is not set
CONFIG_ISERIES_VETH=m
# CONFIG_FDDI is not set
@@ -918,6 +977,7 @@ CONFIG_SLHC=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
CONFIG_NETPOLL=y
CONFIG_NETPOLL_TRAP=y
CONFIG_NET_POLL_CONTROLLER=y
@@ -939,7 +999,6 @@ CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=m
# CONFIG_INPUT_EVBUG is not set
@@ -1002,6 +1061,7 @@ CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_PCI=y
+# CONFIG_SERIAL_8250_CS is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
@@ -1029,14 +1089,18 @@ CONFIG_HVC_RTAS=y
CONFIG_HVC_BEAT=y
CONFIG_HVCS=m
# CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
# CONFIG_HANGCHECK_TIMER is not set
@@ -1068,6 +1132,7 @@ CONFIG_I2C_POWERMAC=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_PASEMI=y
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_I2C_SIMTEC is not set
@@ -1106,6 +1171,13 @@ CONFIG_I2C_POWERMAC=y
# 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
@@ -1122,18 +1194,8 @@ CONFIG_I2C_POWERMAC=y
#
# Graphics support
#
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-
-#
-# Display device support
-#
-CONFIG_DISPLAY_SUPPORT=y
-
-#
-# Display hardware drivers
-#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
@@ -1142,6 +1204,7 @@ CONFIG_FB_DDC=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
@@ -1192,6 +1255,19 @@ CONFIG_FB_RADEON_BACKLIGHT=y
# CONFIG_FB_PM3 is not set
CONFIG_FB_IBM_GXT4500=y
# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
#
# Console display driver support
@@ -1333,6 +1409,12 @@ CONFIG_SND_AOA_SOUNDBUS_I2S=m
# CONFIG_SND_USB_CAIAQ is not set
#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
# System on Chip audio support
#
# CONFIG_SND_SOC is not set
@@ -1348,6 +1430,7 @@ CONFIG_SND_AOA_SOUNDBUS_I2S=m
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
#
# USB Input Devices
@@ -1489,19 +1572,53 @@ CONFIG_EDAC=y
#
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_EDAC_PASEMI=y
+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
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
#
-# DMA Engine support
+# SPI RTC drivers
#
-# CONFIG_DMA_ENGINE is not set
#
-# DMA Clients
+# Platform RTC drivers
#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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
#
-# DMA Devices
+# on-CPU RTC drivers
#
#
@@ -1585,7 +1702,6 @@ CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
#
@@ -1604,10 +1720,7 @@ CONFIG_CRAMFS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
@@ -1619,6 +1732,7 @@ CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
@@ -1626,6 +1740,7 @@ CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
+CONFIG_SUNRPC_XPRT_RDMA=m
# CONFIG_SUNRPC_BIND34 is not set
CONFIG_RPCSEC_GSS_KRB5=y
CONFIG_RPCSEC_GSS_SPKM3=m
@@ -1662,10 +1777,6 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
@@ -1706,10 +1817,6 @@ CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
-
-#
-# Distributed Lock Manager
-#
# CONFIG_DLM is not set
# CONFIG_UCC_SLOW is not set
@@ -1733,18 +1840,17 @@ CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
-
-#
-# Instrumentation Support
-#
+CONFIG_INSTRUMENTATION=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
# CONFIG_KPROBES is not set
+# CONFIG_MARKERS is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
@@ -1768,9 +1874,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUG_PAGEALLOC is not set
@@ -1780,6 +1889,7 @@ CONFIG_XMON=y
# CONFIG_XMON_DEFAULT is not set
CONFIG_XMON_DISASSEMBLY=y
CONFIG_IRQSTACKS=y
+# CONFIG_VIRQ_DEBUG is not set
CONFIG_BOOTX_TEXT=y
# CONFIG_PPC_EARLY_DEBUG is not set
@@ -1788,6 +1898,7 @@ CONFIG_BOOTX_TEXT=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
@@ -1812,6 +1923,7 @@ CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
@@ -1826,9 +1938,12 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
# CONFIG_CRYPTO_CAMELLIA is not set
CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index d3fb7d0c6c1..9ed351f3c96 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1104,6 +1104,16 @@ static struct cpu_spec __initdata cpu_specs[] = {
{
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000850,
+ .cpu_name = "440GR Rev. A",
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER_BOOKE,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .platform = "ppc440",
+ },
+ { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
+ .pvr_mask = 0xf0000fff,
+ .pvr_value = 0x40000858,
.cpu_name = "440EP Rev. A",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
@@ -1115,28 +1125,27 @@ static struct cpu_spec __initdata cpu_specs[] = {
{
.pvr_mask = 0xf0000fff,
.pvr_value = 0x400008d3,
- .cpu_name = "440EP Rev. B",
+ .cpu_name = "440GR Rev. B",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.icache_bsize = 32,
.dcache_bsize = 32,
- .cpu_setup = __setup_cpu_440ep,
.platform = "ppc440",
},
- { /* 440EPX */
- .pvr_mask = 0xf0000ffb,
- .pvr_value = 0x200008D0,
- .cpu_name = "440EPX",
+ { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
+ .pvr_mask = 0xf0000fff,
+ .pvr_value = 0x400008db,
+ .cpu_name = "440EP Rev. B",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.icache_bsize = 32,
.dcache_bsize = 32,
- .cpu_setup = __setup_cpu_440epx,
+ .cpu_setup = __setup_cpu_440ep,
.platform = "ppc440",
},
{ /* 440GRX */
.pvr_mask = 0xf0000ffb,
- .pvr_value = 0x200008D8,
+ .pvr_value = 0x200008D0,
.cpu_name = "440GRX",
.cpu_features = CPU_FTRS_44X,
.cpu_user_features = COMMON_USER_BOOKE,
@@ -1145,6 +1154,17 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_440grx,
.platform = "ppc440",
},
+ { /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */
+ .pvr_mask = 0xf0000ffb,
+ .pvr_value = 0x200008D8,
+ .cpu_name = "440EPX",
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440epx,
+ .platform = "ppc440",
+ },
{ /* 440GP Rev. B */
.pvr_mask = 0xf0000fff,
.pvr_value = 0x40000440,
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 21d889e63e8..a7572cf464b 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -244,6 +244,13 @@ syscall_exit_cont:
andis. r10,r0,DBCR0_IC@h
bnel- load_dbcr0
#endif
+#ifdef CONFIG_44x
+ lis r4,icache_44x_need_flush@ha
+ lwz r5,icache_44x_need_flush@l(r4)
+ cmplwi cr0,r5,0
+ bne- 2f
+1:
+#endif /* CONFIG_44x */
stwcx. r0,0,r1 /* to clear the reservation */
lwz r4,_LINK(r1)
lwz r5,_CCR(r1)
@@ -258,6 +265,12 @@ syscall_exit_cont:
mtspr SPRN_SRR1,r8
SYNC
RFI
+#ifdef CONFIG_44x
+2: li r7,0
+ iccci r0,r0
+ stw r7,icache_44x_need_flush@l(r4)
+ b 1b
+#endif /* CONFIG_44x */
66: li r3,-ENOSYS
b ret_from_syscall
@@ -683,6 +696,16 @@ resume_kernel:
/* interrupts are hard-disabled at this point */
restore:
+#ifdef CONFIG_44x
+ lis r4,icache_44x_need_flush@ha
+ lwz r5,icache_44x_need_flush@l(r4)
+ cmplwi cr0,r5,0
+ beq+ 1f
+ li r6,0
+ iccci r0,r0
+ stw r6,icache_44x_need_flush@l(r4)
+1:
+#endif /* CONFIG_44x */
lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
REST_4GPRS(3, r1)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 97c5857faf0..c34986835a4 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -904,7 +904,7 @@ handle_page_fault:
*/
12: bl .save_nvgprs
addi r3,r1,STACK_FRAME_OVERHEAD
- lwz r4,_DAR(r1)
+ ld r4,_DAR(r1)
bl .low_hash_fault
b .ret_from_except
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index abd2957fe53..c3cf0e8f3ac 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -122,7 +122,7 @@ static ctl_table powersave_nap_sysctl_root[] = {
{
.ctl_name = CTL_KERN,
.procname = "kernel",
- .mode = 0755,
+ .mode = 0555,
.child = powersave_nap_ctl_table,
},
{}
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 8533de50347..8b642ab26d3 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -288,7 +288,16 @@ _GLOBAL(_tlbia)
*/
_GLOBAL(_tlbie)
#if defined(CONFIG_40x)
+ /* We run the search with interrupts disabled because we have to change
+ * the PID and I don't want to preempt when that happens.
+ */
+ mfmsr r5
+ mfspr r6,SPRN_PID
+ wrteei 0
+ mtspr SPRN_PID,r4
tlbsx. r3, 0, r3
+ mtspr SPRN_PID,r6
+ wrtee r5
bne 10f
sync
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -297,23 +306,23 @@ _GLOBAL(_tlbie)
tlbwe r3, r3, TLB_TAG
isync
10:
+
#elif defined(CONFIG_44x)
- mfspr r4,SPRN_MMUCR
- mfspr r5,SPRN_PID /* Get PID */
- rlwimi r4,r5,0,24,31 /* Set TID */
+ mfspr r5,SPRN_MMUCR
+ rlwimi r5,r4,0,24,31 /* Set TID */
/* We have to run the search with interrupts disabled, even critical
* and debug interrupts (in fact the only critical exceptions we have
* are debug and machine check). Otherwise an interrupt which causes
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
- mfmsr r5
+ mfmsr r4
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
- andc r6,r5,r6
+ andc r6,r4,r6
mtmsr r6
- mtspr SPRN_MMUCR,r4
+ mtspr SPRN_MMUCR,r5
tlbsx. r3, 0, r3
- mtmsr r5
+ mtmsr r4
bne 10f
sync
/* There are only 64 TLB entries, so r3 < 64,
@@ -534,12 +543,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
addi r3,r3,L1_CACHE_BYTES
bdnz 0b
sync
+#ifndef CONFIG_44x
+ /* We don't flush the icache on 44x. Those have a virtual icache
+ * and we don't have access to the virtual address here (it's
+ * not the page vaddr but where it's mapped in user space). The
+ * flushing of the icache on these is handled elsewhere, when
+ * a change in the address space occurs, before returning to
+ * user space
+ */
mtctr r4
1: icbi 0,r6
addi r6,r6,L1_CACHE_BYTES
bdnz 1b
sync
isync
+#endif /* CONFIG_44x */
blr
/*
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index b9d88374f14..41e13f4cc6e 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -350,7 +350,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
local_irq_save(flags);
account_system_vtime(current);
- account_process_vtime(current);
+ account_process_tick(current, 0);
calculate_steal_time();
last = _switch(old_thread, new_thread);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 9f329a8928e..acc0d247d3c 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -697,6 +697,18 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
if (prop && (*prop & 0xff000000) == 0x0f000000)
identify_cpu(0, *prop);
+#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU)
+ /*
+ * Since 440GR(x)/440EP(x) processors have the same pvr,
+ * we check the node path and set bit 28 in the cur_cpu_spec
+ * pvr for EP(x) processor version. This bit is always 0 in
+ * the "real" pvr. Then we call identify_cpu again with
+ * the new logical pvr to enable FPU support.
+ */
+ if (strstr(uname, "440EP")) {
+ identify_cpu(0, cur_cpu_spec->pvr_value | 0x8);
+ }
+#endif
}
check_cpu_feature_properties(node);
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 1db10f70ae6..1add6efdb31 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1244,7 +1244,7 @@ static void __init prom_initialize_tce_table(void)
local_alloc_bottom = base;
/* It seems OF doesn't null-terminate the path :-( */
- memset(path, 0, sizeof(path));
+ memset(path, 0, PROM_SCRATCH_SIZE);
/* Call OF to setup the TCE hardware */
if (call_prom("package-to-path", 3, 1, node,
path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index ede77dbbd4d..3b1529c103e 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -291,23 +291,16 @@ static void __init initialize_cache_info(void)
if ( num_cpus == 1 ) {
const u32 *sizep, *lsizep;
u32 size, lsize;
- const char *dc, *ic;
-
- /* Then read cache informations */
- if (machine_is(powermac)) {
- dc = "d-cache-block-size";
- ic = "i-cache-block-size";
- } else {
- dc = "d-cache-line-size";
- ic = "i-cache-line-size";
- }
size = 0;
lsize = cur_cpu_spec->dcache_bsize;
sizep = of_get_property(np, "d-cache-size", NULL);
if (sizep != NULL)
size = *sizep;
- lsizep = of_get_property(np, dc, NULL);
+ lsizep = of_get_property(np, "d-cache-block-size", NULL);
+ /* fallback if block size missing */
+ if (lsizep == NULL)
+ lsizep = of_get_property(np, "d-cache-line-size", NULL);
if (lsizep != NULL)
lsize = *lsizep;
if (sizep == 0 || lsizep == 0)
@@ -324,7 +317,9 @@ static void __init initialize_cache_info(void)
sizep = of_get_property(np, "i-cache-size", NULL);
if (sizep != NULL)
size = *sizep;
- lsizep = of_get_property(np, ic, NULL);
+ lsizep = of_get_property(np, "i-cache-block-size", NULL);
+ if (lsizep == NULL)
+ lsizep = of_get_property(np, "i-cache-line-size", NULL);
if (lsizep != NULL)
lsize = *lsizep;
if (sizep == 0 || lsizep == 0)
diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S
index 69e8f86aa4f..77fc76607ab 100644
--- a/arch/powerpc/kernel/swsusp_32.S
+++ b/arch/powerpc/kernel/swsusp_32.S
@@ -133,10 +133,12 @@ _GLOBAL(swsusp_arch_suspend)
/* Resume code */
_GLOBAL(swsusp_arch_resume)
+#ifdef CONFIG_ALTIVEC
/* Stop pending alitvec streams and memory accesses */
BEGIN_FTR_SECTION
DSSALL
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
sync
/* Disable MSR:DR to make sure we don't take a TLB or
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 9eb3284deac..4beb6329dfb 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -259,7 +259,7 @@ void account_system_vtime(struct task_struct *tsk)
* user and system time records.
* Must be called with interrupts disabled.
*/
-void account_process_vtime(struct task_struct *tsk)
+void account_process_tick(struct task_struct *tsk, int user_tick)
{
cputime_t utime, utimescaled;
@@ -274,18 +274,6 @@ void account_process_vtime(struct task_struct *tsk)
account_user_time_scaled(tsk, utimescaled);
}
-static void account_process_time(struct pt_regs *regs)
-{
- int cpu = smp_processor_id();
-
- account_process_vtime(current);
- run_local_timers();
- if (rcu_pending(cpu))
- rcu_check_callbacks(cpu, user_mode(regs));
- scheduler_tick();
- run_posix_cpu_timers(current);
-}
-
/*
* Stuff for accounting stolen time.
*/
@@ -375,7 +363,6 @@ static void snapshot_purr(void)
#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
#define calc_cputime_factors()
-#define account_process_time(regs) update_process_times(user_mode(regs))
#define calculate_steal_time() do { } while (0)
#endif
@@ -586,7 +573,7 @@ void timer_interrupt(struct pt_regs * regs)
/* not time for this event yet */
now = per_cpu(decrementer_next_tb, cpu) - now;
if (now <= DECREMENTER_MAX)
- set_dec((unsigned int)now - 1);
+ set_dec((int)now);
return;
}
old_regs = set_irq_regs(regs);
@@ -599,20 +586,8 @@ void timer_interrupt(struct pt_regs * regs)
get_lppaca()->int_dword.fields.decr_int = 0;
#endif
- /*
- * We cannot disable the decrementer, so in the period
- * between this cpu's being marked offline in cpu_online_map
- * and calling stop-self, it is taking timer interrupts.
- * Avoid calling into the scheduler rebalancing code if this
- * is the case.
- */
- if (!cpu_is_offline(cpu))
- account_process_time(regs);
-
if (evt->event_handler)
evt->event_handler(evt);
- else
- evt->set_next_event(DECREMENTER_MAX, evt);
#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending())
@@ -836,9 +811,6 @@ static int decrementer_set_next_event(unsigned long evt,
struct clock_event_device *dev)
{
__get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt;
- /* The decrementer interrupts on the 0 -> -1 transition */
- if (evt)
- --evt;
set_dec(evt);
return 0;
}
@@ -871,7 +843,8 @@ void init_decrementer_clockevent(void)
decrementer_clockevent.shift);
decrementer_clockevent.max_delta_ns =
clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent);
- decrementer_clockevent.min_delta_ns = 1000;
+ decrementer_clockevent.min_delta_ns =
+ clockevent_delta2ns(2, &decrementer_clockevent);
register_decrementer_clockevent(cpu);
}
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 823a8cbd60b..f66fa5d966b 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -37,11 +37,10 @@ SECTIONS
ALIGN_FUNCTION();
*(.text.head)
_text = .;
- TEXT_TEXT
+ *(.text .fixup .text.init.refok .exit.text.refok)
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
- *(.fixup)
#ifdef CONFIG_PPC32
*(.got1)
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index e067df836be..3899ea97fbd 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -98,13 +98,12 @@ unsigned long __init mmu_mapin_ram(void)
v = KERNELBASE;
p = PPC_MEMSTART;
- s = 0;
+ s = total_lowmem;
- if (__map_without_ltlbs) {
- return s;
- }
+ if (__map_without_ltlbs)
+ return 0;
- while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
+ while (s >= LARGE_PAGE_SIZE_16M) {
pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
@@ -116,10 +115,10 @@ unsigned long __init mmu_mapin_ram(void)
v += LARGE_PAGE_SIZE_16M;
p += LARGE_PAGE_SIZE_16M;
- s += LARGE_PAGE_SIZE_16M;
+ s -= LARGE_PAGE_SIZE_16M;
}
- while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
+ while (s >= LARGE_PAGE_SIZE_4M) {
pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
@@ -128,8 +127,8 @@ unsigned long __init mmu_mapin_ram(void)
v += LARGE_PAGE_SIZE_4M;
p += LARGE_PAGE_SIZE_4M;
- s += LARGE_PAGE_SIZE_4M;
+ s -= LARGE_PAGE_SIZE_4M;
}
- return s;
+ return total_lowmem - s;
}
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index c3df5047653..04dc08798d3 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -35,6 +35,7 @@
*/
unsigned int tlb_44x_index; /* = 0 */
unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
+int icache_44x_need_flush;
/*
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index a18fda361cc..8135da06e0a 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -309,7 +309,7 @@ good_area:
set_bit(PG_arch_1, &page->flags);
}
pte_update(ptep, 0, _PAGE_HWEXEC);
- _tlbie(address);
+ _tlbie(address, mm->context.id);
pte_unmap_unlock(ptep, ptl);
up_read(&mm->mmap_sem);
return 0;
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
index ad253b95903..e935edd6b72 100644
--- a/arch/powerpc/mm/hash_low_64.S
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -331,7 +331,7 @@ htab_pte_insert_failure:
*****************************************************************************/
/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
- * pte_t *ptep, unsigned long trap, int local)
+ * pte_t *ptep, unsigned long trap, int local, int ssize)
*/
/*
@@ -557,7 +557,8 @@ htab_inval_old_hpte:
mr r4,r31 /* PTE.pte */
li r5,0 /* PTE.hidx */
li r6,MMU_PAGE_64K /* psize */
- ld r7,STK_PARM(r8)(r1) /* local */
+ ld r7,STK_PARM(r9)(r1) /* ssize */
+ ld r8,STK_PARM(r8)(r1) /* local */
bl .flush_hash_page
b htab_insert_pte
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index c78dc912411..f09730bf3a3 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -51,6 +51,7 @@
#include <asm/cputable.h>
#include <asm/sections.h>
#include <asm/spu.h>
+#include <asm/udbg.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -791,8 +792,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
}
if (user_region) {
if (psize != get_paca()->context.user_psize) {
- get_paca()->context.user_psize =
- mm->context.user_psize;
+ get_paca()->context = mm->context;
slb_flush_and_rebolt();
}
} else if (get_paca()->vmalloc_sllp !=
@@ -885,6 +885,9 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
local_irq_restore(flags);
}
+/* WARNING: This is called from hash_low_64.S, if you change this prototype,
+ * do not forget to update the assembly call site !
+ */
void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
int local)
{
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index c94a64fd3c0..eb3a732e91d 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -61,12 +61,12 @@ extern unsigned long total_lowmem;
#define mmu_mapin_ram() (0UL)
#elif defined(CONFIG_4xx)
-#define flush_HPTE(X, va, pg) _tlbie(va)
+#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void);
#elif defined(CONFIG_FSL_BOOKE)
-#define flush_HPTE(X, va, pg) _tlbie(va)
+#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void);
extern void adjust_total_lowmem(void);
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index bbd2c512ee0..27922dff8b9 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -25,6 +25,7 @@
#include <asm/smp.h>
#include <asm/firmware.h>
#include <linux/compiler.h>
+#include <asm/udbg.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -148,6 +149,35 @@ void slb_vmalloc_update(void)
slb_flush_and_rebolt();
}
+/* Helper function to compare esids. There are four cases to handle.
+ * 1. The system is not 1T segment size capable. Use the GET_ESID compare.
+ * 2. The system is 1T capable, both addresses are < 1T, use the GET_ESID compare.
+ * 3. The system is 1T capable, only one of the two addresses is > 1T. This is not a match.
+ * 4. The system is 1T capable, both addresses are > 1T, use the GET_ESID_1T macro to compare.
+ */
+static inline int esids_match(unsigned long addr1, unsigned long addr2)
+{
+ int esid_1t_count;
+
+ /* System is not 1T segment size capable. */
+ if (!cpu_has_feature(CPU_FTR_1T_SEGMENT))
+ return (GET_ESID(addr1) == GET_ESID(addr2));
+
+ esid_1t_count = (((addr1 >> SID_SHIFT_1T) != 0) +
+ ((addr2 >> SID_SHIFT_1T) != 0));
+
+ /* both addresses are < 1T */
+ if (esid_1t_count == 0)
+ return (GET_ESID(addr1) == GET_ESID(addr2));
+
+ /* One address < 1T, the other > 1T. Not a match */
+ if (esid_1t_count == 1)
+ return 0;
+
+ /* Both addresses are > 1T. */
+ return (GET_ESID_1T(addr1) == GET_ESID_1T(addr2));
+}
+
/* Flush all user entries from the segment table of the current processor. */
void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
{
@@ -193,15 +223,14 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
return;
slb_allocate(pc);
- if (GET_ESID(pc) == GET_ESID(stack))
+ if (esids_match(pc,stack))
return;
if (is_kernel_addr(stack))
return;
slb_allocate(stack);
- if ((GET_ESID(pc) == GET_ESID(unmapped_base))
- || (GET_ESID(stack) == GET_ESID(unmapped_base)))
+ if (esids_match(pc,unmapped_base) || esids_match(stack,unmapped_base))
return;
if (is_kernel_addr(unmapped_base))
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 151fd8b82d6..04f74f9f9ab 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -158,6 +158,18 @@ static unsigned int iic_get_irq(void)
return virq;
}
+void iic_setup_cpu(void)
+{
+ out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
+}
+
+u8 iic_get_target_id(int cpu)
+{
+ return per_cpu(iic, cpu).target_id;
+}
+
+EXPORT_SYMBOL_GPL(iic_get_target_id);
+
#ifdef CONFIG_SMP
/* Use the highest interrupt priorities for IPI */
@@ -166,29 +178,17 @@ static inline int iic_ipi_to_irq(int ipi)
return IIC_IRQ_TYPE_IPI + 0xf - ipi;
}
-void iic_setup_cpu(void)
-{
- out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
-}
-
void iic_cause_IPI(int cpu, int mesg)
{
out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4);
}
-u8 iic_get_target_id(int cpu)
-{
- return per_cpu(iic, cpu).target_id;
-}
-EXPORT_SYMBOL_GPL(iic_get_target_id);
-
struct irq_host *iic_get_irq_host(int node)
{
return iic_host;
}
EXPORT_SYMBOL_GPL(iic_get_irq_host);
-
static irqreturn_t iic_ipi_action(int irq, void *dev_id)
{
int ipi = (int)(long)dev_id;
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index 1c0acbad742..e4438456c86 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -44,6 +44,7 @@
#include <asm/rtas.h>
#include "interrupt.h"
+#include <asm/udbg.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
diff --git a/arch/powerpc/platforms/celleb/setup.c b/arch/powerpc/platforms/celleb/setup.c
index 1769d755eff..ddfb35ae741 100644
--- a/arch/powerpc/platforms/celleb/setup.c
+++ b/arch/powerpc/platforms/celleb/setup.c
@@ -49,6 +49,7 @@
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/irq.h>
+#include <asm/time.h>
#include <asm/spu_priv1.h>
#include <asm/firmware.h>
#include <asm/of_platform.h>
diff --git a/arch/powerpc/platforms/iseries/irq.h b/arch/powerpc/platforms/iseries/irq.h
index 69f1b437fc7..a1c23607403 100644
--- a/arch/powerpc/platforms/iseries/irq.h
+++ b/arch/powerpc/platforms/iseries/irq.h
@@ -1,9 +1,13 @@
#ifndef _ISERIES_IRQ_H
#define _ISERIES_IRQ_H
+#ifdef CONFIG_PCI
extern void iSeries_init_IRQ(void);
extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32);
extern void iSeries_activate_IRQs(void);
+#else
+#define iSeries_init_IRQ NULL
+#endif
extern unsigned int iSeries_get_irq(void);
#endif /* _ISERIES_IRQ_H */
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 37ae07ee54a..0877a883411 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -617,10 +617,6 @@ static void iseries_dedicated_idle(void)
}
}
-#ifndef CONFIG_PCI
-void __init iSeries_init_IRQ(void) { }
-#endif
-
static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size,
unsigned long flags)
{
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index d6435b03971..be06cfd9fa3 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -523,15 +523,16 @@ static void __init get_viotape_info(struct device_node *vio_root)
static int __init iseries_vio_init(void)
{
struct device_node *vio_root;
+ int ret = -ENODEV;
if (!firmware_has_feature(FW_FEATURE_ISERIES))
- return -ENODEV;
+ goto out;
iommu_vio_init();
vio_root = of_find_node_by_path("/vdevice");
if (!vio_root)
- return -ENODEV;
+ goto out;
if (viopath_hostLp == HvLpIndexInvalid) {
vio_set_hostlp();
@@ -544,10 +545,11 @@ static int __init iseries_vio_init(void)
get_viocd_info(vio_root);
get_viotape_info(vio_root);
- return 0;
+ ret = 0;
put_node:
of_node_put(vio_root);
- return -ENODEV;
+ out:
+ return ret;
}
arch_initcall(iseries_vio_init);
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 22322b35a0f..fb3d636e088 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -186,6 +186,11 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg);
+ if (!dev) {
+ printk(KERN_WARNING "EEH: no PCI device for this of node\n");
+ return n;
+ }
+
/* Gather bridge-specific registers */
if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
rtas_read_config(pdn, PCI_SEC_STATUS, 2, &cfg);
@@ -198,7 +203,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
}
/* Dump out the PCI-X command and status regs */
- cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_PCIX);
+ cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (cap) {
rtas_read_config(pdn, cap, 4, &cfg);
n += scnprintf(buf+n, len-n, "pcix-cmd:%x\n", cfg);
@@ -210,7 +215,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
}
/* If PCI-E capable, dump PCI-E cap 10, and the AER */
- cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_EXP);
+ cap = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (cap) {
n += scnprintf(buf+n, len-n, "pci-e cap10:\n");
printk(KERN_WARNING
@@ -222,7 +227,7 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg);
}
- cap = pci_find_ext_capability(pdn->pcidev, PCI_EXT_CAP_ID_ERR);
+ cap = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (cap) {
n += scnprintf(buf+n, len-n, "pci-e AER:\n");
printk(KERN_WARNING
@@ -318,7 +323,7 @@ eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs)
if (rets[2] == 0) return -1; /* permanently unavailable */
- if (max_wait_msecs <= 0) return -1;
+ if (max_wait_msecs <= 0) break;
mwait = rets[2];
if (mwait <= 0) {
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 15e015ef686..57e025e84ab 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -105,17 +105,18 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
return;
rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
+
+ /* A driver that needs a reset trumps all others */
+ if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
- if (*res == PCI_ERS_RESULT_DISCONNECT &&
- rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
}
/**
* eeh_report_mmio_enabled - tell drivers that MMIO has been enabled
*
- * Report an EEH error to each device driver, collect up and
- * merge the device driver responses. Cumulative response
- * passed back in "userdata".
+ * Tells each device driver that IO ports, MMIO and config space I/O
+ * are now enabled. Collects up and merges the device driver responses.
+ * Cumulative response passed back in "userdata".
*/
static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
@@ -123,17 +124,16 @@ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver = dev->driver;
- // dev->error_state = pci_channel_mmio_enabled;
-
if (!driver ||
!driver->err_handler ||
!driver->err_handler->mmio_enabled)
return;
rc = driver->err_handler->mmio_enabled (dev);
+
+ /* A driver that needs a reset trumps all others */
+ if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
- if (*res == PCI_ERS_RESULT_DISCONNECT &&
- rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
}
/**
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 8b18a1c4009..b765b7c77b6 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -25,6 +25,7 @@
#include <asm/firmware.h>
#include <asm/prom.h>
+#include <asm/udbg.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 2793a1b100e..f15222bbe13 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -171,6 +171,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
struct pci_dn *pdn;
int hwirq, virq, i, rc;
struct msi_desc *entry;
+ struct msi_msg msg;
pdn = get_pdn(pdev);
if (!pdn)
@@ -213,6 +214,11 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq);
set_irq_msi(virq, entry);
+
+ /* Read config space back so we can restore after reset */
+ read_msi_msg(virq, &msg);
+ entry->msg = msg;
+
unmask_msi_irq(virq);
}
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 7c1b27ac7d3..216c0f5680d 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -137,6 +137,7 @@ static void i8259_unmask_irq(unsigned int irq_nr)
static struct irq_chip i8259_pic = {
.typename = " i8259 ",
.mask = i8259_mask_irq,
+ .disable = i8259_mask_irq,
.unmask = i8259_unmask_irq,
.mask_ack = i8259_mask_and_ack_irq,
};
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
index 9b3baa7317d..6933f9c73b4 100644
--- a/arch/powerpc/sysdev/mv64x60_pci.c
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -24,8 +24,9 @@
#define MV64X60_VAL_LEN_MAX 11
#define MV64X60_PCICFG_CPCI_HOTSWAP 0x68
-static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
- size_t count)
+static ssize_t mv64x60_hs_reg_read(struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
{
struct pci_dev *phb;
u32 v;
@@ -44,8 +45,9 @@ static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
return sprintf(buf, "0x%08x\n", v);
}
-static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, char *buf, loff_t off,
- size_t count)
+static ssize_t mv64x60_hs_reg_write(struct kobject *kobj,
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
{
struct pci_dev *phb;
u32 v;
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index fba7ca17a67..b19bfef2034 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -244,6 +244,13 @@ syscall_exit_cont:
andis. r10,r0,DBCR0_IC@h
bnel- load_dbcr0
#endif
+#ifdef CONFIG_44x
+ lis r4,icache_44x_need_flush@ha
+ lwz r5,icache_44x_need_flush@l(r4)
+ cmplwi cr0,r5,0
+ bne- 2f
+1:
+#endif /* CONFIG_44x */
stwcx. r0,0,r1 /* to clear the reservation */
lwz r4,_LINK(r1)
lwz r5,_CCR(r1)
@@ -258,6 +265,12 @@ syscall_exit_cont:
mtspr SPRN_SRR1,r8
SYNC
RFI
+#ifdef CONFIG_44x
+2: li r7,0
+ iccci r0,r0
+ stw r7,icache_44x_need_flush@l(r4)
+ b 1b
+#endif /* CONFIG_44x */
66: li r3,-ENOSYS
b ret_from_syscall
@@ -679,6 +692,16 @@ resume_kernel:
/* interrupts are hard-disabled at this point */
restore:
+#ifdef CONFIG_44x
+ lis r4,icache_44x_need_flush@ha
+ lwz r5,icache_44x_need_flush@l(r4)
+ cmplwi cr0,r5,0
+ beq+ 1f
+ li r6,0
+ iccci r0,r0
+ stw r6,icache_44x_need_flush@l(r4)
+1:
+#endif /* CONFIG_44x */
lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
REST_4GPRS(3, r1)
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index a22e1f4d94c..e0c850d85c5 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -224,7 +224,16 @@ _GLOBAL(_tlbia)
*/
_GLOBAL(_tlbie)
#if defined(CONFIG_40x)
+ /* We run the search with interrupts disabled because we have to change
+ * the PID and I don't want to preempt when that happens.
+ */
+ mfmsr r5
+ mfspr r6,SPRN_PID
+ wrteei 0
+ mtspr SPRN_PID,r4
tlbsx. r3, 0, r3
+ mtspr SPRN_PID,r6
+ wrtee r5
bne 10f
sync
/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -234,22 +243,21 @@ _GLOBAL(_tlbie)
isync
10:
#elif defined(CONFIG_44x)
- mfspr r4,SPRN_MMUCR
- mfspr r5,SPRN_PID /* Get PID */
- rlwimi r4,r5,0,24,31 /* Set TID */
+ mfspr r5,SPRN_MMUCR
+ rlwimi r5,r4,0,24,31 /* Set TID */
/* We have to run the search with interrupts disabled, even critical
* and debug interrupts (in fact the only critical exceptions we have
* are debug and machine check). Otherwise an interrupt which causes
* a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
- mfmsr r5
+ mfmsr r4
lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
- andc r6,r5,r6
+ andc r6,r4,r6
mtmsr r6
- mtspr SPRN_MMUCR,r4
+ mtspr SPRN_MMUCR,r5
tlbsx. r3, 0, r3
- mtmsr r5
+ mtmsr r4
bne 10f
sync
/* There are only 64 TLB entries, so r3 < 64,
@@ -491,12 +499,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
addi r3,r3,L1_CACHE_BYTES
bdnz 0b
sync
+#ifndef CONFIG_44x
+ /* We don't flush the icache on 44x. Those have a virtual icache
+ * and we don't have access to the virtual address here (it's
+ * not the page vaddr but where it's mapped in user space). The
+ * flushing of the icache on these is handled elsewhere, when
+ * a change in the address space occurs, before returning to
+ * user space
+ */
mtctr r4
1: icbi 0,r6
addi r6,r6,L1_CACHE_BYTES
bdnz 1b
sync
isync
+#endif /* CONFIG_44x */
blr
/*
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c
index 0a0a0487b33..6536a25cfcb 100644
--- a/arch/ppc/mm/44x_mmu.c
+++ b/arch/ppc/mm/44x_mmu.c
@@ -61,6 +61,7 @@ extern char etext[], _stext[];
*/
unsigned int tlb_44x_index = 0;
unsigned int tlb_44x_hwater = 62;
+int icache_44x_need_flush;
/*
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem
diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c
index 838e09db71d..ea785dbaac7 100644
--- a/arch/ppc/mm/4xx_mmu.c
+++ b/arch/ppc/mm/4xx_mmu.c
@@ -99,13 +99,12 @@ unsigned long __init mmu_mapin_ram(void)
v = KERNELBASE;
p = PPC_MEMSTART;
- s = 0;
+ s = total_lowmem;
- if (__map_without_ltlbs) {
- return s;
- }
+ if (__map_without_ltlbs)
+ return 0;
- while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) {
+ while (s >= LARGE_PAGE_SIZE_16M) {
pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
@@ -117,10 +116,10 @@ unsigned long __init mmu_mapin_ram(void)
v += LARGE_PAGE_SIZE_16M;
p += LARGE_PAGE_SIZE_16M;
- s += LARGE_PAGE_SIZE_16M;
+ s -= LARGE_PAGE_SIZE_16M;
}
- while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) {
+ while (s >= LARGE_PAGE_SIZE_4M) {
pmd_t *pmdp;
unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
@@ -129,8 +128,8 @@ unsigned long __init mmu_mapin_ram(void)
v += LARGE_PAGE_SIZE_4M;
p += LARGE_PAGE_SIZE_4M;
- s += LARGE_PAGE_SIZE_4M;
+ s -= LARGE_PAGE_SIZE_4M;
}
- return s;
+ return total_lowmem - s;
}
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 254c23b755e..36c0e7529ed 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -227,7 +227,7 @@ good_area:
set_bit(PG_arch_1, &page->flags);
}
pte_update(ptep, 0, _PAGE_HWEXEC);
- _tlbie(address);
+ _tlbie(address, mm->context.id);
pte_unmap_unlock(ptep, ptl);
up_read(&mm->mmap_sem);
return 0;
diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h
index 540f3292b22..f1d4f2109a9 100644
--- a/arch/ppc/mm/mmu_decl.h
+++ b/arch/ppc/mm/mmu_decl.h
@@ -54,12 +54,12 @@ extern unsigned int num_tlbcam_entries;
#define mmu_mapin_ram() (0UL)
#elif defined(CONFIG_4xx)
-#define flush_HPTE(X, va, pg) _tlbie(va)
+#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void);
#elif defined(CONFIG_FSL_BOOKE)
-#define flush_HPTE(X, va, pg) _tlbie(va)
+#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void);
extern void adjust_total_lowmem(void);
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
index 05d7184d7e1..453643a0eee 100644
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -236,7 +236,7 @@ ebony_early_serial_map(void)
gen550_init(0, &port);
/* Purge TLB entry added in head_44x.S for early serial access */
- _tlbie(UART0_IO_BASE);
+ _tlbie(UART0_IO_BASE, 0);
#endif
port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
index 4b169610f15..b79ebb8a3e6 100644
--- a/arch/ppc/platforms/4xx/luan.c
+++ b/arch/ppc/platforms/4xx/luan.c
@@ -230,9 +230,14 @@ luan_setup_hoses(void)
/* Allocate hoses for PCIX1 and PCIX2 */
hose1 = pcibios_alloc_controller();
+ if (!hose1)
+ return;
+
hose2 = pcibios_alloc_controller();
- if (!hose1 || !hose2)
+ if (!hose2) {
+ pcibios_free_controller(hose1);
return;
+ }
/* Setup PCIX1 */
hose1->first_busno = 0;
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index fd0f971881d..28a712cd480 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -259,7 +259,7 @@ ocotea_early_serial_map(void)
gen550_init(0, &port);
/* Purge TLB entry added in head_44x.S for early serial access */
- _tlbie(UART0_IO_BASE);
+ _tlbie(UART0_IO_BASE, 0);
#endif
port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
diff --git a/arch/ppc/platforms/4xx/taishan.c b/arch/ppc/platforms/4xx/taishan.c
index 888c492b4a4..f6a0c6650f3 100644
--- a/arch/ppc/platforms/4xx/taishan.c
+++ b/arch/ppc/platforms/4xx/taishan.c
@@ -316,7 +316,7 @@ taishan_early_serial_map(void)
gen550_init(0, &port);
/* Purge TLB entry added in head_44x.S for early serial access */
- _tlbie(UART0_IO_BASE);
+ _tlbie(UART0_IO_BASE, 0);
#endif
port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
diff --git a/arch/ppc/syslib/i8259.c b/arch/ppc/syslib/i8259.c
index 1e5a00a4b5f..559f27c6aef 100644
--- a/arch/ppc/syslib/i8259.c
+++ b/arch/ppc/syslib/i8259.c
@@ -127,6 +127,7 @@ static void i8259_unmask_irq(unsigned int irq_nr)
static struct irq_chip i8259_pic = {
.typename = " i8259 ",
.mask = i8259_mask_irq,
+ .disable = i8259_mask_irq,
.unmask = i8259_unmask_irq,
.mask_ack = i8259_mask_and_ack_irq,
};
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 15f0d732353..46588fa9438 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -25,6 +25,7 @@
#include <asm/machdep.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
+#include <asm/ppc_sys.h>
#include "cpm2_pic.h"
@@ -61,7 +62,7 @@ m8260_setup_arch(void)
#endif
identify_ppc_sys_by_name_and_id(BOARD_CHIP_NAME,
- in_be32(CPM_MAP_ADDR + CPM_IMMR_OFFSET));
+ in_be32((void *)CPM_MAP_ADDR + CPM_IMMR_OFFSET));
m82xx_board_setup();
}
@@ -147,12 +148,12 @@ m8260_show_cpuinfo(struct seq_file *m)
seq_printf(m, "vendor\t\t: %s\n"
"machine\t\t: %s\n"
"\n"
- "mem size\t\t: 0x%08x\n"
- "console baud\t\t: %d\n"
+ "mem size\t\t: 0x%08lx\n"
+ "console baud\t\t: %ld\n"
"\n"
- "core clock\t: %u MHz\n"
- "CPM clock\t: %u MHz\n"
- "bus clock\t: %u MHz\n",
+ "core clock\t: %lu MHz\n"
+ "CPM clock\t: %lu MHz\n"
+ "bus clock\t: %lu MHz\n",
CPUINFO_VENDOR, CPUINFO_MACHINE, bp->bi_memsize,
bp->bi_baudrate, bp->bi_intfreq / 1000000,
bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index a963fe81359..22b800ce212 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -145,12 +145,8 @@ void account_ticks(u64 time)
do_timer(ticks);
#endif
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- account_tick_vtime(current);
-#else
while (ticks--)
update_process_times(user_mode(get_irq_regs()));
-#endif
s390_do_profile();
}
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 84ff78de6ba..c5f05b3fb2c 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -32,7 +32,7 @@ static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
* Update process times based on virtual cpu times stored by entry.S
* to the lowcore fields user_timer, system_timer & steal_clock.
*/
-void account_tick_vtime(struct task_struct *tsk)
+void account_process_tick(struct task_struct *tsk, int user_tick)
{
cputime_t cputime;
__u64 timer, clock;
@@ -64,12 +64,6 @@ void account_tick_vtime(struct task_struct *tsk)
S390_lowcore.steal_clock -= cputime << 12;
account_steal_time(tsk, cputime);
}
-
- run_local_timers();
- if (rcu_pending(smp_processor_id()))
- rcu_check_callbacks(smp_processor_id(), rcu_user_flag);
- scheduler_tick();
- run_posix_cpu_timers(tsk);
}
/*
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 22a3eb38438..496d635f89b 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -211,10 +211,12 @@ config SH_SOLUTION_ENGINE
bool "SolutionEngine"
select SOLUTION_ENGINE
select CPU_HAS_IPR_IRQ
- depends on CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7750
+ depends on CPU_SUBTYPE_SH7705 || CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7710 || \
+ CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7750S || \
+ CPU_SUBTYPE_SH7750R
help
- Select SolutionEngine if configuring for a Hitachi SH7709
- or SH7750 evaluation board.
+ Select SolutionEngine if configuring for a Hitachi SH7705, SH7709,
+ SH7710, SH7712, SH7750, SH7750S or SH7750R evaluation board.
config SH_7206_SOLUTION_ENGINE
bool "SolutionEngine7206"
@@ -603,7 +605,7 @@ config BOOT_LINK_OFFSET
config UBC_WAKEUP
bool "Wakeup UBC on startup"
- depends on CPU_SH4
+ depends on CPU_SH4 && !CPU_SH4A
help
Selecting this option will wakeup the User Break Controller (UBC) on
startup. Although the UBC is left in an awake state when the processor
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index ab2f9f3c354..722da6851f5 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -124,12 +124,13 @@ config KGDB_NMI
config SH_KGDB_CONSOLE
bool "Console messages through GDB"
- depends on !SERIAL_SH_SCI_CONSOLE
+ depends on !SERIAL_SH_SCI_CONSOLE && SERIAL_SH_SCI=y
select SERIAL_CORE_CONSOLE
default n
config KGDB_SYSRQ
bool "Allow SysRq 'G' to enter KGDB"
+ depends on MAGIC_SYSRQ
default y
comment "Serial port setup"
diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c
index 943f93aa605..e55c6686b21 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/irq.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hs7751rvoip.h>
diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c
index fa5fa392022..c05625975f2 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/setup.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c
@@ -15,20 +15,6 @@
#include <asm/io.h>
#include <asm/machvec.h>
-static struct ipr_data hs77501rvoip_ipr_map[] = {
-#if defined(CONFIG_HS7751RVOIP_CODEC)
- { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
- { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
-#endif
-};
-
-static void __init hs7751rvoip_init_irq(void)
-{
- make_ipr_irq(hs77501rvoip_ipr_map, ARRAY_SIZE(hs77501rvoip_ipr_map));
-
- init_hs7751rvoip_IRQ();
-}
-
static void hs7751rvoip_power_off(void)
{
ctrl_outw(ctrl_inw(PA_OUTPORTR) & 0xffdf, PA_OUTPORTR);
@@ -75,14 +61,13 @@ static int __init hs7751rvoip_cf_init(void)
return 0;
}
+device_initcall(hs7751rvoip_cf_init);
/*
* Initialize the board
*/
static void __init hs7751rvoip_setup(char **cmdline_p)
{
- device_initcall(hs7751rvoip_cf_init);
-
ctrl_outb(0xf0, PA_OUTPORTR);
pm_power_off = hs7751rvoip_power_off;
@@ -115,6 +100,6 @@ static struct sh_machine_vector mv_hs7751rvoip __initmv = {
.mv_outsw = hs7751rvoip_outsw,
.mv_outsl = hs7751rvoip_outsl,
- .mv_init_irq = hs7751rvoip_init_irq,
+ .mv_init_irq = init_hs7751rvoip_IRQ,
.mv_ioport_map = hs7751rvoip_ioport_map,
};
diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c
index 2dce8bd97f9..0d56fd83bcb 100644
--- a/arch/sh/boards/renesas/sh7710voipgw/setup.c
+++ b/arch/sh/boards/renesas/sh7710voipgw/setup.c
@@ -11,7 +11,6 @@
#include <asm/machvec.h>
#include <asm/irq.h>
#include <asm/io.h>
-#include <asm/irq.h>
static struct ipr_data sh7710voipgw_ipr_map[] = {
{ TIMER2_IRQ, TIMER2_IPR_ADDR, TIMER2_IPR_POS, TIMER2_PRIORITY },
diff --git a/arch/sh/boards/se/7206/irq.c b/arch/sh/boards/se/7206/irq.c
index 27da88486f7..9d5bfc77d0d 100644
--- a/arch/sh/boards/se/7206/irq.c
+++ b/arch/sh/boards/se/7206/irq.c
@@ -9,7 +9,6 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
-#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/se7206.h>
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c
index d07a3368f54..318bc8a3969 100644
--- a/arch/sh/boards/se/770x/setup.c
+++ b/arch/sh/boards/se/770x/setup.c
@@ -94,6 +94,7 @@ static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct heartbeat_data heartbeat_data = {
.bit_pos = heartbeat_bit_pos,
.nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+ .regsize = 16,
};
static struct resource heartbeat_resources[] = {
diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c
index 20f064083cc..eb97dca5b73 100644
--- a/arch/sh/boards/se/7722/setup.c
+++ b/arch/sh/boards/se/7722/setup.c
@@ -16,8 +16,13 @@
#include <asm/machvec.h>
#include <asm/se7722.h>
#include <asm/io.h>
+#include <asm/heartbeat.h>
/* Heartbeat */
+static struct heartbeat_data heartbeat_data = {
+ .regsize = 16,
+};
+
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_LED,
@@ -29,6 +34,9 @@ static struct resource heartbeat_resources[] = {
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
diff --git a/arch/sh/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c
index 76e53b26a80..0f08ab3b2be 100644
--- a/arch/sh/boards/se/7780/setup.c
+++ b/arch/sh/boards/se/7780/setup.c
@@ -14,8 +14,13 @@
#include <asm/machvec.h>
#include <asm/se7780.h>
#include <asm/io.h>
+#include <asm/heartbeat.h>
/* Heartbeat */
+static struct heartbeat_data heartbeat_data = {
+ .regsize = 16,
+};
+
static struct resource heartbeat_resources[] = {
[0] = {
.start = PA_LED,
@@ -27,6 +32,9 @@ static struct resource heartbeat_resources[] = {
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
diff --git a/arch/sh/boards/snapgear/Makefile b/arch/sh/boards/snapgear/Makefile
index 59fc976bfc2..d2d2f4b6a50 100644
--- a/arch/sh/boards/snapgear/Makefile
+++ b/arch/sh/boards/snapgear/Makefile
@@ -2,5 +2,4 @@
# Makefile for the SnapGear specific parts of the kernel
#
-obj-y := setup.o io.o rtc.o
-
+obj-y := setup.o io.o
diff --git a/arch/sh/boards/snapgear/rtc.c b/arch/sh/boards/snapgear/rtc.c
deleted file mode 100644
index edb3dd936cb..00000000000
--- a/arch/sh/boards/snapgear/rtc.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/****************************************************************************/
-/*
- * linux/arch/sh/boards/snapgear/rtc.c -- Secureedge5410 RTC code
- *
- * Copyright (C) 2002 David McCullough <davidm@snapgear.com>
- * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org>
- *
- * The SecureEdge5410 can have one of 2 real time clocks, the SH
- * built in version or the preferred external DS1302. Here we work out
- * each to see what we have and then run with it.
- */
-/****************************************************************************/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/rtc.h>
-#include <linux/mc146818rtc.h>
-#include <asm/io.h>
-
-static int use_ds1302;
-
-/****************************************************************************/
-/*
- * we need to implement a DS1302 driver here that can operate in
- * conjunction with the builtin rtc driver which is already quite friendly
- */
-/*****************************************************************************/
-
-#define RTC_CMD_READ 0x81 /* Read command */
-#define RTC_CMD_WRITE 0x80 /* Write command */
-
-#define RTC_ADDR_YEAR 0x06 /* Address of year register */
-#define RTC_ADDR_DAY 0x05 /* Address of day of week register */
-#define RTC_ADDR_MON 0x04 /* Address of month register */
-#define RTC_ADDR_DATE 0x03 /* Address of day of month register */
-#define RTC_ADDR_HOUR 0x02 /* Address of hour register */
-#define RTC_ADDR_MIN 0x01 /* Address of minute register */
-#define RTC_ADDR_SEC 0x00 /* Address of second register */
-
-#define RTC_RESET 0x1000
-#define RTC_IODATA 0x0800
-#define RTC_SCLK 0x0400
-
-#define set_dirp(x)
-#define get_dirp(x) 0
-#define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
-#define get_dp(x) SECUREEDGE_READ_IOPORT()
-
-static void ds1302_sendbits(unsigned int val)
-{
- int i;
-
- for (i = 8; (i); i--, val >>= 1) {
- set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? RTC_IODATA : 0));
- set_dp(get_dp() | RTC_SCLK); // clock high
- set_dp(get_dp() & ~RTC_SCLK); // clock low
- }
-}
-
-static unsigned int ds1302_recvbits(void)
-{
- unsigned int val;
- int i;
-
- for (i = 0, val = 0; (i < 8); i++) {
- val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i);
- set_dp(get_dp() | RTC_SCLK); // clock high
- set_dp(get_dp() & ~RTC_SCLK); // clock low
- }
- return(val);
-}
-
-static unsigned int ds1302_readbyte(unsigned int addr)
-{
- unsigned int val;
- unsigned long flags;
-
- local_irq_save(flags);
- set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
- set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
-
- set_dp(get_dp() | RTC_RESET);
- ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
- set_dirp(get_dirp() & ~RTC_IODATA);
- val = ds1302_recvbits();
- set_dp(get_dp() & ~RTC_RESET);
- local_irq_restore(flags);
-
- return(val);
-}
-
-static void ds1302_writebyte(unsigned int addr, unsigned int val)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
- set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
- set_dp(get_dp() | RTC_RESET);
- ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
- ds1302_sendbits(val);
- set_dp(get_dp() & ~RTC_RESET);
- local_irq_restore(flags);
-}
-
-static void ds1302_reset(void)
-{
- unsigned long flags;
- /* Hardware dependent reset/init */
- local_irq_save(flags);
- set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
- set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
- local_irq_restore(flags);
-}
-
-/*****************************************************************************/
-
-static inline int bcd2int(int val)
-{
- return((((val & 0xf0) >> 4) * 10) + (val & 0xf));
-}
-
-static inline int int2bcd(int val)
-{
- return(((val / 10) << 4) + (val % 10));
-}
-
-/*****************************************************************************/
-/*
- * Write and Read some RAM in the DS1302, if it works assume it's there
- * Otherwise use the SH4 internal RTC
- */
-
-void snapgear_rtc_gettimeofday(struct timespec *);
-int snapgear_rtc_settimeofday(const time_t);
-
-void __init secureedge5410_rtc_init(void)
-{
- unsigned char *test = "snapgear";
- int i;
-
- ds1302_reset();
-
- use_ds1302 = 1;
-
- for (i = 0; test[i]; i++)
- ds1302_writebyte(32 + i, test[i]);
-
- for (i = 0; test[i]; i++)
- if (ds1302_readbyte(32 + i) != test[i]) {
- use_ds1302 = 0;
- break;
- }
-
- if (use_ds1302) {
- rtc_sh_get_time = snapgear_rtc_gettimeofday;
- rtc_sh_set_time = snapgear_rtc_settimeofday;
- }
-
- printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal");
-}
-
-/****************************************************************************/
-/*
- * our generic interface that chooses the correct code to use
- */
-
-void snapgear_rtc_gettimeofday(struct timespec *ts)
-{
- unsigned int sec, min, hr, day, mon, yr;
-
- if (!use_ds1302)
- return;
-
- sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
- min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
- hr = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR));
- day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE));
- mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON));
- yr = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR));
-
-bad_time:
- if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
- hr > 23 || min > 59 || sec > 59) {
- printk(KERN_ERR
- "SnapGear RTC: invalid value, resetting to 1 Jan 2000\n");
- ds1302_writebyte(RTC_ADDR_MIN, min = 0);
- ds1302_writebyte(RTC_ADDR_HOUR, hr = 0);
- ds1302_writebyte(RTC_ADDR_DAY, 7);
- ds1302_writebyte(RTC_ADDR_DATE, day = 1);
- ds1302_writebyte(RTC_ADDR_MON, mon = 1);
- ds1302_writebyte(RTC_ADDR_YEAR, yr = 0);
- ds1302_writebyte(RTC_ADDR_SEC, sec = 0);
- }
-
- ts->tv_sec = mktime(2000 + yr, mon, day, hr, min, sec);
- if (ts->tv_sec < 0) {
-#if 0
- printk("BAD TIME %d %d %d %d %d %d\n", yr, mon, day, hr, min, sec);
-#endif
- yr = 100;
- goto bad_time;
- }
- ts->tv_nsec = 0;
-}
-
-int snapgear_rtc_settimeofday(const time_t secs)
-{
- int retval = 0;
- int real_seconds, real_minutes, cmos_minutes;
- unsigned long nowtime;
-
- if (!use_ds1302)
- return 0;
-
-/*
- * This is called direct from the kernel timer handling code.
- * It is supposed to synchronize the kernel clock to the RTC.
- */
-
- nowtime = secs;
-
- /* STOP RTC */
- ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
-
- cmos_minutes = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
-
- /*
- * since we're only adjusting minutes and seconds,
- * don't interfere with hour overflow. This avoids
- * messing with unknown time zones but requires your
- * RTC not to be off by more than 15 minutes
- */
- real_seconds = nowtime % 60;
- real_minutes = nowtime / 60;
- if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
- real_minutes += 30; /* correct for half hour time zone */
- real_minutes %= 60;
-
- if (abs(real_minutes - cmos_minutes) < 30) {
- ds1302_writebyte(RTC_ADDR_MIN, int2bcd(real_minutes));
- ds1302_writebyte(RTC_ADDR_SEC, int2bcd(real_seconds));
- } else {
- printk(KERN_WARNING
- "SnapGear RTC: can't update from %d to %d\n",
- cmos_minutes, real_minutes);
- retval = -1;
- }
-
- /* START RTC */
- ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
- return(0);
-}
-
-unsigned char secureedge5410_cmos_read(int addr)
-{
- unsigned char val = 0;
-
- if (!use_ds1302)
- return(__CMOS_READ(addr, w));
-
- switch(addr) {
- case RTC_SECONDS: val = ds1302_readbyte(RTC_ADDR_SEC); break;
- case RTC_SECONDS_ALARM: break;
- case RTC_MINUTES: val = ds1302_readbyte(RTC_ADDR_MIN); break;
- case RTC_MINUTES_ALARM: break;
- case RTC_HOURS: val = ds1302_readbyte(RTC_ADDR_HOUR); break;
- case RTC_HOURS_ALARM: break;
- case RTC_DAY_OF_WEEK: val = ds1302_readbyte(RTC_ADDR_DAY); break;
- case RTC_DAY_OF_MONTH: val = ds1302_readbyte(RTC_ADDR_DATE); break;
- case RTC_MONTH: val = ds1302_readbyte(RTC_ADDR_MON); break;
- case RTC_YEAR: val = ds1302_readbyte(RTC_ADDR_YEAR); break;
- case RTC_REG_A: /* RTC_FREQ_SELECT */ break;
- case RTC_REG_B: /* RTC_CONTROL */ break;
- case RTC_REG_C: /* RTC_INTR_FLAGS */ break;
- case RTC_REG_D: val = RTC_VRT /* RTC_VALID */; break;
- default: break;
- }
-
- return(val);
-}
-
-void secureedge5410_cmos_write(unsigned char val, int addr)
-{
- if (!use_ds1302) {
- __CMOS_WRITE(val, addr, w);
- return;
- }
-
- switch(addr) {
- case RTC_SECONDS: ds1302_writebyte(RTC_ADDR_SEC, val); break;
- case RTC_SECONDS_ALARM: break;
- case RTC_MINUTES: ds1302_writebyte(RTC_ADDR_MIN, val); break;
- case RTC_MINUTES_ALARM: break;
- case RTC_HOURS: ds1302_writebyte(RTC_ADDR_HOUR, val); break;
- case RTC_HOURS_ALARM: break;
- case RTC_DAY_OF_WEEK: ds1302_writebyte(RTC_ADDR_DAY, val); break;
- case RTC_DAY_OF_MONTH: ds1302_writebyte(RTC_ADDR_DATE, val); break;
- case RTC_MONTH: ds1302_writebyte(RTC_ADDR_MON, val); break;
- case RTC_YEAR: ds1302_writebyte(RTC_ADDR_YEAR, val); break;
- case RTC_REG_A: /* RTC_FREQ_SELECT */ break;
- case RTC_REG_B: /* RTC_CONTROL */ break;
- case RTC_REG_C: /* RTC_INTR_FLAGS */ break;
- case RTC_REG_D: /* RTC_VALID */ break;
- default: break;
- }
-}
diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c
index 2b594f60000..7022483f98e 100644
--- a/arch/sh/boards/snapgear/setup.c
+++ b/arch/sh/boards/snapgear/setup.c
@@ -22,20 +22,15 @@
#include <asm/snapgear.h>
#include <asm/irq.h>
#include <asm/io.h>
-#include <asm/rtc.h>
#include <asm/cpu/timer.h>
-extern void secureedge5410_rtc_init(void);
-extern void pcibios_init(void);
-
-/****************************************************************************/
/*
* EraseConfig handling functions
*/
static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
{
- volatile char dummy __attribute__((unused)) = * (volatile char *) 0xb8000000;
+ (void)ctrl_inb(0xb8000000); /* dummy read */
printk("SnapGear: erase switch interrupt!\n");
@@ -76,19 +71,10 @@ static void __init init_snapgear_IRQ(void)
}
/*
- * Initialize the board
- */
-static void __init snapgear_setup(char **cmdline_p)
-{
- board_time_init = secureedge5410_rtc_init;
-}
-
-/*
* The Machine Vector
*/
static struct sh_machine_vector mv_snapgear __initmv = {
.mv_name = "SnapGear SecureEdge5410",
- .mv_setup = snapgear_setup,
.mv_nr_irqs = 72,
.mv_inb = snapgear_inb,
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index 4c5ffdcd55b..1b0f5be01d1 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -39,7 +39,7 @@ KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%8x" \
quiet_cmd_uimage = UIMAGE $@
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \
- -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_LOAD) \
+ -C none -a $(KERNEL_LOAD) -e $(KERNEL_LOAD) \
-n 'Linux-$(KERNELRELEASE)' -d $< $@
$(obj)/uImage: $(obj)/zImage FORCE
diff --git a/arch/sh/cchips/hd6446x/Makefile b/arch/sh/cchips/hd6446x/Makefile
index a106dd9db98..f7de4076e24 100644
--- a/arch/sh/cchips/hd6446x/Makefile
+++ b/arch/sh/cchips/hd6446x/Makefile
@@ -1,2 +1,4 @@
obj-$(CONFIG_HD64461) += hd64461.o
obj-$(CONFIG_HD64465) += hd64465/
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/cchips/voyagergx/Makefile b/arch/sh/cchips/voyagergx/Makefile
index 085de72fd32..f73963cb374 100644
--- a/arch/sh/cchips/voyagergx/Makefile
+++ b/arch/sh/cchips/voyagergx/Makefile
@@ -6,3 +6,4 @@ obj-y := irq.o setup.o
obj-$(CONFIG_USB_OHCI_HCD) += consistent.o
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 2f65ac72f48..fba6b5ba0b3 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -5,7 +5,6 @@
obj-y += pci.o
obj-$(CONFIG_PCI_AUTO) += pci-auto.o
-obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
deleted file mode 100644
index 0814a5afe9b..00000000000
--- a/arch/sh/drivers/pci/pci-st40.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Support functions for the ST40 PCI hardware.
- */
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <asm/pci.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h> /* irqreturn_t */
-
-#include "pci-st40.h"
-
-/* This is in P2 of course */
-#define ST40PCI_BASE_ADDRESS (0xb0000000)
-#define ST40PCI_MEM_ADDRESS (ST40PCI_BASE_ADDRESS+0x0)
-#define ST40PCI_IO_ADDRESS (ST40PCI_BASE_ADDRESS+0x06000000)
-#define ST40PCI_REG_ADDRESS (ST40PCI_BASE_ADDRESS+0x07000000)
-
-#define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x))
-#define ST40PCI_REG_INDEXED(reg, index) \
- (ST40PCI_REG(reg##0) + \
- ((ST40PCI_REG(reg##1) - ST40PCI_REG(reg##0))*index))
-
-#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_INDEXED(reg, index, val) \
- writel((val), ST40PCI_REG_INDEXED(reg, index));
-
-#define ST40PCI_READ(reg) readl(ST40PCI_REG(reg))
-#define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg))
-#define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg))
-
-#define ST40PCI_SERR_IRQ 64
-#define ST40PCI_ERR_IRQ 65
-
-
-/* Macros to extract PLL params */
-#define PLL_MDIV(reg) ( ((unsigned)reg) & 0xff )
-#define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff )
-#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 )
-#define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff )
-
-/* Build up the appropriate settings */
-#define PLL_SET(mdiv,ndiv,pdiv,setup) \
-( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19))
-
-#define PLLPCICR (0xbb040000+0x10)
-
-#define PLLPCICR_POWERON (1<<28)
-#define PLLPCICR_OUT_EN (1<<29)
-#define PLLPCICR_LOCKSELECT (1<<30)
-#define PLLPCICR_LOCK (1<<31)
-
-
-#define PLL_25MHZ 0x793c8512
-#define PLL_33MHZ PLL_SET(18,88,3,295)
-
-static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
- unsigned long pciOffset, unsigned long regionSize);
-
-static __init void SetPCIPLL(void)
-{
- {
- /* Lets play with the PLL values */
- unsigned long pll1cr1;
- unsigned long mdiv, ndiv, pdiv;
- unsigned long muxcr;
- unsigned int muxcr_ratios[4] = { 8, 16, 21, 1 };
- unsigned int freq;
-
-#define CLKGENA 0xbb040000
-#define CLKGENA_PLL2_MUXCR CLKGENA + 0x48
- pll1cr1 = ctrl_inl(PLLPCICR);
- printk("PLL1CR1 %08lx\n", pll1cr1);
- mdiv = PLL_MDIV(pll1cr1);
- ndiv = PLL_NDIV(pll1cr1);
- pdiv = PLL_PDIV(pll1cr1);
- printk("mdiv %02lx ndiv %02lx pdiv %02lx\n", mdiv, ndiv, pdiv);
- freq = ((2*27*ndiv)/mdiv) / (1 << pdiv);
- printk("PLL freq %dMHz\n", freq);
- muxcr = ctrl_inl(CLKGENA_PLL2_MUXCR);
- printk("PCI freq %dMhz\n", freq / muxcr_ratios[muxcr & 3]);
- }
-}
-
-
-struct pci_err {
- unsigned mask;
- const char *error_string;
-};
-
-static struct pci_err int_error[]={
- { INT_MNLTDIM,"MNLTDIM: Master non-lock transfer"},
- { INT_TTADI, "TTADI: Illegal byte enable in I/O transfer"},
- { INT_TMTO, "TMTO: Target memory read/write timeout"},
- { INT_MDEI, "MDEI: Master function disable error"},
- { INT_APEDI, "APEDI: Address parity error"},
- { INT_SDI, "SDI: SERR detected"},
- { INT_DPEITW, "DPEITW: Data parity error target write"},
- { INT_PEDITR, "PEDITR: PERR detected"},
- { INT_TADIM, "TADIM: Target abort detected"},
- { INT_MADIM, "MADIM: Master abort detected"},
- { INT_MWPDI, "MWPDI: PERR from target at data write"},
- { INT_MRDPEI, "MRDPEI: Master read data parity error"}
-};
-#define NUM_PCI_INT_ERRS ARRAY_SIZE(int_error)
-
-static struct pci_err aint_error[]={
- { AINT_MBI, "MBI: Master broken"},
- { AINT_TBTOI, "TBTOI: Target bus timeout"},
- { AINT_MBTOI, "MBTOI: Master bus timeout"},
- { AINT_TAI, "TAI: Target abort"},
- { AINT_MAI, "MAI: Master abort"},
- { AINT_RDPEI, "RDPEI: Read data parity"},
- { AINT_WDPE, "WDPE: Write data parity"}
-};
-
-#define NUM_PCI_AINT_ERRS ARRAY_SIZE(aint_error)
-
-static void print_pci_errors(unsigned reg,struct pci_err *error,int num_errors)
-{
- int i;
-
- for(i=0;i<num_errors;i++) {
- if(reg & error[i].mask) {
- printk("%s\n",error[i].error_string);
- }
- }
-
-}
-
-
-static char * pci_commands[16]={
- "Int Ack",
- "Special Cycle",
- "I/O Read",
- "I/O Write",
- "Reserved",
- "Reserved",
- "Memory Read",
- "Memory Write",
- "Reserved",
- "Reserved",
- "Configuration Read",
- "Configuration Write",
- "Memory Read Multiple",
- "Dual Address Cycle",
- "Memory Read Line",
- "Memory Write-and-Invalidate"
-};
-
-static irqreturn_t st40_pci_irq(int irq, void *dev_instance)
-{
- unsigned pci_int, pci_air, pci_cir, pci_aint;
- static int count=0;
-
-
- pci_int = ST40PCI_READ(INT);pci_aint = ST40PCI_READ(AINT);
- pci_cir = ST40PCI_READ(CIR);pci_air = ST40PCI_READ(AIR);
-
- /* Reset state to stop multiple interrupts */
- ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0);
-
-
- if(++count>1) return IRQ_HANDLED;
-
- printk("** PCI ERROR **\n");
-
- if(pci_int) {
- printk("** INT register status\n");
- print_pci_errors(pci_int,int_error,NUM_PCI_INT_ERRS);
- }
-
- if(pci_aint) {
- printk("** AINT register status\n");
- print_pci_errors(pci_aint,aint_error,NUM_PCI_AINT_ERRS);
- }
-
- printk("** Address and command info\n");
-
- printk("** Command %s : Address 0x%x\n",
- pci_commands[pci_cir&0xf],pci_air);
-
- if(pci_cir&CIR_PIOTEM) {
- printk("CIR_PIOTEM:PIO transfer error for master\n");
- }
- if(pci_cir&CIR_RWTET) {
- printk("CIR_RWTET:Read/Write transfer error for target\n");
- }
-
- return IRQ_HANDLED;
-}
-
-
-/* Rounds a number UP to the nearest power of two. Used for
- * sizing the PCI window.
- */
-static u32 r2p2(u32 num)
-{
- int i = 31;
- u32 tmp = num;
-
- if (num == 0)
- return 0;
-
- do {
- if (tmp & (1 << 31))
- break;
- i--;
- tmp <<= 1;
- } while (i >= 0);
-
- tmp = 1 << i;
- /* If the original number isn't a power of 2, round it up */
- if (tmp != num)
- tmp <<= 1;
-
- return tmp;
-}
-
-static void __init pci_fixup_ide_bases(struct pci_dev *d)
-{
- int i;
-
- /*
- * PCI IDE controllers use non-standard I/O port decoding, respect it.
- */
- if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return;
- printk("PCI: IDE base address fixup for %s\n", pci_name(d));
- for(i=0; i<4; i++) {
- struct resource *r = &d->resource[i];
- if ((r->start & ~0x80) == 0x374) {
- r->start |= 2;
- r->end = r->start;
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
-
-int __init st40pci_init(unsigned memStart, unsigned memSize)
-{
- u32 lsr0;
-
- SetPCIPLL();
-
- /* Initialises the ST40 pci subsystem, performing a reset, then programming
- * up the address space decoders appropriately
- */
-
- /* Should reset core here as well methink */
-
- ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_SOFT_RESET);
-
- /* Loop while core resets */
- while (ST40PCI_READ(CR) & CR_SOFT_RESET);
-
- /* Switch off interrupts */
- ST40PCI_WRITE(INTM, 0);
- ST40PCI_WRITE(AINT, 0);
-
- /* Now, lets reset all the cards on the bus with extreme prejudice */
- ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL);
- udelay(250);
-
- /* Set bus active, take it out of reset */
- ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_BMAM | CR_CFINT | CR_PFCS | CR_PFE);
-
- /* The PCI spec says that no access must be made to the bus until 1 second
- * after reset. This seem ludicrously long, but some delay is needed here
- */
- mdelay(1000);
-
- /* Switch off interrupts */
- ST40PCI_WRITE(INTM, 0);
- ST40PCI_WRITE(AINT, 0);
-
- /* Allow it to be a master */
-
- ST40PCI_WRITE_SHORT(CSR_CMD,
- PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
- PCI_COMMAND_IO);
-
- /* Access to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
- * on the PCI bus. This allows a nice 1-1 bus to phys mapping.
- */
-
-
- ST40PCI_WRITE(MBR, 0x10000000);
- /* Always set the max size 128M (actually, it is only 96MB wide) */
- ST40PCI_WRITE(MBMR, 0x07ff0000);
-
- /* I/O addresses are mapped at 0xb6000000 -> 0xb7000000. These are changed to 0, to
- * allow cards that have legacy io such as vga to function correctly. This gives a
- * maximum of 64K of io/space as only the bottom 16 bits of the address are copied
- * over to the bus when the transaction is made. 64K of io space is more than enough
- */
- ST40PCI_WRITE(IOBR, 0x0);
- /* Set up the 64K window */
- ST40PCI_WRITE(IOBMR, 0x0);
-
- /* Now we set up the mbars so the PCI bus can see the local memory */
- /* Expose a 256M window starting at PCI address 0... */
- ST40PCI_WRITE(CSR_MBAR0, 0);
- ST40PCI_WRITE(LSR0, 0x0fff0001);
-
- /* ... and set up the initial incoming window to expose all of RAM */
- pci_set_rbar_region(7, memStart, memStart, memSize);
-
- /* Maximise timeout values */
- ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff);
- ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff);
- ST40PCI_WRITE_BYTE(CSR_MIT, 0xff);
-
- ST40PCI_WRITE_BYTE(PERF,PERF_MASTER_WRITE_POSTING);
-
- return 1;
-}
-
-char * __devinit pcibios_setup(char *str)
-{
- return str;
-}
-
-
-#define SET_CONFIG_BITS(bus,devfn,where)\
- (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
-
-#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
-
-
-static int CheckForMasterAbort(void)
-{
- if (ST40PCI_READ(INT) & INT_MADIM) {
- /* Should we clear config space version as well ??? */
- ST40PCI_WRITE(INT, INT_MADIM);
- ST40PCI_WRITE_SHORT(CSR_STATUS, 0);
- return 1;
- }
-
- return 0;
-}
-
-/* Write to config register */
-static int st40pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
-{
- ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
- switch (size) {
- case 1:
- *val = (u8)ST40PCI_READ_BYTE(PDR + (where & 3));
- break;
- case 2:
- *val = (u16)ST40PCI_READ_SHORT(PDR + (where & 2));
- break;
- case 4:
- *val = ST40PCI_READ(PDR);
- break;
- }
-
- if (CheckForMasterAbort()){
- switch (size) {
- case 1:
- *val = (u8)0xff;
- break;
- case 2:
- *val = (u16)0xffff;
- break;
- case 4:
- *val = 0xffffffff;
- break;
- }
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int st40pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
-{
- ST40PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
-
- switch (size) {
- case 1:
- ST40PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
- break;
- case 2:
- ST40PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
- break;
- case 4:
- ST40PCI_WRITE(PDR, val);
- break;
- }
-
- CheckForMasterAbort();
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops st40pci_config_ops = {
- .read = st40pci_read,
- .write = st40pci_write,
-};
-
-
-/* Everything hangs off this */
-static struct pci_bus *pci_root_bus;
-
-static int __init pcibios_init(void)
-{
- extern unsigned long memory_start, memory_end;
-
- printk(KERN_ALERT "pci-st40.c: pcibios_init\n");
-
- if (sh_mv.mv_init_pci != NULL) {
- sh_mv.mv_init_pci();
- }
-
- /* The pci subsytem needs to know where memory is and how much
- * of it there is. I've simply made these globals. A better mechanism
- * is probably needed.
- */
- st40pci_init(PHYSADDR(memory_start),
- PHYSADDR(memory_end) - PHYSADDR(memory_start));
-
- if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq,
- IRQF_DISABLED, "st40pci", NULL)) {
- printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
- return -EIO;
- }
-
- /* Enable the PCI interrupts on the device */
- ST40PCI_WRITE(INTM, ~0);
- ST40PCI_WRITE(AINT, ~0);
-
- /* Map the io address apprioately */
-#ifdef CONFIG_HD64465
- hd64465_port_map(PCIBIOS_MIN_IO, (64 * 1024) - PCIBIOS_MIN_IO + 1,
- ST40_IO_ADDR + PCIBIOS_MIN_IO, 0);
-#endif
-
- /* ok, do the scan man */
- pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL);
- pci_assign_unassigned_resources();
-
- return 0;
-}
-subsys_initcall(pcibios_init);
-
-/*
- * Publish a region of local address space over the PCI bus
- * to other devices.
- */
-static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
- unsigned long pciOffset, unsigned long regionSize)
-{
- unsigned long mask;
-
- if (region > 7)
- return;
-
- if (regionSize > (512 * 1024 * 1024))
- return;
-
- mask = r2p2(regionSize) - 0x10000;
-
- /* Disable the region (in case currently in use, should never happen) */
- ST40PCI_WRITE_INDEXED(RSR, region, 0);
-
- /* Start of local address space to publish */
- ST40PCI_WRITE_INDEXED(RLAR, region, PHYSADDR(localAddr) );
-
- /* Start of region in PCI address space as an offset from MBAR0 */
- ST40PCI_WRITE_INDEXED(RBAR, region, pciOffset);
-
- /* Size of region */
- ST40PCI_WRITE_INDEXED(RSR, region, mask | 1);
-}
-
diff --git a/arch/sh/drivers/pci/pci-st40.h b/arch/sh/drivers/pci/pci-st40.h
deleted file mode 100644
index cf0d35bd135..00000000000
--- a/arch/sh/drivers/pci/pci-st40.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Definitions for the ST40 PCI hardware.
- */
-
-#ifndef __PCI_ST40_H__
-#define __PCI_ST40_H__
-
-#define ST40PCI_VCR_STATUS 0x00
-
-#define ST40PCI_VCR_VERSION 0x08
-
-#define ST40PCI_CR 0x10
-
-#define CR_SOFT_RESET (1<<12)
-#define CR_PFCS (1<<11)
-#define CR_PFE (1<<9)
-#define CR_BMAM (1<<6)
-#define CR_HOST (1<<5)
-#define CR_CLKEN (1<<4)
-#define CR_SOCS (1<<3)
-#define CR_IOCS (1<<2)
-#define CR_RSTCTL (1<<1)
-#define CR_CFINT (1<<0)
-#define CR_LOCK_MASK 0x5a000000
-
-
-#define ST40PCI_LSR0 0X14
-#define ST40PCI_LAR0 0x1c
-
-#define ST40PCI_INT 0x24
-#define INT_MNLTDIM (1<<15)
-#define INT_TTADI (1<<14)
-#define INT_TMTO (1<<9)
-#define INT_MDEI (1<<8)
-#define INT_APEDI (1<<7)
-#define INT_SDI (1<<6)
-#define INT_DPEITW (1<<5)
-#define INT_PEDITR (1<<4)
-#define INT_TADIM (1<<3)
-#define INT_MADIM (1<<2)
-#define INT_MWPDI (1<<1)
-#define INT_MRDPEI (1<<0)
-
-
-#define ST40PCI_INTM 0x28
-#define ST40PCI_AIR 0x2c
-
-#define ST40PCI_CIR 0x30
-#define CIR_PIOTEM (1<<31)
-#define CIR_RWTET (1<<26)
-
-#define ST40PCI_AINT 0x40
-#define AINT_MBI (1<<13)
-#define AINT_TBTOI (1<<12)
-#define AINT_MBTOI (1<<11)
-#define AINT_TAI (1<<3)
-#define AINT_MAI (1<<2)
-#define AINT_RDPEI (1<<1)
-#define AINT_WDPE (1<<0)
-
-#define ST40PCI_AINTM 0x44
-#define ST40PCI_BMIR 0x48
-#define ST40PCI_PAR 0x4c
-#define ST40PCI_MBR 0x50
-#define ST40PCI_IOBR 0x54
-#define ST40PCI_PINT 0x58
-#define ST40PCI_PINTM 0x5c
-#define ST40PCI_MBMR 0x70
-#define ST40PCI_IOBMR 0x74
-#define ST40PCI_PDR 0x78
-
-/* H8 specific registers start here */
-#define ST40PCI_WCBAR 0x7c
-#define ST40PCI_LOCCFG_UNLOCK 0x34
-
-#define ST40PCI_RBAR0 0x100
-#define ST40PCI_RSR0 0x104
-#define ST40PCI_RLAR0 0x108
-
-#define ST40PCI_RBAR1 0x110
-#define ST40PCI_RSR1 0x114
-#define ST40PCI_RLAR1 0x118
-
-
-#define ST40PCI_RBAR2 0x120
-#define ST40PCI_RSR2 0x124
-#define ST40PCI_RLAR2 0x128
-
-#define ST40PCI_RBAR3 0x130
-#define ST40PCI_RSR3 0x134
-#define ST40PCI_RLAR3 0x138
-
-#define ST40PCI_RBAR4 0x140
-#define ST40PCI_RSR4 0x144
-#define ST40PCI_RLAR4 0x148
-
-#define ST40PCI_RBAR5 0x150
-#define ST40PCI_RSR5 0x154
-#define ST40PCI_RLAR5 0x158
-
-#define ST40PCI_RBAR6 0x160
-#define ST40PCI_RSR6 0x164
-#define ST40PCI_RLAR6 0x168
-
-#define ST40PCI_RBAR7 0x170
-#define ST40PCI_RSR7 0x174
-#define ST40PCI_RLAR7 0x178
-
-
-#define ST40PCI_RBAR(n) (0x100+(0x10*(n)))
-#define ST40PCI_RSR(n) (0x104+(0x10*(n)))
-#define ST40PCI_RLAR(n) (0x108+(0x10*(n)))
-
-#define ST40PCI_PERF 0x80
-#define PERF_MASTER_WRITE_POSTING (1<<4)
-/* H8 specific registers end here */
-
-
-/* These are configs space registers */
-#define ST40PCI_CSR_VID 0x10000
-#define ST40PCI_CSR_DID 0x10002
-#define ST40PCI_CSR_CMD 0x10004
-#define ST40PCI_CSR_STATUS 0x10006
-#define ST40PCI_CSR_MBAR0 0x10010
-#define ST40PCI_CSR_TRDY 0x10040
-#define ST40PCI_CSR_RETRY 0x10041
-#define ST40PCI_CSR_MIT 0x1000d
-
-#define ST40_IO_ADDR 0xb6000000
-
-#endif /* __PCI_ST40_H__ */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 1f141a8ba17..4b81d9c47b0 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -10,7 +10,6 @@ obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process.o ptrace.o \
obj-y += cpu/ timers/
obj-$(CONFIG_VSYSCALL) += vsyscall/
-
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
@@ -22,3 +21,5 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index 2b2a9e02fb7..b6abf38d3a8 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -46,7 +46,7 @@ ENTRY(exception_handling_table)
.long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/
ENTRY(nmi_slot)
#if defined (CONFIG_KGDB_NMI)
- .long debug_enter /* 1C0 */ ! Allow trap to debugger
+ .long kgdb_handle_exception /* 1C0 */ ! Allow trap to debugger
#else
.long exception_none /* 1C0 */ ! Not implemented yet
#endif
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 21375d777e9..bc9c28a69bf 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -139,14 +139,6 @@ int __init detect_cpu_and_cache_system(void)
boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
CPU_HAS_LLSC;
break;
- case 0x8000:
- boot_cpu_data.type = CPU_ST40RA;
- boot_cpu_data.flags |= CPU_HAS_FPU;
- break;
- case 0x8100:
- boot_cpu_data.type = CPU_ST40GX1;
- boot_cpu_data.flags |= CPU_HAS_FPU;
- break;
case 0x700:
boot_cpu_data.type = CPU_SH4_501;
boot_cpu_data.icache.ways = 2;
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 348da194ec9..0586bc62ad9 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/kernel_stat.h>
#include <linux/seq_file.h>
-#include <linux/irq.h>
#include <asm/processor.h>
#include <asm/machvec.h>
#include <asm/uaccess.h>
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index 2fdc700dfd6..d453c3a1c79 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -102,6 +102,7 @@
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
+#include <linux/module.h>
#include <asm/system.h>
#include <asm/cacheflush.h>
#include <asm/current.h>
@@ -116,7 +117,9 @@ kgdb_debug_hook_t *kgdb_debug_hook;
kgdb_bus_error_hook_t *kgdb_bus_err_hook;
int (*kgdb_getchar)(void);
+EXPORT_SYMBOL_GPL(kgdb_getchar);
void (*kgdb_putchar)(int);
+EXPORT_SYMBOL_GPL(kgdb_putchar);
static void put_debug_char(int c)
{
@@ -136,7 +139,7 @@ static int get_debug_char(void)
#define NUMREGBYTES (MAXREG*4)
#define OUTBUFMAX (NUMREGBYTES*2+512)
-enum regs {
+enum {
R0 = 0, R1, R2, R3, R4, R5, R6, R7,
R8, R9, R10, R11, R12, R13, R14, R15,
PC, PR, GBR, VBR, MACH, MACL, SR,
@@ -176,9 +179,13 @@ int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
/* SCI/UART settings, used in kgdb_console_setup() */
int kgdb_portnum = CONFIG_KGDB_DEFPORT;
+EXPORT_SYMBOL_GPL(kgdb_portnum);
int kgdb_baud = CONFIG_KGDB_DEFBAUD;
+EXPORT_SYMBOL_GPL(kgdb_baud);
char kgdb_parity = CONFIG_KGDB_DEFPARITY;
+EXPORT_SYMBOL_GPL(kgdb_parity);
char kgdb_bits = CONFIG_KGDB_DEFBITS;
+EXPORT_SYMBOL_GPL(kgdb_bits);
/* Jump buffer for setjmp/longjmp */
static jmp_buf rem_com_env;
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 0b8c45d53a4..4156aac8c27 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -303,7 +303,6 @@ static const char *cpu_name[] = {
[CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R",
[CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R",
[CPU_SH7760] = "SH7760",
- [CPU_ST40RA] = "ST40RA", [CPU_ST40GX1] = "ST40GX1",
[CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501",
[CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780",
[CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343",
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 548e4285b37..e1a6de9088b 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -106,7 +106,6 @@ DECLARE_EXPORT(__movmem);
DECLARE_EXPORT(__movstr);
#endif
-#ifdef CONFIG_CPU_SH4
#if __GNUC__ == 4
DECLARE_EXPORT(__movmem_i4_even);
DECLARE_EXPORT(__movmem_i4_odd);
@@ -126,7 +125,6 @@ DECLARE_EXPORT(__movstr_i4_even);
DECLARE_EXPORT(__movstr_i4_odd);
DECLARE_EXPORT(__movstrSI12_i4);
#endif /* __GNUC__ == 4 */
-#endif
#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
defined(CONFIG_SH7705_CACHE_32KB))
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index e23dd1a3fcc..9dc7b698505 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -9,3 +9,5 @@ memcpy-y := memcpy.o
memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o
lib-y += $(memcpy-y)
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index cf446bbab5b..1265f204f7d 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -17,7 +17,7 @@ config CPU_SH4
bool
select CPU_HAS_INTEVT
select CPU_HAS_SR_RB
- select CPU_HAS_PTEA if (!CPU_SUBTYPE_ST40 && !CPU_SH4A) || CPU_SHX2
+ select CPU_HAS_PTEA if !CPU_SH4A || CPU_SHX2
select CPU_HAS_FPU if !CPU_SH4AL_DSP
config CPU_SH4A
@@ -29,10 +29,6 @@ config CPU_SH4AL_DSP
select CPU_SH4A
select CPU_HAS_DSP
-config CPU_SUBTYPE_ST40
- bool
- select CPU_SH4
-
config CPU_SHX2
bool
@@ -152,21 +148,6 @@ config CPU_SUBTYPE_SH4_202
bool "Support SH4-202 processor"
select CPU_SH4
-# ST40 Processor Support
-
-config CPU_SUBTYPE_ST40STB1
- bool "Support ST40STB1/ST40RA processors"
- select CPU_SUBTYPE_ST40
- help
- Select ST40STB1 if you have a ST40RA CPU.
- This was previously called the ST40STB1, hence the option name.
-
-config CPU_SUBTYPE_ST40GX1
- bool "Support ST40GX1 processor"
- select CPU_SUBTYPE_ST40
- help
- Select ST40GX1 if you have a ST40GX1 CPU.
-
# SH-4A Processor Support
config CPU_SUBTYPE_SH7770
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index ee30fb44dfe..aa44607f072 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -33,3 +33,5 @@ endif
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_32BIT) += pmb.o
obj-$(CONFIG_NUMA) += numa.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/clear_page.S b/arch/sh/mm/clear_page.S
index 8a706131e52..7a7c81ee3f0 100644
--- a/arch/sh/mm/clear_page.S
+++ b/arch/sh/mm/clear_page.S
@@ -150,48 +150,3 @@ ENTRY(__clear_user)
.long 8b, .Lbad_clear_user
.long 9b, .Lbad_clear_user
.previous
-
-#if defined(CONFIG_CPU_SH4)
-/*
- * __clear_user_page
- * @to: P3 address (with same color)
- * @orig_to: P1 address
- *
- * void __clear_user_page(void *to, void *orig_to)
- */
-
-/*
- * r0 --- scratch
- * r4 --- to
- * r5 --- orig_to
- * r6 --- to + PAGE_SIZE
- */
-ENTRY(__clear_user_page)
- mov.l .Lpsz,r0
- mov r4,r6
- add r0,r6
- mov #0,r0
- !
-1: ocbi @r5
- add #32,r5
- movca.l r0,@r4
- mov r4,r1
- add #32,r4
- mov.l r0,@-r4
- mov.l r0,@-r4
- mov.l r0,@-r4
- mov.l r0,@-r4
- mov.l r0,@-r4
- mov.l r0,@-r4
- mov.l r0,@-r4
- add #28,r4
- cmp/eq r6,r4
- bf/s 1b
- ocbwb @r1
- !
- rts
- nop
-.Lpsz: .long PAGE_SIZE
-
-#endif
-
diff --git a/arch/sh/mm/copy_page.S b/arch/sh/mm/copy_page.S
index 3d8409daa4b..40685018b95 100644
--- a/arch/sh/mm/copy_page.S
+++ b/arch/sh/mm/copy_page.S
@@ -68,67 +68,6 @@ ENTRY(copy_page_slow)
rts
nop
-#if defined(CONFIG_CPU_SH4)
-/*
- * __copy_user_page
- * @to: P1 address (with same color)
- * @from: P1 address
- * @orig_to: P1 address
- *
- * void __copy_user_page(void *to, void *from, void *orig_to)
- */
-
-/*
- * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
- * r8 --- from + PAGE_SIZE
- * r9 --- orig_to
- * r10 --- to
- * r11 --- from
- */
-ENTRY(__copy_user_page)
- mov.l r8,@-r15
- mov.l r9,@-r15
- mov.l r10,@-r15
- mov.l r11,@-r15
- mov r4,r10
- mov r5,r11
- mov r6,r9
- mov r5,r8
- mov.l .Lpsz,r0
- add r0,r8
- !
-1: ocbi @r9
- add #32,r9
- mov.l @r11+,r0
- mov.l @r11+,r1
- mov.l @r11+,r2
- mov.l @r11+,r3
- mov.l @r11+,r4
- mov.l @r11+,r5
- mov.l @r11+,r6
- mov.l @r11+,r7
- movca.l r0,@r10
- mov r10,r0
- add #32,r10
- mov.l r7,@-r10
- mov.l r6,@-r10
- mov.l r5,@-r10
- mov.l r4,@-r10
- mov.l r3,@-r10
- mov.l r2,@-r10
- mov.l r1,@-r10
- ocbwb @r0
- cmp/eq r11,r8
- bf/s 1b
- add #28,r10
- !
- mov.l @r15+,r11
- mov.l @r15+,r10
- mov.l @r15+,r9
- mov.l @r15+,r8
- rts
- nop
-#endif
.align 2
.Lpsz: .long PAGE_SIZE
/*
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
index 25f5c6f6821..8c7a9ca7987 100644
--- a/arch/sh/mm/pg-sh4.c
+++ b/arch/sh/mm/pg-sh4.c
@@ -9,6 +9,8 @@
#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
@@ -50,34 +52,61 @@ static inline void kunmap_coherent(struct page *page)
void clear_user_page(void *to, unsigned long address, struct page *page)
{
__set_bit(PG_mapped, &page->flags);
- if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
- clear_page(to);
- else {
- void *vto = kmap_coherent(page, address);
- __clear_user_page(vto, to);
- kunmap_coherent(vto);
- }
+
+ clear_page(to);
+ if ((((address & PAGE_MASK) ^ (unsigned long)to) & CACHE_ALIAS))
+ __flush_wback_region(to, PAGE_SIZE);
}
-/*
- * copy_user_page
- * @to: P1 address
- * @from: P1 address
- * @address: U0 address to be mapped
- * @page: page (virt_to_page(to))
- */
-void copy_user_page(void *to, void *from, unsigned long address,
- struct page *page)
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
{
+ void *vto;
+
__set_bit(PG_mapped, &page->flags);
- if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
- copy_page(to, from);
- else {
- void *vfrom = kmap_coherent(page, address);
- __copy_user_page(vfrom, from, to);
- kunmap_coherent(vfrom);
- }
+
+ vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ memcpy(vto, src, len);
+ kunmap_coherent(vto);
+
+ if (vma->vm_flags & VM_EXEC)
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ void *vfrom;
+
+ __set_bit(PG_mapped, &page->flags);
+
+ vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ memcpy(dst, vfrom, len);
+ kunmap_coherent(vfrom);
+}
+
+void copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *vfrom, *vto;
+
+ __set_bit(PG_mapped, &to->flags);
+
+ vto = kmap_atomic(to, KM_USER1);
+ vfrom = kmap_coherent(from, vaddr);
+ copy_page(vto, vfrom);
+ kunmap_coherent(vfrom);
+
+ if (((vaddr ^ (unsigned long)vto) & CACHE_ALIAS))
+ __flush_wback_region(vto, PAGE_SIZE);
+
+ kunmap_atomic(vto, KM_USER1);
+ /* Make sure this page is cleared on other CPU's too before using it */
+ smp_wmb();
}
+EXPORT_SYMBOL(copy_user_highpage);
/*
* For SH-4, we have our own implementation for ptep_get_and_clear
diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile
index 1f25d9bb753..2efc2e79fd2 100644
--- a/arch/sh/oprofile/Makefile
+++ b/arch/sh/oprofile/Makefile
@@ -15,3 +15,4 @@ profdrvr-$(CONFIG_CPU_SUBTYPE_SH7091) := op_model_sh7750.o
oprofile-y := $(DRIVER_OBJS) $(profdrvr-y)
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh64/kernel/process.c b/arch/sh64/kernel/process.c
index ceb9458abda..0761af4d2a4 100644
--- a/arch/sh64/kernel/process.c
+++ b/arch/sh64/kernel/process.c
@@ -26,6 +26,7 @@
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -656,9 +657,6 @@ unsigned long get_wchan(struct task_struct *p)
*/
#if defined(CONFIG_SH64_PROC_ASIDS)
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-
static int
asids_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
{
@@ -686,10 +684,8 @@ asids_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, void
static int __init register_proc_asids(void)
{
- create_proc_read_entry("asids", 0, NULL, asids_proc_info, NULL);
- return 0;
+ create_proc_read_entry("asids", 0, NULL, asids_proc_info, NULL);
+ return 0;
}
-
__initcall(register_proc_asids);
#endif
-
diff --git a/arch/sh64/kernel/traps.c b/arch/sh64/kernel/traps.c
index c03101fab46..f32df3831f4 100644
--- a/arch/sh64/kernel/traps.c
+++ b/arch/sh64/kernel/traps.c
@@ -30,7 +30,6 @@
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/module.h>
-
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -242,9 +241,6 @@ DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current)
#endif /* CONFIG_SH64_ID2815_WORKAROUND */
-
-#include <asm/system.h>
-
/* Called with interrupts disabled */
asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs)
{
@@ -984,4 +980,3 @@ asmlinkage void do_debug_interrupt(unsigned long code, struct pt_regs *regs)
/* Clear all DEBUGINT causes */
poke_real_address_q(DM_EXP_CAUSE_PHY, 0x0);
}
-
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index e1e24f31aa5..01a6756ba37 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -18,7 +18,6 @@
#include <linux/linkage.h>
#include <linux/kernel_stat.h>
#include <linux/signal.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/random.h>
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c
index 9f472a79d37..eeb5a2fc788 100644
--- a/arch/sparc64/kernel/ds.c
+++ b/arch/sparc64/kernel/ds.c
@@ -6,7 +6,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/sched.h>
diff --git a/arch/sparc64/kernel/module.c b/arch/sparc64/kernel/module.c
index 57987152769..158484bf599 100644
--- a/arch/sparc64/kernel/module.c
+++ b/arch/sparc64/kernel/module.c
@@ -11,7 +11,6 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/slab.h>
-#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <asm/processor.h>
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 78caff92673..98c468803ce 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -51,7 +51,6 @@
#include <linux/vfs.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/ptrace.h>
-#include <linux/highuid.h>
#include <asm/types.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 170d6ca8de6..cfc22d3fe54 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -57,7 +57,6 @@
#include <linux/personality.h>
/* For SOCKET_I */
-#include <linux/socket.h>
#include <net/sock.h>
#include <net/compat.h>
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index a2cf955294c..4352ee4d8da 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -28,7 +28,6 @@
#include <linux/jiffies.h>
#include <linux/cpufreq.h>
#include <linux/percpu.h>
-#include <linux/profile.h>
#include <linux/miscdevice.h>
#include <linux/rtc.h>
#include <linux/kernel_stat.h>
@@ -47,7 +46,6 @@
#include <asm/sections.h>
#include <asm/cpudata.h>
#include <asm/uaccess.h>
-#include <asm/prom.h>
#include <asm/irq_regs.h>
DEFINE_SPINLOCK(mostek_lock);
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 18b23181090..df588f0f76e 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -159,20 +159,16 @@ sysenter_do_call:
sysenter_tracesys:
CFI_RESTORE_STATE
+ xchgl %r9d,%ebp
SAVE_REST
CLEAR_RREGS
+ movq %r9,R9(%rsp)
movq $-ENOSYS,RAX(%rsp) /* really needed? */
movq %rsp,%rdi /* &pt_regs -> arg1 */
call syscall_trace_enter
LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */
RESTORE_REST
- movl %ebp, %ebp
- /* no need to do an access_ok check here because rbp has been
- 32bit zero extended */
-1: movl (%rbp),%r9d
- .section __ex_table,"a"
- .quad 1b,ia32_badarg
- .previous
+ xchgl %ebp,%r9d
jmp sysenter_do_call
CFI_ENDPROC
ENDPROC(ia32_sysenter_target)
@@ -262,20 +258,17 @@ cstar_do_call:
cstar_tracesys:
CFI_RESTORE_STATE
+ xchgl %r9d,%ebp
SAVE_REST
CLEAR_RREGS
+ movq %r9,R9(%rsp)
movq $-ENOSYS,RAX(%rsp) /* really needed? */
movq %rsp,%rdi /* &pt_regs -> arg1 */
call syscall_trace_enter
LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */
RESTORE_REST
+ xchgl %ebp,%r9d
movl RSP-ARGOFFSET(%rsp), %r8d
- /* no need to do an access_ok check here because r8 has been
- 32bit zero extended */
-1: movl (%r8),%r9d
- .section __ex_table,"a"
- .quad 1b,ia32_badarg
- .previous
jmp cstar_do_call
END(ia32_cstar_target)
diff --git a/arch/x86/ia32/ptrace32.c b/arch/x86/ia32/ptrace32.c
index f52770ef0ee..4a233ad6269 100644
--- a/arch/x86/ia32/ptrace32.c
+++ b/arch/x86/ia32/ptrace32.c
@@ -228,8 +228,6 @@ static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data)
return ret;
}
-#define COMPAT_GDT_ENTRY_TLS_MIN 6
-
asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
{
struct task_struct *child;
@@ -248,6 +246,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_SYSCALL:
case PTRACE_OLDSETOPTIONS:
case PTRACE_SETOPTIONS:
+ case PTRACE_SET_THREAD_AREA:
+ case PTRACE_GET_THREAD_AREA:
return sys_ptrace(request, pid, addr, data);
default:
@@ -271,12 +271,6 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_SETSIGINFO:
case PTRACE_GETSIGINFO:
return ptrace32_siginfo(request, pid, addr, data);
-
- case PTRACE_SET_THREAD_AREA:
- case PTRACE_GET_THREAD_AREA:
- return sys_ptrace(request, pid,
- addr + GDT_ENTRY_TLS_MIN - COMPAT_GDT_ENTRY_TLS_MIN,
- data);
}
child = ptrace_get_task_struct(pid);
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 9abbdf7562c..3b20613325d 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -139,13 +139,12 @@ struct set_mtrr_data {
mtrr_type smp_type;
};
-#ifdef CONFIG_SMP
-
static void ipi_handler(void *info)
/* [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
[RETURNS] Nothing.
*/
{
+#ifdef CONFIG_SMP
struct set_mtrr_data *data = info;
unsigned long flags;
@@ -168,9 +167,8 @@ static void ipi_handler(void *info)
atomic_dec(&data->count);
local_irq_restore(flags);
-}
-
#endif
+}
static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
return type1 == MTRR_TYPE_UNCACHABLE ||
diff --git a/arch/x86/kernel/i387_64.c b/arch/x86/kernel/i387_64.c
index 56c1f114710..bfaff28fb13 100644
--- a/arch/x86/kernel/i387_64.c
+++ b/arch/x86/kernel/i387_64.c
@@ -92,13 +92,14 @@ int save_i387(struct _fpstate __user *buf)
if (task_thread_info(tsk)->status & TS_USEDFPU) {
err = save_i387_checking((struct i387_fxsave_struct __user *)buf);
if (err) return err;
+ task_thread_info(tsk)->status &= ~TS_USEDFPU;
stts();
- } else {
- if (__copy_to_user(buf, &tsk->thread.i387.fxsave,
+ } else {
+ if (__copy_to_user(buf, &tsk->thread.i387.fxsave,
sizeof(struct i387_fxsave_struct)))
return -1;
- }
- return 1;
+ }
+ return 1;
}
/*
diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c
index f803ed0ed1c..600fd404e44 100644
--- a/arch/x86/kernel/nmi_32.c
+++ b/arch/x86/kernel/nmi_32.c
@@ -51,13 +51,13 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
static int endflag __initdata = 0;
-#ifdef CONFIG_SMP
/* The performance counters used by NMI_LOCAL_APIC don't trigger when
* the CPU is idle. To make sure the NMI watchdog really ticks on all
* CPUs during the test make them busy.
*/
static __init void nmi_cpu_busy(void *data)
{
+#ifdef CONFIG_SMP
local_irq_enable_in_hardirq();
/* Intentionally don't use cpu_relax here. This is
to make sure that the performance counter really ticks,
@@ -67,8 +67,8 @@ static __init void nmi_cpu_busy(void *data)
care if they get somewhat less cycles. */
while (endflag == 0)
mb();
-}
#endif
+}
static int __init check_nmi_watchdog(void)
{
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index e47a9309eb4..0b4a4790557 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -789,6 +789,20 @@ static inline void cfq_slice_expired(struct cfq_data *cfqd, int timed_out)
__cfq_slice_expired(cfqd, cfqq, timed_out);
}
+static int start_idle_class_timer(struct cfq_data *cfqd)
+{
+ unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE;
+ unsigned long now = jiffies;
+
+ if (time_before(now, end) &&
+ time_after_eq(now, cfqd->last_end_request)) {
+ mod_timer(&cfqd->idle_class_timer, end);
+ return 1;
+ }
+
+ return 0;
+}
+
/*
* Get next queue for service. Unless we have a queue preemption,
* we'll simply select the first cfqq in the service tree.
@@ -805,19 +819,14 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd)
cfqq = rb_entry(n, struct cfq_queue, rb_node);
if (cfq_class_idle(cfqq)) {
- unsigned long end;
-
/*
* if we have idle queues and no rt or be queues had
* pending requests, either allow immediate service if
* the grace period has passed or arm the idle grace
* timer
*/
- end = cfqd->last_end_request + CFQ_IDLE_GRACE;
- if (time_before(jiffies, end)) {
- mod_timer(&cfqd->idle_class_timer, end);
+ if (start_idle_class_timer(cfqd))
cfqq = NULL;
- }
}
return cfqq;
@@ -2036,17 +2045,14 @@ out_cont:
static void cfq_idle_class_timer(unsigned long data)
{
struct cfq_data *cfqd = (struct cfq_data *) data;
- unsigned long flags, end;
+ unsigned long flags;
spin_lock_irqsave(cfqd->queue->queue_lock, flags);
/*
* race with a non-idle queue, reset timer
*/
- end = cfqd->last_end_request + CFQ_IDLE_GRACE;
- if (!time_after_eq(jiffies, end))
- mod_timer(&cfqd->idle_class_timer, end);
- else
+ if (!start_idle_class_timer(cfqd))
cfq_schedule_dispatch(cfqd);
spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
@@ -2068,9 +2074,10 @@ static void cfq_put_async_queues(struct cfq_data *cfqd)
cfq_put_queue(cfqd->async_cfqq[0][i]);
if (cfqd->async_cfqq[1][i])
cfq_put_queue(cfqd->async_cfqq[1][i]);
- if (cfqd->async_idle_cfqq)
- cfq_put_queue(cfqd->async_idle_cfqq);
}
+
+ if (cfqd->async_idle_cfqq)
+ cfq_put_queue(cfqd->async_idle_cfqq);
}
static void cfq_exit_queue(elevator_t *e)
@@ -2125,6 +2132,7 @@ static void *cfq_init_queue(struct request_queue *q)
INIT_WORK(&cfqd->unplug_work, cfq_kick_queue);
+ cfqd->last_end_request = jiffies;
cfqd->cfq_quantum = cfq_quantum;
cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1];
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 75c98d58f4d..3b927be0385 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1143,22 +1143,9 @@ EXPORT_SYMBOL(blk_queue_start_tag);
void blk_queue_invalidate_tags(struct request_queue *q)
{
struct list_head *tmp, *n;
- struct request *rq;
-
- list_for_each_safe(tmp, n, &q->tag_busy_list) {
- rq = list_entry_rq(tmp);
- if (rq->tag == -1) {
- printk(KERN_ERR
- "%s: bad tag found on list\n", __FUNCTION__);
- list_del_init(&rq->queuelist);
- rq->cmd_flags &= ~REQ_QUEUED;
- } else
- blk_queue_end_tag(q, rq);
-
- rq->cmd_flags &= ~REQ_STARTED;
- __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
- }
+ list_for_each_safe(tmp, n, &q->tag_busy_list)
+ blk_requeue_request(q, list_entry_rq(tmp));
}
EXPORT_SYMBOL(blk_queue_invalidate_tags);
@@ -1634,15 +1621,7 @@ static void blk_backing_dev_unplug(struct backing_dev_info *bdi,
{
struct request_queue *q = bdi->unplug_io_data;
- /*
- * devices don't necessarily have an ->unplug_fn defined
- */
- if (q->unplug_fn) {
- blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
- q->rq.count[READ] + q->rq.count[WRITE]);
-
- q->unplug_fn(q);
- }
+ blk_unplug(q);
}
static void blk_unplug_work(struct work_struct *work)
@@ -1666,6 +1645,20 @@ static void blk_unplug_timeout(unsigned long data)
kblockd_schedule_work(&q->unplug_work);
}
+void blk_unplug(struct request_queue *q)
+{
+ /*
+ * devices don't necessarily have an ->unplug_fn defined
+ */
+ if (q->unplug_fn) {
+ blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
+ q->rq.count[READ] + q->rq.count[WRITE]);
+
+ q->unplug_fn(q);
+ }
+}
+EXPORT_SYMBOL(blk_unplug);
+
/**
* blk_start_queue - restart a previously stopped queue
* @q: The &struct request_queue in question
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index da3a08fa9e4..ce9dead0f49 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -60,6 +60,7 @@ config ACPI_PROCFS
/proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
/proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
/proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
+ /proc/acpi/battery (/sys/class/power_supply)
/proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
/proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level)
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index f08cca21702..328ce8a0842 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -960,6 +960,13 @@ static int piix_broken_suspend(void)
},
},
{
+ .ident = "Satellite Pro U200",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE PRO U200"),
+ },
+ },
+ {
.ident = "Satellite U205",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 08a52dd45fb..545ea865ceb 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -312,7 +312,7 @@ EXPORT_SYMBOL_GPL(ata_acpi_stm);
*
* RETURNS:
* Number of taskfiles on success, 0 if _GTF doesn't exist or doesn't
- * contain valid data. -errno on other errors.
+ * contain valid data.
*/
static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
void **ptr_to_free)
@@ -339,7 +339,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
ata_dev_printk(dev, KERN_WARNING,
"_GTF evaluation failed (AE 0x%x)\n",
status);
- rc = -EIO;
}
goto out_free;
}
@@ -359,7 +358,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
ata_dev_printk(dev, KERN_WARNING,
"_GTF unexpected object type 0x%x\n",
out_obj->type);
- rc = -EINVAL;
goto out_free;
}
@@ -367,7 +365,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,
ata_dev_printk(dev, KERN_WARNING,
"unexpected _GTF length (%d)\n",
out_obj->buffer.length);
- rc = -EINVAL;
goto out_free;
}
@@ -511,10 +508,7 @@ static int ata_acpi_exec_tfs(struct ata_device *dev)
int gtf_count, i, rc;
/* get taskfiles */
- rc = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
- if (rc < 0)
- return rc;
- gtf_count = rc;
+ gtf_count = ata_dev_get_GTF(dev, &gtf, &ptr_to_free);
/* execute them */
for (i = 0, rc = 0; i < gtf_count; i++) {
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ec3ce120a51..81898036dbc 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3373,14 +3373,20 @@ void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline)
* to clear 0xff after reset. For example, HHD424020F7SV00
* iVDR needs >= 800ms while. Quantum GoVault needs even more
* than that.
+ *
+ * Note that some PATA controllers (pata_ali) explode if
+ * status register is read more than once when there's no
+ * device attached.
*/
- while (1) {
- u8 status = ata_chk_status(ap);
+ if (ap->flags & ATA_FLAG_SATA) {
+ while (1) {
+ u8 status = ata_chk_status(ap);
- if (status != 0xff || time_after(jiffies, deadline))
- return;
+ if (status != 0xff || time_after(jiffies, deadline))
+ return;
- msleep(50);
+ msleep(50);
+ }
}
}
@@ -6821,19 +6827,6 @@ static void ata_host_release(struct device *gendev, void *res)
if (!ap)
continue;
- if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop)
- ap->ops->port_stop(ap);
- }
-
- if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop)
- host->ops->host_stop(host);
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- if (!ap)
- continue;
-
if (ap->scsi_host)
scsi_host_put(ap->scsi_host);
@@ -6960,6 +6953,24 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
return host;
}
+static void ata_host_stop(struct device *gendev, void *res)
+{
+ struct ata_host *host = dev_get_drvdata(gendev);
+ int i;
+
+ WARN_ON(!(host->flags & ATA_HOST_STARTED));
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
+ }
+
+ if (host->ops->host_stop)
+ host->ops->host_stop(host);
+}
+
/**
* ata_host_start - start and freeze ports of an ATA host
* @host: ATA host to start ports for
@@ -6978,6 +6989,8 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
*/
int ata_host_start(struct ata_host *host)
{
+ int have_stop = 0;
+ void *start_dr = NULL;
int i, rc;
if (host->flags & ATA_HOST_STARTED)
@@ -6989,6 +7002,22 @@ int ata_host_start(struct ata_host *host)
if (!host->ops && !ata_port_is_dummy(ap))
host->ops = ap->ops;
+ if (ap->ops->port_stop)
+ have_stop = 1;
+ }
+
+ if (host->ops->host_stop)
+ have_stop = 1;
+
+ if (have_stop) {
+ start_dr = devres_alloc(ata_host_stop, 0, GFP_KERNEL);
+ if (!start_dr)
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
if (ap->ops->port_start) {
rc = ap->ops->port_start(ap);
if (rc) {
@@ -7001,6 +7030,8 @@ int ata_host_start(struct ata_host *host)
ata_eh_freeze_port(ap);
}
+ if (start_dr)
+ devres_add(host->dev, start_dr);
host->flags |= ATA_HOST_STARTED;
return 0;
@@ -7011,6 +7042,7 @@ int ata_host_start(struct ata_host *host)
if (ap->ops->port_stop)
ap->ops->port_stop(ap);
}
+ devres_free(start_dr);
return rc;
}
@@ -7178,6 +7210,10 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
* request IRQ and register it. This helper takes necessasry
* arguments and performs the three steps in one go.
*
+ * An invalid IRQ skips the IRQ registration and expects the host to
+ * have set polling mode on the port. In this case, @irq_handler
+ * should be NULL.
+ *
* LOCKING:
* Inherited from calling layer (may sleep).
*
@@ -7194,6 +7230,12 @@ int ata_host_activate(struct ata_host *host, int irq,
if (rc)
return rc;
+ /* Special case for polling mode */
+ if (!irq) {
+ WARN_ON(irq_handler);
+ return ata_host_register(host, sht);
+ }
+
rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags,
dev_driver_string(host->dev), host);
if (rc)
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index fc72a965643..ac03a90a616 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -1,7 +1,7 @@
/*
* Generic platform device PATA driver
*
- * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2006 - 2007 Paul Mundt
*
* Based on pata_pcmcia:
*
@@ -22,7 +22,7 @@
#include <linux/pata_platform.h>
#define DRV_NAME "pata_platform"
-#define DRV_VERSION "1.1"
+#define DRV_VERSION "1.2"
static int pio_mask = 1;
@@ -120,15 +120,20 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
* Register a platform bus IDE interface. Such interfaces are PIO and we
* assume do not support IRQ sharing.
*
- * Platform devices are expected to contain 3 resources per port:
+ * Platform devices are expected to contain at least 2 resources per port:
*
* - I/O Base (IORESOURCE_IO or IORESOURCE_MEM)
* - CTL Base (IORESOURCE_IO or IORESOURCE_MEM)
+ *
+ * and optionally:
+ *
* - IRQ (IORESOURCE_IRQ)
*
* If the base resources are both mem types, the ioremap() is handled
* here. For IORESOURCE_IO, it's assumed that there's no remapping
* necessary.
+ *
+ * If no IRQ resource is present, PIO polling mode is used instead.
*/
static int __devinit pata_platform_probe(struct platform_device *pdev)
{
@@ -137,11 +142,12 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
struct ata_port *ap;
struct pata_platform_info *pp_info;
unsigned int mmio;
+ int irq;
/*
* Simple resource validation ..
*/
- if (unlikely(pdev->num_resources != 3)) {
+ if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) {
dev_err(&pdev->dev, "invalid number of resources\n");
return -EINVAL;
}
@@ -173,6 +179,13 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
(ctl_res->flags == IORESOURCE_MEM));
/*
+ * And the IRQ
+ */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ irq = 0; /* no irq */
+
+ /*
* Now that that's out of the way, wire up the port..
*/
host = ata_host_alloc(&pdev->dev, 1);
@@ -185,6 +198,14 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
ap->flags |= ATA_FLAG_SLAVE_POSS;
/*
+ * Use polling mode if there's no IRQ
+ */
+ if (!irq) {
+ ap->flags |= ATA_FLAG_PIO_POLLING;
+ ata_port_desc(ap, "no IRQ, using PIO polling");
+ }
+
+ /*
* Handle the MMIO case
*/
if (mmio) {
@@ -213,9 +234,9 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
(unsigned long long)ctl_res->start);
/* activate */
- return ata_host_activate(host, platform_get_irq(pdev, 0),
- ata_interrupt, pp_info ? pp_info->irq_flags
- : 0, &pata_platform_sht);
+ return ata_host_activate(host, irq, irq ? ata_interrupt : NULL,
+ pp_info ? pp_info->irq_flags : 0,
+ &pata_platform_sht);
}
/**
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 35b2df29752..44f9e5d9e36 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1629,7 +1629,7 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class,
/* SATA hardreset fails to retrieve proper device signature on
* some controllers. Don't classify on hardreset. For more
- * info, see http://bugme.osdl.org/show_bug.cgi?id=3352
+ * info, see http://bugzilla.kernel.org/show_bug.cgi?id=3352
*/
return sata_std_hardreset(link, &dummy, deadline);
}
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 6d43ba79e15..2f1de6ec044 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -103,7 +103,7 @@ enum {
QS_DMA_BOUNDARY = ~0UL
};
-typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t;
+typedef enum { qs_state_mmio, qs_state_pkt } qs_state_t;
struct qs_port_priv {
u8 *pkt;
@@ -116,14 +116,15 @@ static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int qs_port_start(struct ata_port *ap);
static void qs_host_stop(struct ata_host *host);
-static void qs_phy_reset(struct ata_port *ap);
static void qs_qc_prep(struct ata_queued_cmd *qc);
static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
static void qs_bmdma_stop(struct ata_queued_cmd *qc);
static u8 qs_bmdma_status(struct ata_port *ap);
static void qs_irq_clear(struct ata_port *ap);
-static void qs_eng_timeout(struct ata_port *ap);
+static void qs_freeze(struct ata_port *ap);
+static void qs_thaw(struct ata_port *ap);
+static void qs_error_handler(struct ata_port *ap);
static struct scsi_host_template qs_ata_sht = {
.module = THIS_MODULE,
@@ -150,11 +151,12 @@ static const struct ata_port_operations qs_ata_ops = {
.check_atapi_dma = qs_check_atapi_dma,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
- .phy_reset = qs_phy_reset,
.qc_prep = qs_qc_prep,
.qc_issue = qs_qc_issue,
.data_xfer = ata_data_xfer,
- .eng_timeout = qs_eng_timeout,
+ .freeze = qs_freeze,
+ .thaw = qs_thaw,
+ .error_handler = qs_error_handler,
.irq_clear = qs_irq_clear,
.irq_on = ata_irq_on,
.scr_read = qs_scr_read,
@@ -169,8 +171,6 @@ static const struct ata_port_info qs_port_info[] = {
/* board_2068_idx */
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_SATA_RESET |
- //FIXME ATA_FLAG_SRST |
ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
.pio_mask = 0x10, /* pio4 */
.udma_mask = ATA_UDMA6,
@@ -219,7 +219,9 @@ static void qs_irq_clear(struct ata_port *ap)
static inline void qs_enter_reg_mode(struct ata_port *ap)
{
u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
+ struct qs_port_priv *pp = ap->private_data;
+ pp->state = qs_state_mmio;
writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
readb(chan + QS_CCT_CTR0); /* flush */
}
@@ -233,23 +235,28 @@ static inline void qs_reset_channel_logic(struct ata_port *ap)
qs_enter_reg_mode(ap);
}
-static void qs_phy_reset(struct ata_port *ap)
+static void qs_freeze(struct ata_port *ap)
{
- struct qs_port_priv *pp = ap->private_data;
+ u8 __iomem *mmio_base = qs_mmio_base(ap->host);
- pp->state = qs_state_idle;
- qs_reset_channel_logic(ap);
- sata_phy_reset(ap);
+ writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
+ qs_enter_reg_mode(ap);
}
-static void qs_eng_timeout(struct ata_port *ap)
+static void qs_thaw(struct ata_port *ap)
{
- struct qs_port_priv *pp = ap->private_data;
+ u8 __iomem *mmio_base = qs_mmio_base(ap->host);
+
+ qs_enter_reg_mode(ap);
+ writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */
+}
+
+static int qs_prereset(struct ata_link *link, unsigned long deadline)
+{
+ struct ata_port *ap = link->ap;
- if (pp->state != qs_state_idle) /* healthy paranoia */
- pp->state = qs_state_mmio;
qs_reset_channel_logic(ap);
- ata_eng_timeout(ap);
+ return ata_std_prereset(link, deadline);
}
static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
@@ -260,6 +267,13 @@ static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
return 0;
}
+static void qs_error_handler(struct ata_port *ap)
+{
+ qs_enter_reg_mode(ap);
+ ata_do_eh(ap, qs_prereset, ata_std_softreset, NULL,
+ ata_std_postreset);
+}
+
static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
{
if (sc_reg > SCR_CONTROL)
@@ -358,7 +372,6 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
switch (qc->tf.protocol) {
case ATA_PROT_DMA:
-
pp->state = qs_state_pkt;
qs_packet_start(qc);
return 0;
@@ -375,6 +388,26 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
return ata_qc_issue_prot(qc);
}
+static void qs_do_or_die(struct ata_queued_cmd *qc, u8 status)
+{
+ qc->err_mask |= ac_err_mask(status);
+
+ if (!qc->err_mask) {
+ ata_qc_complete(qc);
+ } else {
+ struct ata_port *ap = qc->ap;
+ struct ata_eh_info *ehi = &ap->link.eh_info;
+
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "status 0x%02X", status);
+
+ if (qc->err_mask == AC_ERR_DEV)
+ ata_port_abort(ap);
+ else
+ ata_port_freeze(ap);
+ }
+}
+
static inline unsigned int qs_intr_pkt(struct ata_host *host)
{
unsigned int handled = 0;
@@ -406,10 +439,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host)
switch (sHST) {
case 0: /* successful CPB */
case 3: /* device error */
- pp->state = qs_state_idle;
qs_enter_reg_mode(qc->ap);
- qc->err_mask |= ac_err_mask(sDST);
- ata_qc_complete(qc);
+ qs_do_or_die(qc, sDST);
break;
default:
break;
@@ -431,25 +462,27 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
if (ap &&
!(ap->flags & ATA_FLAG_DISABLED)) {
struct ata_queued_cmd *qc;
- struct qs_port_priv *pp = ap->private_data;
- if (!pp || pp->state != qs_state_mmio)
- continue;
+ struct qs_port_priv *pp;
qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
-
- /* check main status, clearing INTRQ */
- u8 status = ata_check_status(ap);
- if ((status & ATA_BUSY))
- continue;
- DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
- ap->print_id, qc->tf.protocol, status);
-
- /* complete taskfile transaction */
- pp->state = qs_state_idle;
- qc->err_mask |= ac_err_mask(status);
- ata_qc_complete(qc);
+ if (!qc || !(qc->flags & ATA_QCFLAG_ACTIVE)) {
+ /*
+ * The qstor hardware generates spurious
+ * interrupts from time to time when switching
+ * in and out of packet mode.
+ * There's no obvious way to know if we're
+ * here now due to that, so just ack the irq
+ * and pretend we knew it was ours.. (ugh).
+ * This does not affect packet mode.
+ */
+ ata_check_status(ap);
handled = 1;
+ continue;
}
+ pp = ap->private_data;
+ if (!pp || pp->state != qs_state_mmio)
+ continue;
+ if (!(qc->tf.flags & ATA_TFLAG_POLLING))
+ handled |= ata_host_intr(ap, qc);
}
}
return handled;
@@ -459,12 +492,13 @@ static irqreturn_t qs_intr(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
unsigned int handled = 0;
+ unsigned long flags;
VPRINTK("ENTER\n");
- spin_lock(&host->lock);
+ spin_lock_irqsave(&host->lock, flags);
handled = qs_intr_pkt(host) | qs_intr_mmio(host);
- spin_unlock(&host->lock);
+ spin_unlock_irqrestore(&host->lock, flags);
VPRINTK("EXIT\n");
@@ -501,7 +535,6 @@ static int qs_port_start(struct ata_port *ap)
rc = ata_port_start(ap);
if (rc)
return rc;
- qs_enter_reg_mode(ap);
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
@@ -512,6 +545,7 @@ static int qs_port_start(struct ata_port *ap)
memset(pp->pkt, 0, QS_PKT_BYTES);
ap->private_data = pp;
+ qs_enter_reg_mode(ap);
addr = (u64)pp->pkt_dma;
writel((u32) addr, chan + QS_CCF_CPBA);
writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a8130a4ad6d..a5ee21319d3 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -358,10 +358,19 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
size_t count)
{
unsigned int major, minor;
+
if (sscanf(buf, "%u:%u", &major, &minor) == 2) {
+ /* pkt_setup_dev() expects caller to hold reference to self */
+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
+
pkt_setup_dev(MKDEV(major, minor), NULL);
+
+ module_put(THIS_MODULE);
+
return count;
}
+
return -EINVAL;
}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 7a003504c26..1bdd2bf4f37 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -730,13 +730,23 @@ static int send_prio_char(struct tty_struct *tty, char ch)
return 0;
}
-int n_tty_ioctl(struct tty_struct * tty, struct file * file,
- unsigned int cmd, unsigned long arg)
+/**
+ * tty_mode_ioctl - mode related ioctls
+ * @tty: tty for the ioctl
+ * @file: file pointer for the tty
+ * @cmd: command
+ * @arg: ioctl argument
+ *
+ * Perform non line discipline specific mode control ioctls. This
+ * is designed to be called by line disciplines to ensure they provide
+ * consistent mode setting.
+ */
+
+int tty_mode_ioctl(struct tty_struct * tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct tty_struct * real_tty;
void __user *p = (void __user *)arg;
- int retval;
- struct tty_ldisc *ld;
if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
tty->driver->subtype == PTY_TYPE_MASTER)
@@ -799,6 +809,93 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
case TCSETA:
return set_termios(real_tty, p, TERMIOS_TERMIO);
+#ifndef TCGETS2
+ case TIOCGLCKTRMIOS:
+ if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
+ return -EFAULT;
+ return 0;
+
+ case TIOCSLCKTRMIOS:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
+ return -EFAULT;
+ return 0;
+#else
+ case TIOCGLCKTRMIOS:
+ if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
+ return -EFAULT;
+ return 0;
+
+ case TIOCSLCKTRMIOS:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
+ return -EFAULT;
+ return 0;
+#endif
+ case TIOCGSOFTCAR:
+ return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg);
+ case TIOCSSOFTCAR:
+ if (get_user(arg, (unsigned int __user *) arg))
+ return -EFAULT;
+ mutex_lock(&tty->termios_mutex);
+ tty->termios->c_cflag =
+ ((tty->termios->c_cflag & ~CLOCAL) |
+ (arg ? CLOCAL : 0));
+ mutex_unlock(&tty->termios_mutex);
+ return 0;
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+EXPORT_SYMBOL_GPL(tty_mode_ioctl);
+
+int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
+{
+ struct tty_ldisc *ld;
+ int retval = tty_check_change(tty);
+ if (retval)
+ return retval;
+
+ ld = tty_ldisc_ref(tty);
+ switch (arg) {
+ case TCIFLUSH:
+ if (ld && ld->flush_buffer)
+ ld->flush_buffer(tty);
+ break;
+ case TCIOFLUSH:
+ if (ld && ld->flush_buffer)
+ ld->flush_buffer(tty);
+ /* fall through */
+ case TCOFLUSH:
+ if (tty->driver->flush_buffer)
+ tty->driver->flush_buffer(tty);
+ break;
+ default:
+ tty_ldisc_deref(ld);
+ return -EINVAL;
+ }
+ tty_ldisc_deref(ld);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(tty_perform_flush);
+
+int n_tty_ioctl(struct tty_struct * tty, struct file * file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct tty_struct * real_tty;
+ int retval;
+
+ if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+ tty->driver->subtype == PTY_TYPE_MASTER)
+ real_tty = tty->link;
+ else
+ real_tty = tty;
+
+ switch (cmd) {
case TCXONC:
retval = tty_check_change(tty);
if (retval)
@@ -829,30 +926,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
}
return 0;
case TCFLSH:
- retval = tty_check_change(tty);
- if (retval)
- return retval;
-
- ld = tty_ldisc_ref(tty);
- switch (arg) {
- case TCIFLUSH:
- if (ld && ld->flush_buffer)
- ld->flush_buffer(tty);
- break;
- case TCIOFLUSH:
- if (ld && ld->flush_buffer)
- ld->flush_buffer(tty);
- /* fall through */
- case TCOFLUSH:
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- break;
- default:
- tty_ldisc_deref(ld);
- return -EINVAL;
- }
- tty_ldisc_deref(ld);
- return 0;
+ return tty_perform_flush(tty, arg);
case TIOCOUTQ:
return put_user(tty->driver->chars_in_buffer ?
tty->driver->chars_in_buffer(tty) : 0,
@@ -862,32 +936,6 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
if (L_ICANON(tty))
retval = inq_canon(tty);
return put_user(retval, (unsigned int __user *) arg);
-#ifndef TCGETS2
- case TIOCGLCKTRMIOS:
- if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
- return -EFAULT;
- return 0;
-
- case TIOCSLCKTRMIOS:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
- return -EFAULT;
- return 0;
-#else
- case TIOCGLCKTRMIOS:
- if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
- return -EFAULT;
- return 0;
-
- case TIOCSLCKTRMIOS:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
- return -EFAULT;
- return 0;
-#endif
-
case TIOCPKT:
{
int pktmode;
@@ -906,19 +954,9 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
tty->packet = 0;
return 0;
}
- case TIOCGSOFTCAR:
- return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg);
- case TIOCSSOFTCAR:
- if (get_user(arg, (unsigned int __user *) arg))
- return -EFAULT;
- mutex_lock(&tty->termios_mutex);
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- mutex_unlock(&tty->termios_mutex);
- return 0;
default:
- return -ENOIOCTLCMD;
+ /* Try the mode commands */
+ return tty_mode_ioctl(tty, file, cmd, arg);
}
}
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 5596df65c8e..624ff3e082f 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -650,13 +650,14 @@ static void sbp2_login(struct work_struct *work)
if (sbp2_send_management_orb(lu, node_id, generation,
SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
if (lu->retries++ < 5) {
- queue_delayed_work(sbp2_wq, &lu->work,
- DIV_ROUND_UP(HZ, 5));
+ if (queue_delayed_work(sbp2_wq, &lu->work,
+ DIV_ROUND_UP(HZ, 5)))
+ kref_get(&lu->tgt->kref);
} else {
fw_error("failed to login to %s LUN %04x\n",
unit->device.bus_id, lu->lun);
- kref_put(&lu->tgt->kref, sbp2_release_target);
}
+ kref_put(&lu->tgt->kref, sbp2_release_target);
return;
}
@@ -914,7 +915,9 @@ static void sbp2_reconnect(struct work_struct *work)
lu->retries = 0;
PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
}
- queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5));
+ if (queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5)))
+ kref_get(&lu->tgt->kref);
+ kref_put(&lu->tgt->kref, sbp2_release_target);
return;
}
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 8904f72f97c..66f38722253 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -200,7 +200,8 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
/* Figure out how many pages the ring will take, and map that memory */
lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT,
- DIV_ROUND_UP(vring_size(lvq->config.num),
+ DIV_ROUND_UP(vring_size(lvq->config.num,
+ PAGE_SIZE),
PAGE_SIZE));
if (!lvq->pages) {
err = -ENOMEM;
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 516d943227e..075b4d99e35 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -94,7 +94,9 @@ static int wf_thread_func(void *data)
DBG("wf: thread started\n");
set_freezable();
- while(!kthread_should_stop()) {
+ while (!kthread_should_stop()) {
+ try_to_freeze();
+
if (time_after_eq(jiffies, next)) {
wf_notify(WF_EVENT_TICK, NULL);
if (wf_overtemp) {
@@ -116,12 +118,6 @@ static int wf_thread_func(void *data)
delay = next - jiffies;
if (delay <= HZ)
schedule_timeout_interruptible(delay);
-
- /* there should be no non-suspend signal, but oh well */
- if (signal_pending(current) && !try_to_freeze()) {
- printk(KERN_WARNING "windfarm: thread got sigl !\n");
- break;
- }
}
DBG("wf: thread stopped\n");
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 7c426d07a55..1b1ef3130e6 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1207,8 +1207,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
prepare_to_wait(&bitmap->overflow_wait, &__wait,
TASK_UNINTERRUPTIBLE);
spin_unlock_irq(&bitmap->lock);
- bitmap->mddev->queue
- ->unplug_fn(bitmap->mddev->queue);
+ blk_unplug(bitmap->mddev->queue);
schedule();
finish_wait(&bitmap->overflow_wait, &__wait);
continue;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 5a7eb650181..e298d8d11f2 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -1000,8 +1000,7 @@ void dm_table_unplug_all(struct dm_table *t)
struct dm_dev *dd = list_entry(d, struct dm_dev, list);
struct request_queue *q = bdev_get_queue(dd->bdev);
- if (q->unplug_fn)
- q->unplug_fn(q);
+ blk_unplug(q);
}
}
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 56a11f6c127..3dac1cfb818 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -87,8 +87,7 @@ static void linear_unplug(struct request_queue *q)
for (i=0; i < mddev->raid_disks; i++) {
struct request_queue *r_queue = bdev_get_queue(conf->disks[i].rdev->bdev);
- if (r_queue->unplug_fn)
- r_queue->unplug_fn(r_queue);
+ blk_unplug(r_queue);
}
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 808cd954945..cef9ebd5a04 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5445,7 +5445,7 @@ void md_do_sync(mddev_t *mddev)
* about not overloading the IO subsystem. (things like an
* e2fsck being done on the RAID array should execute fast)
*/
- mddev->queue->unplug_fn(mddev->queue);
+ blk_unplug(mddev->queue);
cond_resched();
currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2
@@ -5464,7 +5464,7 @@ void md_do_sync(mddev_t *mddev)
* this also signals 'finished resyncing' to md_stop
*/
out:
- mddev->queue->unplug_fn(mddev->queue);
+ blk_unplug(mddev->queue);
wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index b35731cceac..eb631ebed68 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -125,8 +125,7 @@ static void unplug_slaves(mddev_t *mddev)
atomic_inc(&rdev->nr_pending);
rcu_read_unlock();
- if (r_queue->unplug_fn)
- r_queue->unplug_fn(r_queue);
+ blk_unplug(r_queue);
rdev_dec_pending(rdev, mddev);
rcu_read_lock();
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index c111105fc2d..f8e591708d1 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -35,8 +35,7 @@ static void raid0_unplug(struct request_queue *q)
for (i=0; i<mddev->raid_disks; i++) {
struct request_queue *r_queue = bdev_get_queue(devlist[i]->bdev);
- if (r_queue->unplug_fn)
- r_queue->unplug_fn(r_queue);
+ blk_unplug(r_queue);
}
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 85478d6a9c1..4a69c416e04 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -549,8 +549,7 @@ static void unplug_slaves(mddev_t *mddev)
atomic_inc(&rdev->nr_pending);
rcu_read_unlock();
- if (r_queue->unplug_fn)
- r_queue->unplug_fn(r_queue);
+ blk_unplug(r_queue);
rdev_dec_pending(rdev, mddev);
rcu_read_lock();
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index fc6607acb6e..5cdcc938620 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -593,8 +593,7 @@ static void unplug_slaves(mddev_t *mddev)
atomic_inc(&rdev->nr_pending);
rcu_read_unlock();
- if (r_queue->unplug_fn)
- r_queue->unplug_fn(r_queue);
+ blk_unplug(r_queue);
rdev_dec_pending(rdev, mddev);
rcu_read_lock();
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 82af3465a90..1cfc984cc7b 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3186,8 +3186,7 @@ static void unplug_slaves(mddev_t *mddev)
atomic_inc(&rdev->nr_pending);
rcu_read_unlock();
- if (r_queue->unplug_fn)
- r_queue->unplug_fn(r_queue);
+ blk_unplug(r_queue);
rdev_dec_pending(rdev, mddev);
rcu_read_lock();
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 9203a0b221b..1b9c9b6da5b 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -310,7 +310,7 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
}
if (src_size == 0) {
- src_buf = sg_virt(dst);
+ src_buf = sg_virt(src);
src_size = src->length;
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6b80bf77a4e..ff59d2e0475 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1301,7 +1301,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
if ((chip->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
(host->flags & SDHCI_USE_DMA)) {
- DBG("Disabling DMA as it is marked broken");
+ DBG("Disabling DMA as it is marked broken\n");
host->flags &= ~SDHCI_USE_DMA;
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5f800a6dd97..bf8890ebbc4 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -136,10 +136,11 @@ config TUN
If you don't know what to use this for, you don't need it.
config VETH
- tristate "Virtual ethernet device"
+ tristate "Virtual ethernet pair device"
---help---
- The device is an ethernet tunnel. Devices are created in pairs. When
- one end receives the packet it appears on its pair and vice versa.
+ This device is a local ethernet tunnel. Devices are created in pairs.
+ When one end receives the packet it appears on its pair and vice
+ versa.
config NET_SB1000
tristate "General Instruments Surfboard 1000"
@@ -234,7 +235,7 @@ source "drivers/net/arm/Kconfig"
config AX88796
tristate "ASIX AX88796 NE2000 clone support"
- depends on ARM || MIPS
+ depends on ARM || MIPS || SUPERH
select CRC32
select MII
help
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6937ef0e727..a198404a3e3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4405,6 +4405,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
bond_dev->set_multicast_list = bond_set_multicast_list;
bond_dev->change_mtu = bond_change_mtu;
bond_dev->set_mac_address = bond_set_mac_address;
+ bond_dev->validate_addr = NULL;
bond_set_mode_ops(bond, bond->params.mode);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 7a06ade85b0..b29330d8e30 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1193,8 +1193,6 @@ static ssize_t bonding_show_active_slave(struct device *d,
struct bonding *bond = to_bond(d);
int count;
- rtnl_lock();
-
read_lock(&bond->curr_slave_lock);
curr = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
@@ -1216,7 +1214,9 @@ static ssize_t bonding_store_active_slave(struct device *d,
struct slave *new_active = NULL;
struct bonding *bond = to_bond(d);
+ rtnl_lock();
write_lock_bh(&bond->lock);
+
if (!USES_PRIMARY(bond->params.mode)) {
printk(KERN_INFO DRV_NAME
": %s: Unable to change active slave; %s is in mode %d\n",
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index e0119f6a331..580cb4ab2af 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -762,26 +762,20 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
if (copy_from_user(&addr,
(void __user *) arg, AX25_ADDR_LEN)) {
- err = -EFAULT;
- break;
- }
+ err = -EFAULT;
+ break;
+ }
- netif_tx_lock_bh(dev);
- memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
- netif_tx_unlock_bh(dev);
+ netif_tx_lock_bh(dev);
+ memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
+ netif_tx_unlock_bh(dev);
- err = 0;
- break;
- }
-
- /* Allow stty to read, but not set, the serial port */
- case TCGETS:
- case TCGETA:
- err = n_tty_ioctl(tty, (struct file *) file, cmd, arg);
- break;
+ err = 0;
+ break;
+ }
default:
- err = -ENOIOCTLCMD;
+ err = tty_mode_ioctl(tty, file, cmd, arg);
}
sp_put(sp);
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 2c6f7be36e8..fc753d7f674 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -434,11 +434,6 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
IRDA_ASSERT(dev != NULL, return -1;);
switch (cmd) {
- case TCGETS:
- case TCGETA:
- err = n_tty_ioctl(tty, file, cmd, arg);
- break;
-
case IRTTY_IOCTDONGLE:
/* this call blocks for completion */
err = sirdev_set_dongle(dev, (IRDA_DONGLE) arg);
@@ -454,7 +449,7 @@ static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int c
err = -EFAULT;
break;
default:
- err = -ENOIOCTLCMD;
+ err = tty_mode_ioctl(tty, file, cmd, arg);
break;
}
return err;
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index ab4d309a858..09b4fde8d92 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -580,6 +580,16 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
+ pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
+
+ if (macrx & XCT_MACRX_CRC) {
+ /* CRC error flagged */
+ mac->netdev->stats.rx_errors++;
+ mac->netdev->stats.rx_crc_errors++;
+ dev_kfree_skb_irq(skb);
+ goto next;
+ }
+
if (len < 256) {
struct sk_buff *new_skb;
@@ -595,11 +605,10 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
} else
info->skb = NULL;
- pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
-
info->dma = 0;
- skb_put(skb, len);
+ /* Don't include CRC */
+ skb_put(skb, len-4);
if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -614,6 +623,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
skb->protocol = eth_type_trans(skb, mac->netdev);
netif_receive_skb(skb);
+next:
RX_RING(mac, n) = 0;
RX_RING(mac, n+1) = 0;
@@ -1126,7 +1136,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
int i, nfrags;
- dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD;
+ dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
const unsigned char *nh = skb_network_header(skb);
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 27f5b904f48..8d278c87ba4 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -309,16 +309,11 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
err = 0;
break;
- case TCGETS:
- case TCGETA:
- err = n_tty_ioctl(tty, file, cmd, arg);
- break;
-
case TCFLSH:
/* flush our buffers and the serial port's buffer */
if (arg == TCIOFLUSH || arg == TCOFLUSH)
ppp_async_flush_output(ap);
- err = n_tty_ioctl(tty, file, cmd, arg);
+ err = tty_perform_flush(tty, arg);
break;
case FIONREAD:
@@ -329,7 +324,8 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
break;
default:
- err = -ENOIOCTLCMD;
+ /* Try the various mode ioctls */
+ err = tty_mode_ioctl(tty, file, cmd, arg);
}
ap_put(ap);
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index ce64032a465..00e2fb48b4a 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -349,16 +349,11 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
err = 0;
break;
- case TCGETS:
- case TCGETA:
- err = n_tty_ioctl(tty, file, cmd, arg);
- break;
-
case TCFLSH:
/* flush our buffers and the serial port's buffer */
if (arg == TCIOFLUSH || arg == TCOFLUSH)
ppp_sync_flush_output(ap);
- err = n_tty_ioctl(tty, file, cmd, arg);
+ err = tty_perform_flush(tty, arg);
break;
case FIONREAD:
@@ -369,7 +364,8 @@ ppp_synctty_ioctl(struct tty_struct *tty, struct file *file,
break;
default:
- err = -ENOIOCTLCMD;
+ err = tty_mode_ioctl(tty, file, cmd, arg);
+ break;
}
sp_put(ap);
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index f8904fd9236..a7556cd2df7 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -488,7 +488,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
{
struct pppol2tp_session *session = NULL;
struct pppol2tp_tunnel *tunnel;
- unsigned char *ptr;
+ unsigned char *ptr, *optr;
u16 hdrflags;
u16 tunnel_id, session_id;
int length;
@@ -496,7 +496,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
tunnel = pppol2tp_sock_to_tunnel(sock);
if (tunnel == NULL)
- goto error;
+ goto no_tunnel;
/* UDP always verifies the packet length. */
__skb_pull(skb, sizeof(struct udphdr));
@@ -509,7 +509,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
}
/* Point to L2TP header */
- ptr = skb->data;
+ optr = ptr = skb->data;
/* Get L2TP header flags */
hdrflags = ntohs(*(__be16*)ptr);
@@ -637,12 +637,14 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
/* If offset bit set, skip it. */
if (hdrflags & L2TP_HDRFLAG_O) {
offset = ntohs(*(__be16 *)ptr);
- skb->transport_header += 2 + offset;
- if (!pskb_may_pull(skb, skb_transport_offset(skb) + 2))
- goto discard;
+ ptr += 2 + offset;
}
- __skb_pull(skb, skb_transport_offset(skb));
+ offset = ptr - optr;
+ if (!pskb_may_pull(skb, offset))
+ goto discard;
+
+ __skb_pull(skb, offset);
/* Skip PPP header, if present. In testing, Microsoft L2TP clients
* don't send the PPP header (PPP header compression enabled), but
@@ -652,6 +654,9 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
* Note that skb->data[] isn't dereferenced from a u16 ptr here since
* the field may be unaligned.
*/
+ if (!pskb_may_pull(skb, 2))
+ goto discard;
+
if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03))
skb_pull(skb, 2);
@@ -709,6 +714,10 @@ discard:
return 0;
error:
+ /* Put UDP header back */
+ __skb_push(skb, sizeof(struct udphdr));
+
+no_tunnel:
return 1;
}
@@ -1050,6 +1059,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
/* Get routing info from the tunnel socket */
dst_release(skb->dst);
skb->dst = sk_dst_get(sk_tun);
+ skb_orphan(skb);
+ skb->sk = sk_tun;
/* Queue the packet to IP for output */
len = skb->len;
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 30adf726743..a5791114b7b 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1456,16 +1456,11 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
PHYAddr[qdev->mac_index]);
reg &= ~PHY_GIG_ALL_PARAMS;
- if(portConfiguration &
- PORT_CONFIG_FULL_DUPLEX_ENABLED &
- PORT_CONFIG_1000MB_SPEED) {
- reg |= PHY_GIG_ADV_1000F;
- }
-
- if(portConfiguration &
- PORT_CONFIG_HALF_DUPLEX_ENABLED &
- PORT_CONFIG_1000MB_SPEED) {
- reg |= PHY_GIG_ADV_1000H;
+ if(portConfiguration & PORT_CONFIG_1000MB_SPEED) {
+ if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED)
+ reg |= PHY_GIG_ADV_1000F;
+ else
+ reg |= PHY_GIG_ADV_1000H;
}
ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg,
@@ -1645,8 +1640,11 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev)
return 0;
}
-static void ql_link_state_machine(struct ql3_adapter *qdev)
+static void ql_link_state_machine_work(struct work_struct *work)
{
+ struct ql3_adapter *qdev =
+ container_of(work, struct ql3_adapter, link_state_work.work);
+
u32 curr_link_state;
unsigned long hw_flags;
@@ -1661,6 +1659,10 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
"state.\n", qdev->ndev->name);
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+
+ /* Restart timer on 2 second interval. */
+ mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);\
+
return;
}
@@ -1705,6 +1707,9 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
break;
}
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+
+ /* Restart timer on 2 second interval. */
+ mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
}
/*
@@ -3941,19 +3946,7 @@ static void ql_get_board_info(struct ql3_adapter *qdev)
static void ql3xxx_timer(unsigned long ptr)
{
struct ql3_adapter *qdev = (struct ql3_adapter *)ptr;
-
- if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) {
- printk(KERN_DEBUG PFX
- "%s: Reset in progress.\n",
- qdev->ndev->name);
- goto end;
- }
-
- ql_link_state_machine(qdev);
-
- /* Restart timer on 2 second interval. */
-end:
- mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);
+ queue_delayed_work(qdev->workqueue, &qdev->link_state_work, 0);
}
static int __devinit ql3xxx_probe(struct pci_dev *pdev,
@@ -4103,6 +4096,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
qdev->workqueue = create_singlethread_workqueue(ndev->name);
INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work);
INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work);
+ INIT_DELAYED_WORK(&qdev->link_state_work, ql_link_state_machine_work);
init_timer(&qdev->adapter_timer);
qdev->adapter_timer.function = ql3xxx_timer;
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index fbcb0b94963..d0ffb30ef37 100644
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -1286,6 +1286,7 @@ struct ql3_adapter {
struct workqueue_struct *workqueue;
struct delayed_work reset_work;
struct delayed_work tx_timeout_work;
+ struct delayed_work link_state_work;
u32 max_frame_size;
u32 device_id;
u16 phyType;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index b94fa7ef195..1f647b9ce35 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -171,6 +171,8 @@ static struct pci_device_id rtl8169_pci_tbl[] = {
{ PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 },
{ PCI_VENDOR_ID_LINKSYS, 0x1032,
PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
+ { 0x0001, 0x8168,
+ PCI_ANY_ID, 0x2410, 0, 0, RTL_CFG_2 },
{0,},
};
@@ -468,7 +470,7 @@ static void mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{
int i;
- RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0xFF) << 16 | value);
+ RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff));
for (i = 20; i > 0; i--) {
/*
@@ -485,7 +487,7 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
{
int i, value = -1;
- RTL_W32(PHYAR, 0x0 | (reg_addr & 0xFF) << 16);
+ RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16);
for (i = 20; i > 0; i--) {
/*
@@ -493,7 +495,7 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
* the specified MII register.
*/
if (RTL_R32(PHYAR) & 0x80000000) {
- value = (int) (RTL_R32(PHYAR) & 0xFFFF);
+ value = RTL_R32(PHYAR) & 0xffff;
break;
}
udelay(25);
@@ -1245,16 +1247,6 @@ static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
-static void rtl8168b_hw_phy_config(void __iomem *ioaddr)
-{
- struct phy_reg phy_reg_init[] = {
- { 0x1f, 0x0000 },
- { 0x10, 0xf41b },
- { 0x1f, 0x0000 }
- };
-
- rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
-}
static void rtl8168cp_hw_phy_config(void __iomem *ioaddr)
{
@@ -1324,11 +1316,6 @@ static void rtl_hw_phy_config(struct net_device *dev)
case RTL_GIGA_MAC_VER_04:
rtl8169sb_hw_phy_config(ioaddr);
break;
- case RTL_GIGA_MAC_VER_11:
- case RTL_GIGA_MAC_VER_12:
- case RTL_GIGA_MAC_VER_17:
- rtl8168b_hw_phy_config(ioaddr);
- break;
case RTL_GIGA_MAC_VER_18:
rtl8168cp_hw_phy_config(ioaddr);
break;
@@ -1739,7 +1726,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->features |= rtl_try_msi(pdev, ioaddr, cfg);
RTL_W8(Cfg9346, Cfg9346_Lock);
- if (RTL_R8(PHYstatus) & TBI_Enable) {
+ if ((tp->mac_version <= RTL_GIGA_MAC_VER_06) &&
+ (RTL_R8(PHYstatus) & TBI_Enable)) {
tp->set_speed = rtl8169_set_speed_tbi;
tp->get_settings = rtl8169_gset_tbi;
tp->phy_reset_enable = rtl8169_tbi_reset_enable;
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index b822859c8de..73a7e6529ee 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -78,12 +78,6 @@ static char version[] __devinitdata = "rrunner.c: v0.50 11/11/2002 Jes Sorensen
* stack will need to know about I/O vectors or something similar.
*/
-/*
- * sysctl_[wr]mem_max are checked at init time to see if they are at
- * least 256KB and increased to 256KB if they are not. This is done to
- * avoid ending up with socket buffers smaller than the MTU size,
- */
-
static int __devinit rr_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -561,18 +555,6 @@ static int __devinit rr_init(struct net_device *dev)
sram_size = rr_read_eeprom_word(rrpriv, (void *)8);
printk(" SRAM size 0x%06x\n", sram_size);
- if (sysctl_rmem_max < 262144){
- printk(" Receive socket buffer limit too low (%i), "
- "setting to 262144\n", sysctl_rmem_max);
- sysctl_rmem_max = 262144;
- }
-
- if (sysctl_wmem_max < 262144){
- printk(" Transmit socket buffer limit too low (%i), "
- "setting to 262144\n", sysctl_wmem_max);
- sysctl_wmem_max = 262144;
- }
-
return 0;
}
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index c27c7d63b6a..a2070db725c 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -52,7 +52,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.19"
+#define DRV_VERSION "1.20"
#define PFX DRV_NAME " "
/*
@@ -121,6 +121,7 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4357) }, /* 88E8042 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
@@ -134,6 +135,7 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
{ 0 }
};
@@ -156,7 +158,7 @@ static const char *yukon2_name[] = {
static void sky2_set_multicast(struct net_device *dev);
-/* Access to external PHY */
+/* Access to PHY via serial interconnect */
static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
{
int i;
@@ -166,13 +168,22 @@ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
for (i = 0; i < PHY_RETRIES; i++) {
- if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+ u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
+ if (ctrl == 0xffff)
+ goto io_error;
+
+ if (!(ctrl & GM_SMI_CT_BUSY))
return 0;
- udelay(1);
+
+ udelay(10);
}
- printk(KERN_WARNING PFX "%s: phy write timeout\n", hw->dev[port]->name);
+ dev_warn(&hw->pdev->dev,"%s: phy write timeout\n", hw->dev[port]->name);
return -ETIMEDOUT;
+
+io_error:
+ dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
+ return -EIO;
}
static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
@@ -183,23 +194,29 @@ static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
| GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
for (i = 0; i < PHY_RETRIES; i++) {
- if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) {
+ u16 ctrl = gma_read16(hw, port, GM_SMI_CTRL);
+ if (ctrl == 0xffff)
+ goto io_error;
+
+ if (ctrl & GM_SMI_CT_RD_VAL) {
*val = gma_read16(hw, port, GM_SMI_DATA);
return 0;
}
- udelay(1);
+ udelay(10);
}
+ dev_warn(&hw->pdev->dev, "%s: phy read timeout\n", hw->dev[port]->name);
return -ETIMEDOUT;
+io_error:
+ dev_err(&hw->pdev->dev, "%s: phy I/O error\n", hw->dev[port]->name);
+ return -EIO;
}
-static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
+static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
{
u16 v;
-
- if (__gm_phy_read(hw, port, reg, &v) != 0)
- printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
+ __gm_phy_read(hw, port, reg, &v);
return v;
}
@@ -273,8 +290,6 @@ static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
/* disable all GMAC IRQ's */
sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
- /* disable PHY IRQs */
- gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */
gma_write16(hw, port, GM_MC_ADDR_H2, 0);
@@ -1805,29 +1820,6 @@ static void sky2_link_up(struct sky2_port *sky2)
sky2_write8(hw, SK_REG(port, LNK_LED_REG),
LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
- if (hw->flags & SKY2_HW_NEWER_PHY) {
- u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
- u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */
-
- switch(sky2->speed) {
- case SPEED_10:
- led |= PHY_M_LEDC_INIT_CTRL(7);
- break;
-
- case SPEED_100:
- led |= PHY_M_LEDC_STA1_CTRL(7);
- break;
-
- case SPEED_1000:
- led |= PHY_M_LEDC_STA0_CTRL(7);
- break;
- }
-
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
- gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led);
- gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
- }
-
if (netif_msg_link(sky2))
printk(KERN_INFO PFX
"%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
@@ -2247,20 +2239,26 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
do {
struct sky2_port *sky2;
struct sky2_status_le *le = hw->st_le + hw->st_idx;
- unsigned port = le->css & CSS_LINK_BIT;
+ unsigned port;
struct net_device *dev;
struct sk_buff *skb;
u32 status;
u16 length;
+ u8 opcode = le->opcode;
+
+ if (!(opcode & HW_OWNER))
+ break;
hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
+ port = le->css & CSS_LINK_BIT;
dev = hw->dev[port];
sky2 = netdev_priv(dev);
length = le16_to_cpu(le->length);
status = le32_to_cpu(le->status);
- switch (le->opcode & ~HW_OWNER) {
+ le->opcode = 0;
+ switch (opcode & ~HW_OWNER) {
case OP_RXSTAT:
++rx[port];
skb = sky2_receive(dev, length, status);
@@ -2353,7 +2351,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
default:
if (net_ratelimit())
printk(KERN_WARNING PFX
- "unknown status opcode 0x%x\n", le->opcode);
+ "unknown status opcode 0x%x\n", opcode);
}
} while (hw->st_idx != idx);
@@ -2439,13 +2437,26 @@ static void sky2_hw_intr(struct sky2_hw *hw)
if (status & Y2_IS_PCI_EXP) {
/* PCI-Express uncorrectable Error occurred */
- int pos = pci_find_aer_capability(hw->pdev);
+ int aer = pci_find_aer_capability(hw->pdev);
u32 err;
- pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err);
+ if (aer) {
+ pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS,
+ &err);
+ pci_cleanup_aer_uncorrect_error_status(pdev);
+ } else {
+ /* Either AER not configured, or not working
+ * because of bad MMCONFIG, so just do recover
+ * manually.
+ */
+ err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
+ sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
+ 0xfffffffful);
+ }
+
if (net_ratelimit())
dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
- pci_cleanup_aer_uncorrect_error_status(pdev);
+
}
if (status & Y2_HWE_L1_MASK)
@@ -2791,6 +2802,9 @@ static void sky2_reset(struct sky2_hw *hw)
sky2_write8(hw, B0_CTST, CS_RST_SET);
sky2_write8(hw, B0_CTST, CS_RST_CLR);
+ /* allow writes to PCI config */
+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
/* clear PCI errors, if any */
pci_read_config_word(pdev, PCI_STATUS, &status);
status |= PCI_STATUS_ERROR_BITS;
@@ -2800,9 +2814,18 @@ static void sky2_reset(struct sky2_hw *hw)
cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (cap) {
- /* Check for advanced error reporting */
- pci_cleanup_aer_uncorrect_error_status(pdev);
- pci_cleanup_aer_correct_error_status(pdev);
+ if (pci_find_aer_capability(pdev)) {
+ /* Check for advanced error reporting */
+ pci_cleanup_aer_uncorrect_error_status(pdev);
+ pci_cleanup_aer_correct_error_status(pdev);
+ } else {
+ dev_warn(&pdev->dev,
+ "PCI Express Advanced Error Reporting"
+ " not configured or MMCONFIG problem?\n");
+
+ sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
+ 0xfffffffful);
+ }
/* If error bit is stuck on ignore it */
if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
@@ -3974,7 +3997,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
dev->tx_timeout = sky2_tx_timeout;
dev->watchdog_timeo = TX_WATCHDOG;
#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = sky2_netpoll;
+ if (port == 0)
+ dev->poll_controller = sky2_netpoll;
#endif
sky2 = netdev_priv(dev);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 49ee264064a..69525fd7908 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -247,7 +247,8 @@ enum csr_regs {
B3_PA_CTRL = 0x01f0,
B3_PA_TEST = 0x01f2,
- Y2_CFG_SPC = 0x1c00,
+ Y2_CFG_SPC = 0x1c00, /* PCI config space region */
+ Y2_CFG_AER = 0x1d00, /* PCI Advanced Error Report region */
};
/* B0_CTST 16 bit Control/Status register */
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 335b7cc80eb..251a3ce376a 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -1218,14 +1218,8 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
return 0;
/* VSV changes end */
#endif
-
- /* Allow stty to read, but not set, the serial port */
- case TCGETS:
- case TCGETA:
- return n_tty_ioctl(tty, file, cmd, arg);
-
default:
- return -ENOIOCTLCMD;
+ return tty_mode_ioctl(tty, file, cmd, arg);
}
}
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 729fd28c08b..db34e1eb67e 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -224,6 +224,21 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
}
}
+#elif defined(CONFIG_MACH_ZYLONITE)
+
+#define SMC_CAN_USE_8BIT 1
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 0
+#define SMC_IO_SHIFT 0
+#define SMC_NOWAIT 1
+#define SMC_USE_PXA_DMA 1
+#define SMC_inb(a, r) readb((a) + (r))
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
+#define SMC_outb(v, a, r) writeb(v, (a) + (r))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+
#elif defined(CONFIG_ARCH_OMAP)
/* We can only do 16-bit reads and writes in the static memory space. */
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 5a96d74e4ce..a12c9c41b21 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -93,13 +93,9 @@ config USB_RTL8150
To compile this driver as a module, choose M here: the
module will be called rtl8150.
-config USB_USBNET_MII
- tristate
- default n
-
config USB_USBNET
tristate "Multi-purpose USB Networking Framework"
- select MII if USB_USBNET_MII != n
+ select MII
---help---
This driver supports several kinds of network links over USB,
with "minidrivers" built around a common network driver core
@@ -135,7 +131,6 @@ config USB_NET_AX8817X
tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
depends on USB_USBNET && NET_ETHERNET
select CRC32
- select USB_USBNET_MII
default y
help
This option adds support for ASIX AX88xxx based USB 2.0
@@ -190,7 +185,6 @@ config USB_NET_DM9601
tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices"
depends on USB_USBNET
select CRC32
- select USB_USBNET_MII
help
This option adds support for Davicom DM9601 based USB 1.1
10/100 Ethernet adapters.
@@ -225,7 +219,6 @@ config USB_NET_PLUSB
config USB_NET_MCS7830
tristate "MosChip MCS7830 based Ethernet adapters"
depends on USB_USBNET
- select USB_USBNET_MII
help
Choose this option if you're using a 10/100 Ethernet USB2
adapter based on the MosChip 7830 controller. This includes
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index acd5f1c0e63..8ed1fc5cbc7 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -683,9 +683,6 @@ done_nopm:
* they'll probably want to use this base set.
*/
-#if defined(CONFIG_MII) || defined(CONFIG_MII_MODULE)
-#define HAVE_MII
-
int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd)
{
struct usbnet *dev = netdev_priv(net);
@@ -744,8 +741,6 @@ int usbnet_nway_reset(struct net_device *net)
}
EXPORT_SYMBOL_GPL(usbnet_nway_reset);
-#endif /* HAVE_MII */
-
void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
{
struct usbnet *dev = netdev_priv(net);
@@ -776,12 +771,10 @@ EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
/* drivers may override default ethtool_ops in their bind() routine */
static struct ethtool_ops usbnet_ethtool_ops = {
-#ifdef HAVE_MII
.get_settings = usbnet_get_settings,
.set_settings = usbnet_set_settings,
.get_link = usbnet_get_link,
.nway_reset = usbnet_nway_reset,
-#endif
.get_drvinfo = usbnet_get_drvinfo,
.get_msglevel = usbnet_get_msglevel,
.set_msglevel = usbnet_set_msglevel,
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e396c9d2af8..a75be57fb20 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -146,6 +146,7 @@ static void try_fill_recv(struct virtnet_info *vi)
struct scatterlist sg[1+MAX_SKB_FRAGS];
int num, err;
+ sg_init_table(sg, 1+MAX_SKB_FRAGS);
for (;;) {
skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
if (unlikely(!skb))
@@ -231,6 +232,8 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
DECLARE_MAC_BUF(mac);
+ sg_init_table(sg, 1+MAX_SKB_FRAGS);
+
pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest));
free_old_xmit_skbs(vi);
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index c48b1cc63fd..1e89d4de1bb 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -719,12 +719,8 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
return 0;
case SIOCSIFHWADDR:
return -EINVAL;
- /* Allow stty to read, but not set, the serial port */
- case TCGETS:
- case TCGETA:
- return n_tty_ioctl(tty, file, cmd, arg);
default:
- return -ENOIOCTLCMD;
+ return tty_mode_ioctl(tty, file, cmd, arg);
}
}
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index dae5c8d5a31..2b733c58291 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -325,7 +325,7 @@ config HERMES
Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
- PRO/Wireless, and Symbol Spectrum24 High Rate amongst others.
+ IPW2011, and Symbol Spectrum24 High Rate amongst others.
This option includes the guts of the driver, but in order to
actually use a card you will also need to enable support for PCMCIA
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index e3c573e56b6..fdbc351ac33 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -61,16 +61,18 @@ config B43_PCMCIA
If unsure, say N.
-# LED support
+# This config option automatically enables b43 LEDS support,
+# if it's possible.
config B43_LEDS
bool
- depends on B43 && MAC80211_LEDS
+ depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43)
default y
-# RFKILL support
+# This config option automatically enables b43 RFKILL support,
+# if it's possible.
config B43_RFKILL
bool
- depends on B43 && RFKILL && RFKILL_INPUT && INPUT_POLLDEV
+ depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43)
default y
config B43_DEBUG
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 734e70e1a06..ef0075d9f9c 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -128,7 +128,7 @@ static ssize_t shm_read_file(struct b43_wldev *dev,
__le16 *le16buf = (__le16 *)buf;
for (i = 0; i < 0x1000; i++) {
- if (bufsize <= 0)
+ if (bufsize < sizeof(tmp))
break;
tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i);
le16buf[i] = cpu_to_le16(tmp);
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 5058e60e570..2b17c1dc46f 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2985,6 +2985,16 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
if (b43_status(dev) < B43_STAT_STARTED)
return;
+
+ /* Disable and sync interrupts. We must do this before than
+ * setting the status to INITIALIZED, as the interrupt handler
+ * won't care about IRQs then. */
+ spin_lock_irqsave(&wl->irq_lock, flags);
+ dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+ b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
+ b43_synchronize_irq(dev);
+
b43_set_status(dev, B43_STAT_INITIALIZED);
mutex_unlock(&wl->mutex);
@@ -2995,13 +3005,6 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
ieee80211_stop_queues(wl->hw); //FIXME this could cause a deadlock, as mac80211 seems buggy.
- /* Disable and sync interrupts. */
- spin_lock_irqsave(&wl->irq_lock, flags);
- dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
- b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
- spin_unlock_irqrestore(&wl->irq_lock, flags);
- b43_synchronize_irq(dev);
-
b43_mac_suspend(dev);
free_irq(dev->dev->irq, dev);
b43dbg(wl, "Wireless interface stopped\n");
@@ -3661,7 +3664,6 @@ static int b43_setup_modes(struct b43_wldev *dev,
static void b43_wireless_core_detach(struct b43_wldev *dev)
{
- b43_rfkill_free(dev);
/* We release firmware that late to not be required to re-request
* is all the time when we reinit the core. */
b43_release_firmware(dev);
@@ -3747,7 +3749,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
if (!wl->current_dev)
wl->current_dev = dev;
INIT_WORK(&dev->restart_work, b43_chip_reset);
- b43_rfkill_alloc(dev);
b43_radio_turn_off(dev, 1);
b43_switch_analog(dev, 0);
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index b242a9a90dd..b79a6bd5396 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -65,12 +65,12 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
tuple_t tuple;
cisparse_t parse;
int err = -ENOMEM;
- int res;
+ int res = 0;
unsigned char buf[64];
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
if (!ssb)
- goto out;
+ goto out_error;
err = -ENODEV;
tuple.DesiredTuple = CISTPL_CONFIG;
@@ -96,10 +96,12 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
dev->io.NumPorts2 = 0;
dev->io.Attributes2 = 0;
- win.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+ win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM |
+ WIN_ENABLE | WIN_DATA_WIDTH_16 |
+ WIN_USE_WAIT;
win.Base = 0;
win.Size = SSB_CORE_SIZE;
- win.AccessSpeed = 1000;
+ win.AccessSpeed = 250;
res = pcmcia_request_window(&dev, &win, &dev->win);
if (res != CS_SUCCESS)
goto err_kfree_ssb;
@@ -108,21 +110,34 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
mem.Page = 0;
res = pcmcia_map_mem_page(dev->win, &mem);
if (res != CS_SUCCESS)
- goto err_kfree_ssb;
+ goto err_disable;
+
+ dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED;
+ dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID;
+ dev->irq.Handler = NULL; /* The handler is registered later. */
+ dev->irq.Instance = NULL;
+ res = pcmcia_request_irq(dev, &dev->irq);
+ if (res != CS_SUCCESS)
+ goto err_disable;
res = pcmcia_request_configuration(dev, &dev->conf);
if (res != CS_SUCCESS)
goto err_disable;
err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);
+ if (err)
+ goto err_disable;
dev->priv = ssb;
- out:
- return err;
- err_disable:
+ return 0;
+
+err_disable:
pcmcia_disable_device(dev);
- err_kfree_ssb:
+err_kfree_ssb:
kfree(ssb);
+out_error:
+ printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
+ res, err);
return err;
}
@@ -131,22 +146,21 @@ static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev)
struct ssb_bus *ssb = dev->priv;
ssb_bus_unregister(ssb);
- pcmcia_release_window(dev->win);
pcmcia_disable_device(dev);
kfree(ssb);
dev->priv = NULL;
}
static struct pcmcia_driver b43_pcmcia_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "b43-pcmcia",
- },
- .id_table = b43_pcmcia_tbl,
- .probe = b43_pcmcia_probe,
- .remove = b43_pcmcia_remove,
- .suspend = b43_pcmcia_suspend,
- .resume = b43_pcmcia_resume,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "b43-pcmcia",
+ },
+ .id_table = b43_pcmcia_tbl,
+ .probe = b43_pcmcia_probe,
+ .remove = __devexit_p(b43_pcmcia_remove),
+ .suspend = b43_pcmcia_suspend,
+ .resume = b43_pcmcia_resume,
};
int b43_pcmcia_init(void)
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 800e0a61a7f..9b1f905ffbf 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -47,32 +47,35 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
struct b43_wldev *dev = poll_dev->private;
struct b43_wl *wl = dev->wl;
bool enabled;
+ bool report_change = 0;
mutex_lock(&wl->mutex);
B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED);
enabled = b43_is_hw_radio_enabled(dev);
if (unlikely(enabled != dev->radio_hw_enable)) {
dev->radio_hw_enable = enabled;
+ report_change = 1;
b43info(wl, "Radio hardware status changed to %s\n",
enabled ? "ENABLED" : "DISABLED");
- mutex_unlock(&wl->mutex);
+ }
+ mutex_unlock(&wl->mutex);
+
+ if (unlikely(report_change))
input_report_key(poll_dev->input, KEY_WLAN, enabled);
- } else
- mutex_unlock(&wl->mutex);
}
-/* Called when the RFKILL toggled in software.
- * This is called without locking. */
+/* Called when the RFKILL toggled in software. */
static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
{
struct b43_wldev *dev = data;
struct b43_wl *wl = dev->wl;
int err = 0;
- mutex_lock(&wl->mutex);
- if (b43_status(dev) < B43_STAT_INITIALIZED)
- goto out_unlock;
+ if (!wl->rfkill.registered)
+ return 0;
+ mutex_lock(&wl->mutex);
+ B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED);
switch (state) {
case RFKILL_STATE_ON:
if (!dev->radio_hw_enable) {
@@ -89,7 +92,6 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
b43_radio_turn_off(dev, 0);
break;
}
-
out_unlock:
mutex_unlock(&wl->mutex);
@@ -98,11 +100,11 @@ out_unlock:
char * b43_rfkill_led_name(struct b43_wldev *dev)
{
- struct b43_wl *wl = dev->wl;
+ struct b43_rfkill *rfk = &(dev->wl->rfkill);
- if (!wl->rfkill.rfkill)
+ if (!rfk->registered)
return NULL;
- return rfkill_get_led_name(wl->rfkill.rfkill);
+ return rfkill_get_led_name(rfk->rfkill);
}
void b43_rfkill_init(struct b43_wldev *dev)
@@ -111,53 +113,13 @@ void b43_rfkill_init(struct b43_wldev *dev)
struct b43_rfkill *rfk = &(wl->rfkill);
int err;
- if (rfk->rfkill) {
- err = rfkill_register(rfk->rfkill);
- if (err) {
- b43warn(wl, "Failed to register RF-kill button\n");
- goto err_free_rfk;
- }
- }
- if (rfk->poll_dev) {
- err = input_register_polled_device(rfk->poll_dev);
- if (err) {
- b43warn(wl, "Failed to register RF-kill polldev\n");
- goto err_free_polldev;
- }
- }
-
- return;
-err_free_rfk:
- rfkill_free(rfk->rfkill);
- rfk->rfkill = NULL;
-err_free_polldev:
- input_free_polled_device(rfk->poll_dev);
- rfk->poll_dev = NULL;
-}
-
-void b43_rfkill_exit(struct b43_wldev *dev)
-{
- struct b43_rfkill *rfk = &(dev->wl->rfkill);
-
- if (rfk->poll_dev)
- input_unregister_polled_device(rfk->poll_dev);
- if (rfk->rfkill)
- rfkill_unregister(rfk->rfkill);
-}
-
-void b43_rfkill_alloc(struct b43_wldev *dev)
-{
- struct b43_wl *wl = dev->wl;
- struct b43_rfkill *rfk = &(wl->rfkill);
+ rfk->registered = 0;
+ rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
+ if (!rfk->rfkill)
+ goto out_error;
snprintf(rfk->name, sizeof(rfk->name),
"b43-%s", wiphy_name(wl->hw->wiphy));
-
- rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
- if (!rfk->rfkill) {
- b43warn(wl, "Failed to allocate RF-kill button\n");
- return;
- }
rfk->rfkill->name = rfk->name;
rfk->rfkill->state = RFKILL_STATE_ON;
rfk->rfkill->data = dev;
@@ -165,18 +127,45 @@ void b43_rfkill_alloc(struct b43_wldev *dev)
rfk->rfkill->user_claim_unsupported = 1;
rfk->poll_dev = input_allocate_polled_device();
- if (rfk->poll_dev) {
- rfk->poll_dev->private = dev;
- rfk->poll_dev->poll = b43_rfkill_poll;
- rfk->poll_dev->poll_interval = 1000; /* msecs */
- } else
- b43warn(wl, "Failed to allocate RF-kill polldev\n");
+ if (!rfk->poll_dev)
+ goto err_free_rfk;
+ rfk->poll_dev->private = dev;
+ rfk->poll_dev->poll = b43_rfkill_poll;
+ rfk->poll_dev->poll_interval = 1000; /* msecs */
+
+ err = rfkill_register(rfk->rfkill);
+ if (err)
+ goto err_free_polldev;
+ err = input_register_polled_device(rfk->poll_dev);
+ if (err)
+ goto err_unreg_rfk;
+
+ rfk->registered = 1;
+
+ return;
+err_unreg_rfk:
+ rfkill_unregister(rfk->rfkill);
+err_free_polldev:
+ input_free_polled_device(rfk->poll_dev);
+ rfk->poll_dev = NULL;
+err_free_rfk:
+ rfkill_free(rfk->rfkill);
+ rfk->rfkill = NULL;
+out_error:
+ rfk->registered = 0;
+ b43warn(wl, "RF-kill button init failed\n");
}
-void b43_rfkill_free(struct b43_wldev *dev)
+void b43_rfkill_exit(struct b43_wldev *dev)
{
struct b43_rfkill *rfk = &(dev->wl->rfkill);
+ if (!rfk->registered)
+ return;
+ rfk->registered = 0;
+
+ input_unregister_polled_device(rfk->poll_dev);
+ rfkill_unregister(rfk->rfkill);
input_free_polled_device(rfk->poll_dev);
rfk->poll_dev = NULL;
rfkill_free(rfk->rfkill);
diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h
index 29544e8c9e5..adacf936d81 100644
--- a/drivers/net/wireless/b43/rfkill.h
+++ b/drivers/net/wireless/b43/rfkill.h
@@ -15,14 +15,14 @@ struct b43_rfkill {
struct rfkill *rfkill;
/* The poll device for the RFKILL input button */
struct input_polled_dev *poll_dev;
+ /* Did initialization succeed? Used for freeing. */
+ bool registered;
/* The unique name of this rfkill switch */
- char name[32];
+ char name[sizeof("b43-phy4294967295")];
};
-/* All the init functions return void, because we are not interested
+/* The init function returns void, because we are not interested
* in failing the b43 init process when rfkill init failed. */
-void b43_rfkill_alloc(struct b43_wldev *dev);
-void b43_rfkill_free(struct b43_wldev *dev);
void b43_rfkill_init(struct b43_wldev *dev);
void b43_rfkill_exit(struct b43_wldev *dev);
@@ -36,12 +36,6 @@ struct b43_rfkill {
/* empty */
};
-static inline void b43_rfkill_alloc(struct b43_wldev *dev)
-{
-}
-static inline void b43_rfkill_free(struct b43_wldev *dev)
-{
-}
static inline void b43_rfkill_init(struct b43_wldev *dev)
{
}
diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c
index eefa6fb7968..619b4534ef0 100644
--- a/drivers/net/wireless/b43legacy/debugfs.c
+++ b/drivers/net/wireless/b43legacy/debugfs.c
@@ -124,7 +124,7 @@ static ssize_t shm_read_file(struct b43legacy_wldev *dev, char *buf, size_t bufs
__le16 *le16buf = (__le16 *)buf;
for (i = 0; i < 0x1000; i++) {
- if (bufsize <= 0)
+ if (bufsize < sizeof(tmp))
break;
tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED, 2 * i);
le16buf[i] = cpu_to_le16(tmp);
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index f0e56dfc9ec..3bde1e9ab42 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2781,6 +2781,17 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
return;
+
+ /* Disable and sync interrupts. We must do this before than
+ * setting the status to INITIALIZED, as the interrupt handler
+ * won't care about IRQs then. */
+ spin_lock_irqsave(&wl->irq_lock, flags);
+ dev->irq_savedstate = b43legacy_interrupt_disable(dev,
+ B43legacy_IRQ_ALL);
+ b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
+ spin_unlock_irqrestore(&wl->irq_lock, flags);
+ b43legacy_synchronize_irq(dev);
+
b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
mutex_unlock(&wl->mutex);
@@ -2791,14 +2802,6 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
ieee80211_stop_queues(wl->hw); /* FIXME this could cause a deadlock */
- /* Disable and sync interrupts. */
- spin_lock_irqsave(&wl->irq_lock, flags);
- dev->irq_savedstate = b43legacy_interrupt_disable(dev,
- B43legacy_IRQ_ALL);
- b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
- spin_unlock_irqrestore(&wl->irq_lock, flags);
- b43legacy_synchronize_irq(dev);
-
b43legacy_mac_suspend(dev);
free_irq(dev->dev->irq, dev);
b43legacydbg(wl, "Wireless interface stopped\n");
@@ -3332,7 +3335,7 @@ out_mutex_unlock:
return err;
}
-void b43legacy_stop(struct ieee80211_hw *hw)
+static void b43legacy_stop(struct ieee80211_hw *hw)
{
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
struct b43legacy_wldev *dev = wl->current_dev;
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 7da3664b851..fc876ba1857 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -444,7 +444,7 @@ static int prism2_pci_resume(struct pci_dev *pdev)
MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
-static struct pci_driver prism2_pci_drv_id = {
+static struct pci_driver prism2_pci_driver = {
.name = "hostap_pci",
.id_table = prism2_pci_id_table,
.probe = prism2_pci_probe,
@@ -458,13 +458,13 @@ static struct pci_driver prism2_pci_drv_id = {
static int __init init_prism2_pci(void)
{
- return pci_register_driver(&prism2_pci_drv_id);
+ return pci_register_driver(&prism2_pci_driver);
}
static void __exit exit_prism2_pci(void)
{
- pci_unregister_driver(&prism2_pci_drv_id);
+ pci_unregister_driver(&prism2_pci_driver);
}
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 8d53d08b969..fc6cdd8086c 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -1267,7 +1267,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
IPW2100_INTA_FATAL_ERROR |
IPW2100_INTA_PARITY_ERROR);
}
- } while (i--);
+ } while (--i);
/* Clear out any pending INTAs since we aren't supposed to have
* interrupts enabled at this point... */
@@ -1339,7 +1339,7 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
break;
- } while (i--);
+ } while (--i);
priv->status &= ~STATUS_RESET_PENDING;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4f22a7174ca..be7c9f42a34 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -8354,6 +8354,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
SET_IEEE80211_DEV(hw, &pdev->dev);
+ hw->rate_control_algorithm = "iwl-3945-rs";
+
IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
priv = hw->priv;
priv->hw = hw;
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index d60adcb9bd4..6757c6c1b25 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -8955,6 +8955,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
SET_IEEE80211_DEV(hw, &pdev->dev);
+ hw->rate_control_algorithm = "iwl-4965-rs";
+
IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
priv = hw->priv;
priv->hw = hw;
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 1cbbd96fdbd..be5cfd8402c 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -912,6 +912,10 @@ static int wlan_cmd_set_boot2_ver(wlan_private * priv,
return 0;
}
+/*
+ * Note: NEVER use libertas_queue_cmd() with addtail==0 other than for
+ * the command timer, because it does not account for queued commands.
+ */
void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail)
{
unsigned long flags;
@@ -941,10 +945,11 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
spin_lock_irqsave(&adapter->driver_lock, flags);
- if (addtail)
+ if (addtail) {
list_add_tail((struct list_head *)cmdnode,
&adapter->cmdpendingq);
- else
+ adapter->nr_cmd_pending++;
+ } else
list_add((struct list_head *)cmdnode, &adapter->cmdpendingq);
spin_unlock_irqrestore(&adapter->driver_lock, flags);
@@ -1412,7 +1417,6 @@ int libertas_prepare_and_send_command(wlan_private * priv,
cmdnode->cmdwaitqwoken = 0;
libertas_queue_cmd(adapter, cmdnode, 1);
- adapter->nr_cmd_pending++;
wake_up_interruptible(&priv->waitq);
if (wait_option & CMD_OPTION_WAITFORRSP) {
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 0360cad363a..ec89dabc412 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -148,11 +148,11 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
{
int i;
- for (i = 0; i < 500; i++) {
+ for (i = 0; i < 1000; i++) {
u8 val = if_cs_read8(card, addr);
if (val == reg)
return i;
- udelay(100);
+ udelay(500);
}
return -ETIME;
}
@@ -878,6 +878,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
goto out3;
}
+ /* Clear any interrupt cause that happend while sending
+ * firmware/initializing card */
+ if_cs_write16(card, IF_CS_C_INT_CAUSE, IF_CS_C_IC_MASK);
if_cs_enable_ints(card);
/* And finally bring the card up */
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index a8e17076e7d..b24425f7488 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -182,12 +182,14 @@ static int if_sdio_handle_data(struct if_sdio_card *card,
goto out;
}
- skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+ skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + NET_IP_ALIGN);
if (!skb) {
ret = -ENOMEM;
goto out;
}
+ skb_reserve(skb, NET_IP_ALIGN);
+
data = skb_put(skb, size);
memcpy(data, buffer, size);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 4a6a0bd01ff..85ea8a8e658 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -196,6 +196,14 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
struct rt2x00_dev *rt2x00dev = hw->priv;
struct interface *intf = &rt2x00dev->interface;
+ /* FIXME: Beaconing is broken in rt2x00. */
+ if (conf->type == IEEE80211_IF_TYPE_IBSS ||
+ conf->type == IEEE80211_IF_TYPE_AP) {
+ ERROR(rt2x00dev,
+ "rt2x00 does not support Adhoc or Master mode");
+ return -EOPNOTSUPP;
+ }
+
/*
* Don't allow interfaces to be added while
* either the device has disappeared or when
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 4bd14b33186..88efe1bae58 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -2735,16 +2735,8 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
return -EFAULT;
return set_mac_address(strip_info, &addr);
}
- /*
- * Allow stty to read, but not set, the serial port
- */
-
- case TCGETS:
- case TCGETA:
- return n_tty_ioctl(tty, file, cmd, arg);
- break;
default:
- return -ENOIOCTLCMD;
+ return tty_mode_ioctl(tty, file, cmd, arg);
break;
}
return 0;
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 78277a118b6..8e8c8b8e81e 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -351,8 +351,10 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
- if (rtc_valid_tm(tm) < 0)
+ if (rtc_valid_tm(tm) < 0) {
dev_err(dev, "invalid date\n");
+ rtc_time_to_tm(0, tm);
+ }
return 0;
}
@@ -588,7 +590,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
&sh_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
+ if (IS_ERR(rtc->rtc_dev)) {
ret = PTR_ERR(rtc->rtc_dev);
goto err_badmap;
}
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index e89ae29645d..d24621ce799 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -77,7 +77,6 @@
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
# define SCSPTR0 0xA4400000 /* 16 bit SCIF */
-# define SCI_NPORTS 2
# define SCIF_ORER 0x0001 /* overrun error bit */
# define PACR 0xa4050100
# define PBCR 0xa4050102
@@ -102,12 +101,6 @@
# 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_ST40STB1)
-# define SCSPTR1 0xffe00020 /* 16 bit SCIF */
-# 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 <asm/hardware.h>
# define SCIF_BASE_ADDR 0x01030000
@@ -116,8 +109,7 @@
# define SCIF_LSR2_OFFS 0x0000024
# define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */
# define SCLSR2 ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */
-# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,
- TE=1,RE=1,REIE=1 */
+# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0, TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
#elif defined(CONFIG_H83007) || defined(CONFIG_H83068)
# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
@@ -577,15 +569,6 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */
return 1;
}
-#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-static inline int sci_rxd_in(struct uart_port *port)
-{
- if (port->mapbase == 0xffe00000)
- return ctrl_inw(SCSPTR1)&0x0001 ? 1 : 0; /* SCIF */
- else
- return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
-
-}
#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
static inline int sci_rxd_in(struct uart_port *port)
{
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index dfef83f1496..a85f2d31a68 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -329,12 +329,14 @@ static struct uart_ops ulite_ops = {
static void ulite_console_wait_tx(struct uart_port *port)
{
int i;
+ u8 val;
- /* wait up to 10ms for the character(s) to be sent */
- for (i = 0; i < 10000; i++) {
- if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
+ /* Spin waiting for TX fifo to have space available */
+ for (i = 0; i < 100000; i++) {
+ val = readb(port->membase + ULITE_STATUS);
+ if ((val & ULITE_STATUS_TXFULL) == 0)
break;
- udelay(1);
+ cpu_relax();
}
}
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index 7d873b3b051..4d0282b821b 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -107,16 +107,17 @@ int superhyway_add_devices(struct superhyway_bus *bus,
static int __init superhyway_init(void)
{
struct superhyway_bus *bus;
- int ret = 0;
+ int ret;
- device_register(&superhyway_bus_device);
+ ret = device_register(&superhyway_bus_device);
+ if (unlikely(ret))
+ return ret;
for (bus = superhyway_channels; bus->ops; bus++)
ret |= superhyway_scan_bus(bus);
return ret;
}
-
postcore_initcall(superhyway_init);
static const struct superhyway_device_id *
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index c12a741b557..85a20546e82 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -440,6 +440,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
break;
case SSB_BUSTYPE_PCMCIA:
#ifdef CONFIG_SSB_PCMCIAHOST
+ sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
dev->parent = &bus->host_pcmcia->dev;
#endif
break;
@@ -1147,7 +1148,10 @@ static int __init ssb_modinit(void)
return err;
}
-subsys_initcall(ssb_modinit);
+/* ssb must be initialized after PCI but before the ssb drivers.
+ * That means we must use some initcall between subsys_initcall
+ * and device_initcall. */
+fs_initcall(ssb_modinit);
static void __exit ssb_modexit(void)
{
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index b6abee846f0..bb44a76b3eb 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -63,17 +63,17 @@ int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
err = pcmcia_access_configuration_register(pdev, &reg);
if (err != CS_SUCCESS)
goto error;
- read_addr |= (reg.Value & 0xF) << 12;
+ read_addr |= ((u32)(reg.Value & 0x0F)) << 12;
reg.Offset = 0x30;
err = pcmcia_access_configuration_register(pdev, &reg);
if (err != CS_SUCCESS)
goto error;
- read_addr |= reg.Value << 16;
+ read_addr |= ((u32)reg.Value) << 16;
reg.Offset = 0x32;
err = pcmcia_access_configuration_register(pdev, &reg);
if (err != CS_SUCCESS)
goto error;
- read_addr |= reg.Value << 24;
+ read_addr |= ((u32)reg.Value) << 24;
cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
if (cur_core == coreidx)
@@ -152,28 +152,29 @@ error:
goto out_unlock;
}
-/* These are the main device register access functions.
- * do_select_core is inline to have the likely hotpath inline.
- * All unlikely codepaths are out-of-line. */
-static inline int do_select_core(struct ssb_bus *bus,
- struct ssb_device *dev,
- u16 *offset)
+static int select_core_and_segment(struct ssb_device *dev,
+ u16 *offset)
{
+ struct ssb_bus *bus = dev->bus;
int err;
- u8 need_seg = (*offset >= 0x800) ? 1 : 0;
+ u8 need_segment;
+
+ if (*offset >= 0x800) {
+ *offset -= 0x800;
+ need_segment = 1;
+ } else
+ need_segment = 0;
if (unlikely(dev != bus->mapped_device)) {
err = ssb_pcmcia_switch_core(bus, dev);
if (unlikely(err))
return err;
}
- if (unlikely(need_seg != bus->mapped_pcmcia_seg)) {
- err = ssb_pcmcia_switch_segment(bus, need_seg);
+ if (unlikely(need_segment != bus->mapped_pcmcia_seg)) {
+ err = ssb_pcmcia_switch_segment(bus, need_segment);
if (unlikely(err))
return err;
}
- if (need_seg == 1)
- *offset -= 0x800;
return 0;
}
@@ -181,32 +182,31 @@ static inline int do_select_core(struct ssb_bus *bus,
static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
{
struct ssb_bus *bus = dev->bus;
- u16 x;
- if (unlikely(do_select_core(bus, dev, &offset)))
+ if (unlikely(select_core_and_segment(dev, &offset)))
return 0xFFFF;
- x = readw(bus->mmio + offset);
- return x;
+ return readw(bus->mmio + offset);
}
static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
{
struct ssb_bus *bus = dev->bus;
- u32 x;
+ u32 lo, hi;
- if (unlikely(do_select_core(bus, dev, &offset)))
+ if (unlikely(select_core_and_segment(dev, &offset)))
return 0xFFFFFFFF;
- x = readl(bus->mmio + offset);
+ lo = readw(bus->mmio + offset);
+ hi = readw(bus->mmio + offset + 2);
- return x;
+ return (lo | (hi << 16));
}
static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
{
struct ssb_bus *bus = dev->bus;
- if (unlikely(do_select_core(bus, dev, &offset)))
+ if (unlikely(select_core_and_segment(dev, &offset)))
return;
writew(value, bus->mmio + offset);
}
@@ -215,12 +215,12 @@ static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
{
struct ssb_bus *bus = dev->bus;
- if (unlikely(do_select_core(bus, dev, &offset)))
+ if (unlikely(select_core_and_segment(dev, &offset)))
return;
- readw(bus->mmio + offset);
- writew(value >> 16, bus->mmio + offset + 2);
- readw(bus->mmio + offset);
- writew(value, bus->mmio + offset);
+ writeb((value & 0xFF000000) >> 24, bus->mmio + offset + 3);
+ writeb((value & 0x00FF0000) >> 16, bus->mmio + offset + 2);
+ writeb((value & 0x0000FF00) >> 8, bus->mmio + offset + 1);
+ writeb((value & 0x000000FF) >> 0, bus->mmio + offset + 0);
}
/* Not "static", as it's used in main.c */
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 5fb8675e0d6..d0e4cb61826 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -874,6 +874,8 @@ static int cyber2000fb_set_par(struct fb_info *info)
default:
BUG();
}
+ break;
+
case 24:/* TRUECOLOUR, 16m */
hw.co_pixfmt = CO_PIXFMT_24BPP;
hw.width *= 3;
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 0e4baca21b8..1dc04b6684e 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -53,7 +53,7 @@ struct vring_virtqueue
unsigned int num_added;
/* Last used index we've seen. */
- unsigned int last_used_idx;
+ u16 last_used_idx;
/* How to notify other side. FIXME: commonalize hcalls! */
void (*notify)(struct virtqueue *vq);
@@ -277,11 +277,17 @@ struct virtqueue *vring_new_virtqueue(unsigned int num,
struct vring_virtqueue *vq;
unsigned int i;
+ /* We assume num is a power of 2. */
+ if (num & (num - 1)) {
+ dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
+ return NULL;
+ }
+
vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
if (!vq)
return NULL;
- vring_init(&vq->vring, num, pages);
+ vring_init(&vq->vring, num, pages, PAGE_SIZE);
vq->vq.callback = callback;
vq->vq.vdev = vdev;
vq->vq.vq_ops = &vring_vq_ops;
diff --git a/fs/Kconfig b/fs/Kconfig
index c75c9540649..429a0022850 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -2007,7 +2007,7 @@ config CIFS_EXPERIMENTAL
config CIFS_UPCALL
bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
depends on CIFS_EXPERIMENTAL
- depends on CONNECTOR
+ depends on KEYS
help
Enables an upcall mechanism for CIFS which will be used to contact
userspace helper utilities to provide SPNEGO packaged Kerberos
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 3d419163c3d..64dd22239b2 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,7 @@
+Version 1.52
+------------
+Fix oops on second mount to server when null auth is used.
+
Version 1.51
------------
Fix memory leak in statfs when mounted to very old servers (e.g.
@@ -12,7 +16,12 @@ leak that causes cifsd not to stop and rmmod to fail to cleanup
cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
bigendian architectures. Fix possible memory corruption when
EAGAIN returned on kern_recvmsg. Return better error if server
-requires packet signing but client has disabled it.
+requires packet signing but client has disabled it. When mounted
+with cifsacl mount option - mode bits are approximated based
+on the contents of the ACL of the file or directory. When cifs
+mount helper is missing convert make sure that UNC name
+has backslash (not forward slash) between ip address of server
+and the share name.
Version 1.50
------------
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index ff6ba8d823f..45e42fb97c1 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -3,4 +3,9 @@
#
obj-$(CONFIG_CIFS) += cifs.o
-cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o
+cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
+ link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
+ md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o \
+ readdir.o ioctl.o sess.o export.o cifsacl.o
+
+cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 2a01f3ef96a..bcda2c6b6a0 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -77,8 +77,12 @@
#define SPNEGO_OID_LEN 7
#define NTLMSSP_OID_LEN 10
+#define KRB5_OID_LEN 7
+#define MSKRB5_OID_LEN 7
static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
+static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 };
+static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 };
/*
* ASN.1 context.
@@ -457,6 +461,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
unsigned long *oid = NULL;
unsigned int cls, con, tag, oidlen, rc;
int use_ntlmssp = FALSE;
+ int use_kerberos = FALSE;
*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
@@ -545,18 +550,28 @@ decode_negTokenInit(unsigned char *security_blob, int length,
return 0;
}
if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
- rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
- if (rc) {
+ if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
+
cFYI(1,
("OID len = %d oid = 0x%lx 0x%lx "
"0x%lx 0x%lx",
oidlen, *oid, *(oid + 1),
*(oid + 2), *(oid + 3)));
- rc = compare_oid(oid, oidlen,
- NTLMSSP_OID, NTLMSSP_OID_LEN);
- kfree(oid);
- if (rc)
+
+ if (compare_oid(oid, oidlen,
+ MSKRB5_OID,
+ MSKRB5_OID_LEN))
+ use_kerberos = TRUE;
+ else if (compare_oid(oid, oidlen,
+ KRB5_OID,
+ KRB5_OID_LEN))
+ use_kerberos = TRUE;
+ else if (compare_oid(oid, oidlen,
+ NTLMSSP_OID,
+ NTLMSSP_OID_LEN))
use_ntlmssp = TRUE;
+
+ kfree(oid);
}
} else {
cFYI(1, ("Should be an oid what is going on?"));
@@ -609,12 +624,10 @@ decode_negTokenInit(unsigned char *security_blob, int length,
ctx.pointer)); /* is this UTF-8 or ASCII? */
}
- /* if (use_kerberos)
- *secType = Kerberos
- else */
- if (use_ntlmssp) {
+ if (use_kerberos)
+ *secType = Kerberos;
+ else if (use_ntlmssp)
*secType = NTLMSSP;
- }
return 1;
}
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
new file mode 100644
index 00000000000..ad54a3a6e43
--- /dev/null
+++ b/fs/cifs/cifs_spnego.c
@@ -0,0 +1,128 @@
+/*
+ * fs/cifs/cifs_spnego.c -- SPNEGO upcall management for CIFS
+ *
+ * Copyright (c) 2007 Red Hat, Inc.
+ * Author(s): Jeff Layton (jlayton@redhat.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/list.h>
+#include <linux/string.h>
+#include <keys/user-type.h>
+#include <linux/key-type.h>
+#include "cifsglob.h"
+#include "cifs_spnego.h"
+#include "cifs_debug.h"
+
+/* create a new cifs key */
+static int
+cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen)
+{
+ char *payload;
+ int ret;
+
+ ret = -ENOMEM;
+ payload = kmalloc(datalen, GFP_KERNEL);
+ if (!payload)
+ goto error;
+
+ /* attach the data */
+ memcpy(payload, data, datalen);
+ rcu_assign_pointer(key->payload.data, payload);
+ ret = 0;
+
+error:
+ return ret;
+}
+
+static void
+cifs_spnego_key_destroy(struct key *key)
+{
+ kfree(key->payload.data);
+}
+
+
+/*
+ * keytype for CIFS spnego keys
+ */
+struct key_type cifs_spnego_key_type = {
+ .name = "cifs.spnego",
+ .instantiate = cifs_spnego_key_instantiate,
+ .match = user_match,
+ .destroy = cifs_spnego_key_destroy,
+ .describe = user_describe,
+};
+
+/* get a key struct with a SPNEGO security blob, suitable for session setup */
+struct key *
+cifs_get_spnego_key(struct cifsSesInfo *sesInfo, const char *hostname)
+{
+ struct TCP_Server_Info *server = sesInfo->server;
+ char *description, *dp;
+ size_t desc_len;
+ struct key *spnego_key;
+
+
+ /* version + ;ip{4|6}= + address + ;host=hostname +
+ ;sec= + ;uid= + NULL */
+ desc_len = 4 + 5 + 32 + 1 + 5 + strlen(hostname) +
+ strlen(";sec=krb5") + 7 + sizeof(uid_t)*2 + 1;
+ spnego_key = ERR_PTR(-ENOMEM);
+ description = kzalloc(desc_len, GFP_KERNEL);
+ if (description == NULL)
+ goto out;
+
+ dp = description;
+ /* start with version and hostname portion of UNC string */
+ spnego_key = ERR_PTR(-EINVAL);
+ sprintf(dp, "0x%2.2x;host=%s;", CIFS_SPNEGO_UPCALL_VERSION,
+ hostname);
+ dp = description + strlen(description);
+
+ /* add the server address */
+ if (server->addr.sockAddr.sin_family == AF_INET)
+ sprintf(dp, "ip4=" NIPQUAD_FMT,
+ NIPQUAD(server->addr.sockAddr.sin_addr));
+ else if (server->addr.sockAddr.sin_family == AF_INET6)
+ sprintf(dp, "ip6=" NIP6_SEQFMT,
+ NIP6(server->addr.sockAddr6.sin6_addr));
+ else
+ goto out;
+
+ dp = description + strlen(description);
+
+ /* for now, only sec=krb5 is valid */
+ if (server->secType == Kerberos)
+ sprintf(dp, ";sec=krb5");
+ else
+ goto out;
+
+ dp = description + strlen(description);
+ sprintf(dp, ";uid=0x%x", sesInfo->linux_uid);
+
+ cFYI(1, ("key description = %s", description));
+ spnego_key = request_key(&cifs_spnego_key_type, description, "");
+
+ if (cifsFYI && !IS_ERR(spnego_key)) {
+ struct cifs_spnego_msg *msg = spnego_key->payload.data;
+ cifs_dump_mem("SPNEGO reply blob:", msg->data,
+ msg->secblob_len + msg->sesskey_len);
+ }
+
+out:
+ kfree(description);
+ return spnego_key;
+}
diff --git a/fs/cifs/cifs_spnego.h b/fs/cifs/cifs_spnego.h
new file mode 100644
index 00000000000..f443f3b3513
--- /dev/null
+++ b/fs/cifs/cifs_spnego.h
@@ -0,0 +1,46 @@
+/*
+ * fs/cifs/cifs_spnego.h -- SPNEGO upcall management for CIFS
+ *
+ * Copyright (c) 2007 Red Hat, Inc.
+ * Author(s): Jeff Layton (jlayton@redhat.com)
+ * Steve French (sfrench@us.ibm.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _CIFS_SPNEGO_H
+#define _CIFS_SPNEGO_H
+
+#define CIFS_SPNEGO_UPCALL_VERSION 1
+
+/*
+ * The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION.
+ * The flags field is for future use. The request-key callout should set
+ * sesskey_len and secblob_len, and then concatenate the SessKey+SecBlob
+ * and stuff it in the data field.
+ */
+struct cifs_spnego_msg {
+ uint32_t version;
+ uint32_t flags;
+ uint32_t sesskey_len;
+ uint32_t secblob_len;
+ uint8_t data[1];
+};
+
+#ifdef __KERNEL__
+extern struct key_type cifs_spnego_key_type;
+#endif /* KERNEL */
+
+#endif /* _CIFS_SPNEGO_H */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index e8e56353f5a..dabbce00712 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -38,13 +38,13 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
{{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
{{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"},
{{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"},
- {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"}
-};
+ {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} }
+;
/* security id for everyone */
-static const struct cifs_sid sid_everyone =
- {1, 1, {0, 0, 0, 0, 0, 0}, {} };
+static const struct cifs_sid sid_everyone = {
+ 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
/* group users */
static const struct cifs_sid sid_user =
{1, 2 , {0, 0, 0, 0, 0, 5}, {} };
@@ -97,7 +97,7 @@ int match_sid(struct cifs_sid *ctsid)
/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
the same returns 1, if they do not match returns 0 */
-int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
+int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
{
int i;
int num_subauth, num_sat, num_saw;
@@ -129,66 +129,142 @@ int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
return (1); /* sids compare/match */
}
+/*
+ change posix mode to reflect permissions
+ pmode is the existing mode (we only want to overwrite part of this
+ bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
+*/
+static void access_flags_to_mode(__u32 ace_flags, int type, umode_t *pmode,
+ umode_t *pbits_to_set)
+{
+ /* the order of ACEs is important. The canonical order is to begin with
+ DENY entries followed by ALLOW, otherwise an allow entry could be
+ encountered first, making the subsequent deny entry like "dead code"
+ which would be superflous since Windows stops when a match is made
+ for the operation you are trying to perform for your user */
+
+ /* For deny ACEs we change the mask so that subsequent allow access
+ control entries do not turn on the bits we are denying */
+ if (type == ACCESS_DENIED) {
+ if (ace_flags & GENERIC_ALL) {
+ *pbits_to_set &= ~S_IRWXUGO;
+ }
+ if ((ace_flags & GENERIC_WRITE) ||
+ ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
+ *pbits_to_set &= ~S_IWUGO;
+ if ((ace_flags & GENERIC_READ) ||
+ ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
+ *pbits_to_set &= ~S_IRUGO;
+ if ((ace_flags & GENERIC_EXECUTE) ||
+ ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
+ *pbits_to_set &= ~S_IXUGO;
+ return;
+ } else if (type != ACCESS_ALLOWED) {
+ cERROR(1, ("unknown access control type %d", type));
+ return;
+ }
+ /* else ACCESS_ALLOWED type */
+
+ if (ace_flags & GENERIC_ALL) {
+ *pmode |= (S_IRWXUGO & (*pbits_to_set));
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("all perms"));
+#endif
+ return;
+ }
+ if ((ace_flags & GENERIC_WRITE) ||
+ ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
+ *pmode |= (S_IWUGO & (*pbits_to_set));
+ if ((ace_flags & GENERIC_READ) ||
+ ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
+ *pmode |= (S_IRUGO & (*pbits_to_set));
+ if ((ace_flags & GENERIC_EXECUTE) ||
+ ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
+ *pmode |= (S_IXUGO & (*pbits_to_set));
+
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("access flags 0x%x mode now 0x%x", ace_flags, *pmode));
+#endif
+ return;
+}
+
+/*
+ Generate access flags to reflect permissions mode is the existing mode.
+ This function is called for every ACE in the DACL whose SID matches
+ with either owner or group or everyone.
+*/
+
+static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
+ __u32 *pace_flags)
+{
+ /* reset access mask */
+ *pace_flags = 0x0;
+
+ /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
+ mode &= bits_to_use;
+
+ /* check for R/W/X UGO since we do not know whose flags
+ is this but we have cleared all the bits sans RWX for
+ either user or group or other as per bits_to_use */
+ if (mode & S_IRUGO)
+ *pace_flags |= SET_FILE_READ_RIGHTS;
+ if (mode & S_IWUGO)
+ *pace_flags |= SET_FILE_WRITE_RIGHTS;
+ if (mode & S_IXUGO)
+ *pace_flags |= SET_FILE_EXEC_RIGHTS;
+
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
+#endif
+ return;
+}
+
-static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
+#ifdef CONFIG_CIFS_DEBUG2
+static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
{
int num_subauth;
/* validate that we do not go past end of acl */
- /* XXX this if statement can be removed
- if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) {
+ if (le16_to_cpu(pace->size) < 16) {
+ cERROR(1, ("ACE too small, %d", le16_to_cpu(pace->size)));
+ return;
+ }
+
+ if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
cERROR(1, ("ACL too small to parse ACE"));
return;
- } */
+ }
- num_subauth = pace->num_subauth;
+ num_subauth = pace->sid.num_subauth;
if (num_subauth) {
-#ifdef CONFIG_CIFS_DEBUG2
int i;
- cFYI(1, ("ACE revision %d num_subauth %d",
- pace->revision, pace->num_subauth));
+ cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
+ pace->sid.revision, pace->sid.num_subauth, pace->type,
+ pace->flags, pace->size));
for (i = 0; i < num_subauth; ++i) {
cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
- le32_to_cpu(pace->sub_auth[i])));
+ le32_to_cpu(pace->sid.sub_auth[i])));
}
/* BB add length check to make sure that we do not have huge
num auths and therefore go off the end */
-
- cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1])));
-#endif
}
return;
}
-
-static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl)
-{
- /* validate that we do not go past end of acl */
- if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) {
- cERROR(1, ("ACL too small to parse NT ACE"));
- return;
- }
-
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x",
- pntace->type, pntace->flags, pntace->size,
- pntace->access_req));
#endif
- return;
-}
-
static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
- struct cifs_sid *pownersid, struct cifs_sid *pgrpsid)
+ struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
+ struct inode *inode)
{
int i;
int num_aces = 0;
int acl_size;
char *acl_base;
- struct cifs_ntace **ppntace;
struct cifs_ace **ppace;
/* BB need to add parm so we can store the SID BB */
@@ -205,50 +281,63 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
le32_to_cpu(pdacl->num_aces)));
#endif
+ /* reset rwx permissions for user/group/other.
+ Also, if num_aces is 0 i.e. DACL has no ACEs,
+ user/group/other have no permissions */
+ inode->i_mode &= ~(S_IRWXUGO);
+
+ if (!pdacl) {
+ /* no DACL in the security descriptor, set
+ all the permissions for user/group/other */
+ inode->i_mode |= S_IRWXUGO;
+ return;
+ }
acl_base = (char *)pdacl;
acl_size = sizeof(struct cifs_acl);
num_aces = le32_to_cpu(pdacl->num_aces);
if (num_aces > 0) {
- ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *),
- GFP_KERNEL);
+ umode_t user_mask = S_IRWXU;
+ umode_t group_mask = S_IRWXG;
+ umode_t other_mask = S_IRWXO;
+
ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
GFP_KERNEL);
/* cifscred->cecount = pdacl->num_aces;
- cifscred->ntaces = kmalloc(num_aces *
- sizeof(struct cifs_ntace *), GFP_KERNEL);
cifscred->aces = kmalloc(num_aces *
sizeof(struct cifs_ace *), GFP_KERNEL);*/
for (i = 0; i < num_aces; ++i) {
- ppntace[i] = (struct cifs_ntace *)
- (acl_base + acl_size);
- ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] +
- sizeof(struct cifs_ntace));
-
- parse_ntace(ppntace[i], end_of_acl);
- if (end_of_acl < ((char *)ppace[i] +
- (le16_to_cpu(ppntace[i]->size) -
- sizeof(struct cifs_ntace)))) {
- cERROR(1, ("ACL too small to parse ACE"));
- break;
- } else
- parse_ace(ppace[i], end_of_acl);
-
-/* memcpy((void *)(&(cifscred->ntaces[i])),
- (void *)ppntace[i],
- sizeof(struct cifs_ntace));
- memcpy((void *)(&(cifscred->aces[i])),
+ ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
+#ifdef CONFIG_CIFS_DEBUG2
+ dump_ace(ppace[i], end_of_acl);
+#endif
+ if (compare_sids(&(ppace[i]->sid), pownersid))
+ access_flags_to_mode(ppace[i]->access_req,
+ ppace[i]->type,
+ &(inode->i_mode),
+ &user_mask);
+ if (compare_sids(&(ppace[i]->sid), pgrpsid))
+ access_flags_to_mode(ppace[i]->access_req,
+ ppace[i]->type,
+ &(inode->i_mode),
+ &group_mask);
+ if (compare_sids(&(ppace[i]->sid), &sid_everyone))
+ access_flags_to_mode(ppace[i]->access_req,
+ ppace[i]->type,
+ &(inode->i_mode),
+ &other_mask);
+
+/* memcpy((void *)(&(cifscred->aces[i])),
(void *)ppace[i],
sizeof(struct cifs_ace)); */
- acl_base = (char *)ppntace[i];
- acl_size = le16_to_cpu(ppntace[i]->size);
+ acl_base = (char *)ppace[i];
+ acl_size = le16_to_cpu(ppace[i]->size);
}
kfree(ppace);
- kfree(ppntace);
}
return;
@@ -257,20 +346,20 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
{
-
/* BB need to add parm so we can store the SID BB */
- /* validate that we do not go past end of acl */
- if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) {
- cERROR(1, ("ACL too small to parse SID"));
+ /* validate that we do not go past end of ACL - sid must be at least 8
+ bytes long (assuming no sub-auths - e.g. the null SID */
+ if (end_of_acl < (char *)psid + 8) {
+ cERROR(1, ("ACL too small to parse SID %p", psid));
return -EINVAL;
}
if (psid->num_subauth) {
#ifdef CONFIG_CIFS_DEBUG2
int i;
- cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x",
- psid->revision, psid->num_subauth, psid->sub_auth[0]));
+ cFYI(1, ("SID revision %d num_auth %d",
+ psid->revision, psid->num_subauth));
for (i = 0; i < psid->num_subauth; i++) {
cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
@@ -289,27 +378,32 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
/* Convert CIFS ACL to POSIX form */
-int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
+static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
+ struct inode *inode)
{
int rc;
struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
char *end_of_acl = ((char *)pntsd) + acl_len;
+ __u32 dacloffset;
+
+ if ((inode == NULL) || (pntsd == NULL))
+ return -EIO;
owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
le32_to_cpu(pntsd->osidoffset));
group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
le32_to_cpu(pntsd->gsidoffset));
- dacl_ptr = (struct cifs_acl *)((char *)pntsd +
- le32_to_cpu(pntsd->dacloffset));
+ dacloffset = le32_to_cpu(pntsd->dacloffset);
+ dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
"sacloffset 0x%x dacloffset 0x%x",
pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
le32_to_cpu(pntsd->gsidoffset),
- le32_to_cpu(pntsd->sacloffset),
- le32_to_cpu(pntsd->dacloffset)));
+ le32_to_cpu(pntsd->sacloffset), dacloffset));
#endif
+/* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
rc = parse_sid(owner_sid_ptr, end_of_acl);
if (rc)
return rc;
@@ -318,16 +412,120 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
if (rc)
return rc;
- parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr);
+ if (dacloffset)
+ parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
+ group_sid_ptr, inode);
+ else
+ cFYI(1, ("no ACL")); /* BB grant all or default perms? */
/* cifscred->uid = owner_sid_ptr->rid;
cifscred->gid = group_sid_ptr->rid;
memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
- sizeof (struct cifs_sid));
+ sizeof(struct cifs_sid));
memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
- sizeof (struct cifs_sid)); */
+ sizeof(struct cifs_sid)); */
return (0);
}
+
+
+/* Retrieve an ACL from the server */
+static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
+ const char *path)
+{
+ struct cifsFileInfo *open_file;
+ int unlock_file = FALSE;
+ int xid;
+ int rc = -EIO;
+ __u16 fid;
+ struct super_block *sb;
+ struct cifs_sb_info *cifs_sb;
+ struct cifs_ntsd *pntsd = NULL;
+
+ cFYI(1, ("get mode from ACL for %s", path));
+
+ if (inode == NULL)
+ return NULL;
+
+ xid = GetXid();
+ open_file = find_readable_file(CIFS_I(inode));
+ sb = inode->i_sb;
+ if (sb == NULL) {
+ FreeXid(xid);
+ return NULL;
+ }
+ cifs_sb = CIFS_SB(sb);
+
+ if (open_file) {
+ unlock_file = TRUE;
+ fid = open_file->netfid;
+ } else {
+ int oplock = FALSE;
+ /* open file */
+ rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
+ READ_CONTROL, 0, &fid, &oplock, NULL,
+ cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (rc != 0) {
+ cERROR(1, ("Unable to open file to get ACL"));
+ FreeXid(xid);
+ return NULL;
+ }
+ }
+
+ rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
+ cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
+ if (unlock_file == TRUE)
+ atomic_dec(&open_file->wrtPending);
+ else
+ CIFSSMBClose(xid, cifs_sb->tcon, fid);
+
+ FreeXid(xid);
+ return pntsd;
+}
+
+/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
+void acl_to_uid_mode(struct inode *inode, const char *path)
+{
+ struct cifs_ntsd *pntsd = NULL;
+ u32 acllen = 0;
+ int rc = 0;
+
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("converting ACL to mode for %s", path));
+#endif
+ pntsd = get_cifs_acl(&acllen, inode, path);
+
+ /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
+ if (pntsd)
+ rc = parse_sec_desc(pntsd, acllen, inode);
+ if (rc)
+ cFYI(1, ("parse sec desc failed rc = %d", rc));
+
+ kfree(pntsd);
+ return;
+}
+
+/* Convert mode bits to an ACL so we can update the ACL on the server */
+int mode_to_acl(struct inode *inode, const char *path)
+{
+ int rc = 0;
+ __u32 acllen = 0;
+ struct cifs_ntsd *pntsd = NULL;
+
+ cFYI(1, ("set ACL from mode for %s", path));
+
+ /* Get the security descriptor */
+ pntsd = get_cifs_acl(&acllen, inode, path);
+
+ /* Add/Modify the three ACEs for owner, group, everyone
+ while retaining the other ACEs */
+
+ /* Set the security descriptor */
+
+
+ kfree(pntsd);
+ return rc;
+}
#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 420f8781364..93a7c3462ea 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -35,6 +35,9 @@
#define UBITSHIFT 6
#define GBITSHIFT 3
+#define ACCESS_ALLOWED 0
+#define ACCESS_DENIED 1
+
struct cifs_ntsd {
__le16 revision; /* revision level */
__le16 type;
@@ -48,7 +51,7 @@ struct cifs_sid {
__u8 revision; /* revision level */
__u8 num_subauth;
__u8 authority[6];
- __le32 sub_auth[5]; /* sub_auth[num_subauth] */ /* BB FIXME endianness BB */
+ __le32 sub_auth[5]; /* sub_auth[num_subauth] */
} __attribute__((packed));
struct cifs_acl {
@@ -57,18 +60,12 @@ struct cifs_acl {
__le32 num_aces;
} __attribute__((packed));
-struct cifs_ntace { /* first part of ACE which contains perms */
+struct cifs_ace {
__u8 type;
__u8 flags;
__le16 size;
__le32 access_req;
-} __attribute__((packed));
-
-struct cifs_ace { /* last part of ACE which includes user info */
- __u8 revision; /* revision level */
- __u8 num_subauth;
- __u8 authority[6];
- __le32 sub_auth[5];
+ struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
} __attribute__((packed));
struct cifs_wksid {
@@ -79,7 +76,7 @@ struct cifs_wksid {
#ifdef CONFIG_CIFS_EXPERIMENTAL
extern int match_sid(struct cifs_sid *);
-extern int compare_sids(struct cifs_sid *, struct cifs_sid *);
+extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 632070b4275..4ff8939c6cc 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -99,15 +99,16 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
MD5Init(&context);
MD5Update(&context, (char *)&key->data, key->len);
for (i = 0; i < n_vec; i++) {
+ if (iov[i].iov_len == 0)
+ continue;
if (iov[i].iov_base == NULL) {
cERROR(1, ("null iovec entry"));
return -EIO;
- } else if (iov[i].iov_len == 0)
- break; /* bail out if we are sent nothing to sign */
+ }
/* The first entry includes a length field (which does not get
signed that occupies the first 4 bytes before the header */
if (i == 0) {
- if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */
+ if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
break; /* nothing to sign or corrupt header */
MD5Update(&context, iov[0].iov_base+4,
iov[0].iov_len-4);
@@ -122,7 +123,7 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
- __u32 * pexpected_response_sequence_number)
+ __u32 *pexpected_response_sequence_number)
{
int rc = 0;
char smb_signature[20];
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index a6fbea57c4b..416dc9fe896 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -43,6 +43,8 @@
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
#include <linux/mm.h>
+#include <linux/key-type.h>
+#include "cifs_spnego.h"
#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
#ifdef CONFIG_CIFS_QUOTA
@@ -1005,12 +1007,16 @@ init_cifs(void)
rc = register_filesystem(&cifs_fs_type);
if (rc)
goto out_destroy_request_bufs;
-
+#ifdef CONFIG_CIFS_UPCALL
+ rc = register_key_type(&cifs_spnego_key_type);
+ if (rc)
+ goto out_unregister_filesystem;
+#endif
oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
if (IS_ERR(oplockThread)) {
rc = PTR_ERR(oplockThread);
cERROR(1, ("error %d create oplock thread", rc));
- goto out_unregister_filesystem;
+ goto out_unregister_key_type;
}
dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
@@ -1024,7 +1030,11 @@ init_cifs(void)
out_stop_oplock_thread:
kthread_stop(oplockThread);
+ out_unregister_key_type:
+#ifdef CONFIG_CIFS_UPCALL
+ unregister_key_type(&cifs_spnego_key_type);
out_unregister_filesystem:
+#endif
unregister_filesystem(&cifs_fs_type);
out_destroy_request_bufs:
cifs_destroy_request_bufs();
@@ -1046,6 +1056,9 @@ exit_cifs(void)
#ifdef CONFIG_PROC_FS
cifs_proc_clean();
#endif
+#ifdef CONFIG_CIFS_UPCALL
+ unregister_key_type(&cifs_spnego_key_type);
+#endif
unregister_filesystem(&cifs_fs_type);
cifs_destroy_inodecache();
cifs_destroy_mids();
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 5574ba3ab1f..2a21dc66f0d 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -106,5 +106,5 @@ extern int cifs_ioctl(struct inode *inode, struct file *filep,
extern const struct export_operations cifs_export_ops;
#endif /* EXPERIMENTAL */
-#define CIFS_VERSION "1.51"
+#define CIFS_VERSION "1.52"
#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index c41ff74e912..dbe6b846f37 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -220,6 +220,23 @@
| FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
+#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA \
+ | FILE_READ_ATTRIBUTES \
+ | FILE_WRITE_ATTRIBUTES \
+ | DELETE | READ_CONTROL | WRITE_DAC \
+ | WRITE_OWNER | SYNCHRONIZE)
+#define SET_FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
+ | FILE_READ_EA | FILE_WRITE_EA \
+ | FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES \
+ | FILE_WRITE_ATTRIBUTES \
+ | DELETE | READ_CONTROL | WRITE_DAC \
+ | WRITE_OWNER | SYNCHRONIZE)
+#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \
+ | FILE_READ_ATTRIBUTES \
+ | FILE_WRITE_ATTRIBUTES \
+ | DELETE | READ_CONTROL | WRITE_DAC \
+ | WRITE_OWNER | SYNCHRONIZE)
+
/*
* Invalid readdir handle
@@ -1211,6 +1228,29 @@ typedef struct smb_com_transaction_qsec_req {
__le32 AclFlags;
} __attribute__((packed)) QUERY_SEC_DESC_REQ;
+
+typedef struct smb_com_transaction_ssec_req {
+ struct smb_hdr hdr; /* wct = 19 */
+ __u8 MaxSetupCount;
+ __u16 Reserved;
+ __le32 TotalParameterCount;
+ __le32 TotalDataCount;
+ __le32 MaxParameterCount;
+ __le32 MaxDataCount;
+ __le32 ParameterCount;
+ __le32 ParameterOffset;
+ __le32 DataCount;
+ __le32 DataOffset;
+ __u8 SetupCount; /* no setup words follow subcommand */
+ /* SNIA spec incorrectly included spurious pad here */
+ __le16 SubCommand; /* 3 = SET_SECURITY_DESC */
+ __le16 ByteCount; /* bcc = 3 + 8 */
+ __u8 Pad[3];
+ __u16 Fid;
+ __u16 Reserved2;
+ __le32 AclFlags;
+} __attribute__((packed)) SET_SEC_DESC_REQ;
+
typedef struct smb_com_transaction_change_notify_req {
struct smb_hdr hdr; /* wct = 23 */
__u8 MaxSetupCount;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 1a883663b22..dd1d7c200ee 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -61,6 +61,9 @@ extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *);
+#endif
extern unsigned int smbCalcSize(struct smb_hdr *ptr);
extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length,
@@ -73,6 +76,8 @@ extern void header_assemble(struct smb_hdr *, char /* command */ ,
extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
struct cifsSesInfo *ses,
void **request_buf);
+extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo,
+ const char *hostname);
extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
const int stage,
const struct nls_table *nls_cp);
@@ -92,6 +97,8 @@ extern int cifs_get_inode_info(struct inode **pinode,
extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path,
struct super_block *sb, int xid);
+extern void acl_to_uid_mode(struct inode *inode, const char *search_path);
+extern int mode_to_acl(struct inode *inode, const char *path);
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
const char *);
@@ -311,7 +318,6 @@ extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
#ifdef CONFIG_CIFS_WEAK_PW_HASH
extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
#endif /* CIFS_WEAK_PW_HASH */
-extern int parse_sec_desc(struct cifs_ntsd *, int);
extern int CIFSSMBCopy(int xid,
struct cifsTconInfo *source_tcon,
const char *fromName,
@@ -336,8 +342,7 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
const void *ea_value, const __u16 ea_value_len,
const struct nls_table *nls_codepage, int remap_special_chars);
extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
- __u16 fid, char *acl_inf, const int buflen,
- const int acl_type /* ACCESS vs. DEFAULT */);
+ __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
char *acl_inf, const int buflen, const int acl_type,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f0d9a485d09..59d7b7c037a 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -647,8 +647,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
count - 16,
&server->secType);
if (rc == 1) {
- /* BB Need to fill struct for sessetup here */
- rc = -EOPNOTSUPP;
+ rc = 0;
} else {
rc = -EINVAL;
}
@@ -2486,6 +2485,7 @@ querySymLinkRetry:
return rc;
}
+#ifdef CONFIG_CIFS_EXPERIMENTAL
/* Initialize NT TRANSACT SMB into small smb request buffer.
This assumes that all NT TRANSACTS that we init here have
total parm and data under about 400 bytes (to fit in small cifs
@@ -2494,7 +2494,7 @@ querySymLinkRetry:
MaxSetupCount (size of returned setup area) and
MaxParameterCount (returned parms size) must be set by caller */
static int
-smb_init_ntransact(const __u16 sub_command, const int setup_count,
+smb_init_nttransact(const __u16 sub_command, const int setup_count,
const int parm_len, struct cifsTconInfo *tcon,
void **ret_buf)
{
@@ -2525,12 +2525,15 @@ smb_init_ntransact(const __u16 sub_command, const int setup_count,
static int
validate_ntransact(char *buf, char **ppparm, char **ppdata,
- int *pdatalen, int *pparmlen)
+ __u32 *pparmlen, __u32 *pdatalen)
{
char *end_of_smb;
__u32 data_count, data_offset, parm_count, parm_offset;
struct smb_com_ntransact_rsp *pSMBr;
+ *pdatalen = 0;
+ *pparmlen = 0;
+
if (buf == NULL)
return -EINVAL;
@@ -2567,8 +2570,11 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
cFYI(1, ("parm count and data count larger than SMB"));
return -EINVAL;
}
+ *pdatalen = data_count;
+ *pparmlen = parm_count;
return 0;
}
+#endif /* CIFS_EXPERIMENTAL */
int
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3067,8 +3073,7 @@ GetExtAttrOut:
/* Get Security Descriptor (by handle) from remote server for a file or dir */
int
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
- /* BB fix up return info */ char *acl_inf, const int buflen,
- const int acl_type)
+ struct cifs_ntsd **acl_inf, __u32 *pbuflen)
{
int rc = 0;
int buf_type = 0;
@@ -3077,7 +3082,10 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
cFYI(1, ("GetCifsACL"));
- rc = smb_init_ntransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
+ *pbuflen = 0;
+ *acl_inf = NULL;
+
+ rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
8 /* parm len */, tcon, (void **) &pSMB);
if (rc)
return rc;
@@ -3099,34 +3107,52 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
if (rc) {
cFYI(1, ("Send error in QuerySecDesc = %d", rc));
} else { /* decode response */
- struct cifs_ntsd *psec_desc;
__le32 * parm;
- int parm_len;
- int data_len;
- int acl_len;
+ __u32 parm_len;
+ __u32 acl_len;
struct smb_com_ntransact_rsp *pSMBr;
+ char *pdata;
/* validate_nttransact */
rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
- (char **)&psec_desc,
- &parm_len, &data_len);
+ &pdata, &parm_len, pbuflen);
if (rc)
goto qsec_out;
pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
- cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc));
+ cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, *acl_inf));
if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
rc = -EIO; /* bad smb */
+ *pbuflen = 0;
goto qsec_out;
}
/* BB check that data area is minimum length and as big as acl_len */
acl_len = le32_to_cpu(*parm);
- /* BB check if (acl_len > bufsize) */
+ if (acl_len != *pbuflen) {
+ cERROR(1, ("acl length %d does not match %d",
+ acl_len, *pbuflen));
+ if (*pbuflen > acl_len)
+ *pbuflen = acl_len;
+ }
- parse_sec_desc(psec_desc, acl_len);
+ /* check if buffer is big enough for the acl
+ header followed by the smallest SID */
+ if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
+ (*pbuflen >= 64 * 1024)) {
+ cERROR(1, ("bad acl length %d", *pbuflen));
+ rc = -EINVAL;
+ *pbuflen = 0;
+ } else {
+ *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
+ if (*acl_inf == NULL) {
+ *pbuflen = 0;
+ rc = -ENOMEM;
+ }
+ memcpy(*acl_inf, pdata, *pbuflen);
+ }
}
qsec_out:
if (buf_type == CIFS_SMALL_BUFFER)
@@ -3381,7 +3407,7 @@ UnixQPathInfoRetry:
memcpy((char *) pFindData,
(char *) &pSMBr->hdr.Protocol +
data_offset,
- sizeof (FILE_UNIX_BASIC_INFO));
+ sizeof(FILE_UNIX_BASIC_INFO));
}
}
cifs_buf_release(pSMB);
@@ -3649,7 +3675,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
pSMB->SearchHandle = searchHandle; /* always kept as le */
pSMB->SearchCount =
- cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO));
+ cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
pSMB->ResumeKey = psrch_inf->resume_key;
pSMB->SearchFlags =
@@ -4331,7 +4357,7 @@ QFSDeviceRetry:
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc || (pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO)))
+ if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO)))
rc = -EIO; /* bad smb */
else {
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 19ee11f7f35..1102160f666 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -793,7 +793,7 @@ cifs_parse_mount_options(char *options, const char *devname,
vol->linux_gid = current->gid;
vol->dir_mode = S_IRWXUGO;
/* 2767 perms indicate mandatory locking support */
- vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
+ vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
vol->rw = TRUE;
@@ -1790,7 +1790,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (volume_info.nullauth) {
cFYI(1, ("null user"));
- volume_info.username = NULL;
+ volume_info.username = "";
} else if (volume_info.username) {
/* BB fixme parse for domain name here */
cFYI(1, ("Username: %s", volume_info.username));
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 793404b1092..37dc97af148 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -593,7 +593,7 @@ static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
* case take precedence. If a is not a negative dentry, this
* should have no side effects
*/
- memcpy((unsigned char *)a->name, b->name, a->len);
+ memcpy(a->name, b->name, a->len);
return 0;
}
return 1;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 1e7e4c06d9e..68ad4ca0cfa 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1026,6 +1026,37 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
return total_written;
}
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode)
+{
+ struct cifsFileInfo *open_file = NULL;
+
+ read_lock(&GlobalSMBSeslock);
+ /* we could simply get the first_list_entry since write-only entries
+ are always at the end of the list but since the first entry might
+ have a close pending, we go through the whole list */
+ list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
+ if (open_file->closePend)
+ continue;
+ if (open_file->pfile && ((open_file->pfile->f_flags & O_RDWR) ||
+ (open_file->pfile->f_flags & O_RDONLY))) {
+ if (!open_file->invalidHandle) {
+ /* found a good file */
+ /* lock it so it will not be closed on us */
+ atomic_inc(&open_file->wrtPending);
+ read_unlock(&GlobalSMBSeslock);
+ return open_file;
+ } /* else might as well continue, and look for
+ another, or simply have the caller reopen it
+ again rather than trying to fix this handle */
+ } else /* write only file */
+ break; /* write only files are last so must be done */
+ }
+ read_unlock(&GlobalSMBSeslock);
+ return NULL;
+}
+#endif
+
struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
{
struct cifsFileInfo *open_file;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 5e8b388be3b..7d907e84e03 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -289,7 +289,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
-static int get_sfu_uid_mode(struct inode *inode,
+static int get_sfu_mode(struct inode *inode,
const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid)
{
@@ -527,11 +527,16 @@ int cifs_get_inode_info(struct inode **pinode,
/* BB fill in uid and gid here? with help from winbind?
or retrieve from NTFS stream extended attribute */
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ /* fill in 0777 bits from ACL */
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+ cFYI(1, ("Getting mode bits from ACL"));
+ acl_to_uid_mode(inode, search_path);
+ }
+#endif
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
- /* fill in uid, gid, mode from server ACL */
- /* BB FIXME this should also take into account the
- * default uid specified on mount if present */
- get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
+ /* fill in remaining high mode bits e.g. SUID, VTX */
+ get_sfu_mode(inode, search_path, cifs_sb, xid);
} else if (atomic_read(&cifsInfo->inUse) == 0) {
inode->i_uid = cifs_sb->mnt_uid;
inode->i_gid = cifs_sb->mnt_gid;
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c
index e5c3e121269..f13f96d42fc 100644
--- a/fs/cifs/md5.c
+++ b/fs/cifs/md5.c
@@ -276,8 +276,8 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len,
}
/* start out by storing key in pads */
- memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad));
- memset(ctx->k_opad, 0, sizeof (ctx->k_opad));
+ memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));
+ memset(ctx->k_opad, 0, sizeof(ctx->k_opad));
memcpy(ctx->k_ipad, key, key_len);
memcpy(ctx->k_opad, key, key_len);
@@ -307,8 +307,8 @@ hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
}
/* start out by storing key in pads */
- memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad));
- memset(ctx->k_opad, 0, sizeof (ctx->k_opad));
+ memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));
+ memset(ctx->k_opad, 0, sizeof(ctx->k_opad));
memcpy(ctx->k_ipad, key, key_len);
memcpy(ctx->k_opad, key, key_len);
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 51ec681fe74..15546c2354c 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -73,7 +73,7 @@ sesInfoAlloc(void)
{
struct cifsSesInfo *ret_buf;
- ret_buf = kzalloc(sizeof (struct cifsSesInfo), GFP_KERNEL);
+ ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
if (ret_buf) {
write_lock(&GlobalSMBSeslock);
atomic_inc(&sesInfoAllocCount);
@@ -109,7 +109,7 @@ struct cifsTconInfo *
tconInfoAlloc(void)
{
struct cifsTconInfo *ret_buf;
- ret_buf = kzalloc(sizeof (struct cifsTconInfo), GFP_KERNEL);
+ ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
if (ret_buf) {
write_lock(&GlobalSMBSeslock);
atomic_inc(&tconInfoAllocCount);
@@ -298,7 +298,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
buffer->smb_buf_length =
- (2 * word_count) + sizeof (struct smb_hdr) -
+ (2 * word_count) + sizeof(struct smb_hdr) -
4 /* RFC 1001 length field does not count */ +
2 /* for bcc field itself */ ;
/* Note that this is the only network field that has to be converted
@@ -422,8 +422,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
__u32 clc_len; /* calculated length */
cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
- if (length < 2 + sizeof (struct smb_hdr)) {
- if ((length >= sizeof (struct smb_hdr) - 1)
+ if (length < 2 + sizeof(struct smb_hdr)) {
+ if ((length >= sizeof(struct smb_hdr) - 1)
&& (smb->Status.CifsError != 0)) {
smb->WordCount = 0;
/* some error cases do not return wct and bcc */
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index f06359cb22e..646e1f06941 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -132,6 +132,34 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
{0, 0}
};
+
+/* if the mount helper is missing we need to reverse the 1st slash
+ from '/' to backslash in order to format the UNC properly for
+ ip address parsing and for tree connect (unless the user
+ remembered to put the UNC name in properly). Fortunately we do
+ not have to call this twice (we check for IPv4 addresses
+ first, so it is already converted by the time we
+ try IPv6 addresses */
+static int canonicalize_unc(char *cp)
+{
+ int i;
+
+ for (i = 0; i <= 46 /* INET6_ADDRSTRLEN */ ; i++) {
+ if (cp[i] == 0)
+ break;
+ if (cp[i] == '\\')
+ break;
+ if (cp[i] == '/') {
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("change slash to backslash in malformed UNC"));
+#endif
+ cp[i] = '\\';
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* Convert string containing dotted ip address to binary form */
/* returns 0 if invalid address */
@@ -141,11 +169,13 @@ cifs_inet_pton(int address_family, char *cp, void *dst)
int ret = 0;
/* calculate length by finding first slash or NULL */
- /* BB Should we convert '/' slash to '\' here since it seems already
- * done before this */
- if ( address_family == AF_INET ) {
- ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL);
- } else if ( address_family == AF_INET6 ) {
+ if (address_family == AF_INET) {
+ ret = in4_pton(cp, -1 /* len */, dst, '\\', NULL);
+ if (ret == 0) {
+ if (canonicalize_unc(cp))
+ ret = in4_pton(cp, -1, dst, '\\', NULL);
+ }
+ } else if (address_family == AF_INET6) {
ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
}
#ifdef CONFIG_CIFS_DEBUG2
@@ -740,7 +770,7 @@ cifs_print_status(__u32 status_code)
static void
-ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode)
+ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode)
{
int i;
if (ntstatus == 0) {
@@ -793,8 +823,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */
for (i = 0;
i <
- sizeof (mapping_table_ERRDOS) /
- sizeof (struct smb_to_posix_error); i++) {
+ sizeof(mapping_table_ERRDOS) /
+ sizeof(struct smb_to_posix_error); i++) {
if (mapping_table_ERRDOS[i].smb_err == 0)
break;
else if (mapping_table_ERRDOS[i].smb_err ==
@@ -807,8 +837,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
} else if (smberrclass == ERRSRV) { /* server class of error codes */
for (i = 0;
i <
- sizeof (mapping_table_ERRSRV) /
- sizeof (struct smb_to_posix_error); i++) {
+ sizeof(mapping_table_ERRSRV) /
+ sizeof(struct smb_to_posix_error); i++) {
if (mapping_table_ERRSRV[i].smb_err == 0)
break;
else if (mapping_table_ERRSRV[i].smb_err ==
@@ -837,14 +867,14 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
unsigned int
smbCalcSize(struct smb_hdr *ptr)
{
- return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
+ return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
2 /* size of the bcc field */ + BCC(ptr));
}
unsigned int
smbCalcSize_LE(struct smb_hdr *ptr)
{
- return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
+ return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr)));
}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 3746580e970..0f22def4bdf 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -171,7 +171,13 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
/* Linux can not store file creation time unfortunately so ignore it */
cifsInfo->cifsAttrs = attr;
- cifsInfo->time = jiffies;
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+ /* get more accurate mode via ACL - so force inode refresh */
+ cifsInfo->time = 0;
+ } else
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
+ cifsInfo->time = jiffies;
/* treat dos attribute of read-only as read-only mode bit e.g. 555? */
/* 2767 perms - indicate mandatory locking */
@@ -495,7 +501,7 @@ ffirst_retry:
static int cifs_unicode_bytelen(char *str)
{
int len;
- __le16 * ustr = (__le16 *)str;
+ __le16 *ustr = (__le16 *)str;
for (len = 0; len <= PATH_MAX; len++) {
if (ustr[len] == 0)
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index 90542a39be1..58bbfd992cc 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -80,7 +80,7 @@ SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
/* Routines for Windows NT MD4 Hash functions. */
static int
-_my_wcslen(__u16 * str)
+_my_wcslen(__u16 *str)
{
int len = 0;
while (*str++ != 0)
@@ -96,7 +96,7 @@ _my_wcslen(__u16 * str)
*/
static int
-_my_mbstowcs(__u16 * dst, const unsigned char *src, int len)
+_my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
{ /* BB not a very good conversion routine - change/fix */
int i;
__u16 val;
@@ -125,9 +125,9 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
/* Password cannot be longer than 128 characters */
if (passwd) {
len = strlen((char *) passwd);
- if (len > 128) {
+ if (len > 128)
len = 128;
- }
+
/* Password must be converted to NT unicode */
_my_mbstowcs(wpwd, passwd, len);
} else
@@ -135,7 +135,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
wpwd[len] = 0; /* Ensure string is null terminated */
/* Calculate length in bytes */
- len = _my_wcslen(wpwd) * sizeof (__u16);
+ len = _my_wcslen(wpwd) * sizeof(__u16);
mdfour(p16, (unsigned char *) wpwd, len);
memset(wpwd, 0, 129 * 2);
@@ -167,7 +167,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
E_P16((unsigned char *) passwd, (unsigned char *) p16);
/* clear out local copy of user's password (just being paranoid). */
- memset(passwd, '\0', sizeof (passwd));
+ memset(passwd, '\0', sizeof(passwd));
}
#endif
@@ -189,8 +189,10 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
return;
dom_u = user_u + 1024;
- /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
- push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
+ /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2,
+ STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
+ push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2,
+ STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
/* BB user and domain may need to be uppercased */
user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 369e838bebd..54e8ef96cb7 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -265,7 +265,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
__u16 fid;
int oplock = FALSE;
- if (experimEnabled)
+ struct cifs_ntsd *pacl = NULL;
+ __u32 buflen = 0;
+ if (experimEnabled)
rc = CIFSSMBOpen(xid, pTcon, full_path,
FILE_OPEN, GENERIC_READ, 0, &fid,
&oplock, NULL, cifs_sb->local_nls,
@@ -273,10 +275,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
CIFS_MOUNT_MAP_SPECIAL_CHR);
/* else rc is EOPNOTSUPP from above */
- if(rc == 0) {
- rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
- ea_value, buf_size,
- ACL_TYPE_ACCESS);
+ if (rc == 0) {
+ rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &pacl,
+ &buflen);
CIFSSMBClose(xid, pTcon, fid);
}
}
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 58bf3f5cdbe..e9923ca9c2d 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -1062,7 +1062,7 @@ static int sctp_listen_for_all(void)
subscribe.sctp_shutdown_event = 1;
subscribe.sctp_partial_delivery_event = 1;
- result = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+ result = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE,
(char *)&bufsize, sizeof(bufsize));
if (result)
log_print("Error increasing buffer space on socket %d", result);
@@ -1454,10 +1454,6 @@ int dlm_lowcomms_start(void)
if (!con_cache)
goto out;
- /* Set some sysctl minima */
- if (sysctl_rmem_max < NEEDED_RMEM)
- sysctl_rmem_max = NEEDED_RMEM;
-
/* Start listening */
if (dlm_config.ci_protocol == 0)
error = tcp_listen_for_all();
diff --git a/fs/exec.c b/fs/exec.c
index 2c942e2d14e..4ccaaa4b13b 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1692,7 +1692,10 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
if (!binfmt || !binfmt->core_dump)
goto fail;
down_write(&mm->mmap_sem);
- if (!get_dumpable(mm)) {
+ /*
+ * If another thread got here first, or we are not dumpable, bail out.
+ */
+ if (mm->core_waiters || !get_dumpable(mm)) {
up_write(&mm->mmap_sem);
goto fail;
}
@@ -1706,7 +1709,6 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
flag = O_EXCL; /* Stop rewrite attacks */
current->fsuid = 0; /* Dump root private */
}
- set_dumpable(mm, 0);
retval = coredump_wait(exit_code);
if (retval < 0)
diff --git a/fs/ioprio.c b/fs/ioprio.c
index d6ff77e8e7e..e4e01bc7f33 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -78,6 +78,10 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
break;
+ case IOPRIO_CLASS_NONE:
+ if (data)
+ return -EINVAL;
+ break;
default:
return -EINVAL;
}
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 4ba7f0bdc24..ce62c152823 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -3946,7 +3946,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
struct ocfs2_merge_ctxt ctxt;
struct ocfs2_extent_list *rightmost_el;
- if (!rec->e_flags & OCFS2_EXT_UNWRITTEN) {
+ if (!(rec->e_flags & OCFS2_EXT_UNWRITTEN)) {
ret = -EIO;
mlog_errno(ret);
goto out;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index c69c1b30015..556e34ccb00 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -729,6 +729,27 @@ static void ocfs2_clear_page_regions(struct page *page,
}
/*
+ * Nonsparse file systems fully allocate before we get to the write
+ * code. This prevents ocfs2_write() from tagging the write as an
+ * allocating one, which means ocfs2_map_page_blocks() might try to
+ * read-in the blocks at the tail of our file. Avoid reading them by
+ * testing i_size against each block offset.
+ */
+static int ocfs2_should_read_blk(struct inode *inode, struct page *page,
+ unsigned int block_start)
+{
+ u64 offset = page_offset(page) + block_start;
+
+ if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
+ return 1;
+
+ if (i_size_read(inode) > offset)
+ return 1;
+
+ return 0;
+}
+
+/*
* Some of this taken from block_prepare_write(). We already have our
* mapping by now though, and the entire write will be allocating or
* it won't, so not much need to use BH_New.
@@ -781,6 +802,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
set_buffer_uptodate(bh);
} else if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
!buffer_new(bh) &&
+ ocfs2_should_read_blk(inode, page, block_start) &&
(block_start < from || block_end > to)) {
ll_rw_block(READ, 1, &bh);
*wait_bh++=bh;
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 9cc7c0418b7..f02ccb34604 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -267,7 +267,7 @@ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
current_page = cs / spp;
page = reg->hr_slot_data[current_page];
- vec_len = min(PAGE_CACHE_SIZE,
+ vec_len = min(PAGE_CACHE_SIZE - vec_start,
(max_slots-cs) * (PAGE_CACHE_SIZE/spp) );
mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n",
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 3094ddb7a25..1957a5ed219 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -318,9 +318,9 @@ out_attach:
static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
struct ocfs2_dentry_lock *dl)
{
+ iput(dl->dl_inode);
ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
ocfs2_lock_res_free(&dl->dl_lockres);
- iput(dl->dl_inode);
kfree(dl);
}
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 6a2f143e269..63b28fdceb4 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -208,9 +208,9 @@ out:
return NULL;
}
-struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen,
- struct inode *dir,
- struct ocfs2_dir_entry **res_dir)
+static struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen,
+ struct inode *dir,
+ struct ocfs2_dir_entry **res_dir)
{
struct super_block *sb;
struct buffer_head *bh_use[NAMEI_RA_SIZE];
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 41c76ff2fcf..4e97dcceaf8 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -670,7 +670,7 @@ static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *loc
{
mlog_entry_void();
- BUG_ON((!lockres->l_flags & OCFS2_LOCK_BUSY));
+ BUG_ON((!(lockres->l_flags & OCFS2_LOCK_BUSY)));
BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED);
if (lockres->l_requested > LKM_NLMODE &&
@@ -980,18 +980,6 @@ again:
goto unlock;
}
- if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) {
- /* lock has not been created yet. */
- spin_unlock_irqrestore(&lockres->l_lock, flags);
-
- ret = ocfs2_lock_create(osb, lockres, LKM_NLMODE, 0);
- if (ret < 0) {
- mlog_errno(ret);
- goto out;
- }
- goto again;
- }
-
if (lockres->l_flags & OCFS2_LOCK_BLOCKED &&
!ocfs2_may_continue_on_blocked_lock(lockres, level)) {
/* is the lock is currently blocked on behalf of
@@ -1006,7 +994,14 @@ again:
mlog(ML_ERROR, "lockres %s has action %u pending\n",
lockres->l_name, lockres->l_action);
- lockres->l_action = OCFS2_AST_CONVERT;
+ if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) {
+ lockres->l_action = OCFS2_AST_ATTACH;
+ lkm_flags &= ~LKM_CONVERT;
+ } else {
+ lockres->l_action = OCFS2_AST_CONVERT;
+ lkm_flags |= LKM_CONVERT;
+ }
+
lockres->l_requested = level;
lockres_or_flags(lockres, OCFS2_LOCK_BUSY);
spin_unlock_irqrestore(&lockres->l_lock, flags);
@@ -1021,7 +1016,7 @@ again:
status = dlmlock(osb->dlm,
level,
&lockres->l_lksb,
- lkm_flags|LKM_CONVERT,
+ lkm_flags,
lockres->l_name,
OCFS2_LOCK_ID_MAX_LEN - 1,
ocfs2_locking_ast,
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index f92fe91ff26..bbac7cd33e0 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1891,9 +1891,11 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
ssize_t written = 0;
size_t ocount; /* original count */
size_t count; /* after file limit checks */
- loff_t *ppos = &iocb->ki_pos;
+ loff_t old_size, *ppos = &iocb->ki_pos;
+ u32 old_clusters;
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_path.dentry->d_inode;
+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
mlog_entry("(0x%p, %u, '%.*s')\n", file,
(unsigned int)nr_segs,
@@ -1949,6 +1951,13 @@ relock:
goto relock;
}
+ /*
+ * To later detect whether a journal commit for sync writes is
+ * necessary, we sample i_size, and cluster count here.
+ */
+ old_size = i_size_read(inode);
+ old_clusters = OCFS2_I(inode)->ip_clusters;
+
/* communicate with ocfs2_dio_end_io */
ocfs2_iocb_set_rw_locked(iocb, rw_level);
@@ -1978,6 +1987,21 @@ out_dio:
/* buffered aio wouldn't have proper lock coverage today */
BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
+ if ((file->f_flags & O_SYNC && !direct_io) || IS_SYNC(inode)) {
+ /*
+ * The generic write paths have handled getting data
+ * to disk, but since we don't make use of the dirty
+ * inode list, a manual journal commit is necessary
+ * here.
+ */
+ if (old_size != i_size_read(inode) ||
+ old_clusters != OCFS2_I(inode)->ip_clusters) {
+ ret = journal_force_commit(osb->journal->j_journal);
+ if (ret < 0)
+ written = ret;
+ }
+ }
+
/*
* deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
* function pointer which is called when o_direct io completes so that
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 729259016c1..989ac271858 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1105,9 +1105,16 @@ static int ocfs2_rename(struct inode *old_dir,
goto bail;
}
- if (!new_de && new_inode)
- mlog(ML_ERROR, "inode %lu does not exist in it's parent "
- "directory!", new_inode->i_ino);
+ if (!new_de && new_inode) {
+ /*
+ * Target was unlinked by another node while we were
+ * waiting to get to ocfs2_rename(). There isn't
+ * anything we can do here to help the situation, so
+ * bubble up the appropriate error.
+ */
+ status = -ENOENT;
+ goto bail;
+ }
/* In case we need to overwrite an existing file, we blow it
* away first */
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index 749def054a3..153554cf557 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -26,13 +26,6 @@
#include "internal.h"
-struct proc_dir_entry *proc_net_create(struct net *net,
- const char *name, mode_t mode, get_info_t *get_info)
-{
- return create_proc_info_entry(name,mode, net->proc_net, get_info);
-}
-EXPORT_SYMBOL_GPL(proc_net_create);
-
struct proc_dir_entry *proc_net_fops_create(struct net *net,
const char *name, mode_t mode, const struct file_operations *fops)
{
diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h
index fb90b421f31..ede377ec914 100644
--- a/include/asm-arm/hardware/iop3xx.h
+++ b/include/asm-arm/hardware/iop3xx.h
@@ -231,7 +231,7 @@ extern int init_atu;
IOP3XX_PCI_IO_WINDOW_SIZE - 1)
#define IOP3XX_PCI_UPPER_IO_VA (IOP3XX_PCI_LOWER_IO_VA +\
IOP3XX_PCI_IO_WINDOW_SIZE - 1)
-#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) addr -\
+#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) (addr) -\
IOP3XX_PCI_LOWER_IO_PA) +\
IOP3XX_PCI_LOWER_IO_VA)
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index d2e8171d1d4..5e0182485d8 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -249,7 +249,7 @@ extern struct page *empty_zero_page;
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
#define set_pte_at(mm,addr,ptep,pteval) do { \
- set_pte_ext(ptep, pteval, (addr) >= PAGE_OFFSET ? 0 : PTE_EXT_NG); \
+ set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \
} while (0)
/*
diff --git a/include/asm-frv/irq.h b/include/asm-frv/irq.h
index 8fefd6b827a..3a66ebd754b 100644
--- a/include/asm-frv/irq.h
+++ b/include/asm-frv/irq.h
@@ -12,9 +12,6 @@
#ifndef _ASM_IRQ_H_
#define _ASM_IRQ_H_
-/* this number is used when no interrupt has been assigned */
-#define NO_IRQ (-1)
-
#define NR_IRQS 48
#define IRQ_BASE_CPU (0 * 16)
#define IRQ_BASE_FPGA (1 * 16)
diff --git a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h
index abfcb3a2588..8a695d3407d 100644
--- a/include/asm-ia64/pal.h
+++ b/include/asm-ia64/pal.h
@@ -1379,10 +1379,11 @@ struct pal_features_s;
static inline s64
ia64_pal_proc_get_features (u64 *features_avail,
u64 *features_status,
- u64 *features_control)
+ u64 *features_control,
+ u64 features_set)
{
struct ia64_pal_retval iprv;
- PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, 0, 0);
+ PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, features_set, 0);
if (iprv.status == 0) {
*features_avail = iprv.v0;
*features_status = iprv.v1;
diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h
index 86a54a4a8a2..fea2d8ff1e7 100644
--- a/include/asm-powerpc/pgtable-ppc32.h
+++ b/include/asm-powerpc/pgtable-ppc32.h
@@ -11,6 +11,11 @@
extern unsigned long va_to_phys(unsigned long address);
extern pte_t *va_to_pte(unsigned long address);
extern unsigned long ioremap_bot, ioremap_base;
+
+#ifdef CONFIG_44x
+extern int icache_44x_need_flush;
+#endif
+
#endif /* __ASSEMBLY__ */
/*
@@ -562,6 +567,10 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr,
: "=&r" (old), "=&r" (tmp), "=m" (*p)
: "r" (p), "r" (clr), "r" (set), "m" (*p)
: "cc" );
+#ifdef CONFIG_44x
+ if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+ icache_44x_need_flush = 1;
+#endif
return old;
}
#else
@@ -582,6 +591,10 @@ static inline unsigned long long pte_update(pte_t *p, unsigned long clr,
: "=&r" (old), "=&r" (tmp), "=m" (*p)
: "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
: "cc" );
+#ifdef CONFIG_44x
+ if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+ icache_44x_need_flush = 1;
+#endif
return old;
}
#endif
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h
index cc6d8722825..11d5383b2f0 100644
--- a/include/asm-powerpc/systbl.h
+++ b/include/asm-powerpc/systbl.h
@@ -308,8 +308,8 @@ COMPAT_SYS_SPU(move_pages)
SYSCALL_SPU(getcpu)
COMPAT_SYS(epoll_pwait)
COMPAT_SYS_SPU(utimensat)
-COMPAT_SYS(fallocate)
COMPAT_SYS_SPU(signalfd)
COMPAT_SYS_SPU(timerfd)
SYSCALL_SPU(eventfd)
COMPAT_SYS_SPU(sync_file_range2)
+COMPAT_SYS(fallocate)
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
index f05895522f7..780f8264275 100644
--- a/include/asm-powerpc/time.h
+++ b/include/asm-powerpc/time.h
@@ -176,25 +176,31 @@ static inline unsigned int get_dec(void)
#endif
}
+/*
+ * Note: Book E and 4xx processors differ from other PowerPC processors
+ * in when the decrementer generates its interrupt: on the 1 to 0
+ * transition for Book E/4xx, but on the 0 to -1 transition for others.
+ */
static inline void set_dec(int val)
{
#if defined(CONFIG_40x)
mtspr(SPRN_PIT, val);
#elif defined(CONFIG_8xx_CPU6)
- set_dec_cpu6(val);
+ set_dec_cpu6(val - 1);
#else
+#ifndef CONFIG_BOOKE
+ --val;
+#endif
#ifdef CONFIG_PPC_ISERIES
- int cur_dec;
-
if (firmware_has_feature(FW_FEATURE_ISERIES) &&
get_lppaca()->shared_proc) {
get_lppaca()->virtual_decr = val;
- cur_dec = get_dec();
- if (cur_dec > val)
+ if (get_dec() > val)
HvCall_setVirtualDecr();
- } else
+ return;
+ }
#endif
- mtspr(SPRN_DEC, val);
+ mtspr(SPRN_DEC, val);
#endif /* not 40x or 8xx_CPU6 */
}
diff --git a/include/asm-powerpc/tlbflush.h b/include/asm-powerpc/tlbflush.h
index b6b036ccee3..e7b4c0d298a 100644
--- a/include/asm-powerpc/tlbflush.h
+++ b/include/asm-powerpc/tlbflush.h
@@ -1,5 +1,6 @@
#ifndef _ASM_POWERPC_TLBFLUSH_H
#define _ASM_POWERPC_TLBFLUSH_H
+
/*
* TLB flushing:
*
@@ -16,9 +17,6 @@
*/
#ifdef __KERNEL__
-struct mm_struct;
-struct vm_area_struct;
-
#if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
/*
* TLB flushing for software loaded TLB chips
@@ -28,7 +26,9 @@ struct vm_area_struct;
* specific tlbie's
*/
-extern void _tlbie(unsigned long address);
+#include <linux/mm.h>
+
+extern void _tlbie(unsigned long address, unsigned int pid);
#if defined(CONFIG_40x) || defined(CONFIG_8xx)
#define _tlbia() asm volatile ("tlbia; sync" : : : "memory")
@@ -44,13 +44,13 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
- _tlbie(vmaddr);
+ _tlbie(vmaddr, vma->vm_mm->context.id);
}
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr)
{
- _tlbie(vmaddr);
+ _tlbie(vmaddr, vma->vm_mm->context.id);
}
static inline void flush_tlb_range(struct vm_area_struct *vma,
diff --git a/include/asm-sh/cacheflush.h b/include/asm-sh/cacheflush.h
index aa558da0847..b91246153b7 100644
--- a/include/asm-sh/cacheflush.h
+++ b/include/asm-sh/cacheflush.h
@@ -43,21 +43,31 @@ extern void __flush_purge_region(void *start, int size);
extern void __flush_invalidate_region(void *start, int size);
#endif
-#define flush_cache_vmap(start, end) flush_cache_all()
-#define flush_cache_vunmap(start, end) flush_cache_all()
+#ifdef CONFIG_CPU_SH4
+extern void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len);
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+extern void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len);
+#else
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do { \
flush_cache_page(vma, vaddr, page_to_pfn(page));\
memcpy(dst, src, len); \
flush_icache_user_range(vma, page, vaddr, len); \
} while (0)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
do { \
flush_cache_page(vma, vaddr, page_to_pfn(page));\
memcpy(dst, src, len); \
} while (0)
+#endif
+
+#define flush_cache_vmap(start, end) flush_cache_all()
+#define flush_cache_vunmap(start, end) flush_cache_all()
#define HAVE_ARCH_UNMAPPED_AREA
diff --git a/include/asm-sh/cpu-sh3/timer.h b/include/asm-sh/cpu-sh3/timer.h
index 3880ce047fe..7b795ac5477 100644
--- a/include/asm-sh/cpu-sh3/timer.h
+++ b/include/asm-sh/cpu-sh3/timer.h
@@ -23,8 +23,7 @@
* ---------------------------------------------------------------------------
*/
-#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \
- !defined(CONFIG_CPU_SUBTYPE_SH7727)
+#if !defined(CONFIG_CPU_SUBTYPE_SH7720)
#define TMU_TOCR 0xfffffe90 /* Byte access */
#endif
@@ -58,8 +57,7 @@
#define TMU2_TCOR 0xfffffeac /* Long access */
#define TMU2_TCNT 0xfffffeb0 /* Long access */
#define TMU2_TCR 0xfffffeb4 /* Word access */
-#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \
- !defined(CONFIG_CPU_SUBTYPE_SH7727)
+#if !defined(CONFIG_CPU_SUBTYPE_SH7720)
#define TMU2_TCPR2 0xfffffeb8 /* Long access */
#endif
#endif
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
index 3aa8b07da47..d00a8fde7c7 100644
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -73,10 +73,13 @@ extern void copy_page_nommu(void *to, void *from);
#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
(defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB))
struct page;
-extern void clear_user_page(void *to, unsigned long address, struct page *pg);
-extern void copy_user_page(void *to, void *from, unsigned long address, struct page *pg);
-extern void __clear_user_page(void *to, void *orig_to);
-extern void __copy_user_page(void *to, void *from, void *orig_to);
+struct vm_area_struct;
+extern void clear_user_page(void *to, unsigned long address, struct page *page);
+#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
+#endif
#else
#define clear_user_page(page, vaddr, pg) clear_page(page)
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index 0b1d7c66565..8f1e8be8d15 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -322,7 +322,9 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
#define PAGE_KERNEL __pgprot(0)
#define PAGE_KERNEL_NOCACHE __pgprot(0)
#define PAGE_KERNEL_RO __pgprot(0)
-#define PAGE_KERNEL_PCC __pgprot(0)
+
+#define PAGE_KERNEL_PCC(slot, type) \
+ __pgprot(0)
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h
index ab0028db645..fda68480f37 100644
--- a/include/asm-sh/processor.h
+++ b/include/asm-sh/processor.h
@@ -49,7 +49,7 @@ enum cpu_type {
/* SH-4 types */
CPU_SH7750, CPU_SH7750S, CPU_SH7750R, CPU_SH7751, CPU_SH7751R,
- CPU_SH7760, CPU_ST40RA, CPU_ST40GX1, CPU_SH4_202, CPU_SH4_501,
+ CPU_SH7760, CPU_SH4_202, CPU_SH4_501,
/* SH-4A types */
CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SHX3,
diff --git a/include/asm-sh/ptrace.h b/include/asm-sh/ptrace.h
index ed358a376e6..b9789c8b4d1 100644
--- a/include/asm-sh/ptrace.h
+++ b/include/asm-sh/ptrace.h
@@ -42,9 +42,6 @@
#define REG_FPSCR 55
#define REG_FPUL 56
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD 0x00000001
-
/*
* This struct defines the way the registers are stored on the
* kernel stack during a system call or other kernel entry.
diff --git a/include/asm-sh/vga.h b/include/asm-sh/vga.h
new file mode 100644
index 00000000000..06a5de8ace1
--- /dev/null
+++ b/include/asm-sh/vga.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_SH_VGA_H
+#define __ASM_SH_VGA_H
+
+/* Stupid drivers. */
+
+#endif /* __ASM_SH_VGA_H */
diff --git a/include/asm-sh64/ptrace.h b/include/asm-sh64/ptrace.h
index a6d4da519db..c424f80e3ae 100644
--- a/include/asm-sh64/ptrace.h
+++ b/include/asm-sh64/ptrace.h
@@ -32,6 +32,4 @@ struct pt_regs {
extern void show_regs(struct pt_regs *);
#endif
-#define PTRACE_O_TRACESYSGOOD 0x00000001
-
#endif /* __ASM_SH64_PTRACE_H */
diff --git a/include/asm-sparc64/vio.h b/include/asm-sparc64/vio.h
index f7417e91b17..d4de32f0f8a 100644
--- a/include/asm-sparc64/vio.h
+++ b/include/asm-sparc64/vio.h
@@ -8,6 +8,7 @@
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/list.h>
+#include <linux/log2.h>
#include <asm/ldc.h>
#include <asm/mdesc.h>
@@ -257,8 +258,7 @@ static inline void *vio_dring_entry(struct vio_dring_state *dr,
static inline u32 vio_dring_avail(struct vio_dring_state *dr,
unsigned int ring_size)
{
- /* Ensure build-time power-of-2. */
- BUILD_BUG_ON(ring_size & (ring_size - 1));
+ BUILD_BUG_ON(!is_power_of_2(ring_size));
return (dr->pending -
((dr->prod - dr->cons) & (ring_size - 1)));
diff --git a/include/asm-x86/i387_64.h b/include/asm-x86/i387_64.h
index 0217b74cc9f..3a4ffba3d6b 100644
--- a/include/asm-x86/i387_64.h
+++ b/include/asm-x86/i387_64.h
@@ -203,6 +203,11 @@ static inline void save_init_fpu(struct task_struct *tsk)
*/
static inline int restore_i387(struct _fpstate __user *buf)
{
+ set_used_math();
+ if (!(task_thread_info(current)->status & TS_USEDFPU)) {
+ clts();
+ task_thread_info(current)->status |= TS_USEDFPU;
+ }
return restore_fpu_checking((__force struct i387_fxsave_struct *)buf);
}
diff --git a/include/asm-x86/mach-voyager/setup_arch.h b/include/asm-x86/mach-voyager/setup_arch.h
index 84d01ad3345..1710ae10eb6 100644
--- a/include/asm-x86/mach-voyager/setup_arch.h
+++ b/include/asm-x86/mach-voyager/setup_arch.h
@@ -1,5 +1,7 @@
#include <asm/voyager.h>
-#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *)(PARAM+0x40))
+#include <asm/setup_32.h>
+#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *) \
+ (&boot_params.apm_bios_info))
/* Hook to call BIOS initialisation function */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 8396db24d01..d18ee67b40f 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -697,6 +697,7 @@ extern int blk_execute_rq(struct request_queue *, struct gendisk *,
extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,
struct request *, int, rq_end_io_fn *);
extern int blk_verify_command(unsigned char *, int);
+extern void blk_unplug(struct request_queue *q);
static inline struct request_queue *bdev_get_queue(struct block_device *bdev)
{
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index 7da2cee8e13..35a8277ec1b 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -128,6 +128,18 @@ struct igmpmsg
#ifdef __KERNEL__
#include <net/sock.h>
+#ifdef CONFIG_IP_MROUTE
+static inline int ip_mroute_opt(int opt)
+{
+ return (opt >= MRT_BASE) && (opt <= MRT_BASE + 10);
+}
+#else
+static inline int ip_mroute_opt(int opt)
+{
+ return 0;
+}
+#endif
+
extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index f2eaea2234e..b87e83a5e07 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -4,25 +4,28 @@ header-y += nfnetlink_conntrack.h
header-y += nfnetlink_log.h
header-y += nfnetlink_queue.h
header-y += xt_CLASSIFY.h
+header-y += xt_CONNMARK.h
+header-y += xt_CONNSECMARK.h
+header-y += xt_DSCP.h
+header-y += xt_MARK.h
+header-y += xt_NFLOG.h
+header-y += xt_NFQUEUE.h
+header-y += xt_SECMARK.h
+header-y += xt_TCPMSS.h
header-y += xt_comment.h
header-y += xt_connbytes.h
header-y += xt_connmark.h
-header-y += xt_CONNMARK.h
header-y += xt_conntrack.h
header-y += xt_dccp.h
header-y += xt_dscp.h
-header-y += xt_DSCP.h
header-y += xt_esp.h
-header-y += xt_helper.h
header-y += xt_hashlimit.h
+header-y += xt_helper.h
header-y += xt_length.h
header-y += xt_limit.h
header-y += xt_mac.h
header-y += xt_mark.h
-header-y += xt_MARK.h
header-y += xt_multiport.h
-header-y += xt_NFQUEUE.h
-header-y += xt_NFLOG.h
header-y += xt_pkttype.h
header-y += xt_policy.h
header-y += xt_realm.h
@@ -32,9 +35,6 @@ header-y += xt_statistic.h
header-y += xt_string.h
header-y += xt_tcpmss.h
header-y += xt_tcpudp.h
-header-y += xt_SECMARK.h
-header-y += xt_CONNSECMARK.h
-header-y += xt_TCPMSS.h
unifdef-y += nf_conntrack_common.h
unifdef-y += nf_conntrack_ftp.h
diff --git a/include/linux/netfilter_ipv4/Kbuild b/include/linux/netfilter_ipv4/Kbuild
index 7185792b900..3a7105bb8f3 100644
--- a/include/linux/netfilter_ipv4/Kbuild
+++ b/include/linux/netfilter_ipv4/Kbuild
@@ -1,47 +1,47 @@
-header-y += ipt_addrtype.h
-header-y += ipt_ah.h
header-y += ipt_CLASSIFY.h
header-y += ipt_CLUSTERIP.h
+header-y += ipt_CONNMARK.h
+header-y += ipt_DSCP.h
+header-y += ipt_ECN.h
+header-y += ipt_LOG.h
+header-y += ipt_MARK.h
+header-y += ipt_NFQUEUE.h
+header-y += ipt_REJECT.h
+header-y += ipt_SAME.h
+header-y += ipt_TCPMSS.h
+header-y += ipt_TOS.h
+header-y += ipt_TTL.h
+header-y += ipt_ULOG.h
+header-y += ipt_addrtype.h
+header-y += ipt_ah.h
header-y += ipt_comment.h
header-y += ipt_connbytes.h
header-y += ipt_connmark.h
-header-y += ipt_CONNMARK.h
header-y += ipt_conntrack.h
header-y += ipt_dccp.h
header-y += ipt_dscp.h
-header-y += ipt_DSCP.h
header-y += ipt_ecn.h
-header-y += ipt_ECN.h
header-y += ipt_esp.h
header-y += ipt_hashlimit.h
header-y += ipt_helper.h
header-y += ipt_iprange.h
header-y += ipt_length.h
header-y += ipt_limit.h
-header-y += ipt_LOG.h
header-y += ipt_mac.h
header-y += ipt_mark.h
-header-y += ipt_MARK.h
header-y += ipt_multiport.h
-header-y += ipt_NFQUEUE.h
header-y += ipt_owner.h
header-y += ipt_physdev.h
header-y += ipt_pkttype.h
header-y += ipt_policy.h
header-y += ipt_realm.h
header-y += ipt_recent.h
-header-y += ipt_REJECT.h
-header-y += ipt_SAME.h
header-y += ipt_sctp.h
header-y += ipt_state.h
header-y += ipt_string.h
header-y += ipt_tcpmss.h
-header-y += ipt_TCPMSS.h
header-y += ipt_tos.h
-header-y += ipt_TOS.h
header-y += ipt_ttl.h
-header-y += ipt_TTL.h
-header-y += ipt_ULOG.h
unifdef-y += ip_queue.h
unifdef-y += ip_tables.h
diff --git a/include/linux/netfilter_ipv6/Kbuild b/include/linux/netfilter_ipv6/Kbuild
index 9dd978d149f..8887a5fcd1d 100644
--- a/include/linux/netfilter_ipv6/Kbuild
+++ b/include/linux/netfilter_ipv6/Kbuild
@@ -14,8 +14,8 @@ header-y += ip6t_mark.h
header-y += ip6t_multiport.h
header-y += ip6t_opts.h
header-y += ip6t_owner.h
-header-y += ip6t_policy.h
header-y += ip6t_physdev.h
+header-y += ip6t_policy.h
header-y += ip6t_rt.h
unifdef-y += ip6_tables.h
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 7c1f3b1d2ee..d5bfaba595c 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -192,7 +192,7 @@ extern int netlink_unregister_notifier(struct notifier_block *nb);
/* finegrained unicast helpers: */
struct sock *netlink_getsockbyfilp(struct file *filp);
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
- long timeo, struct sock *ssk);
+ long *timeo, struct sock *ssk);
void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
int netlink_sendskb(struct sock *sk, struct sk_buff *skb);
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 1ff46167206..1273c6ec535 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -196,8 +196,6 @@ static inline struct proc_dir_entry *create_proc_info_entry(const char *name,
return res;
}
-extern struct proc_dir_entry *proc_net_create(struct net *net,
- const char *name, mode_t mode, get_info_t *get_info);
extern struct proc_dir_entry *proc_net_fops_create(struct net *net,
const char *name, mode_t mode, const struct file_operations *fops);
extern void proc_net_remove(struct net *net, const char *name);
@@ -208,7 +206,6 @@ extern void proc_net_remove(struct net *net, const char *name);
#define proc_bus NULL
#define proc_net_fops_create(net, name, mode, fops) ({ (void)(mode), NULL; })
-#define proc_net_create(net, name, mode, info) ({ (void)(mode), NULL; })
static inline void proc_net_remove(struct net *net, const char *name) {}
static inline void proc_flush_task(struct task_struct *task)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 155d7438f7a..ee800e7a70d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -254,6 +254,7 @@ long io_schedule_timeout(long timeout);
extern void cpu_init (void);
extern void trap_init(void);
+extern void account_process_tick(struct task_struct *task, int user);
extern void update_process_times(int user);
extern void scheduler_tick(void);
@@ -862,7 +863,6 @@ struct sched_entity {
struct load_weight load; /* for load-balancing */
struct rb_node run_node;
unsigned int on_rq;
- int peer_preempt;
u64 exec_start;
u64 sum_exec_runtime;
@@ -1460,12 +1460,17 @@ extern void sched_idle_next(void);
#ifdef CONFIG_SCHED_DEBUG
extern unsigned int sysctl_sched_latency;
-extern unsigned int sysctl_sched_nr_latency;
+extern unsigned int sysctl_sched_min_granularity;
extern unsigned int sysctl_sched_wakeup_granularity;
extern unsigned int sysctl_sched_batch_wakeup_granularity;
extern unsigned int sysctl_sched_child_runs_first;
extern unsigned int sysctl_sched_features;
extern unsigned int sysctl_sched_migration_cost;
+extern unsigned int sysctl_sched_nr_migrate;
+
+int sched_nr_latency_handler(struct ctl_table *table, int write,
+ struct file *file, void __user *buffer, size_t *length,
+ loff_t *ppos);
#endif
extern unsigned int sysctl_sched_compat_yield;
@@ -1983,6 +1988,14 @@ static inline void inc_syscw(struct task_struct *tsk)
}
#endif
+#ifdef CONFIG_SMP
+void migration_init(void);
+#else
+static inline void migration_init(void)
+{
+}
+#endif
+
#endif /* __KERNEL__ */
#endif
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 94e49915a8c..91140fe8c11 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -387,7 +387,9 @@ extern void skb_truesize_bug(struct sk_buff *skb);
static inline void skb_truesize_check(struct sk_buff *skb)
{
- if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
+ int len = sizeof(struct sk_buff) + skb->len;
+
+ if (unlikely((int)skb->truesize < len))
skb_truesize_bug(skb);
}
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 259a13c3bd9..c25e66bcecf 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -84,11 +84,12 @@ void smp_prepare_boot_cpu(void);
* These macros fold the SMP functionality into a single CPU system
*/
#define raw_smp_processor_id() 0
-static inline int up_smp_call_function(void)
+static inline int up_smp_call_function(void (*func)(void *), void *info)
{
return 0;
}
-#define smp_call_function(func,info,retry,wait) (up_smp_call_function())
+#define smp_call_function(func, info, retry, wait) \
+ (up_smp_call_function(func, info))
#define on_each_cpu(func,info,retry,wait) \
({ \
local_irq_disable(); \
@@ -107,6 +108,8 @@ static inline void smp_send_reschedule(int cpu) { }
local_irq_enable(); \
0; \
})
+#define smp_call_function_mask(mask, func, info, wait) \
+ (up_smp_call_function(func, info))
#endif /* !SMP */
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 56164d7ba0a..c555f5442bd 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -332,7 +332,9 @@ extern void tty_ldisc_flush(struct tty_struct *tty);
extern int tty_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg);
-
+extern int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg);
extern dev_t tty_devnum(struct tty_struct *tty);
extern void proc_clear_tty(struct task_struct *p);
extern struct tty_struct *get_current_tty(void);
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index ac69e7bb5a1..1a4ed49f647 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -67,7 +67,7 @@ struct vring {
};
/* The standard layout for the ring is a continuous chunk of memory which looks
- * like this. The used fields will be aligned to a "num+1" boundary.
+ * like this. We assume num is a power of 2.
*
* struct vring
* {
@@ -79,8 +79,8 @@ struct vring {
* __u16 avail_idx;
* __u16 available[num];
*
- * // Padding so a correctly-chosen num value will cache-align used_idx.
- * char pad[sizeof(struct vring_desc) - sizeof(avail_flags)];
+ * // Padding to the next page boundary.
+ * char pad[];
*
* // A ring of used descriptor heads with free-running index.
* __u16 used_flags;
@@ -88,18 +88,21 @@ struct vring {
* struct vring_used_elem used[num];
* };
*/
-static inline void vring_init(struct vring *vr, unsigned int num, void *p)
+static inline void vring_init(struct vring *vr, unsigned int num, void *p,
+ unsigned int pagesize)
{
vr->num = num;
vr->desc = p;
- vr->avail = p + num*sizeof(struct vring);
- vr->used = p + (num+1)*(sizeof(struct vring) + sizeof(__u16));
+ vr->avail = p + num*sizeof(struct vring_desc);
+ vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + pagesize-1)
+ & ~(pagesize - 1));
}
-static inline unsigned vring_size(unsigned int num)
+static inline unsigned vring_size(unsigned int num, unsigned int pagesize)
{
- return (num + 1) * (sizeof(struct vring_desc) + sizeof(__u16))
- + sizeof(__u32) + num * sizeof(struct vring_used_elem);
+ return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num)
+ + pagesize - 1) & ~(pagesize - 1))
+ + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num;
}
#ifdef __KERNEL__
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 0864a775de2..a1c805d7f48 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -12,7 +12,7 @@ extern void unix_gc(void);
#define UNIX_HASH_SIZE 256
-extern atomic_t unix_tot_inflight;
+extern unsigned int unix_tot_inflight;
struct unix_address {
atomic_t refcnt;
diff --git a/include/net/dst.h b/include/net/dst.h
index e9ff4a4caef..2f65e894b82 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -143,6 +143,13 @@ static inline void dst_hold(struct dst_entry * dst)
atomic_inc(&dst->__refcnt);
}
+static inline void dst_use(struct dst_entry *dst, unsigned long time)
+{
+ dst_hold(dst);
+ dst->__use++;
+ dst->lastuse = time;
+}
+
static inline
struct dst_entry * dst_clone(struct dst_entry * dst)
{
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 017aebd9068..41a301e3864 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -107,4 +107,7 @@ extern int fib_rules_unregister(struct fib_rules_ops *);
extern int fib_rules_lookup(struct fib_rules_ops *,
struct flowi *, int flags,
struct fib_lookup_arg *);
+extern int fib_default_rule_add(struct fib_rules_ops *,
+ u32 pref, u32 table,
+ u32 flags);
#endif
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 4427dcd1e53..469216d9366 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -23,6 +23,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/wait.h>
+#include <linux/vmalloc.h>
#include <net/inet_connection_sock.h>
#include <net/inet_sock.h>
@@ -37,7 +38,6 @@
* I'll experiment with dynamic table growth later.
*/
struct inet_ehash_bucket {
- rwlock_t lock;
struct hlist_head chain;
struct hlist_head twchain;
};
@@ -100,6 +100,9 @@ struct inet_hashinfo {
* TIME_WAIT sockets use a separate chain (twchain).
*/
struct inet_ehash_bucket *ehash;
+ rwlock_t *ehash_locks;
+ unsigned int ehash_size;
+ unsigned int ehash_locks_mask;
/* Ok, let's try this, I give up, we do need a local binding
* TCP hash as well as the others for fast bind/connect.
@@ -107,7 +110,7 @@ struct inet_hashinfo {
struct inet_bind_hashbucket *bhash;
unsigned int bhash_size;
- unsigned int ehash_size;
+ /* Note : 4 bytes padding on 64 bit arches */
/* All sockets in TCP_LISTEN state will be in here. This is the only
* table where wildcard'd TCP sockets can exist. Hash function here
@@ -134,6 +137,62 @@ static inline struct inet_ehash_bucket *inet_ehash_bucket(
return &hashinfo->ehash[hash & (hashinfo->ehash_size - 1)];
}
+static inline rwlock_t *inet_ehash_lockp(
+ struct inet_hashinfo *hashinfo,
+ unsigned int hash)
+{
+ return &hashinfo->ehash_locks[hash & hashinfo->ehash_locks_mask];
+}
+
+static inline int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo)
+{
+ unsigned int i, size = 256;
+#if defined(CONFIG_PROVE_LOCKING)
+ unsigned int nr_pcpus = 2;
+#else
+ unsigned int nr_pcpus = num_possible_cpus();
+#endif
+ if (nr_pcpus >= 4)
+ size = 512;
+ if (nr_pcpus >= 8)
+ size = 1024;
+ if (nr_pcpus >= 16)
+ size = 2048;
+ if (nr_pcpus >= 32)
+ size = 4096;
+ if (sizeof(rwlock_t) != 0) {
+#ifdef CONFIG_NUMA
+ if (size * sizeof(rwlock_t) > PAGE_SIZE)
+ hashinfo->ehash_locks = vmalloc(size * sizeof(rwlock_t));
+ else
+#endif
+ hashinfo->ehash_locks = kmalloc(size * sizeof(rwlock_t),
+ GFP_KERNEL);
+ if (!hashinfo->ehash_locks)
+ return ENOMEM;
+ for (i = 0; i < size; i++)
+ rwlock_init(&hashinfo->ehash_locks[i]);
+ }
+ hashinfo->ehash_locks_mask = size - 1;
+ return 0;
+}
+
+static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
+{
+ if (hashinfo->ehash_locks) {
+#ifdef CONFIG_NUMA
+ unsigned int size = (hashinfo->ehash_locks_mask + 1) *
+ sizeof(rwlock_t);
+ if (size > PAGE_SIZE)
+ vfree(hashinfo->ehash_locks);
+ else
+#else
+ kfree(hashinfo->ehash_locks);
+#endif
+ hashinfo->ehash_locks = NULL;
+ }
+}
+
extern struct inet_bind_bucket *
inet_bind_bucket_create(struct kmem_cache *cachep,
struct inet_bind_hashbucket *head,
@@ -222,7 +281,7 @@ static inline void __inet_hash(struct inet_hashinfo *hashinfo,
sk->sk_hash = inet_sk_ehashfn(sk);
head = inet_ehash_bucket(hashinfo, sk->sk_hash);
list = &head->chain;
- lock = &head->lock;
+ lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
write_lock(lock);
}
__sk_add_node(sk, list);
@@ -253,7 +312,7 @@ static inline void inet_unhash(struct inet_hashinfo *hashinfo, struct sock *sk)
inet_listen_wlock(hashinfo);
lock = &hashinfo->lhash_lock;
} else {
- lock = &inet_ehash_bucket(hashinfo, sk->sk_hash)->lock;
+ lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
write_lock_bh(lock);
}
@@ -354,9 +413,10 @@ static inline struct sock *
*/
unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+ rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
prefetch(head->chain.first);
- read_lock(&head->lock);
+ read_lock(lock);
sk_for_each(sk, node, &head->chain) {
if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
goto hit; /* You sunk my battleship! */
@@ -369,7 +429,7 @@ static inline struct sock *
}
sk = NULL;
out:
- read_unlock(&head->lock);
+ read_unlock(lock);
return sk;
hit:
sock_hold(sk);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 8cadc77c7df..ed514bfb61b 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -185,6 +185,12 @@ static inline void fib_select_default(const struct flowi *flp, struct fib_result
}
#else /* CONFIG_IP_MULTIPLE_TABLES */
+extern void __init fib4_rules_init(void);
+
+#ifdef CONFIG_NET_CLS_ROUTE
+extern u32 fib_rules_tclass(struct fib_result *res);
+#endif
+
#define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
#define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
@@ -214,15 +220,6 @@ extern __be32 __fib_res_prefsrc(struct fib_result *res);
/* Exported by fib_hash.c */
extern struct fib_table *fib_hash_init(u32 id);
-#ifdef CONFIG_IP_MULTIPLE_TABLES
-extern void __init fib4_rules_init(void);
-
-#ifdef CONFIG_NET_CLS_ROUTE
-extern u32 fib_rules_tclass(struct fib_result *res);
-#endif
-
-#endif
-
static inline void fib_combine_itag(u32 *itag, struct fib_result *res)
{
#ifdef CONFIG_NET_CLS_ROUTE
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 41870564df8..67ea2c0c0ab 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -520,6 +520,10 @@ struct ip_vs_conn {
spinlock_t lock; /* lock for state transition */
volatile __u16 flags; /* status flags */
volatile __u16 state; /* state info */
+ volatile __u16 old_state; /* old state, to be used for
+ * state transition triggerd
+ * synchronization
+ */
/* Control members */
struct ip_vs_conn *control; /* Master control connection */
@@ -901,6 +905,10 @@ extern int ip_vs_use_count_inc(void);
extern void ip_vs_use_count_dec(void);
extern int ip_vs_control_init(void);
extern void ip_vs_control_cleanup(void);
+extern struct ip_vs_dest *
+ip_vs_find_dest(__be32 daddr, __be16 dport,
+ __be32 vaddr, __be16 vport, __u16 protocol);
+extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp);
/*
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5fcc4c10434..17b60391fcd 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -706,11 +706,16 @@ enum ieee80211_hw_flags {
*
* @queues: number of available hardware transmit queues for
* data packets. WMM/QoS requires at least four.
+ *
+ * @rate_control_algorithm: rate control algorithm for this hardware.
+ * If unset (NULL), the default algorithm will be used. Must be
+ * set before calling ieee80211_register_hw().
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
struct wiphy *wiphy;
struct workqueue_struct *workqueue;
+ const char *rate_control_algorithm;
void *priv;
u32 flags;
unsigned int extra_tx_headroom;
@@ -936,27 +941,11 @@ enum ieee80211_erp_change_flags {
* and remove_interface calls, i.e. while the interface with the
* given local_address is enabled.
*
- * @set_ieee8021x: Enable/disable IEEE 802.1X. This item requests wlan card
- * to pass unencrypted EAPOL-Key frames even when encryption is
- * configured. If the wlan card does not require such a configuration,
- * this function pointer can be set to NULL.
- *
- * @set_port_auth: Set port authorization state (IEEE 802.1X PAE) to be
- * authorized (@authorized=1) or unauthorized (=0). This function can be
- * used if the wlan hardware or low-level driver implements PAE.
- * mac80211 will filter frames based on authorization state in any case,
- * so this function pointer can be NULL if low-level driver does not
- * require event notification about port state changes.
- *
* @hw_scan: Ask the hardware to service the scan request, no need to start
* the scan state machine in stack.
*
* @get_stats: return low-level statistics
*
- * @set_privacy_invoked: For devices that generate their own beacons and probe
- * response or association responses this updates the state of privacy_invoked
- * returns 0 for success or an error number.
- *
* @get_sequence_counter: For devices that have internal sequence counters this
* callback allows mac80211 to access the current value of a counter.
* This callback seems not well-defined, tell us if you need it.
@@ -1029,14 +1018,9 @@ struct ieee80211_ops {
int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
const u8 *local_address, const u8 *address,
struct ieee80211_key_conf *key);
- int (*set_ieee8021x)(struct ieee80211_hw *hw, int use_ieee8021x);
- int (*set_port_auth)(struct ieee80211_hw *hw, u8 *addr,
- int authorized);
int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
int (*get_stats)(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
- int (*set_privacy_invoked)(struct ieee80211_hw *hw,
- int privacy_invoked);
int (*get_sequence_counter)(struct ieee80211_hw *hw,
u8* addr, u8 keyidx, u8 txrx,
u32* iv32, u16* iv16);
diff --git a/include/net/sock.h b/include/net/sock.h
index 20de3fa7ae4..5504fb9fa88 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -560,6 +560,14 @@ struct proto {
void (*unhash)(struct sock *sk);
int (*get_port)(struct sock *sk, unsigned short snum);
+#ifdef CONFIG_SMP
+ /* Keeping track of sockets in use */
+ void (*inuse_add)(struct proto *prot, int inc);
+ int (*inuse_getval)(const struct proto *prot);
+ int *inuse_ptr;
+#else
+ int inuse;
+#endif
/* Memory pressure */
void (*enter_memory_pressure)(void);
atomic_t *memory_allocated; /* Current allocated memory. */
@@ -592,12 +600,38 @@ struct proto {
#ifdef SOCK_REFCNT_DEBUG
atomic_t socks;
#endif
- struct {
- int inuse;
- u8 __pad[SMP_CACHE_BYTES - sizeof(int)];
- } stats[NR_CPUS];
};
+/*
+ * Special macros to let protos use a fast version of inuse{get|add}
+ * using a static percpu variable per proto instead of an allocated one,
+ * saving one dereference.
+ * This might be changed if/when dynamic percpu vars become fast.
+ */
+#ifdef CONFIG_SMP
+# define DEFINE_PROTO_INUSE(NAME) \
+static DEFINE_PER_CPU(int, NAME##_inuse); \
+static void NAME##_inuse_add(struct proto *prot, int inc) \
+{ \
+ __get_cpu_var(NAME##_inuse) += inc; \
+} \
+ \
+static int NAME##_inuse_getval(const struct proto *prot)\
+{ \
+ int res = 0, cpu; \
+ \
+ for_each_possible_cpu(cpu) \
+ res += per_cpu(NAME##_inuse, cpu); \
+ return res; \
+}
+# define REF_PROTO_INUSE(NAME) \
+ .inuse_add = NAME##_inuse_add, \
+ .inuse_getval = NAME##_inuse_getval,
+#else
+# define DEFINE_PROTO_INUSE(NAME)
+# define REF_PROTO_INUSE(NAME)
+#endif
+
extern int proto_register(struct proto *prot, int alloc_slab);
extern void proto_unregister(struct proto *prot);
@@ -629,12 +663,29 @@ static inline void sk_refcnt_debug_release(const struct sock *sk)
/* Called with local bh disabled */
static __inline__ void sock_prot_inc_use(struct proto *prot)
{
- prot->stats[smp_processor_id()].inuse++;
+#ifdef CONFIG_SMP
+ prot->inuse_add(prot, 1);
+#else
+ prot->inuse++;
+#endif
}
static __inline__ void sock_prot_dec_use(struct proto *prot)
{
- prot->stats[smp_processor_id()].inuse--;
+#ifdef CONFIG_SMP
+ prot->inuse_add(prot, -1);
+#else
+ prot->inuse--;
+#endif
+}
+
+static __inline__ int sock_prot_inuse(struct proto *proto)
+{
+#ifdef CONFIG_SMP
+ return proto->inuse_getval(proto);
+#else
+ return proto->inuse;
+#endif
}
/* With per-bucket locks this operation is not-atomic, so that
diff --git a/init/main.c b/init/main.c
index f605a969ea6..80b04b6c515 100644
--- a/init/main.c
+++ b/init/main.c
@@ -56,6 +56,7 @@
#include <linux/pid_namespace.h>
#include <linux/device.h>
#include <linux/kthread.h>
+#include <linux/sched.h>
#include <asm/io.h>
#include <asm/bugs.h>
@@ -747,11 +748,8 @@ __setup("nosoftlockup", nosoftlockup_setup);
static void __init do_pre_smp_initcalls(void)
{
extern int spawn_ksoftirqd(void);
-#ifdef CONFIG_SMP
- extern int migration_init(void);
migration_init();
-#endif
spawn_ksoftirqd();
if (!nosoftlockup)
spawn_softlockup_task();
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index bfa274ba9ed..1e04cd464af 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -1010,6 +1010,8 @@ asmlinkage long sys_mq_notify(mqd_t mqdes,
return -EINVAL;
}
if (notification.sigev_notify == SIGEV_THREAD) {
+ long timeo;
+
/* create the notify skb */
nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL);
ret = -ENOMEM;
@@ -1038,8 +1040,8 @@ retry:
goto out;
}
- ret = netlink_attachskb(sock, nc, 0,
- MAX_SCHEDULE_TIMEOUT, NULL);
+ timeo = MAX_SCHEDULE_TIMEOUT;
+ ret = netlink_attachskb(sock, nc, 0, &timeo, NULL);
if (ret == 1)
goto retry;
if (ret) {
diff --git a/kernel/fork.c b/kernel/fork.c
index 28a74015198..8ca1a14cdc8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1123,6 +1123,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->blocked_on = NULL; /* not blocked yet */
#endif
+ /* Perform scheduler related setup. Assign this task to a CPU. */
+ sched_fork(p, clone_flags);
+
if ((retval = security_task_alloc(p)))
goto bad_fork_cleanup_policy;
if ((retval = audit_alloc(p)))
@@ -1212,9 +1215,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
INIT_LIST_HEAD(&p->ptrace_children);
INIT_LIST_HEAD(&p->ptrace_list);
- /* Perform scheduler related setup. Assign this task to a CPU. */
- sched_fork(p, clone_flags);
-
/* Now that the task is set up, run cgroup callbacks if
* necessary. We need to run them before the task is visible
* on the tasklist. */
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 00b572666cc..0a43def6fee 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -30,6 +30,15 @@ fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
return 0;
}
+static void __user *futex_uaddr(struct robust_list *entry,
+ compat_long_t futex_offset)
+{
+ compat_uptr_t base = ptr_to_compat(entry);
+ void __user *uaddr = compat_ptr(base + futex_offset);
+
+ return uaddr;
+}
+
/*
* Walk curr->robust_list (very carefully, it's a userspace list!)
* and mark any locks found there dead, and notify any waiters.
@@ -76,11 +85,12 @@ void compat_exit_robust_list(struct task_struct *curr)
* A pending lock might already be on the list, so
* dont process it twice:
*/
- if (entry != pending)
- if (handle_futex_death((void __user *)entry + futex_offset,
- curr, pi))
- return;
+ if (entry != pending) {
+ void __user *uaddr = futex_uaddr(entry, futex_offset);
+ if (handle_futex_death(uaddr, curr, pi))
+ return;
+ }
if (rc)
return;
uentry = next_uentry;
@@ -94,9 +104,11 @@ void compat_exit_robust_list(struct task_struct *curr)
cond_resched();
}
- if (pending)
- handle_futex_death((void __user *)pending + futex_offset,
- curr, pip);
+ if (pending) {
+ void __user *uaddr = futex_uaddr(pending, futex_offset);
+
+ handle_futex_death(uaddr, curr, pip);
+ }
}
asmlinkage long
diff --git a/kernel/sched.c b/kernel/sched.c
index 3f6bd111290..b18f231a487 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -75,7 +75,7 @@
*/
unsigned long long __attribute__((weak)) sched_clock(void)
{
- return (unsigned long long)jiffies * (1000000000 / HZ);
+ return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
}
/*
@@ -99,8 +99,8 @@ unsigned long long __attribute__((weak)) sched_clock(void)
/*
* Some helpers for converting nanosecond timing to jiffy resolution
*/
-#define NS_TO_JIFFIES(TIME) ((unsigned long)(TIME) / (1000000000 / HZ))
-#define JIFFIES_TO_NS(TIME) ((TIME) * (1000000000 / HZ))
+#define NS_TO_JIFFIES(TIME) ((unsigned long)(TIME) / (NSEC_PER_SEC / HZ))
+#define JIFFIES_TO_NS(TIME) ((TIME) * (NSEC_PER_SEC / HZ))
#define NICE_0_LOAD SCHED_LOAD_SCALE
#define NICE_0_SHIFT SCHED_LOAD_SHIFT
@@ -460,7 +460,6 @@ enum {
SCHED_FEAT_TREE_AVG = 4,
SCHED_FEAT_APPROX_AVG = 8,
SCHED_FEAT_WAKEUP_PREEMPT = 16,
- SCHED_FEAT_PREEMPT_RESTRICT = 32,
};
const_debug unsigned int sysctl_sched_features =
@@ -468,12 +467,17 @@ const_debug unsigned int sysctl_sched_features =
SCHED_FEAT_START_DEBIT * 1 |
SCHED_FEAT_TREE_AVG * 0 |
SCHED_FEAT_APPROX_AVG * 0 |
- SCHED_FEAT_WAKEUP_PREEMPT * 1 |
- SCHED_FEAT_PREEMPT_RESTRICT * 1;
+ SCHED_FEAT_WAKEUP_PREEMPT * 1;
#define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
/*
+ * Number of tasks to iterate in a single balance run.
+ * Limited because this is done with IRQs disabled.
+ */
+const_debug unsigned int sysctl_sched_nr_migrate = 32;
+
+/*
* For kernel-internal use: high-speed (but slightly incorrect) per-cpu
* clock constructed from sched_clock():
*/
@@ -2237,7 +2241,7 @@ balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
enum cpu_idle_type idle, int *all_pinned,
int *this_best_prio, struct rq_iterator *iterator)
{
- int pulled = 0, pinned = 0, skip_for_load;
+ int loops = 0, pulled = 0, pinned = 0, skip_for_load;
struct task_struct *p;
long rem_load_move = max_load_move;
@@ -2251,10 +2255,10 @@ balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
*/
p = iterator->start(iterator->arg);
next:
- if (!p)
+ if (!p || loops++ > sysctl_sched_nr_migrate)
goto out;
/*
- * To help distribute high priority tasks accross CPUs we don't
+ * To help distribute high priority tasks across CPUs we don't
* skip a task if it will be the highest priority task (i.e. smallest
* prio value) on its new queue regardless of its load weight
*/
@@ -2271,8 +2275,7 @@ next:
rem_load_move -= p->se.load.weight;
/*
- * We only want to steal up to the prescribed number of tasks
- * and the prescribed amount of weighted load.
+ * We only want to steal up to the prescribed amount of weighted load.
*/
if (rem_load_move > 0) {
if (p->prio < *this_best_prio)
@@ -4992,6 +4995,32 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
*/
cpumask_t nohz_cpu_mask = CPU_MASK_NONE;
+/*
+ * Increase the granularity value when there are more CPUs,
+ * because with more CPUs the 'effective latency' as visible
+ * to users decreases. But the relationship is not linear,
+ * so pick a second-best guess by going with the log2 of the
+ * number of CPUs.
+ *
+ * This idea comes from the SD scheduler of Con Kolivas:
+ */
+static inline void sched_init_granularity(void)
+{
+ unsigned int factor = 1 + ilog2(num_online_cpus());
+ const unsigned long limit = 200000000;
+
+ sysctl_sched_min_granularity *= factor;
+ if (sysctl_sched_min_granularity > limit)
+ sysctl_sched_min_granularity = limit;
+
+ sysctl_sched_latency *= factor;
+ if (sysctl_sched_latency > limit)
+ sysctl_sched_latency = limit;
+
+ sysctl_sched_wakeup_granularity *= factor;
+ sysctl_sched_batch_wakeup_granularity *= factor;
+}
+
#ifdef CONFIG_SMP
/*
* This is how migration works:
@@ -5621,7 +5650,7 @@ static struct notifier_block __cpuinitdata migration_notifier = {
.priority = 10
};
-int __init migration_init(void)
+void __init migration_init(void)
{
void *cpu = (void *)(long)smp_processor_id();
int err;
@@ -5631,8 +5660,6 @@ int __init migration_init(void)
BUG_ON(err == NOTIFY_BAD);
migration_call(&migration_notifier, CPU_ONLINE, cpu);
register_cpu_notifier(&migration_notifier);
-
- return 0;
}
#endif
@@ -6688,10 +6715,12 @@ void __init sched_init_smp(void)
/* Move init over to a non-isolated CPU */
if (set_cpus_allowed(current, non_isolated_cpus) < 0)
BUG();
+ sched_init_granularity();
}
#else
void __init sched_init_smp(void)
{
+ sched_init_granularity();
}
#endif /* CONFIG_SMP */
@@ -7228,7 +7257,7 @@ static u64 cpu_usage_read(struct cgroup *cgrp, struct cftype *cft)
spin_unlock_irqrestore(&cpu_rq(i)->lock, flags);
}
/* Convert from ns to ms */
- do_div(res, 1000000);
+ do_div(res, NSEC_PER_MSEC);
return res;
}
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 415e5c38554..ca198a797bf 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -211,7 +211,7 @@ static int sched_debug_show(struct seq_file *m, void *v)
#define PN(x) \
SEQ_printf(m, " .%-40s: %Ld.%06ld\n", #x, SPLIT_NS(x))
PN(sysctl_sched_latency);
- PN(sysctl_sched_nr_latency);
+ PN(sysctl_sched_min_granularity);
PN(sysctl_sched_wakeup_granularity);
PN(sysctl_sched_batch_wakeup_granularity);
PN(sysctl_sched_child_runs_first);
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 01859f662ab..d3c03070872 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -22,7 +22,7 @@
/*
* Targeted preemption latency for CPU-bound tasks:
- * (default: 20ms, units: nanoseconds)
+ * (default: 20ms * ilog(ncpus), units: nanoseconds)
*
* NOTE: this latency value is not the same as the concept of
* 'timeslice length' - timeslices in CFS are of variable length
@@ -32,19 +32,24 @@
* (to see the precise effective timeslice length of your workload,
* run vmstat and monitor the context-switches (cs) field)
*/
-const_debug unsigned int sysctl_sched_latency = 20000000ULL;
+unsigned int sysctl_sched_latency = 20000000ULL;
/*
- * After fork, child runs first. (default) If set to 0 then
- * parent will (try to) run first.
+ * Minimal preemption granularity for CPU-bound tasks:
+ * (default: 1 msec * ilog(ncpus), units: nanoseconds)
*/
-const_debug unsigned int sysctl_sched_child_runs_first = 1;
+unsigned int sysctl_sched_min_granularity = 1000000ULL;
/*
- * Minimal preemption granularity for CPU-bound tasks:
- * (default: 2 msec, units: nanoseconds)
+ * is kept at sysctl_sched_latency / sysctl_sched_min_granularity
+ */
+unsigned int sched_nr_latency = 20;
+
+/*
+ * After fork, child runs first. (default) If set to 0 then
+ * parent will (try to) run first.
*/
-const_debug unsigned int sysctl_sched_nr_latency = 20;
+const_debug unsigned int sysctl_sched_child_runs_first = 1;
/*
* sys_sched_yield() compat mode
@@ -56,23 +61,23 @@ unsigned int __read_mostly sysctl_sched_compat_yield;
/*
* SCHED_BATCH wake-up granularity.
- * (default: 10 msec, units: nanoseconds)
+ * (default: 10 msec * ilog(ncpus), units: nanoseconds)
*
* This option delays the preemption effects of decoupled workloads
* and reduces their over-scheduling. Synchronous workloads will still
* have immediate wakeup/sleep latencies.
*/
-const_debug unsigned int sysctl_sched_batch_wakeup_granularity = 10000000UL;
+unsigned int sysctl_sched_batch_wakeup_granularity = 10000000UL;
/*
* SCHED_OTHER wake-up granularity.
- * (default: 10 msec, units: nanoseconds)
+ * (default: 10 msec * ilog(ncpus), units: nanoseconds)
*
* This option delays the preemption effects of decoupled workloads
* and reduces their over-scheduling. Synchronous workloads will still
* have immediate wakeup/sleep latencies.
*/
-const_debug unsigned int sysctl_sched_wakeup_granularity = 10000000UL;
+unsigned int sysctl_sched_wakeup_granularity = 10000000UL;
const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
@@ -212,6 +217,22 @@ static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
* Scheduling class statistics methods:
*/
+#ifdef CONFIG_SCHED_DEBUG
+int sched_nr_latency_handler(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+
+ if (ret || !write)
+ return ret;
+
+ sched_nr_latency = DIV_ROUND_UP(sysctl_sched_latency,
+ sysctl_sched_min_granularity);
+
+ return 0;
+}
+#endif
/*
* The idea is to set a period in which each task runs once.
@@ -224,7 +245,7 @@ static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
static u64 __sched_period(unsigned long nr_running)
{
u64 period = sysctl_sched_latency;
- unsigned long nr_latency = sysctl_sched_nr_latency;
+ unsigned long nr_latency = sched_nr_latency;
if (unlikely(nr_running > nr_latency)) {
period *= nr_running;
@@ -259,6 +280,7 @@ static u64 __sched_vslice(unsigned long rq_weight, unsigned long nr_running)
{
u64 vslice = __sched_period(nr_running);
+ vslice *= NICE_0_LOAD;
do_div(vslice, rq_weight);
return vslice;
@@ -472,19 +494,26 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
} else if (sched_feat(APPROX_AVG) && cfs_rq->nr_running)
vruntime += sched_vslice(cfs_rq)/2;
+ /*
+ * The 'current' period is already promised to the current tasks,
+ * however the extra weight of the new task will slow them down a
+ * little, place the new task so that it fits in the slot that
+ * stays open at the end.
+ */
if (initial && sched_feat(START_DEBIT))
vruntime += sched_vslice_add(cfs_rq, se);
if (!initial) {
+ /* sleeps upto a single latency don't count. */
if (sched_feat(NEW_FAIR_SLEEPERS) && entity_is_task(se) &&
task_of(se)->policy != SCHED_BATCH)
vruntime -= sysctl_sched_latency;
- vruntime = max_t(s64, vruntime, se->vruntime);
+ /* ensure we never gain time by being placed backwards. */
+ vruntime = max_vruntime(se->vruntime, vruntime);
}
se->vruntime = vruntime;
-
}
static void
@@ -517,7 +546,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
update_stats_dequeue(cfs_rq, se);
if (sleep) {
- se->peer_preempt = 0;
#ifdef CONFIG_SCHEDSTATS
if (entity_is_task(se)) {
struct task_struct *tsk = task_of(se);
@@ -545,10 +573,8 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
ideal_runtime = sched_slice(cfs_rq, curr);
delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime;
- if (delta_exec > ideal_runtime ||
- (sched_feat(PREEMPT_RESTRICT) && curr->peer_preempt))
+ if (delta_exec > ideal_runtime)
resched_task(rq_of(cfs_rq)->curr);
- curr->peer_preempt = 0;
}
static void
@@ -811,7 +837,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
struct task_struct *curr = rq->curr;
struct cfs_rq *cfs_rq = task_cfs_rq(curr);
struct sched_entity *se = &curr->se, *pse = &p->se;
- s64 delta, gran;
+ unsigned long gran;
if (unlikely(rt_prio(p->prio))) {
update_rq_clock(rq);
@@ -826,24 +852,20 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
if (unlikely(p->policy == SCHED_BATCH))
return;
- if (sched_feat(WAKEUP_PREEMPT)) {
- while (!is_same_group(se, pse)) {
- se = parent_entity(se);
- pse = parent_entity(pse);
- }
+ if (!sched_feat(WAKEUP_PREEMPT))
+ return;
- delta = se->vruntime - pse->vruntime;
- gran = sysctl_sched_wakeup_granularity;
- if (unlikely(se->load.weight != NICE_0_LOAD))
- gran = calc_delta_fair(gran, &se->load);
+ while (!is_same_group(se, pse)) {
+ se = parent_entity(se);
+ pse = parent_entity(pse);
+ }
- if (delta > gran) {
- int now = !sched_feat(PREEMPT_RESTRICT);
+ gran = sysctl_sched_wakeup_granularity;
+ if (unlikely(se->load.weight != NICE_0_LOAD))
+ gran = calc_delta_fair(gran, &se->load);
- if (now || p->prio < curr->prio || !se->peer_preempt++)
- resched_task(curr);
- }
- }
+ if (pse->vruntime + gran < se->vruntime)
+ resched_task(curr);
}
static struct task_struct *pick_next_task_fair(struct rq *rq)
@@ -1045,8 +1067,9 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
update_curr(cfs_rq);
place_entity(cfs_rq, se, 1);
+ /* 'curr' will be NULL if the child belongs to a different group */
if (sysctl_sched_child_runs_first && this_cpu == task_cpu(p) &&
- curr->vruntime < se->vruntime) {
+ curr && curr->vruntime < se->vruntime) {
/*
* Upon rescheduling, sched_class::put_prev_task() will place
* 'current' within the tree based on its new key value.
@@ -1054,7 +1077,6 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
swap(curr->vruntime, se->vruntime);
}
- se->peer_preempt = 0;
enqueue_task_fair(rq, p, 0);
resched_task(rq->curr);
}
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
index ef1a7df80ea..630178e53bb 100644
--- a/kernel/sched_stats.h
+++ b/kernel/sched_stats.h
@@ -127,7 +127,7 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta)
# define schedstat_set(var, val) do { } while (0)
#endif
-#ifdef CONFIG_SCHEDSTATS
+#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
/*
* Called when a process is dequeued from the active array and given
* the cpu. We should note that with the exception of interactive
@@ -155,7 +155,7 @@ static inline void sched_info_dequeued(struct task_struct *t)
*/
static void sched_info_arrive(struct task_struct *t)
{
- unsigned long long now = sched_clock(), delta = 0;
+ unsigned long long now = task_rq(t)->clock, delta = 0;
if (t->sched_info.last_queued)
delta = now - t->sched_info.last_queued;
@@ -186,7 +186,7 @@ static inline void sched_info_queued(struct task_struct *t)
{
if (unlikely(sched_info_on()))
if (!t->sched_info.last_queued)
- t->sched_info.last_queued = sched_clock();
+ t->sched_info.last_queued = task_rq(t)->clock;
}
/*
@@ -195,7 +195,8 @@ static inline void sched_info_queued(struct task_struct *t)
*/
static inline void sched_info_depart(struct task_struct *t)
{
- unsigned long long delta = sched_clock() - t->sched_info.last_arrival;
+ unsigned long long delta = task_rq(t)->clock -
+ t->sched_info.last_arrival;
t->sched_info.cpu_time += delta;
rq_sched_info_depart(task_rq(t), delta);
@@ -231,5 +232,5 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
#else
#define sched_info_queued(t) do { } while (0)
#define sched_info_switch(t, next) do { } while (0)
-#endif /* CONFIG_SCHEDSTATS */
+#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 3b4efbe2644..3a1744fed2b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -226,20 +226,23 @@ static struct ctl_table root_table[] = {
#ifdef CONFIG_SCHED_DEBUG
static unsigned long min_sched_granularity_ns = 100000; /* 100 usecs */
-static unsigned long max_sched_granularity_ns = 1000000000; /* 1 second */
+static unsigned long max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */
static unsigned long min_wakeup_granularity_ns; /* 0 usecs */
-static unsigned long max_wakeup_granularity_ns = 1000000000; /* 1 second */
+static unsigned long max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */
#endif
static struct ctl_table kern_table[] = {
#ifdef CONFIG_SCHED_DEBUG
{
.ctl_name = CTL_UNNUMBERED,
- .procname = "sched_nr_latency",
- .data = &sysctl_sched_nr_latency,
+ .procname = "sched_min_granularity_ns",
+ .data = &sysctl_sched_min_granularity,
.maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = &sched_nr_latency_handler,
+ .strategy = &sysctl_intvec,
+ .extra1 = &min_sched_granularity_ns,
+ .extra2 = &max_sched_granularity_ns,
},
{
.ctl_name = CTL_UNNUMBERED,
@@ -247,7 +250,7 @@ static struct ctl_table kern_table[] = {
.data = &sysctl_sched_latency,
.maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = &proc_dointvec_minmax,
+ .proc_handler = &sched_nr_latency_handler,
.strategy = &sysctl_intvec,
.extra1 = &min_sched_granularity_ns,
.extra2 = &max_sched_granularity_ns,
@@ -298,6 +301,14 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "sched_nr_migrate",
+ .data = &sysctl_sched_nr_migrate,
+ .maxlen = sizeof(unsigned int),
+ .mode = 644,
+ .proc_handler = &proc_dointvec,
+ },
#endif
{
.ctl_name = CTL_UNNUMBERED,
diff --git a/kernel/timer.c b/kernel/timer.c
index 00e44e2afd6..a05817c021d 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -817,6 +817,19 @@ unsigned long next_timer_interrupt(void)
#endif
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+void account_process_tick(struct task_struct *p, int user_tick)
+{
+ if (user_tick) {
+ account_user_time(p, jiffies_to_cputime(1));
+ account_user_time_scaled(p, jiffies_to_cputime(1));
+ } else {
+ account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
+ account_system_time_scaled(p, jiffies_to_cputime(1));
+ }
+}
+#endif
+
/*
* Called from the timer interrupt handler to charge one tick to the current
* process. user_tick is 1 if the tick is user time, 0 for system.
@@ -827,13 +840,7 @@ void update_process_times(int user_tick)
int cpu = smp_processor_id();
/* Note: this timer irq context must be accounted for as well. */
- if (user_tick) {
- account_user_time(p, jiffies_to_cputime(1));
- account_user_time_scaled(p, jiffies_to_cputime(1));
- } else {
- account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
- account_system_time_scaled(p, jiffies_to_cputime(1));
- }
+ account_process_tick(p, user_tick);
run_local_timers();
if (rcu_pending(cpu))
rcu_check_callbacks(cpu, user_tick);
diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
index 802f11f0bf5..b5c3287d8ea 100644
--- a/lib/libcrc32c.c
+++ b/lib/libcrc32c.c
@@ -33,7 +33,6 @@
#include <linux/crc32c.h>
#include <linux/compiler.h>
#include <linux/module.h>
-#include <asm/byteorder.h>
MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
@@ -161,15 +160,13 @@ static const u32 crc32c_table[256] = {
*/
u32 __pure
-crc32c_le(u32 seed, unsigned char const *data, size_t length)
+crc32c_le(u32 crc, unsigned char const *data, size_t length)
{
- u32 crc = __cpu_to_le32(seed);
-
while (length--)
crc =
crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
- return __le32_to_cpu(crc);
+ return crc;
}
#endif /* CRC_LE_BITS == 8 */
diff --git a/mm/slub.c b/mm/slub.c
index 84f59fde1a1..9acb413858a 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1080,7 +1080,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
struct page *page;
struct kmem_cache_node *n;
void *start;
- void *end;
void *last;
void *p;
@@ -1101,7 +1100,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
SetSlabDebug(page);
start = page_address(page);
- end = start + s->objects * s->size;
if (unlikely(s->flags & SLAB_POISON))
memset(start, POISON_INUSE, PAGE_SIZE << s->order);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 3fe4fc86055..6567213959c 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -376,6 +376,7 @@ void vlan_setup(struct net_device *new_dev)
new_dev->init = vlan_dev_init;
new_dev->open = vlan_dev_open;
new_dev->stop = vlan_dev_stop;
+ new_dev->set_mac_address = vlan_set_mac_address;
new_dev->set_multicast_list = vlan_dev_set_multicast_list;
new_dev->change_rx_flags = vlan_change_rx_flags;
new_dev->destructor = free_netdev;
@@ -636,6 +637,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
if (!vlandev)
continue;
+ flgs = vlandev->flags;
+ if (!(flgs & IFF_UP))
+ continue;
+
vlan_sync_address(dev, vlandev);
}
break;
@@ -747,6 +752,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
vlan_dev_set_ingress_priority(dev,
args.u.skb_priority,
args.vlan_qos);
+ err = 0;
break;
case SET_VLAN_EGRESS_PRIORITY_CMD:
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index cf4a80d06b3..2cd1393073e 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -60,6 +60,7 @@ int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev
int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
int vlan_dev_open(struct net_device* dev);
int vlan_dev_stop(struct net_device* dev);
+int vlan_set_mac_address(struct net_device *dev, void *p);
int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd);
void vlan_dev_set_ingress_priority(const struct net_device *dev,
u32 skb_prio, short vlan_prio);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 1a1740aa9a8..7a36878241d 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -665,6 +665,32 @@ int vlan_dev_stop(struct net_device *dev)
return 0;
}
+int vlan_set_mac_address(struct net_device *dev, void *p)
+{
+ struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+ struct sockaddr *addr = p;
+ int err;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (!(dev->flags & IFF_UP))
+ goto out;
+
+ if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) {
+ err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN);
+ if (err < 0)
+ return err;
+ }
+
+ if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
+ dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN);
+
+out:
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ return 0;
+}
+
int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c
index 1a46952a56d..18141392a9b 100644
--- a/net/bridge/netfilter/ebt_arp.c
+++ b/net/bridge/netfilter/ebt_arp.c
@@ -34,7 +34,7 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
ah->ar_pro, EBT_ARP_PTYPE))
return EBT_NOMATCH;
- if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) {
+ if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
__be32 saddr, daddr, *sap, *dap;
if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
diff --git a/net/core/dev.c b/net/core/dev.c
index be6cedab5aa..dd7e30754cb 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4330,7 +4330,6 @@ static struct hlist_head *netdev_create_hash(void)
static int __net_init netdev_init(struct net *net)
{
INIT_LIST_HEAD(&net->dev_base_head);
- rwlock_init(&dev_base_lock);
net->dev_name_head = netdev_create_hash();
if (net->dev_name_head == NULL)
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index ae354057d84..647973daca2 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -168,13 +168,13 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from)
da = from->mc_list;
while (da != NULL) {
next = da->next;
- if (!da->da_synced)
- continue;
- __dev_addr_delete(&to->mc_list, &to->mc_count,
- da->da_addr, da->da_addrlen, 0);
- da->da_synced = 0;
- __dev_addr_delete(&from->mc_list, &from->mc_count,
- da->da_addr, da->da_addrlen, 0);
+ if (da->da_synced) {
+ __dev_addr_delete(&to->mc_list, &to->mc_count,
+ da->da_addr, da->da_addrlen, 0);
+ da->da_synced = 0;
+ __dev_addr_delete(&from->mc_list, &from->mc_count,
+ da->da_addr, da->da_addrlen, 0);
+ }
da = next;
}
__dev_set_rx_mode(to);
diff --git a/net/core/dst.c b/net/core/dst.c
index 16958e64e57..03daead3592 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -18,7 +18,6 @@
#include <linux/types.h>
#include <net/net_namespace.h>
-#include <net/net_namespace.h>
#include <net/dst.h>
/*
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 13de6f53f09..848132b6cb7 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -18,6 +18,28 @@
static LIST_HEAD(rules_ops);
static DEFINE_SPINLOCK(rules_mod_lock);
+int fib_default_rule_add(struct fib_rules_ops *ops,
+ u32 pref, u32 table, u32 flags)
+{
+ struct fib_rule *r;
+
+ r = kzalloc(ops->rule_size, GFP_KERNEL);
+ if (r == NULL)
+ return -ENOMEM;
+
+ atomic_set(&r->refcnt, 1);
+ r->action = FR_ACT_TO_TBL;
+ r->pref = pref;
+ r->table = table;
+ r->flags = flags;
+
+ /* The lock is not required here, the list in unreacheable
+ * at the moment this function is called */
+ list_add_tail(&r->list, &ops->rules_list);
+ return 0;
+}
+EXPORT_SYMBOL(fib_default_rule_add);
+
static void notify_rule_change(int event, struct fib_rule *rule,
struct fib_rules_ops *ops, struct nlmsghdr *nlh,
u32 pid);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 05979e35696..29b8ee4e35d 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1435,6 +1435,8 @@ int neigh_table_clear(struct neigh_table *tbl)
kfree(tbl->phash_buckets);
tbl->phash_buckets = NULL;
+ remove_proc_entry(tbl->id, init_net.proc_net_stat);
+
free_percpu(tbl->stats);
tbl->stats = NULL;
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index e9f0964ce70..3f6d37deac4 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -64,6 +64,20 @@ static struct net *net_alloc(void)
return kmem_cache_zalloc(net_cachep, GFP_KERNEL);
}
+static void net_free(struct net *net)
+{
+ if (!net)
+ return;
+
+ if (unlikely(atomic_read(&net->use_count) != 0)) {
+ printk(KERN_EMERG "network namespace not free! Usage: %d\n",
+ atomic_read(&net->use_count));
+ return;
+ }
+
+ kmem_cache_free(net_cachep, net);
+}
+
struct net *copy_net_ns(unsigned long flags, struct net *old_net)
{
struct net *new_net = NULL;
@@ -100,20 +114,6 @@ out:
return new_net;
}
-static void net_free(struct net *net)
-{
- if (!net)
- return;
-
- if (unlikely(atomic_read(&net->use_count) != 0)) {
- printk(KERN_EMERG "network namespace not free! Usage: %d\n",
- atomic_read(&net->use_count));
- return;
- }
-
- kmem_cache_free(net_cachep, net);
-}
-
static void cleanup_net(struct work_struct *work)
{
struct pernet_operations *ops;
diff --git a/net/core/sock.c b/net/core/sock.c
index 12ad2067a98..8fc2f84209e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1801,11 +1801,65 @@ EXPORT_SYMBOL(sk_common_release);
static DEFINE_RWLOCK(proto_list_lock);
static LIST_HEAD(proto_list);
+#ifdef CONFIG_SMP
+/*
+ * Define default functions to keep track of inuse sockets per protocol
+ * Note that often used protocols use dedicated functions to get a speed increase.
+ * (see DEFINE_PROTO_INUSE/REF_PROTO_INUSE)
+ */
+static void inuse_add(struct proto *prot, int inc)
+{
+ per_cpu_ptr(prot->inuse_ptr, smp_processor_id())[0] += inc;
+}
+
+static int inuse_get(const struct proto *prot)
+{
+ int res = 0, cpu;
+ for_each_possible_cpu(cpu)
+ res += per_cpu_ptr(prot->inuse_ptr, cpu)[0];
+ return res;
+}
+
+static int inuse_init(struct proto *prot)
+{
+ if (!prot->inuse_getval || !prot->inuse_add) {
+ prot->inuse_ptr = alloc_percpu(int);
+ if (prot->inuse_ptr == NULL)
+ return -ENOBUFS;
+
+ prot->inuse_getval = inuse_get;
+ prot->inuse_add = inuse_add;
+ }
+ return 0;
+}
+
+static void inuse_fini(struct proto *prot)
+{
+ if (prot->inuse_ptr != NULL) {
+ free_percpu(prot->inuse_ptr);
+ prot->inuse_ptr = NULL;
+ prot->inuse_getval = NULL;
+ prot->inuse_add = NULL;
+ }
+}
+#else
+static inline int inuse_init(struct proto *prot)
+{
+ return 0;
+}
+
+static inline void inuse_fini(struct proto *prot)
+{
+}
+#endif
+
int proto_register(struct proto *prot, int alloc_slab)
{
char *request_sock_slab_name = NULL;
char *timewait_sock_slab_name;
- int rc = -ENOBUFS;
+
+ if (inuse_init(prot))
+ goto out;
if (alloc_slab) {
prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0,
@@ -1814,7 +1868,7 @@ int proto_register(struct proto *prot, int alloc_slab)
if (prot->slab == NULL) {
printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n",
prot->name);
- goto out;
+ goto out_free_inuse;
}
if (prot->rsk_prot != NULL) {
@@ -1858,9 +1912,8 @@ int proto_register(struct proto *prot, int alloc_slab)
write_lock(&proto_list_lock);
list_add(&prot->node, &proto_list);
write_unlock(&proto_list_lock);
- rc = 0;
-out:
- return rc;
+ return 0;
+
out_free_timewait_sock_slab_name:
kfree(timewait_sock_slab_name);
out_free_request_sock_slab:
@@ -1873,7 +1926,10 @@ out_free_request_sock_slab_name:
out_free_sock_slab:
kmem_cache_destroy(prot->slab);
prot->slab = NULL;
- goto out;
+out_free_inuse:
+ inuse_fini(prot);
+out:
+ return -ENOBUFS;
}
EXPORT_SYMBOL(proto_register);
@@ -1884,6 +1940,7 @@ void proto_unregister(struct proto *prot)
list_del(&prot->node);
write_unlock(&proto_list_lock);
+ inuse_fini(prot);
if (prot->slab != NULL) {
kmem_cache_destroy(prot->slab);
prot->slab = NULL;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 01a6a808bdb..db17b83e8d3 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -922,6 +922,8 @@ static struct timewait_sock_ops dccp_timewait_sock_ops = {
.twsk_obj_size = sizeof(struct inet_timewait_sock),
};
+DEFINE_PROTO_INUSE(dccp_v4)
+
static struct proto dccp_v4_prot = {
.name = "DCCP",
.owner = THIS_MODULE,
@@ -950,6 +952,7 @@ static struct proto dccp_v4_prot = {
.compat_setsockopt = compat_dccp_setsockopt,
.compat_getsockopt = compat_dccp_getsockopt,
#endif
+ REF_PROTO_INUSE(dccp_v4)
};
static struct net_protocol dccp_v4_protocol = {
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 62428ff137d..87c98fb86fa 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1107,6 +1107,8 @@ static struct timewait_sock_ops dccp6_timewait_sock_ops = {
.twsk_obj_size = sizeof(struct dccp6_timewait_sock),
};
+DEFINE_PROTO_INUSE(dccp_v6)
+
static struct proto dccp_v6_prot = {
.name = "DCCPv6",
.owner = THIS_MODULE,
@@ -1135,6 +1137,7 @@ static struct proto dccp_v6_prot = {
.compat_setsockopt = compat_dccp_setsockopt,
.compat_getsockopt = compat_dccp_getsockopt,
#endif
+ REF_PROTO_INUSE(dccp_v6)
};
static struct inet6_protocol dccp_v6_protocol = {
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index d8497392803..7a3bea9c28c 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1072,11 +1072,13 @@ static int __init dccp_init(void)
}
for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
- rwlock_init(&dccp_hashinfo.ehash[i].lock);
INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain);
INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain);
}
+ if (inet_ehash_locks_alloc(&dccp_hashinfo))
+ goto out_free_dccp_ehash;
+
bhash_order = ehash_order;
do {
@@ -1091,7 +1093,7 @@ static int __init dccp_init(void)
if (!dccp_hashinfo.bhash) {
DCCP_CRIT("Failed to allocate DCCP bind hash table");
- goto out_free_dccp_ehash;
+ goto out_free_dccp_locks;
}
for (i = 0; i < dccp_hashinfo.bhash_size; i++) {
@@ -1121,6 +1123,8 @@ out_free_dccp_mib:
out_free_dccp_bhash:
free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
dccp_hashinfo.bhash = NULL;
+out_free_dccp_locks:
+ inet_ehash_locks_free(&dccp_hashinfo);
out_free_dccp_ehash:
free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
dccp_hashinfo.ehash = NULL;
@@ -1139,6 +1143,7 @@ static void __exit dccp_fini(void)
free_pages((unsigned long)dccp_hashinfo.ehash,
get_order(dccp_hashinfo.ehash_size *
sizeof(struct inet_ehash_bucket)));
+ inet_ehash_locks_free(&dccp_hashinfo);
kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
dccp_ackvec_exit();
dccp_sysctl_exit();
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 26130afd802..66e266fb590 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -1439,7 +1439,7 @@ static const struct file_operations dn_dev_seq_fops = {
#endif /* CONFIG_PROC_FS */
-static int __initdata addr[2];
+static int addr[2];
module_param_array(addr, int, NULL, 0444);
MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 97eee5e8fbb..66663e5d7ac 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -293,9 +293,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route *
dn_rt_hash_table[hash].chain);
rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth);
- rth->u.dst.__use++;
- dst_hold(&rth->u.dst);
- rth->u.dst.lastuse = now;
+ dst_use(&rth->u.dst, now);
spin_unlock_bh(&dn_rt_hash_table[hash].lock);
dnrt_drop(rt);
@@ -308,9 +306,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route *
rcu_assign_pointer(rt->u.dst.dn_next, dn_rt_hash_table[hash].chain);
rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt);
- dst_hold(&rt->u.dst);
- rt->u.dst.__use++;
- rt->u.dst.lastuse = now;
+ dst_use(&rt->u.dst, now);
spin_unlock_bh(&dn_rt_hash_table[hash].lock);
*rp = rt;
return 0;
@@ -1182,9 +1178,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl
(flp->mark == rt->fl.mark) &&
(rt->fl.iif == 0) &&
(rt->fl.oif == flp->oif)) {
- rt->u.dst.lastuse = jiffies;
- dst_hold(&rt->u.dst);
- rt->u.dst.__use++;
+ dst_use(&rt->u.dst, jiffies);
rcu_read_unlock_bh();
*pprt = &rt->u.dst;
return 0;
@@ -1456,9 +1450,7 @@ int dn_route_input(struct sk_buff *skb)
(rt->fl.oif == 0) &&
(rt->fl.mark == skb->mark) &&
(rt->fl.iif == cb->iif)) {
- rt->u.dst.lastuse = jiffies;
- dst_hold(&rt->u.dst);
- rt->u.dst.__use++;
+ dst_use(&rt->u.dst, jiffies);
rcu_read_unlock();
skb->dst = (struct dst_entry *)rt;
return 0;
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index ddd3f04f091..ffebea04cc9 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -48,15 +48,6 @@ struct dn_fib_rule
u8 flags;
};
-static struct dn_fib_rule default_rule = {
- .common = {
- .refcnt = ATOMIC_INIT(2),
- .pref = 0x7fff,
- .table = RT_TABLE_MAIN,
- .action = FR_ACT_TO_TBL,
- },
-};
-
int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res)
{
@@ -262,8 +253,8 @@ static struct fib_rules_ops dn_fib_rules_ops = {
void __init dn_fib_rules_init(void)
{
- list_add_tail(&default_rule.common.list,
- &dn_fib_rules_ops.rules_list);
+ BUG_ON(fib_default_rule_add(&dn_fib_rules_ops, 0x7fff,
+ RT_TABLE_MAIN, 0));
fib_rules_register(&dn_fib_rules_ops);
}
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 4cce3534e40..58b22619ab1 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -25,7 +25,6 @@
#include <net/ieee80211.h>
#include <linux/crypto.h>
-#include <linux/scatterlist.h>
#include <linux/crc32.h>
MODULE_AUTHOR("Jouni Malinen");
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 866fc04c44f..3fa30c40779 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -22,7 +22,6 @@
#include <net/ieee80211.h>
#include <linux/crypto.h>
-#include <linux/scatterlist.h>
#include <linux/crc32.h>
MODULE_AUTHOR("Jouni Malinen");
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index ac36767b56e..e01b59aedc5 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -470,7 +470,7 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
{
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
struct iw_mlme *mlme = (struct iw_mlme *)extra;
- u16 reason = cpu_to_le16(mlme->reason_code);
+ u16 reason = mlme->reason_code;
struct ieee80211softmac_network *net;
int err = -EINVAL;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 60123905dbb..732d8f088b1 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -59,6 +59,13 @@ struct fib_table *ip_fib_main_table;
#define FIB_TABLE_HASHSZ 1
static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
+static void __init fib4_rules_init(void)
+{
+ ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
+ hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
+ ip_fib_main_table = fib_hash_init(RT_TABLE_MAIN);
+ hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
+}
#else
#define FIB_TABLE_HASHSZ 256
@@ -905,14 +912,8 @@ void __init ip_fib_init(void)
for (i = 0; i < FIB_TABLE_HASHSZ; i++)
INIT_HLIST_HEAD(&fib_table_hash[i]);
-#ifndef CONFIG_IP_MULTIPLE_TABLES
- ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
- hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
- ip_fib_main_table = fib_hash_init(RT_TABLE_MAIN);
- hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
-#else
+
fib4_rules_init();
-#endif
register_netdevice_notifier(&fib_netdev_notifier);
register_inetaddr_notifier(&fib_inetaddr_notifier);
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index f16839c6a72..a0ada3a8d8d 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -49,33 +49,6 @@ struct fib4_rule
#endif
};
-static struct fib4_rule default_rule = {
- .common = {
- .refcnt = ATOMIC_INIT(2),
- .pref = 0x7FFF,
- .table = RT_TABLE_DEFAULT,
- .action = FR_ACT_TO_TBL,
- },
-};
-
-static struct fib4_rule main_rule = {
- .common = {
- .refcnt = ATOMIC_INIT(2),
- .pref = 0x7FFE,
- .table = RT_TABLE_MAIN,
- .action = FR_ACT_TO_TBL,
- },
-};
-
-static struct fib4_rule local_rule = {
- .common = {
- .refcnt = ATOMIC_INIT(2),
- .table = RT_TABLE_LOCAL,
- .action = FR_ACT_TO_TBL,
- .flags = FIB_RULE_PERMANENT,
- },
-};
-
#ifdef CONFIG_NET_CLS_ROUTE
u32 fib_rules_tclass(struct fib_result *res)
{
@@ -319,11 +292,27 @@ static struct fib_rules_ops fib4_rules_ops = {
.owner = THIS_MODULE,
};
-void __init fib4_rules_init(void)
+static int __init fib_default_rules_init(void)
{
- list_add_tail(&local_rule.common.list, &fib4_rules_ops.rules_list);
- list_add_tail(&main_rule.common.list, &fib4_rules_ops.rules_list);
- list_add_tail(&default_rule.common.list, &fib4_rules_ops.rules_list);
+ int err;
+
+ err = fib_default_rule_add(&fib4_rules_ops, 0,
+ RT_TABLE_LOCAL, FIB_RULE_PERMANENT);
+ if (err < 0)
+ return err;
+ err = fib_default_rule_add(&fib4_rules_ops, 0x7FFE,
+ RT_TABLE_MAIN, 0);
+ if (err < 0)
+ return err;
+ err = fib_default_rule_add(&fib4_rules_ops, 0x7FFF,
+ RT_TABLE_DEFAULT, 0);
+ if (err < 0)
+ return err;
+ return 0;
+}
+void __init fib4_rules_init(void)
+{
+ BUG_ON(fib_default_rules_init());
fib_rules_register(&fib4_rules_ops);
}
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index dc429b6b0ba..b0170732b5e 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -747,13 +747,14 @@ skip_listen_ht:
for (i = s_i; i < hashinfo->ehash_size; i++) {
struct inet_ehash_bucket *head = &hashinfo->ehash[i];
+ rwlock_t *lock = inet_ehash_lockp(hashinfo, i);
struct sock *sk;
struct hlist_node *node;
if (i > s_i)
s_num = 0;
- read_lock_bh(&head->lock);
+ read_lock_bh(lock);
num = 0;
sk_for_each(sk, node, &head->chain) {
struct inet_sock *inet = inet_sk(sk);
@@ -769,7 +770,7 @@ skip_listen_ht:
r->id.idiag_dport)
goto next_normal;
if (inet_csk_diag_dump(sk, skb, cb) < 0) {
- read_unlock_bh(&head->lock);
+ read_unlock_bh(lock);
goto done;
}
next_normal:
@@ -791,14 +792,14 @@ next_normal:
r->id.idiag_dport)
goto next_dying;
if (inet_twsk_diag_dump(tw, skb, cb) < 0) {
- read_unlock_bh(&head->lock);
+ read_unlock_bh(lock);
goto done;
}
next_dying:
++num;
}
}
- read_unlock_bh(&head->lock);
+ read_unlock_bh(lock);
}
done:
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 16eecc7046a..67704da04fc 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -204,12 +204,13 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport);
unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+ rwlock_t *lock = inet_ehash_lockp(hinfo, hash);
struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
prefetch(head->chain.first);
- write_lock(&head->lock);
+ write_lock(lock);
/* Check TIME-WAIT sockets first. */
sk_for_each(sk2, node, &head->twchain) {
@@ -239,7 +240,7 @@ unique:
BUG_TRAP(sk_unhashed(sk));
__sk_add_node(sk, &head->chain);
sock_prot_inc_use(sk->sk_prot);
- write_unlock(&head->lock);
+ write_unlock(lock);
if (twp) {
*twp = tw;
@@ -255,7 +256,7 @@ unique:
return 0;
not_unique:
- write_unlock(&head->lock);
+ write_unlock(lock);
return -EADDRNOTAVAIL;
}
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 4e189e28f30..a60b99e0ebd 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -20,16 +20,16 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw,
struct inet_bind_hashbucket *bhead;
struct inet_bind_bucket *tb;
/* Unlink from established hashes. */
- struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, tw->tw_hash);
+ rwlock_t *lock = inet_ehash_lockp(hashinfo, tw->tw_hash);
- write_lock(&ehead->lock);
+ write_lock(lock);
if (hlist_unhashed(&tw->tw_node)) {
- write_unlock(&ehead->lock);
+ write_unlock(lock);
return;
}
__hlist_del(&tw->tw_node);
sk_node_init(&tw->tw_node);
- write_unlock(&ehead->lock);
+ write_unlock(lock);
/* Disassociate with bind bucket. */
bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_num, hashinfo->bhash_size)];
@@ -59,6 +59,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
const struct inet_sock *inet = inet_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk);
struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, sk->sk_hash);
+ rwlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
struct inet_bind_hashbucket *bhead;
/* Step 1: Put TW into bind hash. Original socket stays there too.
Note, that any socket with inet->num != 0 MUST be bound in
@@ -71,7 +72,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
inet_twsk_add_bind_node(tw, &tw->tw_tb->owners);
spin_unlock(&bhead->lock);
- write_lock(&ehead->lock);
+ write_lock(lock);
/* Step 2: Remove SK from established hash. */
if (__sk_del_node_init(sk))
@@ -81,7 +82,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
inet_twsk_add_node(tw, &ehead->twchain);
atomic_inc(&tw->tw_refcnt);
- write_unlock(&ehead->lock);
+ write_unlock(lock);
}
EXPORT_SYMBOL_GPL(__inet_twsk_hashdance);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e5f7dc2de30..fd99fbd685e 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1183,6 +1183,17 @@ error:
return err;
}
+static void ip_cork_release(struct inet_sock *inet)
+{
+ inet->cork.flags &= ~IPCORK_OPT;
+ kfree(inet->cork.opt);
+ inet->cork.opt = NULL;
+ if (inet->cork.rt) {
+ ip_rt_put(inet->cork.rt);
+ inet->cork.rt = NULL;
+ }
+}
+
/*
* Combined all pending IP fragments on the socket as one IP datagram
* and push them out.
@@ -1276,13 +1287,7 @@ int ip_push_pending_frames(struct sock *sk)
}
out:
- inet->cork.flags &= ~IPCORK_OPT;
- kfree(inet->cork.opt);
- inet->cork.opt = NULL;
- if (inet->cork.rt) {
- ip_rt_put(inet->cork.rt);
- inet->cork.rt = NULL;
- }
+ ip_cork_release(inet);
return err;
error:
@@ -1295,19 +1300,12 @@ error:
*/
void ip_flush_pending_frames(struct sock *sk)
{
- struct inet_sock *inet = inet_sk(sk);
struct sk_buff *skb;
while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
kfree_skb(skb);
- inet->cork.flags &= ~IPCORK_OPT;
- kfree(inet->cork.opt);
- inet->cork.opt = NULL;
- if (inet->cork.rt) {
- ip_rt_put(inet->cork.rt);
- inet->cork.rt = NULL;
- }
+ ip_cork_release(inet_sk(sk));
}
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index f51f20e487c..82817e55436 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -437,10 +437,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
/* If optlen==0, it is equivalent to val == 0 */
-#ifdef CONFIG_IP_MROUTE
- if (optname >= MRT_BASE && optname <= (MRT_BASE + 10))
+ if (ip_mroute_opt(optname))
return ip_mroute_setsockopt(sk,optname,optval,optlen);
-#endif
err = 0;
lock_sock(sk);
@@ -909,11 +907,9 @@ int ip_setsockopt(struct sock *sk, int level,
#ifdef CONFIG_NETFILTER
/* we need to exclude all possible ENOPROTOOPTs except default case */
if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
- optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY
-#ifdef CONFIG_IP_MROUTE
- && (optname < MRT_BASE || optname > (MRT_BASE + 10))
-#endif
- ) {
+ optname != IP_IPSEC_POLICY &&
+ optname != IP_XFRM_POLICY &&
+ !ip_mroute_opt(optname)) {
lock_sock(sk);
err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
release_sock(sk);
@@ -935,11 +931,9 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname,
#ifdef CONFIG_NETFILTER
/* we need to exclude all possible ENOPROTOOPTs except default case */
if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
- optname != IP_IPSEC_POLICY && optname != IP_XFRM_POLICY
-#ifdef CONFIG_IP_MROUTE
- && (optname < MRT_BASE || optname > (MRT_BASE + 10))
-#endif
- ) {
+ optname != IP_IPSEC_POLICY &&
+ optname != IP_XFRM_POLICY &&
+ !ip_mroute_opt(optname)) {
lock_sock(sk);
err = compat_nf_setsockopt(sk, PF_INET, optname,
optval, optlen);
@@ -967,11 +961,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
if (level != SOL_IP)
return -EOPNOTSUPP;
-#ifdef CONFIG_IP_MROUTE
- if (optname >= MRT_BASE && optname <= MRT_BASE+10) {
+ if (ip_mroute_opt(optname))
return ip_mroute_getsockopt(sk,optname,optval,optlen);
- }
-#endif
if (get_user(len,optlen))
return -EFAULT;
@@ -1171,11 +1162,8 @@ int ip_getsockopt(struct sock *sk, int level,
err = do_ip_getsockopt(sk, level, optname, optval, optlen);
#ifdef CONFIG_NETFILTER
/* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS
-#ifdef CONFIG_IP_MROUTE
- && (optname < MRT_BASE || optname > MRT_BASE+10)
-#endif
- ) {
+ if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
+ !ip_mroute_opt(optname)) {
int len;
if (get_user(len,optlen))
@@ -1200,11 +1188,8 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
int err = do_ip_getsockopt(sk, level, optname, optval, optlen);
#ifdef CONFIG_NETFILTER
/* we need to exclude all possible ENOPROTOOPTs except default case */
- if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS
-#ifdef CONFIG_IP_MROUTE
- && (optname < MRT_BASE || optname > MRT_BASE+10)
-#endif
- ) {
+ if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
+ !ip_mroute_opt(optname)) {
int len;
if (get_user(len, optlen))
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index ca1b5fdb8d3..2c44a94c213 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <asm/semaphore.h>
#include <linux/crypto.h>
+#include <linux/err.h>
#include <linux/pfkeyv2.h>
#include <linux/percpu.h>
#include <linux/smp.h>
@@ -344,7 +345,7 @@ static struct crypto_comp **ipcomp_alloc_tfms(const char *alg_name)
for_each_possible_cpu(cpu) {
struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
CRYPTO_ALG_ASYNC);
- if (!tfm)
+ if (IS_ERR(tfm))
goto error;
*per_cpu_ptr(tfms, cpu) = tfm;
}
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 4b702f708d3..b7eeae622d9 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -426,6 +426,25 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
/*
+ * Check if there is a destination for the connection, if so
+ * bind the connection to the destination.
+ */
+struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp)
+{
+ struct ip_vs_dest *dest;
+
+ if ((cp) && (!cp->dest)) {
+ dest = ip_vs_find_dest(cp->daddr, cp->dport,
+ cp->vaddr, cp->vport, cp->protocol);
+ ip_vs_bind_dest(cp, dest);
+ return dest;
+ } else
+ return NULL;
+}
+EXPORT_SYMBOL(ip_vs_try_bind_dest);
+
+
+/*
* Unbind a connection entry with its VS destination
* Called by the ip_vs_conn_expire function.
*/
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index c6ed7654e83..20c884a5772 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -979,15 +979,23 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
ret = NF_ACCEPT;
}
- /* increase its packet counter and check if it is needed
- to be synchronized */
+ /* Increase its packet counter and check if it is needed
+ * to be synchronized
+ *
+ * Sync connection if it is about to close to
+ * encorage the standby servers to update the connections timeout
+ */
atomic_inc(&cp->in_pkts);
if ((ip_vs_sync_state & IP_VS_STATE_MASTER) &&
- (cp->protocol != IPPROTO_TCP ||
- cp->state == IP_VS_TCP_S_ESTABLISHED) &&
- (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
- == sysctl_ip_vs_sync_threshold[0]))
+ (((cp->protocol != IPPROTO_TCP ||
+ cp->state == IP_VS_TCP_S_ESTABLISHED) &&
+ (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
+ == sysctl_ip_vs_sync_threshold[0])) ||
+ ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
+ ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
+ (cp->state == IP_VS_TCP_S_CLOSE)))))
ip_vs_sync_conn(cp);
+ cp->old_state = cp->state;
ip_vs_conn_put(cp);
return ret;
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 7345fc252a2..3c4d22a468e 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -579,6 +579,32 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
return NULL;
}
+/*
+ * Find destination by {daddr,dport,vaddr,protocol}
+ * Cretaed to be used in ip_vs_process_message() in
+ * the backup synchronization daemon. It finds the
+ * destination to be bound to the received connection
+ * on the backup.
+ *
+ * ip_vs_lookup_real_service() looked promissing, but
+ * seems not working as expected.
+ */
+struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport,
+ __be32 vaddr, __be16 vport, __u16 protocol)
+{
+ struct ip_vs_dest *dest;
+ struct ip_vs_service *svc;
+
+ svc = ip_vs_service_get(0, protocol, vaddr, vport);
+ if (!svc)
+ return NULL;
+ dest = ip_vs_lookup_dest(svc, daddr, dport);
+ if (dest)
+ atomic_inc(&dest->refcnt);
+ ip_vs_service_put(svc);
+ return dest;
+}
+EXPORT_SYMBOL(ip_vs_find_dest);
/*
* Lookup dest by {svc,addr,port} in the destination trash.
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 0d4d9721cbd..bd930efc18d 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -284,6 +284,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
struct ip_vs_sync_conn_options *opt;
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp;
+ struct ip_vs_dest *dest;
char *p;
int i;
@@ -317,20 +318,34 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
s->caddr, s->cport,
s->vaddr, s->vport);
if (!cp) {
+ /*
+ * Find the appropriate destination for the connection.
+ * If it is not found the connection will remain unbound
+ * but still handled.
+ */
+ dest = ip_vs_find_dest(s->daddr, s->dport,
+ s->vaddr, s->vport,
+ s->protocol);
cp = ip_vs_conn_new(s->protocol,
s->caddr, s->cport,
s->vaddr, s->vport,
s->daddr, s->dport,
- flags, NULL);
+ flags, dest);
+ if (dest)
+ atomic_dec(&dest->refcnt);
if (!cp) {
IP_VS_ERR("ip_vs_conn_new failed\n");
return;
}
cp->state = ntohs(s->state);
} else if (!cp->dest) {
- /* it is an entry created by the synchronization */
- cp->state = ntohs(s->state);
- cp->flags = flags | IP_VS_CONN_F_HASHED;
+ dest = ip_vs_try_bind_dest(cp);
+ if (!dest) {
+ /* it is an unbound entry created by
+ * synchronization */
+ cp->flags = flags | IP_VS_CONN_F_HASHED;
+ } else
+ atomic_dec(&dest->refcnt);
} /* Note that we don't touch its state and flags
if it is a normal entry. */
@@ -342,6 +357,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
p += SIMPLE_CONN_SIZE;
atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
+ cp->state = ntohs(s->state);
pp = ip_vs_proto_get(s->protocol);
cp->timeout = pp->timeout_table[cp->state];
ip_vs_conn_put(cp);
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 409d273f6f8..7456833d6ad 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -41,27 +41,27 @@ obj-$(CONFIG_NF_NAT) += iptable_nat.o
obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
# matches
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
+obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
+obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
-obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
-obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
-obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
+obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
-obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
# targets
-obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
-obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
+obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
+obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
-obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
+obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
+obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
-obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
-obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
-obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
+obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
+obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
# generic ARP tables
obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 10a2ce09fd8..14d64a383db 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -22,6 +22,7 @@
#include <linux/spinlock.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/security.h>
#include <linux/mutex.h>
#include <net/net_namespace.h>
@@ -607,15 +608,11 @@ static ctl_table ipq_root_table[] = {
{ .ctl_name = 0 }
};
-#ifdef CONFIG_PROC_FS
-static int
-ipq_get_info(char *buffer, char **start, off_t offset, int length)
+static int ip_queue_show(struct seq_file *m, void *v)
{
- int len;
-
read_lock_bh(&queue_lock);
- len = sprintf(buffer,
+ seq_printf(m,
"Peer PID : %d\n"
"Copy mode : %hu\n"
"Copy range : %u\n"
@@ -632,16 +629,21 @@ ipq_get_info(char *buffer, char **start, off_t offset, int length)
queue_user_dropped);
read_unlock_bh(&queue_lock);
+ return 0;
+}
- *start = buffer + offset;
- len -= offset;
- if (len > length)
- len = length;
- else if (len < 0)
- len = 0;
- return len;
+static int ip_queue_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ip_queue_show, NULL);
}
-#endif /* CONFIG_PROC_FS */
+
+static const struct file_operations ip_queue_proc_fops = {
+ .open = ip_queue_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
static struct nf_queue_handler nfqh = {
.name = "ip_queue",
@@ -661,10 +663,11 @@ static int __init ip_queue_init(void)
goto cleanup_netlink_notifier;
}
- proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info);
- if (proc)
+ proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
+ if (proc) {
proc->owner = THIS_MODULE;
- else {
+ proc->proc_fops = &ip_queue_proc_fops;
+ } else {
printk(KERN_ERR "ip_queue: failed to create proc entry\n");
goto cleanup_ipqnl;
}
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c
index 35a5aa69cd9..c31b8766825 100644
--- a/net/ipv4/netfilter/nf_nat_amanda.c
+++ b/net/ipv4/netfilter/nf_nat_amanda.c
@@ -69,7 +69,7 @@ static void __exit nf_nat_amanda_fini(void)
static int __init nf_nat_amanda_init(void)
{
- BUG_ON(rcu_dereference(nf_nat_amanda_hook));
+ BUG_ON(nf_nat_amanda_hook != NULL);
rcu_assign_pointer(nf_nat_amanda_hook, help);
return 0;
}
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c
index e1a16d3ea4c..a1d5d58a58b 100644
--- a/net/ipv4/netfilter/nf_nat_ftp.c
+++ b/net/ipv4/netfilter/nf_nat_ftp.c
@@ -147,7 +147,7 @@ static void __exit nf_nat_ftp_fini(void)
static int __init nf_nat_ftp_init(void)
{
- BUG_ON(rcu_dereference(nf_nat_ftp_hook));
+ BUG_ON(nf_nat_ftp_hook != NULL);
rcu_assign_pointer(nf_nat_ftp_hook, nf_nat_ftp);
return 0;
}
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index a868c8c4132..93e18ef114f 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -544,15 +544,15 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
/****************************************************************************/
static int __init init(void)
{
- BUG_ON(rcu_dereference(set_h245_addr_hook) != NULL);
- BUG_ON(rcu_dereference(set_h225_addr_hook) != NULL);
- BUG_ON(rcu_dereference(set_sig_addr_hook) != NULL);
- BUG_ON(rcu_dereference(set_ras_addr_hook) != NULL);
- BUG_ON(rcu_dereference(nat_rtp_rtcp_hook) != NULL);
- BUG_ON(rcu_dereference(nat_t120_hook) != NULL);
- BUG_ON(rcu_dereference(nat_h245_hook) != NULL);
- BUG_ON(rcu_dereference(nat_callforwarding_hook) != NULL);
- BUG_ON(rcu_dereference(nat_q931_hook) != NULL);
+ BUG_ON(set_h245_addr_hook != NULL);
+ BUG_ON(set_h225_addr_hook != NULL);
+ BUG_ON(set_sig_addr_hook != NULL);
+ BUG_ON(set_ras_addr_hook != NULL);
+ BUG_ON(nat_rtp_rtcp_hook != NULL);
+ BUG_ON(nat_t120_hook != NULL);
+ BUG_ON(nat_h245_hook != NULL);
+ BUG_ON(nat_callforwarding_hook != NULL);
+ BUG_ON(nat_q931_hook != NULL);
rcu_assign_pointer(set_h245_addr_hook, set_h245_addr);
rcu_assign_pointer(set_h225_addr_hook, set_h225_addr);
diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c
index 766e2c16c6b..fe6f9cef6c8 100644
--- a/net/ipv4/netfilter/nf_nat_irc.c
+++ b/net/ipv4/netfilter/nf_nat_irc.c
@@ -74,7 +74,7 @@ static void __exit nf_nat_irc_fini(void)
static int __init nf_nat_irc_init(void)
{
- BUG_ON(rcu_dereference(nf_nat_irc_hook));
+ BUG_ON(nf_nat_irc_hook != NULL);
rcu_assign_pointer(nf_nat_irc_hook, help);
return 0;
}
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index e1385a09907..6817e7995f3 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -281,16 +281,16 @@ static int __init nf_nat_helper_pptp_init(void)
{
nf_nat_need_gre();
- BUG_ON(rcu_dereference(nf_nat_pptp_hook_outbound));
+ BUG_ON(nf_nat_pptp_hook_outbound != NULL);
rcu_assign_pointer(nf_nat_pptp_hook_outbound, pptp_outbound_pkt);
- BUG_ON(rcu_dereference(nf_nat_pptp_hook_inbound));
+ BUG_ON(nf_nat_pptp_hook_inbound != NULL);
rcu_assign_pointer(nf_nat_pptp_hook_inbound, pptp_inbound_pkt);
- BUG_ON(rcu_dereference(nf_nat_pptp_hook_exp_gre));
+ BUG_ON(nf_nat_pptp_hook_exp_gre != NULL);
rcu_assign_pointer(nf_nat_pptp_hook_exp_gre, pptp_exp_gre);
- BUG_ON(rcu_dereference(nf_nat_pptp_hook_expectfn));
+ BUG_ON(nf_nat_pptp_hook_expectfn != NULL);
rcu_assign_pointer(nf_nat_pptp_hook_expectfn, pptp_nat_expected);
return 0;
}
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index ce9edbcc01e..3ca98971a1e 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -293,8 +293,8 @@ static void __exit nf_nat_sip_fini(void)
static int __init nf_nat_sip_init(void)
{
- BUG_ON(rcu_dereference(nf_nat_sip_hook));
- BUG_ON(rcu_dereference(nf_nat_sdp_hook));
+ BUG_ON(nf_nat_sip_hook != NULL);
+ BUG_ON(nf_nat_sdp_hook != NULL);
rcu_assign_pointer(nf_nat_sip_hook, ip_nat_sip);
rcu_assign_pointer(nf_nat_sdp_hook, ip_nat_sdp);
return 0;
diff --git a/net/ipv4/netfilter/nf_nat_tftp.c b/net/ipv4/netfilter/nf_nat_tftp.c
index 0ecec701cb4..1360a94766d 100644
--- a/net/ipv4/netfilter/nf_nat_tftp.c
+++ b/net/ipv4/netfilter/nf_nat_tftp.c
@@ -43,7 +43,7 @@ static void __exit nf_nat_tftp_fini(void)
static int __init nf_nat_tftp_init(void)
{
- BUG_ON(rcu_dereference(nf_nat_tftp_hook));
+ BUG_ON(nf_nat_tftp_hook != NULL);
rcu_assign_pointer(nf_nat_tftp_hook, help);
return 0;
}
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index ffdccc0972e..ce34b281803 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -46,17 +46,6 @@
#include <net/sock.h>
#include <net/raw.h>
-static int fold_prot_inuse(struct proto *proto)
-{
- int res = 0;
- int cpu;
-
- for_each_possible_cpu(cpu)
- res += proto->stats[cpu].inuse;
-
- return res;
-}
-
/*
* Report socket allocation statistics [mea@utu.fi]
*/
@@ -64,12 +53,12 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
{
socket_seq_show(seq);
seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n",
- fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
+ sock_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated),
atomic_read(&tcp_memory_allocated));
- seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
- seq_printf(seq, "UDPLITE: inuse %d\n", fold_prot_inuse(&udplite_prot));
- seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
+ seq_printf(seq, "UDP: inuse %d\n", sock_prot_inuse(&udp_prot));
+ seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse(&udplite_prot));
+ seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse(&raw_prot));
seq_printf(seq, "FRAG: inuse %d memory %d\n",
ip_frag_nqueues(), ip_frag_mem());
return 0;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 3916faca3af..66b42f547bf 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -760,6 +760,8 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
}
}
+DEFINE_PROTO_INUSE(raw)
+
struct proto raw_prot = {
.name = "RAW",
.owner = THIS_MODULE,
@@ -781,6 +783,7 @@ struct proto raw_prot = {
.compat_setsockopt = compat_raw_setsockopt,
.compat_getsockopt = compat_raw_getsockopt,
#endif
+ REF_PROTO_INUSE(raw)
};
#ifdef CONFIG_PROC_FS
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 21b12de9e65..45651834e1e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -851,9 +851,7 @@ restart:
*/
rcu_assign_pointer(rt_hash_table[hash].chain, rth);
- rth->u.dst.__use++;
- dst_hold(&rth->u.dst);
- rth->u.dst.lastuse = now;
+ dst_use(&rth->u.dst, now);
spin_unlock_bh(rt_hash_lock_addr(hash));
rt_drop(rt);
@@ -1813,11 +1811,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
goto martian_destination;
err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos);
- if (err == -ENOBUFS)
- goto e_nobufs;
- if (err == -EINVAL)
- goto e_inval;
-
done:
in_dev_put(in_dev);
if (free_res)
@@ -1935,9 +1928,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rth->fl.oif == 0 &&
rth->fl.mark == skb->mark &&
rth->fl.fl4_tos == tos) {
- rth->u.dst.lastuse = jiffies;
- dst_hold(&rth->u.dst);
- rth->u.dst.__use++;
+ dst_use(&rth->u.dst, jiffies);
RT_CACHE_STAT_INC(in_hit);
rcu_read_unlock();
skb->dst = (struct dst_entry*)rth;
@@ -2331,9 +2322,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
rth->fl.mark == flp->mark &&
!((rth->fl.fl4_tos ^ flp->fl4_tos) &
(IPTOS_RT_MASK | RTO_ONLINK))) {
- rth->u.dst.lastuse = jiffies;
- dst_hold(&rth->u.dst);
- rth->u.dst.__use++;
+ dst_use(&rth->u.dst, jiffies);
RT_CACHE_STAT_INC(out_hit);
rcu_read_unlock_bh();
*rp = rth;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index c64072bb504..8e65182f7af 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2456,11 +2456,11 @@ void __init tcp_init(void)
thash_entries ? 0 : 512 * 1024);
tcp_hashinfo.ehash_size = 1 << tcp_hashinfo.ehash_size;
for (i = 0; i < tcp_hashinfo.ehash_size; i++) {
- rwlock_init(&tcp_hashinfo.ehash[i].lock);
INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].chain);
INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].twchain);
}
-
+ if (inet_ehash_locks_alloc(&tcp_hashinfo))
+ panic("TCP: failed to alloc ehash_locks");
tcp_hashinfo.bhash =
alloc_large_system_hash("TCP bind",
sizeof(struct inet_bind_hashbucket),
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index ca9590f4f52..20c9440ab85 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1400,11 +1400,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
/* DSACK info lost if out-of-mem, try SACK still */
if (in_sack <= 0)
in_sack = tcp_match_skb_to_sack(sk, skb, start_seq, end_seq);
- if (in_sack < 0)
+ if (unlikely(in_sack < 0))
break;
- fack_count += tcp_skb_pcount(skb);
-
sacked = TCP_SKB_CB(skb)->sacked;
/* Account D-SACK for retransmitted packet. */
@@ -1419,19 +1417,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
if ((dup_sack && in_sack) &&
(sacked&TCPCB_SACKED_ACKED))
reord = min(fack_count, reord);
- } else {
- /* If it was in a hole, we detected reordering. */
- if (fack_count < prior_fackets &&
- !(sacked&TCPCB_SACKED_ACKED))
- reord = min(fack_count, reord);
}
/* Nothing to do; acked frame is about to be dropped. */
+ fack_count += tcp_skb_pcount(skb);
continue;
}
- if (!in_sack)
+ if (!in_sack) {
+ fack_count += tcp_skb_pcount(skb);
continue;
+ }
if (!(sacked&TCPCB_SACKED_ACKED)) {
if (sacked & TCPCB_SACKED_RETRANS) {
@@ -1448,12 +1444,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
tp->retransmit_skb_hint = NULL;
}
} else {
- /* New sack for not retransmitted frame,
- * which was in hole. It is reordering.
- */
- if (!(sacked & TCPCB_RETRANS) &&
- fack_count < prior_fackets)
- reord = min(fack_count, reord);
+ if (!(sacked & TCPCB_RETRANS)) {
+ /* New sack for not retransmitted frame,
+ * which was in hole. It is reordering.
+ */
+ if (fack_count < prior_fackets)
+ reord = min(fack_count, reord);
+
+ /* SACK enhanced F-RTO (RFC4138; Appendix B) */
+ if (!after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark))
+ flag |= FLAG_ONLY_ORIG_SACKED;
+ }
if (sacked & TCPCB_LOST) {
TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
@@ -1462,24 +1463,13 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
/* clear lost hint */
tp->retransmit_skb_hint = NULL;
}
- /* SACK enhanced F-RTO detection.
- * Set flag if and only if non-rexmitted
- * segments below frto_highmark are
- * SACKed (RFC4138; Appendix B).
- * Clearing correct due to in-order walk
- */
- if (after(end_seq, tp->frto_highmark)) {
- flag &= ~FLAG_ONLY_ORIG_SACKED;
- } else {
- if (!(sacked & TCPCB_RETRANS))
- flag |= FLAG_ONLY_ORIG_SACKED;
- }
}
TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED;
flag |= FLAG_DATA_SACKED;
tp->sacked_out += tcp_skb_pcount(skb);
+ fack_count += tcp_skb_pcount(skb);
if (fack_count > tp->fackets_out)
tp->fackets_out = fack_count;
@@ -1490,6 +1480,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
} else {
if (dup_sack && (sacked&TCPCB_RETRANS))
reord = min(fack_count, reord);
+
+ fack_count += tcp_skb_pcount(skb);
}
/* D-SACK. We can detect redundant retransmission
@@ -1504,6 +1496,12 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
tp->retransmit_skb_hint = NULL;
}
}
+
+ /* SACK enhanced FRTO (RFC4138, Appendix B): Clearing correct
+ * due to in-order walk
+ */
+ if (after(end_seq, tp->frto_highmark))
+ flag &= ~FLAG_ONLY_ORIG_SACKED;
}
if (tp->retrans_out &&
@@ -1515,7 +1513,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss &&
(!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark)))
- tcp_update_reordering(sk, ((tp->fackets_out + 1) - reord), 0);
+ tcp_update_reordering(sk, tp->fackets_out - reord, 0);
#if FASTRETRANS_DEBUG > 0
BUG_TRAP((int)tp->sacked_out >= 0);
@@ -2630,7 +2628,8 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
* is before the ack sequence we can discard it as it's confirmed to have
* arrived at the other end.
*/
-static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
+static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
+ int prior_fackets)
{
struct tcp_sock *tp = tcp_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2639,6 +2638,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
int fully_acked = 1;
int flag = 0;
int prior_packets = tp->packets_out;
+ u32 cnt = 0;
+ u32 reord = tp->packets_out;
s32 seq_rtt = -1;
ktime_t last_ackt = net_invalid_timestamp();
@@ -2679,10 +2680,14 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
if ((flag & FLAG_DATA_ACKED) ||
(packets_acked > 1))
flag |= FLAG_NONHEAD_RETRANS_ACKED;
- } else if (seq_rtt < 0) {
- seq_rtt = now - scb->when;
- if (fully_acked)
- last_ackt = skb->tstamp;
+ } else {
+ if (seq_rtt < 0) {
+ seq_rtt = now - scb->when;
+ if (fully_acked)
+ last_ackt = skb->tstamp;
+ }
+ if (!(sacked & TCPCB_SACKED_ACKED))
+ reord = min(cnt, reord);
}
if (sacked & TCPCB_SACKED_ACKED)
@@ -2693,12 +2698,16 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
if ((sacked & TCPCB_URG) && tp->urg_mode &&
!before(end_seq, tp->snd_up))
tp->urg_mode = 0;
- } else if (seq_rtt < 0) {
- seq_rtt = now - scb->when;
- if (fully_acked)
- last_ackt = skb->tstamp;
+ } else {
+ if (seq_rtt < 0) {
+ seq_rtt = now - scb->when;
+ if (fully_acked)
+ last_ackt = skb->tstamp;
+ }
+ reord = min(cnt, reord);
}
tp->packets_out -= packets_acked;
+ cnt += packets_acked;
/* Initial outgoing SYN's get put onto the write_queue
* just like anything else we transmit. It is not
@@ -2730,13 +2739,18 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p)
tcp_ack_update_rtt(sk, flag, seq_rtt);
tcp_rearm_rto(sk);
+ if (tcp_is_reno(tp)) {
+ tcp_remove_reno_sacks(sk, pkts_acked);
+ } else {
+ /* Non-retransmitted hole got filled? That's reordering */
+ if (reord < prior_fackets)
+ tcp_update_reordering(sk, tp->fackets_out - reord, 0);
+ }
+
tp->fackets_out -= min(pkts_acked, tp->fackets_out);
/* hint's skb might be NULL but we don't need to care */
tp->fastpath_cnt_hint -= min_t(u32, pkts_acked,
tp->fastpath_cnt_hint);
- if (tcp_is_reno(tp))
- tcp_remove_reno_sacks(sk, pkts_acked);
-
if (ca_ops->pkts_acked) {
s32 rtt_us = -1;
@@ -3019,6 +3033,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
u32 ack_seq = TCP_SKB_CB(skb)->seq;
u32 ack = TCP_SKB_CB(skb)->ack_seq;
u32 prior_in_flight;
+ u32 prior_fackets;
s32 seq_rtt;
int prior_packets;
int frto_cwnd = 0;
@@ -3043,6 +3058,8 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache);
}
+ prior_fackets = tp->fackets_out;
+
if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
/* Window is constant, pure forward advance.
* No more checks are required.
@@ -3084,7 +3101,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
prior_in_flight = tcp_packets_in_flight(tp);
/* See if we can take anything off of the retransmit queue. */
- flag |= tcp_clean_rtx_queue(sk, &seq_rtt);
+ flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets);
/* Guarantee sacktag reordering detection against wrap-arounds */
if (before(tp->frto_highmark, tp->snd_una))
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d438dfb0c8f..e566f3c6767 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2049,8 +2049,9 @@ static void *established_get_first(struct seq_file *seq)
struct sock *sk;
struct hlist_node *node;
struct inet_timewait_sock *tw;
+ rwlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, st->bucket);
- read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+ read_lock_bh(lock);
sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
if (sk->sk_family != st->family) {
continue;
@@ -2067,7 +2068,7 @@ static void *established_get_first(struct seq_file *seq)
rc = tw;
goto out;
}
- read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+ read_unlock_bh(lock);
st->state = TCP_SEQ_STATE_ESTABLISHED;
}
out:
@@ -2094,11 +2095,11 @@ get_tw:
cur = tw;
goto out;
}
- read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+ read_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
st->state = TCP_SEQ_STATE_ESTABLISHED;
if (++st->bucket < tcp_hashinfo.ehash_size) {
- read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+ read_lock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
} else {
cur = NULL;
@@ -2206,7 +2207,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v)
case TCP_SEQ_STATE_TIME_WAIT:
case TCP_SEQ_STATE_ESTABLISHED:
if (v)
- read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
+ read_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
break;
}
}
@@ -2417,6 +2418,8 @@ void tcp4_proc_exit(void)
}
#endif /* CONFIG_PROC_FS */
+DEFINE_PROTO_INUSE(tcp)
+
struct proto tcp_prot = {
.name = "TCP",
.owner = THIS_MODULE,
@@ -2451,6 +2454,7 @@ struct proto tcp_prot = {
.compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt,
#endif
+ REF_PROTO_INUSE(tcp)
};
void __init tcp_v4_init(struct net_proto_family *ops)
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c
index a794a8ca8b4..978b3fd61e6 100644
--- a/net/ipv4/tunnel4.c
+++ b/net/ipv4/tunnel4.c
@@ -17,6 +17,11 @@ static struct xfrm_tunnel *tunnel4_handlers;
static struct xfrm_tunnel *tunnel64_handlers;
static DEFINE_MUTEX(tunnel4_mutex);
+static inline struct xfrm_tunnel **fam_handlers(unsigned short family)
+{
+ return (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
+}
+
int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family)
{
struct xfrm_tunnel **pprev;
@@ -25,8 +30,7 @@ int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family)
mutex_lock(&tunnel4_mutex);
- for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
- *pprev; pprev = &(*pprev)->next) {
+ for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) {
if ((*pprev)->priority > priority)
break;
if ((*pprev)->priority == priority)
@@ -53,8 +57,7 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family)
mutex_lock(&tunnel4_mutex);
- for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
- *pprev; pprev = &(*pprev)->next) {
+ for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) {
if (*pprev == handler) {
*pprev = handler->next;
ret = 0;
@@ -118,6 +121,17 @@ static void tunnel4_err(struct sk_buff *skb, u32 info)
break;
}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static void tunnel64_err(struct sk_buff *skb, u32 info)
+{
+ struct xfrm_tunnel *handler;
+
+ for (handler = tunnel64_handlers; handler; handler = handler->next)
+ if (!handler->err_handler(skb, info))
+ break;
+}
+#endif
+
static struct net_protocol tunnel4_protocol = {
.handler = tunnel4_rcv,
.err_handler = tunnel4_err,
@@ -127,7 +141,7 @@ static struct net_protocol tunnel4_protocol = {
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static struct net_protocol tunnel64_protocol = {
.handler = tunnel64_rcv,
- .err_handler = tunnel4_err,
+ .err_handler = tunnel64_err,
.no_policy = 1,
};
#endif
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 4bc25b46f33..03c400ca14c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1430,6 +1430,8 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
}
+DEFINE_PROTO_INUSE(udp)
+
struct proto udp_prot = {
.name = "UDP",
.owner = THIS_MODULE,
@@ -1452,6 +1454,7 @@ struct proto udp_prot = {
.compat_setsockopt = compat_udp_setsockopt,
.compat_getsockopt = compat_udp_getsockopt,
#endif
+ REF_PROTO_INUSE(udp)
};
/* ------------------------------------------------------------------------ */
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index 94977205abb..f5baeb3e8b8 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -44,6 +44,8 @@ static struct net_protocol udplite_protocol = {
.no_policy = 1,
};
+DEFINE_PROTO_INUSE(udplite)
+
struct proto udplite_prot = {
.name = "UDP-Lite",
.owner = THIS_MODULE,
@@ -67,6 +69,7 @@ struct proto udplite_prot = {
.compat_setsockopt = compat_udp_setsockopt,
.compat_getsockopt = compat_udp_getsockopt,
#endif
+ REF_PROTO_INUSE(udplite)
};
static struct inet_protosw udplite4_protosw = {
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 706622af206..428c6b0e26d 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -31,25 +31,6 @@ struct fib6_rule
static struct fib_rules_ops fib6_rules_ops;
-static struct fib6_rule main_rule = {
- .common = {
- .refcnt = ATOMIC_INIT(2),
- .pref = 0x7FFE,
- .action = FR_ACT_TO_TBL,
- .table = RT6_TABLE_MAIN,
- },
-};
-
-static struct fib6_rule local_rule = {
- .common = {
- .refcnt = ATOMIC_INIT(2),
- .pref = 0,
- .action = FR_ACT_TO_TBL,
- .table = RT6_TABLE_LOCAL,
- .flags = FIB_RULE_PERMANENT,
- },
-};
-
struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
pol_lookup_t lookup)
{
@@ -270,11 +251,23 @@ static struct fib_rules_ops fib6_rules_ops = {
.owner = THIS_MODULE,
};
-void __init fib6_rules_init(void)
+static int __init fib6_default_rules_init(void)
{
- list_add_tail(&local_rule.common.list, &fib6_rules_ops.rules_list);
- list_add_tail(&main_rule.common.list, &fib6_rules_ops.rules_list);
+ int err;
+
+ err = fib_default_rule_add(&fib6_rules_ops, 0,
+ RT6_TABLE_LOCAL, FIB_RULE_PERMANENT);
+ if (err < 0)
+ return err;
+ err = fib_default_rule_add(&fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0);
+ if (err < 0)
+ return err;
+ return 0;
+}
+void __init fib6_rules_init(void)
+{
+ BUG_ON(fib6_default_rules_init());
fib_rules_register(&fib6_rules_ops);
}
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index d6f1026f194..adc73adadfa 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -37,9 +37,8 @@ void __inet6_hash(struct inet_hashinfo *hashinfo,
} else {
unsigned int hash;
sk->sk_hash = hash = inet6_sk_ehashfn(sk);
- hash &= (hashinfo->ehash_size - 1);
- list = &hashinfo->ehash[hash].chain;
- lock = &hashinfo->ehash[hash].lock;
+ list = &inet_ehash_bucket(hashinfo, hash)->chain;
+ lock = inet_ehash_lockp(hashinfo, hash);
write_lock(lock);
}
@@ -70,9 +69,10 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
*/
unsigned int hash = inet6_ehashfn(daddr, hnum, saddr, sport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+ rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
prefetch(head->chain.first);
- read_lock(&head->lock);
+ read_lock(lock);
sk_for_each(sk, node, &head->chain) {
/* For IPV6 do the cheaper port and family tests first. */
if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif))
@@ -92,12 +92,12 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
goto hit;
}
}
- read_unlock(&head->lock);
+ read_unlock(lock);
return NULL;
hit:
sock_hold(sk);
- read_unlock(&head->lock);
+ read_unlock(lock);
return sk;
}
EXPORT_SYMBOL(__inet6_lookup_established);
@@ -175,12 +175,13 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
const unsigned int hash = inet6_ehashfn(daddr, lport, saddr,
inet->dport);
struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+ rwlock_t *lock = inet_ehash_lockp(hinfo, hash);
struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
prefetch(head->chain.first);
- write_lock(&head->lock);
+ write_lock(lock);
/* Check TIME-WAIT sockets first. */
sk_for_each(sk2, node, &head->twchain) {
@@ -216,7 +217,7 @@ unique:
__sk_add_node(sk, &head->chain);
sk->sk_hash = hash;
sock_prot_inc_use(sk->sk_prot);
- write_unlock(&head->lock);
+ write_unlock(lock);
if (twp != NULL) {
*twp = tw;
@@ -231,7 +232,7 @@ unique:
return 0;
not_unique:
- write_unlock(&head->lock);
+ write_unlock(lock);
return -EADDRNOTAVAIL;
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 653fc0a8235..86e1835ce4e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1339,6 +1339,19 @@ error:
return err;
}
+static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
+{
+ inet->cork.flags &= ~IPCORK_OPT;
+ kfree(np->cork.opt);
+ np->cork.opt = NULL;
+ if (np->cork.rt) {
+ dst_release(&np->cork.rt->u.dst);
+ np->cork.rt = NULL;
+ inet->cork.flags &= ~IPCORK_ALLFRAG;
+ }
+ memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
+}
+
int ip6_push_pending_frames(struct sock *sk)
{
struct sk_buff *skb, *tmp_skb;
@@ -1415,15 +1428,7 @@ int ip6_push_pending_frames(struct sock *sk)
}
out:
- inet->cork.flags &= ~IPCORK_OPT;
- kfree(np->cork.opt);
- np->cork.opt = NULL;
- if (np->cork.rt) {
- dst_release(&np->cork.rt->u.dst);
- np->cork.rt = NULL;
- inet->cork.flags &= ~IPCORK_ALLFRAG;
- }
- memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
+ ip6_cork_release(inet, np);
return err;
error:
goto out;
@@ -1431,8 +1436,6 @@ error:
void ip6_flush_pending_frames(struct sock *sk)
{
- struct inet_sock *inet = inet_sk(sk);
- struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff *skb;
while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
@@ -1442,14 +1445,5 @@ void ip6_flush_pending_frames(struct sock *sk)
kfree_skb(skb);
}
- inet->cork.flags &= ~IPCORK_OPT;
-
- kfree(np->cork.opt);
- np->cork.opt = NULL;
- if (np->cork.rt) {
- dst_release(&np->cork.rt->u.dst);
- np->cork.rt = NULL;
- inet->cork.flags &= ~IPCORK_ALLFRAG;
- }
- memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
+ ip6_cork_release(inet_sk(sk), inet6_sk(sk));
}
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 85eb4798d8d..0cd4056f912 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -36,6 +36,7 @@
#include <net/ipcomp.h>
#include <asm/semaphore.h>
#include <linux/crypto.h>
+#include <linux/err.h>
#include <linux/pfkeyv2.h>
#include <linux/random.h>
#include <linux/percpu.h>
@@ -358,7 +359,7 @@ static struct crypto_comp **ipcomp6_alloc_tfms(const char *alg_name)
for_each_possible_cpu(cpu) {
struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
CRYPTO_ALG_ASYNC);
- if (!tfm)
+ if (IS_ERR(tfm))
goto error;
*per_cpu_ptr(tfms, cpu) = tfm;
}
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 4513eab7739..e789ec44d23 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -4,25 +4,29 @@
# Link order matters here.
obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
-obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
-obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o
-obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
-obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
-obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
-obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
-obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
-obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
-obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
-obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
-obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
-obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
# objects for l3 independent conntrack
nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o
# l3 independent conntrack
obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o
+
+# matches
+obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o
+obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
+obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
+obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
+obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
+obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
+obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o
+obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
+obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
+
+# targets
+obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o
+obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
+obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 6413a30d9f6..e273605eef8 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -23,6 +23,7 @@
#include <linux/spinlock.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/mutex.h>
#include <net/net_namespace.h>
#include <net/sock.h>
@@ -596,15 +597,11 @@ static ctl_table ipq_root_table[] = {
{ .ctl_name = 0 }
};
-#ifdef CONFIG_PROC_FS
-static int
-ipq_get_info(char *buffer, char **start, off_t offset, int length)
+static int ip6_queue_show(struct seq_file *m, void *v)
{
- int len;
-
read_lock_bh(&queue_lock);
- len = sprintf(buffer,
+ seq_printf(m,
"Peer PID : %d\n"
"Copy mode : %hu\n"
"Copy range : %u\n"
@@ -621,16 +618,21 @@ ipq_get_info(char *buffer, char **start, off_t offset, int length)
queue_user_dropped);
read_unlock_bh(&queue_lock);
+ return 0;
+}
- *start = buffer + offset;
- len -= offset;
- if (len > length)
- len = length;
- else if (len < 0)
- len = 0;
- return len;
+static int ip6_queue_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ip6_queue_show, NULL);
}
-#endif /* CONFIG_PROC_FS */
+
+static const struct file_operations ip6_queue_proc_fops = {
+ .open = ip6_queue_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
static struct nf_queue_handler nfqh = {
.name = "ip6_queue",
@@ -650,10 +652,11 @@ static int __init ip6_queue_init(void)
goto cleanup_netlink_notifier;
}
- proc = proc_net_create(&init_net, IPQ_PROC_FS_NAME, 0, ipq_get_info);
- if (proc)
+ proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net);
+ if (proc) {
proc->owner = THIS_MODULE;
- else {
+ proc->proc_fops = &ip6_queue_proc_fops;
+ } else {
printk(KERN_ERR "ip6_queue: failed to create proc entry\n");
goto cleanup_ipqnl;
}
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index be526ad9254..8631ed7fe8a 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -32,27 +32,16 @@
static struct proc_dir_entry *proc_net_devsnmp6;
-static int fold_prot_inuse(struct proto *proto)
-{
- int res = 0;
- int cpu;
-
- for_each_possible_cpu(cpu)
- res += proto->stats[cpu].inuse;
-
- return res;
-}
-
static int sockstat6_seq_show(struct seq_file *seq, void *v)
{
seq_printf(seq, "TCP6: inuse %d\n",
- fold_prot_inuse(&tcpv6_prot));
+ sock_prot_inuse(&tcpv6_prot));
seq_printf(seq, "UDP6: inuse %d\n",
- fold_prot_inuse(&udpv6_prot));
+ sock_prot_inuse(&udpv6_prot));
seq_printf(seq, "UDPLITE6: inuse %d\n",
- fold_prot_inuse(&udplitev6_prot));
+ sock_prot_inuse(&udplitev6_prot));
seq_printf(seq, "RAW6: inuse %d\n",
- fold_prot_inuse(&rawv6_prot));
+ sock_prot_inuse(&rawv6_prot));
seq_printf(seq, "FRAG6: inuse %d memory %d\n",
ip6_frag_nqueues(), ip6_frag_mem());
return 0;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ca24ef19cd8..807260d0358 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1144,6 +1144,8 @@ static int rawv6_init_sk(struct sock *sk)
return(0);
}
+DEFINE_PROTO_INUSE(rawv6)
+
struct proto rawv6_prot = {
.name = "RAWv6",
.owner = THIS_MODULE,
@@ -1166,6 +1168,7 @@ struct proto rawv6_prot = {
.compat_setsockopt = compat_rawv6_setsockopt,
.compat_getsockopt = compat_rawv6_getsockopt,
#endif
+ REF_PROTO_INUSE(rawv6)
};
#ifdef CONFIG_PROC_FS
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 95f8e4a62f6..6ecb5e6fae2 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -38,12 +38,8 @@
#include <linux/in6.h>
#include <linux/init.h>
#include <linux/if_arp.h>
-
-#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#endif
-
#include <net/net_namespace.h>
#include <net/snmp.h>
#include <net/ipv6.h>
@@ -548,12 +544,8 @@ restart:
rt = rt6_device_match(rt, fl->oif, flags);
BACKTRACK(&fl->fl6_src);
out:
- dst_hold(&rt->u.dst);
+ dst_use(&rt->u.dst, jiffies);
read_unlock_bh(&table->tb6_lock);
-
- rt->u.dst.lastuse = jiffies;
- rt->u.dst.__use++;
-
return rt;
}
@@ -2288,71 +2280,50 @@ struct rt6_proc_arg
static int rt6_info_route(struct rt6_info *rt, void *p_arg)
{
- struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg;
-
- if (arg->skip < arg->offset / RT6_INFO_LEN) {
- arg->skip++;
- return 0;
- }
-
- if (arg->len >= arg->length)
- return 0;
+ struct seq_file *m = p_arg;
- arg->len += sprintf(arg->buffer + arg->len,
- NIP6_SEQFMT " %02x ",
- NIP6(rt->rt6i_dst.addr),
- rt->rt6i_dst.plen);
+ seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_dst.addr),
+ rt->rt6i_dst.plen);
#ifdef CONFIG_IPV6_SUBTREES
- arg->len += sprintf(arg->buffer + arg->len,
- NIP6_SEQFMT " %02x ",
- NIP6(rt->rt6i_src.addr),
- rt->rt6i_src.plen);
+ seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_src.addr),
+ rt->rt6i_src.plen);
#else
- arg->len += sprintf(arg->buffer + arg->len,
- "00000000000000000000000000000000 00 ");
+ seq_puts(m, "00000000000000000000000000000000 00 ");
#endif
if (rt->rt6i_nexthop) {
- arg->len += sprintf(arg->buffer + arg->len,
- NIP6_SEQFMT,
- NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
+ seq_printf(m, NIP6_SEQFMT,
+ NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
} else {
- arg->len += sprintf(arg->buffer + arg->len,
- "00000000000000000000000000000000");
+ seq_puts(m, "00000000000000000000000000000000");
}
- arg->len += sprintf(arg->buffer + arg->len,
- " %08x %08x %08x %08x %8s\n",
- rt->rt6i_metric, atomic_read(&rt->u.dst.__refcnt),
- rt->u.dst.__use, rt->rt6i_flags,
- rt->rt6i_dev ? rt->rt6i_dev->name : "");
+ seq_printf(m, " %08x %08x %08x %08x %8s\n",
+ rt->rt6i_metric, atomic_read(&rt->u.dst.__refcnt),
+ rt->u.dst.__use, rt->rt6i_flags,
+ rt->rt6i_dev ? rt->rt6i_dev->name : "");
return 0;
}
-static int rt6_proc_info(char *buffer, char **start, off_t offset, int length)
+static int ipv6_route_show(struct seq_file *m, void *v)
{
- struct rt6_proc_arg arg = {
- .buffer = buffer,
- .offset = offset,
- .length = length,
- };
-
- fib6_clean_all(rt6_info_route, 0, &arg);
-
- *start = buffer;
- if (offset)
- *start += offset % RT6_INFO_LEN;
-
- arg.len -= offset % RT6_INFO_LEN;
-
- if (arg.len > length)
- arg.len = length;
- if (arg.len < 0)
- arg.len = 0;
+ fib6_clean_all(rt6_info_route, 0, m);
+ return 0;
+}
- return arg.len;
+static int ipv6_route_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ipv6_route_show, NULL);
}
+static const struct file_operations ipv6_route_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ipv6_route_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int rt6_stats_seq_show(struct seq_file *seq, void *v)
{
seq_printf(seq, "%04x %04x %04x %04x %04x %04x %04x\n",
@@ -2489,22 +2460,14 @@ ctl_table ipv6_route_table[] = {
void __init ip6_route_init(void)
{
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *p;
-#endif
ip6_dst_ops.kmem_cachep =
kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
fib6_init();
-#ifdef CONFIG_PROC_FS
- p = proc_net_create(&init_net, "ipv6_route", 0, rt6_proc_info);
- if (p)
- p->owner = THIS_MODULE;
-
+ proc_net_fops_create(&init_net, "ipv6_route", 0, &ipv6_route_proc_fops);
proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
-#endif
#ifdef CONFIG_XFRM
xfrm6_init();
#endif
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 06be2a1f273..3aad861975a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2107,6 +2107,8 @@ void tcp6_proc_exit(void)
}
#endif
+DEFINE_PROTO_INUSE(tcpv6)
+
struct proto tcpv6_prot = {
.name = "TCPv6",
.owner = THIS_MODULE,
@@ -2141,6 +2143,7 @@ struct proto tcpv6_prot = {
.compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt,
#endif
+ REF_PROTO_INUSE(tcpv6)
};
static struct inet6_protocol tcpv6_protocol = {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index caebad6ee51..ee1cc3f8599 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -205,12 +205,11 @@ out:
return err;
csum_copy_err:
+ UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
skb_kill_datagram(sk, skb, flags);
- if (flags & MSG_DONTWAIT) {
- UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
+ if (flags & MSG_DONTWAIT)
return -EAGAIN;
- }
goto try_again;
}
@@ -971,6 +970,8 @@ void udp6_proc_exit(void) {
/* ------------------------------------------------------------------------ */
+DEFINE_PROTO_INUSE(udpv6)
+
struct proto udpv6_prot = {
.name = "UDPv6",
.owner = THIS_MODULE,
@@ -992,6 +993,7 @@ struct proto udpv6_prot = {
.compat_setsockopt = compat_udpv6_setsockopt,
.compat_getsockopt = compat_udpv6_getsockopt,
#endif
+ REF_PROTO_INUSE(udpv6)
};
static struct inet_protosw udpv6_protosw = {
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 766566f7de4..5a0379f7141 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -40,6 +40,8 @@ static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
}
+DEFINE_PROTO_INUSE(udplitev6)
+
struct proto udplitev6_prot = {
.name = "UDPLITEv6",
.owner = THIS_MODULE,
@@ -62,6 +64,7 @@ struct proto udplitev6_prot = {
.compat_setsockopt = compat_udpv6_setsockopt,
.compat_getsockopt = compat_udpv6_getsockopt,
#endif
+ REF_PROTO_INUSE(udplitev6)
};
static struct inet_protosw udplite6_protosw = {
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index a195a66e0cc..c76a9523091 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -92,11 +92,6 @@ extern int ipxrtr_route_skb(struct sk_buff *skb);
extern struct ipx_route *ipxrtr_lookup(__be32 net);
extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
-#undef IPX_REFCNT_DEBUG
-#ifdef IPX_REFCNT_DEBUG
-atomic_t ipx_sock_nr;
-#endif
-
struct ipx_interface *ipx_interfaces_head(void)
{
struct ipx_interface *rc = NULL;
@@ -151,14 +146,7 @@ static void ipx_destroy_socket(struct sock *sk)
{
ipx_remove_socket(sk);
skb_queue_purge(&sk->sk_receive_queue);
-#ifdef IPX_REFCNT_DEBUG
- atomic_dec(&ipx_sock_nr);
- printk(KERN_DEBUG "IPX socket %p released, %d are still alive\n", sk,
- atomic_read(&ipx_sock_nr));
- if (atomic_read(&sk->sk_refcnt) != 1)
- printk(KERN_DEBUG "Destruction sock ipx %p delayed, cnt=%d\n",
- sk, atomic_read(&sk->sk_refcnt));
-#endif
+ sk_refcnt_debug_dec(sk);
sock_put(sk);
}
@@ -1384,11 +1372,8 @@ static int ipx_create(struct net *net, struct socket *sock, int protocol)
sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto);
if (!sk)
goto out;
-#ifdef IPX_REFCNT_DEBUG
- atomic_inc(&ipx_sock_nr);
- printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk,
- atomic_read(&ipx_sock_nr));
-#endif
+
+ sk_refcnt_debug_inc(sk);
sock_init_data(sock, sk);
sk->sk_no_check = 1; /* Checksum off by default */
sock->ops = &ipx_dgram_ops;
@@ -1409,6 +1394,7 @@ static int ipx_release(struct socket *sock)
sock_set_flag(sk, SOCK_DEAD);
sock->sk = NULL;
+ sk_refcnt_debug_release(sk);
ipx_destroy_socket(sk);
out:
return 0;
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 6fffb3845ab..ce176e691af 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -13,6 +13,18 @@ config MAC80211
This option enables the hardware independent IEEE 802.11
networking stack.
+config MAC80211_RCSIMPLE
+ bool "'simple' rate control algorithm" if EMBEDDED
+ default y
+ depends on MAC80211
+ help
+ This option allows you to turn off the 'simple' rate
+ control algorithm in mac80211. If you do turn it off,
+ you absolutely need another rate control algorithm.
+
+ Say Y unless you know you will have another algorithm
+ available.
+
config MAC80211_LEDS
bool "Enable LED triggers"
depends on MAC80211 && LEDS_TRIGGERS
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 219cd9f9341..1e6237b3484 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -1,8 +1,9 @@
-obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o
+obj-$(CONFIG_MAC80211) += mac80211.o
mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o
mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o
mac80211-objs-$(CONFIG_NET_SCHED) += wme.o
+mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o
mac80211-objs := \
ieee80211.o \
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index f484ca7ade9..e0ee65a969b 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -1072,7 +1072,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
- result = ieee80211_init_rate_ctrl_alg(local, NULL);
+ result = ieee80211_init_rate_ctrl_alg(local,
+ hw->rate_control_algorithm);
if (result < 0) {
printk(KERN_DEBUG "%s: Failed to initialize rate control "
"algorithm\n", wiphy_name(local->hw.wiphy));
@@ -1233,8 +1234,17 @@ static int __init ieee80211_init(void)
BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
+#ifdef CONFIG_MAC80211_RCSIMPLE
+ ret = ieee80211_rate_control_register(&mac80211_rcsimple);
+ if (ret)
+ return ret;
+#endif
+
ret = ieee80211_wme_register();
if (ret) {
+#ifdef CONFIG_MAC80211_RCSIMPLE
+ ieee80211_rate_control_unregister(&mac80211_rcsimple);
+#endif
printk(KERN_DEBUG "ieee80211_init: failed to "
"initialize WME (err=%d)\n", ret);
return ret;
@@ -1248,6 +1258,10 @@ static int __init ieee80211_init(void)
static void __exit ieee80211_exit(void)
{
+#ifdef CONFIG_MAC80211_RCSIMPLE
+ ieee80211_rate_control_unregister(&mac80211_rcsimple);
+#endif
+
ieee80211_wme_unregister();
ieee80211_debugfs_netdev_exit();
}
diff --git a/net/mac80211/ieee80211_common.h b/net/mac80211/ieee80211_common.h
deleted file mode 100644
index c15295d43d8..00000000000
--- a/net/mac80211/ieee80211_common.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * IEEE 802.11 driver (80211.o) -- hostapd interface
- * Copyright 2002-2004, Instant802 Networks, Inc.
- *
- * 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.
- */
-
-#ifndef IEEE80211_COMMON_H
-#define IEEE80211_COMMON_H
-
-#include <linux/types.h>
-
-/*
- * This is common header information with user space. It is used on all
- * frames sent to wlan#ap interface.
- */
-
-#define IEEE80211_FI_VERSION 0x80211001
-
-struct ieee80211_frame_info {
- __be32 version;
- __be32 length;
- __be64 mactime;
- __be64 hosttime;
- __be32 phytype;
- __be32 channel;
- __be32 datarate;
- __be32 antenna;
- __be32 priority;
- __be32 ssi_type;
- __be32 ssi_signal;
- __be32 ssi_noise;
- __be32 preamble;
- __be32 encoding;
-
- /* Note: this structure is otherwise identical to capture format used
- * in linux-wlan-ng, but this additional field is used to provide meta
- * data about the frame to hostapd. This was the easiest method for
- * providing this information, but this might change in the future. */
- __be32 msg_type;
-} __attribute__ ((packed));
-
-
-enum ieee80211_msg_type {
- ieee80211_msg_normal = 0,
- ieee80211_msg_tx_callback_ack = 1,
- ieee80211_msg_tx_callback_fail = 2,
- /* hole at 3, was ieee80211_msg_passive_scan but unused */
- /* hole at 4, was ieee80211_msg_wep_frame_unknown_key but now unused */
- ieee80211_msg_michael_mic_failure = 5,
- /* hole at 6, was monitor but never sent to userspace */
- ieee80211_msg_sta_not_assoc = 7,
- /* 8 was ieee80211_msg_set_aid_for_sta */
- /* 9 was ieee80211_msg_key_threshold_notification */
- /* 11 was ieee80211_msg_radar */
-};
-
-struct ieee80211_msg_key_notification {
- int tx_rx_count;
- char ifname[IFNAMSIZ];
- u8 addr[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast keys */
-};
-
-
-enum ieee80211_phytype {
- ieee80211_phytype_fhss_dot11_97 = 1,
- ieee80211_phytype_dsss_dot11_97 = 2,
- ieee80211_phytype_irbaseband = 3,
- ieee80211_phytype_dsss_dot11_b = 4,
- ieee80211_phytype_pbcc_dot11_b = 5,
- ieee80211_phytype_ofdm_dot11_g = 6,
- ieee80211_phytype_pbcc_dot11_g = 7,
- ieee80211_phytype_ofdm_dot11_a = 8,
-};
-
-enum ieee80211_ssi_type {
- ieee80211_ssi_none = 0,
- ieee80211_ssi_norm = 1, /* normalized, 0-1000 */
- ieee80211_ssi_dbm = 2,
- ieee80211_ssi_raw = 3, /* raw SSI */
-};
-
-struct ieee80211_radar_info {
- int channel;
- int radar;
- int radar_type;
-};
-
-#endif /* IEEE80211_COMMON_H */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4b4ed2a5803..b4e32ab3664 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -230,6 +230,7 @@ struct ieee80211_if_vlan {
#define IEEE80211_STA_AUTO_SSID_SEL BIT(10)
#define IEEE80211_STA_AUTO_BSSID_SEL BIT(11)
#define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12)
+#define IEEE80211_STA_PRIVACY_INVOKED BIT(13)
struct ieee80211_if_sta {
enum {
IEEE80211_DISABLED, IEEE80211_AUTHENTICATE,
@@ -259,7 +260,6 @@ struct ieee80211_if_sta {
unsigned long request;
struct sk_buff_head skb_queue;
- int key_management_enabled;
unsigned long last_probe;
#define IEEE80211_AUTH_ALG_OPEN BIT(0)
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 6caa3ec2cff..7027eed4d4a 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -917,7 +917,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *data, char *extra)
{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
int ret = 0;
@@ -927,18 +926,21 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
case IW_AUTH_CIPHER_GROUP:
case IW_AUTH_WPA_ENABLED:
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- break;
case IW_AUTH_KEY_MGMT:
+ break;
+ case IW_AUTH_PRIVACY_INVOKED:
if (sdata->type != IEEE80211_IF_TYPE_STA)
ret = -EINVAL;
else {
+ sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
/*
- * Key management was set by wpa_supplicant,
- * we only need this to associate to a network
- * that has privacy enabled regardless of not
- * having a key.
+ * Privacy invoked by wpa_supplicant, store the
+ * value and allow associating to a protected
+ * network without having a key up front.
*/
- sdata->u.sta.key_management_enabled = !!data->value;
+ if (data->value)
+ sdata->u.sta.flags |=
+ IEEE80211_STA_PRIVACY_INVOKED;
}
break;
case IW_AUTH_80211_AUTH_ALG:
@@ -948,11 +950,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
else
ret = -EOPNOTSUPP;
break;
- case IW_AUTH_PRIVACY_INVOKED:
- if (local->ops->set_privacy_invoked)
- ret = local->ops->set_privacy_invoked(
- local_to_hw(local), data->value);
- break;
default:
ret = -EOPNOTSUPP;
break;
diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c
index 93abb8fff14..7254bd60983 100644
--- a/net/mac80211/ieee80211_rate.c
+++ b/net/mac80211/ieee80211_rate.c
@@ -25,13 +25,25 @@ int ieee80211_rate_control_register(struct rate_control_ops *ops)
{
struct rate_control_alg *alg;
+ if (!ops->name)
+ return -EINVAL;
+
+ mutex_lock(&rate_ctrl_mutex);
+ list_for_each_entry(alg, &rate_ctrl_algs, list) {
+ if (!strcmp(alg->ops->name, ops->name)) {
+ /* don't register an algorithm twice */
+ WARN_ON(1);
+ return -EALREADY;
+ }
+ }
+
alg = kzalloc(sizeof(*alg), GFP_KERNEL);
if (alg == NULL) {
+ mutex_unlock(&rate_ctrl_mutex);
return -ENOMEM;
}
alg->ops = ops;
- mutex_lock(&rate_ctrl_mutex);
list_add_tail(&alg->list, &rate_ctrl_algs);
mutex_unlock(&rate_ctrl_mutex);
@@ -61,9 +73,12 @@ ieee80211_try_rate_control_ops_get(const char *name)
struct rate_control_alg *alg;
struct rate_control_ops *ops = NULL;
+ if (!name)
+ return NULL;
+
mutex_lock(&rate_ctrl_mutex);
list_for_each_entry(alg, &rate_ctrl_algs, list) {
- if (!name || !strcmp(alg->ops->name, name))
+ if (!strcmp(alg->ops->name, name))
if (try_module_get(alg->ops->module)) {
ops = alg->ops;
break;
@@ -80,9 +95,12 @@ ieee80211_rate_control_ops_get(const char *name)
{
struct rate_control_ops *ops;
+ if (!name)
+ name = "simple";
+
ops = ieee80211_try_rate_control_ops_get(name);
if (!ops) {
- request_module("rc80211_%s", name ? name : "default");
+ request_module("rc80211_%s", name);
ops = ieee80211_try_rate_control_ops_get(name);
}
return ops;
diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h
index 7cd1ebab4f8..23688139ffb 100644
--- a/net/mac80211/ieee80211_rate.h
+++ b/net/mac80211/ieee80211_rate.h
@@ -65,6 +65,9 @@ struct rate_control_ref {
struct kref kref;
};
+/* default 'simple' algorithm */
+extern struct rate_control_ops mac80211_rcsimple;
+
int ieee80211_rate_control_register(struct rate_control_ops *ops);
void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index fda0e06453e..2079e988fc5 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -704,10 +704,11 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
- int res = 0;
+ int bss_privacy;
+ int wep_privacy;
+ int privacy_invoked;
- if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL) ||
- ifsta->key_management_enabled)
+ if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
return 0;
bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
@@ -715,13 +716,16 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
if (!bss)
return 0;
- if (ieee80211_sta_wep_configured(dev) !=
- !!(bss->capability & WLAN_CAPABILITY_PRIVACY))
- res = 1;
+ bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
+ wep_privacy = !!ieee80211_sta_wep_configured(dev);
+ privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
ieee80211_rx_bss_put(dev, bss);
- return res;
+ if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
+ return 0;
+
+ return 1;
}
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c
index 314b8de8886..da72737364e 100644
--- a/net/mac80211/rc80211_simple.c
+++ b/net/mac80211/rc80211_simple.c
@@ -7,7 +7,6 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/types.h>
@@ -29,8 +28,6 @@
#define RATE_CONTROL_INTERVAL (HZ / 20)
#define RATE_CONTROL_MIN_TX 10
-MODULE_ALIAS("rc80211_default");
-
static void rate_control_rate_inc(struct ieee80211_local *local,
struct sta_info *sta)
{
@@ -394,8 +391,7 @@ static void rate_control_simple_remove_sta_debugfs(void *priv, void *priv_sta)
}
#endif
-static struct rate_control_ops rate_control_simple = {
- .module = THIS_MODULE,
+struct rate_control_ops mac80211_rcsimple = {
.name = "simple",
.tx_status = rate_control_simple_tx_status,
.get_rate = rate_control_simple_get_rate,
@@ -410,22 +406,3 @@ static struct rate_control_ops rate_control_simple = {
.remove_sta_debugfs = rate_control_simple_remove_sta_debugfs,
#endif
};
-
-
-static int __init rate_control_simple_init(void)
-{
- return ieee80211_rate_control_register(&rate_control_simple);
-}
-
-
-static void __exit rate_control_simple_exit(void)
-{
- ieee80211_rate_control_unregister(&rate_control_simple);
-}
-
-
-subsys_initcall(rate_control_simple_init);
-module_exit(rate_control_simple_exit);
-
-MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211");
-MODULE_LICENSE("GPL");
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ece77766ea2..428a9fcf57d 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -509,9 +509,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx)
rx->key->tx_rx_count++;
/* TODO: add threshold stuff again */
} else {
+#ifdef CONFIG_MAC80211_DEBUG
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX protected frame,"
" but have no key\n", rx->dev->name);
+#endif /* CONFIG_MAC80211_DEBUG */
return TXRX_DROP;
}
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index a84a23310ff..9bf0e1cc530 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -314,9 +314,11 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx)
if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
+#ifdef CONFIG_MAC80211_DEBUG
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
"failed\n", rx->dev->name);
+#endif /* CONFIG_MAC80211_DEBUG */
return TXRX_DROP;
}
} else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 6695efba57e..20cec1cb956 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -323,9 +323,12 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx)
&rx->u.rx.tkip_iv32,
&rx->u.rx.tkip_iv16);
if (res != TKIP_DECRYPT_OK || wpa_test) {
- printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from "
- "%s (res=%d)\n",
- rx->dev->name, print_mac(mac, rx->sta->addr), res);
+#ifdef CONFIG_MAC80211_DEBUG
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: TKIP decrypt failed for RX "
+ "frame from %s (res=%d)\n", rx->dev->name,
+ print_mac(mac, rx->sta->addr), res);
+#endif /* CONFIG_MAC80211_DEBUG */
return TXRX_DROP;
}
@@ -594,9 +597,12 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx)
skb->data + hdrlen + CCMP_HDR_LEN, data_len,
skb->data + skb->len - CCMP_MIC_LEN,
skb->data + hdrlen + CCMP_HDR_LEN)) {
- printk(KERN_DEBUG "%s: CCMP decrypt failed for RX "
- "frame from %s\n", rx->dev->name,
- print_mac(mac, rx->sta->addr));
+#ifdef CONFIG_MAC80211_DEBUG
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: CCMP decrypt failed "
+ "for RX frame from %s\n", rx->dev->name,
+ print_mac(mac, rx->sta->addr));
+#endif /* CONFIG_MAC80211_DEBUG */
return TXRX_DROP;
}
}
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 93c58f97383..ad0e36ebea3 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -40,15 +40,15 @@ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
# targets
obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
-obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
-obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
-obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
# matches
obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
@@ -59,22 +59,22 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o
obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o
obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o
obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index aa2831587b8..2dfac325356 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -23,14 +23,13 @@ static inline int overlap(int min1, int max1, int min2, int max2)
/* Functions to register sockopt ranges (exclusive). */
int nf_register_sockopt(struct nf_sockopt_ops *reg)
{
- struct list_head *i;
+ struct nf_sockopt_ops *ops;
int ret = 0;
if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
return -EINTR;
- list_for_each(i, &nf_sockopts) {
- struct nf_sockopt_ops *ops = (struct nf_sockopt_ops *)i;
+ list_for_each_entry(ops, &nf_sockopts, list) {
if (ops->pf == reg->pf
&& (overlap(ops->set_optmin, ops->set_optmax,
reg->set_optmin, reg->set_optmax)
@@ -65,7 +64,6 @@ EXPORT_SYMBOL(nf_unregister_sockopt);
static int nf_sockopt(struct sock *sk, int pf, int val,
char __user *opt, int *len, int get)
{
- struct list_head *i;
struct nf_sockopt_ops *ops;
int ret;
@@ -75,8 +73,7 @@ static int nf_sockopt(struct sock *sk, int pf, int val,
if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
return -EINTR;
- list_for_each(i, &nf_sockopts) {
- ops = (struct nf_sockopt_ops *)i;
+ list_for_each_entry(ops, &nf_sockopts, list) {
if (ops->pf == pf) {
if (!try_module_get(ops->owner))
goto out_nosup;
@@ -124,7 +121,6 @@ EXPORT_SYMBOL(nf_getsockopt);
static int compat_nf_sockopt(struct sock *sk, int pf, int val,
char __user *opt, int *len, int get)
{
- struct list_head *i;
struct nf_sockopt_ops *ops;
int ret;
@@ -135,8 +131,7 @@ static int compat_nf_sockopt(struct sock *sk, int pf, int val,
if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
return -EINTR;
- list_for_each(i, &nf_sockopts) {
- ops = (struct nf_sockopt_ops *)i;
+ list_for_each_entry(ops, &nf_sockopts, list) {
if (ops->pf == pf) {
if (!try_module_get(ops->owner))
goto out_nosup;
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 06cff1d1369..d7becf08a93 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -4,7 +4,8 @@
* (c) 2000 Gerd Knorr <kraxel@bytesex.org>
* Nov 2002: Martin Bene <martin.bene@icomedias.com>:
* only ignore TIME_WAIT or gone connections
- * Copyright © Jan Engelhardt <jengelh@gmx.de>, 2007
+ * (C) CC Computer Consultants GmbH, 2007
+ * Contact: <jengelh@computergmbh.de>
*
* based on ...
*
@@ -306,7 +307,7 @@ static void __exit xt_connlimit_exit(void)
module_init(xt_connlimit_init);
module_exit(xt_connlimit_exit);
-MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("netfilter xt_connlimit match module");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_connlimit");
diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c
index ef48bbd9357..ff44f86c24c 100644
--- a/net/netfilter/xt_time.c
+++ b/net/netfilter/xt_time.c
@@ -1,6 +1,7 @@
/*
* xt_time
- * Copyright © Jan Engelhardt <jengelh@computergmbh.de>, 2007
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: <jengelh@computergmbh.de>
*
* based on ipt_time by Fabrice MARIE <fabrice@netfilter.org>
* This is a module which is used for time matching
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
index bec427915b3..af75b8c3f20 100644
--- a/net/netfilter/xt_u32.c
+++ b/net/netfilter/xt_u32.c
@@ -2,7 +2,8 @@
* xt_u32 - kernel module to match u32 packet content
*
* Original author: Don Cohen <don@isis.cs3-inc.com>
- * © Jan Engelhardt <jengelh@gmx.de>, 2007
+ * (C) CC Computer Consultants GmbH, 2007
+ * Contact: <jengelh@computergmbh.de>
*/
#include <linux/module.h>
@@ -129,7 +130,7 @@ static void __exit xt_u32_exit(void)
module_init(xt_u32_init);
module_exit(xt_u32_exit);
-MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("netfilter u32 match module");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_u32");
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 26017125557..415c97236f6 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -752,7 +752,7 @@ struct sock *netlink_getsockbyfilp(struct file *filp)
* 1: repeat lookup - reference dropped while waiting for socket memory.
*/
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
- long timeo, struct sock *ssk)
+ long *timeo, struct sock *ssk)
{
struct netlink_sock *nlk;
@@ -761,7 +761,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
test_bit(0, &nlk->state)) {
DECLARE_WAITQUEUE(wait, current);
- if (!timeo) {
+ if (!*timeo) {
if (!ssk || netlink_is_kernel(ssk))
netlink_overrun(sk);
sock_put(sk);
@@ -775,7 +775,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
test_bit(0, &nlk->state)) &&
!sock_flag(sk, SOCK_DEAD))
- timeo = schedule_timeout(timeo);
+ *timeo = schedule_timeout(*timeo);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&nlk->wait, &wait);
@@ -783,7 +783,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
if (signal_pending(current)) {
kfree_skb(skb);
- return sock_intr_errno(timeo);
+ return sock_intr_errno(*timeo);
}
return 1;
}
@@ -877,7 +877,7 @@ retry:
if (netlink_is_kernel(sk))
return netlink_unicast_kernel(sk, skb);
- err = netlink_attachskb(sk, skb, nonblock, timeo, ssk);
+ err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk);
if (err == 1)
goto retry;
if (err)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 4cb2dfba099..eb6be5030c7 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -139,9 +139,6 @@ dev->hard_header == NULL (ll header is added by device, we cannot control it)
static HLIST_HEAD(packet_sklist);
static DEFINE_RWLOCK(packet_sklist_lock);
-static atomic_t packet_socks_nr;
-
-
/* Private packet socket structures. */
struct packet_mclist
@@ -236,10 +233,7 @@ static void packet_sock_destruct(struct sock *sk)
return;
}
- atomic_dec(&packet_socks_nr);
-#ifdef PACKET_REFCNT_DEBUG
- printk(KERN_DEBUG "PACKET socket %p is free, %d are alive\n", sk, atomic_read(&packet_socks_nr));
-#endif
+ sk_refcnt_debug_dec(sk);
}
@@ -515,7 +509,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
sll->sll_hatype = dev->type;
sll->sll_protocol = skb->protocol;
sll->sll_pkttype = skb->pkt_type;
- if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST)
+ if (unlikely(po->origdev))
sll->sll_ifindex = orig_dev->ifindex;
else
sll->sll_ifindex = dev->ifindex;
@@ -661,7 +655,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
sll->sll_hatype = dev->type;
sll->sll_protocol = skb->protocol;
sll->sll_pkttype = skb->pkt_type;
- if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST)
+ if (unlikely(po->origdev))
sll->sll_ifindex = orig_dev->ifindex;
else
sll->sll_ifindex = dev->ifindex;
@@ -849,6 +843,7 @@ static int packet_release(struct socket *sock)
/* Purge queues */
skb_queue_purge(&sk->sk_receive_queue);
+ sk_refcnt_debug_release(sk);
sock_put(sk);
return 0;
@@ -1010,7 +1005,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
po->num = proto;
sk->sk_destruct = packet_sock_destruct;
- atomic_inc(&packet_socks_nr);
+ sk_refcnt_debug_inc(sk);
/*
* Attach a protocol block
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 51d151c0e96..73d60a30712 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -27,6 +27,10 @@
#include <linux/mutex.h>
#include <linux/rfkill.h>
+/* Get declaration of rfkill_switch_all() to shut up sparse. */
+#include "rfkill-input.h"
+
+
MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
MODULE_VERSION("1.0");
MODULE_DESCRIPTION("RF switch support");
@@ -276,21 +280,17 @@ static struct class rfkill_class = {
static int rfkill_add_switch(struct rfkill *rfkill)
{
- int retval;
-
- retval = mutex_lock_interruptible(&rfkill_mutex);
- if (retval)
- return retval;
+ int error;
- retval = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]);
- if (retval)
- goto out;
+ mutex_lock(&rfkill_mutex);
- list_add_tail(&rfkill->node, &rfkill_list);
+ error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]);
+ if (!error)
+ list_add_tail(&rfkill->node, &rfkill_list);
- out:
mutex_unlock(&rfkill_mutex);
- return retval;
+
+ return error;
}
static void rfkill_remove_switch(struct rfkill *rfkill)
@@ -387,20 +387,23 @@ int rfkill_register(struct rfkill *rfkill)
if (!rfkill->toggle_radio)
return -EINVAL;
+ if (rfkill->type >= RFKILL_TYPE_MAX)
+ return -EINVAL;
+
+ snprintf(dev->bus_id, sizeof(dev->bus_id),
+ "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
+
+ rfkill_led_trigger_register(rfkill);
error = rfkill_add_switch(rfkill);
if (error)
return error;
- snprintf(dev->bus_id, sizeof(dev->bus_id),
- "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
-
error = device_add(dev);
if (error) {
rfkill_remove_switch(rfkill);
return error;
}
- rfkill_led_trigger_register(rfkill);
return 0;
}
@@ -416,9 +419,9 @@ EXPORT_SYMBOL(rfkill_register);
*/
void rfkill_unregister(struct rfkill *rfkill)
{
- rfkill_led_trigger_unregister(rfkill);
device_del(&rfkill->dev);
rfkill_remove_switch(rfkill);
+ rfkill_led_trigger_unregister(rfkill);
put_device(&rfkill->dev);
}
EXPORT_SYMBOL(rfkill_unregister);
@@ -448,5 +451,5 @@ static void __exit rfkill_exit(void)
class_unregister(&rfkill_class);
}
-module_init(rfkill_init);
+subsys_initcall(rfkill_init);
module_exit(rfkill_exit);
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 9e98c6e567d..c3900820916 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -91,7 +91,7 @@ static struct tc_u_common *u32_list;
static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
{
- unsigned h = (key & sel->hmask)>>fshift;
+ unsigned h = ntohl(key & sel->hmask)>>fshift;
return h;
}
@@ -613,17 +613,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
n->ht_up = ht;
n->handle = handle;
-{
- u8 i = 0;
- u32 mask = s->hmask;
- if (mask) {
- while (!(mask & 1)) {
- i++;
- mask>>=1;
- }
- }
- n->fshift = i;
-}
+ n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
#ifdef CONFIG_CLS_U32_MARK
if (tb[TCA_U32_MARK-1]) {
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 421281d9dd1..c0ed06d4a50 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -252,6 +252,9 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
static inline int teql_resolve(struct sk_buff *skb,
struct sk_buff *skb_res, struct net_device *dev)
{
+ if (dev->qdisc == &noop_qdisc)
+ return -ENODEV;
+
if (dev->header_ops == NULL ||
skb->dst == NULL ||
skb->dst->neighbour == NULL)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index bd6f42a15a4..a7ecf3159e5 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6455,6 +6455,8 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
}
+DEFINE_PROTO_INUSE(sctp)
+
/* This proto struct describes the ULP interface for SCTP. */
struct proto sctp_prot = {
.name = "SCTP",
@@ -6483,9 +6485,12 @@ struct proto sctp_prot = {
.memory_pressure = &sctp_memory_pressure,
.enter_memory_pressure = sctp_enter_memory_pressure,
.memory_allocated = &sctp_memory_allocated,
+ REF_PROTO_INUSE(sctp)
};
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+DEFINE_PROTO_INUSE(sctpv6)
+
struct proto sctpv6_prot = {
.name = "SCTPv6",
.owner = THIS_MODULE,
@@ -6513,5 +6518,6 @@ struct proto sctpv6_prot = {
.memory_pressure = &sctp_memory_pressure,
.enter_memory_pressure = sctp_enter_memory_pressure,
.memory_allocated = &sctp_memory_allocated,
+ REF_PROTO_INUSE(sctpv6)
};
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 515e7a692f9..e835da8fc09 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -457,7 +457,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
* What the above comment does talk about? --ANK(980817)
*/
- if (atomic_read(&unix_tot_inflight))
+ if (unix_tot_inflight)
unix_gc(); /* Garbage collect fds */
return 0;
@@ -599,15 +599,14 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
struct sock *sk = NULL;
struct unix_sock *u;
- if (atomic_read(&unix_nr_socks) >= 2*get_max_files())
+ atomic_inc(&unix_nr_socks);
+ if (atomic_read(&unix_nr_socks) > 2 * get_max_files())
goto out;
sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto);
if (!sk)
goto out;
- atomic_inc(&unix_nr_socks);
-
sock_init_data(sock,sk);
lockdep_set_class(&sk->sk_receive_queue.lock,
&af_unix_sk_receive_queue_lock_key);
@@ -625,6 +624,8 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
init_waitqueue_head(&u->peer_wait);
unix_insert_socket(unix_sockets_unbound, sk);
out:
+ if (sk == NULL)
+ atomic_dec(&unix_nr_socks);
return sk;
}
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 406b6433e46..ebdff3d877a 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -92,7 +92,7 @@ static LIST_HEAD(gc_inflight_list);
static LIST_HEAD(gc_candidates);
static DEFINE_SPINLOCK(unix_gc_lock);
-atomic_t unix_tot_inflight = ATOMIC_INIT(0);
+unsigned int unix_tot_inflight;
static struct sock *unix_get_socket(struct file *filp)
@@ -133,7 +133,7 @@ void unix_inflight(struct file *fp)
} else {
BUG_ON(list_empty(&u->link));
}
- atomic_inc(&unix_tot_inflight);
+ unix_tot_inflight++;
spin_unlock(&unix_gc_lock);
}
}
@@ -147,7 +147,7 @@ void unix_notinflight(struct file *fp)
BUG_ON(list_empty(&u->link));
if (atomic_dec_and_test(&u->inflight))
list_del_init(&u->link);
- atomic_dec(&unix_tot_inflight);
+ unix_tot_inflight--;
spin_unlock(&unix_gc_lock);
}
}
@@ -161,7 +161,7 @@ static inline struct sk_buff *sock_queue_head(struct sock *sk)
for (skb = sock_queue_head(sk)->next, next = skb->next; \
skb != sock_queue_head(sk); skb = next, next = skb->next)
-static void scan_inflight(struct sock *x, void (*func)(struct sock *),
+static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
struct sk_buff_head *hitlist)
{
struct sk_buff *skb;
@@ -185,9 +185,9 @@ static void scan_inflight(struct sock *x, void (*func)(struct sock *),
* if it indeed does so
*/
struct sock *sk = unix_get_socket(*fp++);
- if(sk) {
+ if (sk) {
hit = true;
- func(sk);
+ func(unix_sk(sk));
}
}
if (hit && hitlist != NULL) {
@@ -199,7 +199,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct sock *),
spin_unlock(&x->sk_receive_queue.lock);
}
-static void scan_children(struct sock *x, void (*func)(struct sock *),
+static void scan_children(struct sock *x, void (*func)(struct unix_sock *),
struct sk_buff_head *hitlist)
{
if (x->sk_state != TCP_LISTEN)
@@ -235,20 +235,18 @@ static void scan_children(struct sock *x, void (*func)(struct sock *),
}
}
-static void dec_inflight(struct sock *sk)
+static void dec_inflight(struct unix_sock *usk)
{
- atomic_dec(&unix_sk(sk)->inflight);
+ atomic_dec(&usk->inflight);
}
-static void inc_inflight(struct sock *sk)
+static void inc_inflight(struct unix_sock *usk)
{
- atomic_inc(&unix_sk(sk)->inflight);
+ atomic_inc(&usk->inflight);
}
-static void inc_inflight_move_tail(struct sock *sk)
+static void inc_inflight_move_tail(struct unix_sock *u)
{
- struct unix_sock *u = unix_sk(sk);
-
atomic_inc(&u->inflight);
/*
* If this is still a candidate, move it to the end of the
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 7551af1f789..9e70a160d7d 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -325,7 +325,7 @@ static uint16_t spec_order[] = {
AVTAB_MEMBER
};
-int avtab_read_item(void *fp, u32 vers, struct avtab *a,
+int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
int (*insertf)(struct avtab *a, struct avtab_key *k,
struct avtab_datum *d, void *p),
void *p)
@@ -333,10 +333,11 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
__le16 buf16[4];
u16 enabled;
__le32 buf32[7];
- u32 items, items2, val;
+ u32 items, items2, val, vers = pol->policyvers;
struct avtab_key key;
struct avtab_datum datum;
int i, rc;
+ unsigned set;
memset(&key, 0, sizeof(struct avtab_key));
memset(&datum, 0, sizeof(struct avtab_datum));
@@ -420,12 +421,35 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
key.target_class = le16_to_cpu(buf16[items++]);
key.specified = le16_to_cpu(buf16[items++]);
+ if (!policydb_type_isvalid(pol, key.source_type) ||
+ !policydb_type_isvalid(pol, key.target_type) ||
+ !policydb_class_isvalid(pol, key.target_class)) {
+ printk(KERN_WARNING "security: avtab: invalid type or class\n");
+ return -1;
+ }
+
+ set = 0;
+ for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
+ if (key.specified & spec_order[i])
+ set++;
+ }
+ if (!set || set > 1) {
+ printk(KERN_WARNING
+ "security: avtab: more than one specifier\n");
+ return -1;
+ }
+
rc = next_entry(buf32, fp, sizeof(u32));
if (rc < 0) {
printk("security: avtab: truncated entry\n");
return -1;
}
datum.data = le32_to_cpu(*buf32);
+ if ((key.specified & AVTAB_TYPE) &&
+ !policydb_type_isvalid(pol, datum.data)) {
+ printk(KERN_WARNING "security: avtab: invalid type\n");
+ return -1;
+ }
return insertf(a, &key, &datum, p);
}
@@ -435,7 +459,7 @@ static int avtab_insertf(struct avtab *a, struct avtab_key *k,
return avtab_insert(a, k, d);
}
-int avtab_read(struct avtab *a, void *fp, u32 vers)
+int avtab_read(struct avtab *a, void *fp, struct policydb *pol)
{
int rc;
__le32 buf[1];
@@ -459,7 +483,7 @@ int avtab_read(struct avtab *a, void *fp, u32 vers)
goto bad;
for (i = 0; i < nel; i++) {
- rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL);
+ rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL);
if (rc) {
if (rc == -ENOMEM)
printk(KERN_ERR "security: avtab: out of memory\n");
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index d8edf8ca56d..8da6a842808 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -64,12 +64,13 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k);
void avtab_destroy(struct avtab *h);
void avtab_hash_eval(struct avtab *h, char *tag);
-int avtab_read_item(void *fp, uint32_t vers, struct avtab *a,
+struct policydb;
+int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
int (*insert)(struct avtab *a, struct avtab_key *k,
struct avtab_datum *d, void *p),
void *p);
-int avtab_read(struct avtab *a, void *fp, u32 vers);
+int avtab_read(struct avtab *a, void *fp, struct policydb *pol);
struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key,
struct avtab_datum *datum);
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 45b93a827c8..50ad85d4b77 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -362,7 +362,8 @@ static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list *
data.head = NULL;
data.tail = NULL;
for (i = 0; i < len; i++) {
- rc = avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, cond_insertf, &data);
+ rc = avtab_read_item(&p->te_cond_avtab, fp, p, cond_insertf,
+ &data);
if (rc)
return rc;
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index c1a6b22d48d..920b5e36a1a 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -129,8 +129,8 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
c_iter->bitmap[cmap_idx]
|= e_iter->maps[cmap_idx] << cmap_sft;
- e_iter = e_iter->next;
}
+ e_iter = e_iter->next;
}
return 0;
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 9a11deaaa9e..fb5d70a6628 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -157,49 +157,55 @@ void mls_sid_to_context(struct context *context,
return;
}
+int mls_level_isvalid(struct policydb *p, struct mls_level *l)
+{
+ struct level_datum *levdatum;
+ struct ebitmap_node *node;
+ int i;
+
+ if (!l->sens || l->sens > p->p_levels.nprim)
+ return 0;
+ levdatum = hashtab_search(p->p_levels.table,
+ p->p_sens_val_to_name[l->sens - 1]);
+ if (!levdatum)
+ return 0;
+
+ ebitmap_for_each_positive_bit(&l->cat, node, i) {
+ if (i > p->p_cats.nprim)
+ return 0;
+ if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
+ /*
+ * Category may not be associated with
+ * sensitivity.
+ */
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int mls_range_isvalid(struct policydb *p, struct mls_range *r)
+{
+ return (mls_level_isvalid(p, &r->level[0]) &&
+ mls_level_isvalid(p, &r->level[1]) &&
+ mls_level_dom(&r->level[1], &r->level[0]));
+}
+
/*
* Return 1 if the MLS fields in the security context
* structure `c' are valid. Return 0 otherwise.
*/
int mls_context_isvalid(struct policydb *p, struct context *c)
{
- struct level_datum *levdatum;
struct user_datum *usrdatum;
- struct ebitmap_node *node;
- int i, l;
if (!selinux_mls_enabled)
return 1;
- /*
- * MLS range validity checks: high must dominate low, low level must
- * be valid (category set <-> sensitivity check), and high level must
- * be valid (category set <-> sensitivity check)
- */
- if (!mls_level_dom(&c->range.level[1], &c->range.level[0]))
- /* High does not dominate low. */
+ if (!mls_range_isvalid(p, &c->range))
return 0;
- for (l = 0; l < 2; l++) {
- if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim)
- return 0;
- levdatum = hashtab_search(p->p_levels.table,
- p->p_sens_val_to_name[c->range.level[l].sens - 1]);
- if (!levdatum)
- return 0;
-
- ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
- if (i > p->p_cats.nprim)
- return 0;
- if (!ebitmap_get_bit(&levdatum->level->cat, i))
- /*
- * Category may not be associated with
- * sensitivity in low level.
- */
- return 0;
- }
- }
-
if (c->role == OBJECT_R_VAL)
return 1;
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 096d1b4ef7f..ab53663d9f5 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -27,6 +27,8 @@
int mls_compute_context_len(struct context *context);
void mls_sid_to_context(struct context *context, char **scontext);
int mls_context_isvalid(struct policydb *p, struct context *c);
+int mls_range_isvalid(struct policydb *p, struct mls_range *r);
+int mls_level_isvalid(struct policydb *p, struct mls_level *l);
int mls_context_to_sid(char oldc,
char **scontext,
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 539828b229b..b582aae3c62 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -713,6 +713,27 @@ out:
return rc;
}
+int policydb_class_isvalid(struct policydb *p, unsigned int class)
+{
+ if (!class || class > p->p_classes.nprim)
+ return 0;
+ return 1;
+}
+
+int policydb_role_isvalid(struct policydb *p, unsigned int role)
+{
+ if (!role || role > p->p_roles.nprim)
+ return 0;
+ return 1;
+}
+
+int policydb_type_isvalid(struct policydb *p, unsigned int type)
+{
+ if (!type || type > p->p_types.nprim)
+ return 0;
+ return 1;
+}
+
/*
* Return 1 if the fields in the security context
* structure `c' are valid. Return 0 otherwise.
@@ -1260,6 +1281,7 @@ static int mls_read_level(struct mls_level *lp, void *fp)
"categories\n");
goto bad;
}
+
return 0;
bad:
@@ -1563,7 +1585,7 @@ int policydb_read(struct policydb *p, void *fp)
p->symtab[i].nprim = nprim;
}
- rc = avtab_read(&p->te_avtab, fp, p->policyvers);
+ rc = avtab_read(&p->te_avtab, fp, p);
if (rc)
goto bad;
@@ -1595,6 +1617,12 @@ int policydb_read(struct policydb *p, void *fp)
tr->role = le32_to_cpu(buf[0]);
tr->type = le32_to_cpu(buf[1]);
tr->new_role = le32_to_cpu(buf[2]);
+ if (!policydb_role_isvalid(p, tr->role) ||
+ !policydb_type_isvalid(p, tr->type) ||
+ !policydb_role_isvalid(p, tr->new_role)) {
+ rc = -EINVAL;
+ goto bad;
+ }
ltr = tr;
}
@@ -1619,6 +1647,11 @@ int policydb_read(struct policydb *p, void *fp)
goto bad;
ra->role = le32_to_cpu(buf[0]);
ra->new_role = le32_to_cpu(buf[1]);
+ if (!policydb_role_isvalid(p, ra->role) ||
+ !policydb_role_isvalid(p, ra->new_role)) {
+ rc = -EINVAL;
+ goto bad;
+ }
lra = ra;
}
@@ -1872,9 +1905,19 @@ int policydb_read(struct policydb *p, void *fp)
rt->target_class = le32_to_cpu(buf[0]);
} else
rt->target_class = SECCLASS_PROCESS;
+ if (!policydb_type_isvalid(p, rt->source_type) ||
+ !policydb_type_isvalid(p, rt->target_type) ||
+ !policydb_class_isvalid(p, rt->target_class)) {
+ rc = -EINVAL;
+ goto bad;
+ }
rc = mls_read_range_helper(&rt->target_range, fp);
if (rc)
goto bad;
+ if (!mls_range_isvalid(p, &rt->target_range)) {
+ printk(KERN_WARNING "security: rangetrans: invalid range\n");
+ goto bad;
+ }
lrt = rt;
}
}
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 844d310f4f1..ed6fc687c66 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -251,6 +251,9 @@ struct policydb {
extern void policydb_destroy(struct policydb *p);
extern int policydb_load_isids(struct policydb *p, struct sidtab *s);
extern int policydb_context_isvalid(struct policydb *p, struct context *c);
+extern int policydb_class_isvalid(struct policydb *p, unsigned int class);
+extern int policydb_type_isvalid(struct policydb *p, unsigned int type);
+extern int policydb_role_isvalid(struct policydb *p, unsigned int role);
extern int policydb_read(struct policydb *p, void *fp);
#define PERM_SYMTAB_SIZE 32
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 36a191e7004..e0760396903 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -211,26 +211,27 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX)
return -EINVAL;
- if (uctx->ctx_len >= PAGE_SIZE)
+ str_len = uctx->ctx_len;
+ if (str_len >= PAGE_SIZE)
return -ENOMEM;
*ctxp = ctx = kmalloc(sizeof(*ctx) +
- uctx->ctx_len + 1,
+ str_len + 1,
GFP_KERNEL);
if (!ctx)
return -ENOMEM;
ctx->ctx_doi = uctx->ctx_doi;
- ctx->ctx_len = uctx->ctx_len;
+ ctx->ctx_len = str_len;
ctx->ctx_alg = uctx->ctx_alg;
memcpy(ctx->ctx_str,
uctx+1,
- ctx->ctx_len);
- ctx->ctx_str[ctx->ctx_len] = 0;
+ str_len);
+ ctx->ctx_str[str_len] = 0;
rc = security_context_to_sid(ctx->ctx_str,
- ctx->ctx_len,
+ str_len,
&ctx->ctx_sid);
if (rc)