From da8bb080163f8b71f50e579fd5ee06d6c8f27c54 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Sun, 31 Oct 2010 13:40:12 +0000 Subject: [PATCH] --- yaml --- r: 224545 b: refs/heads/master c: cf43298864fdfd687202db8c736473522bfceb98 h: refs/heads/master i: 224543: b7ead281d04e72e206b7069e7ae219f1e9759572 v: v3 --- [refs] | 2 +- .../ABI/obsolete/proc-pid-oom_adj | 22 - trunk/Documentation/block/switching-sched.txt | 8 +- .../xfs-delayed-logging-design.txt | 11 + trunk/Documentation/kernel-parameters.txt | 2 +- trunk/Documentation/leds-class.txt | 21 +- trunk/Documentation/leds/leds-lp5521.txt | 88 - trunk/Documentation/leds/leds-lp5523.txt | 83 - trunk/Documentation/networking/ip-sysctl.txt | 33 +- trunk/Documentation/networking/stmmac.txt | 48 +- trunk/Documentation/rbtree.txt | 4 +- trunk/Documentation/sysctl/kernel.txt | 14 - trunk/MAINTAINERS | 21 +- trunk/arch/arm/Kconfig | 2 +- trunk/arch/arm/common/gic.c | 28 +- trunk/arch/arm/include/asm/hardware/it8152.h | 2 +- trunk/arch/arm/kernel/hw_breakpoint.c | 3 +- trunk/arch/arm/kernel/perf_event.c | 2 +- trunk/arch/arm/kernel/stacktrace.c | 2 +- trunk/arch/arm/kernel/traps.c | 5 +- trunk/arch/arm/kernel/unwind.c | 2 +- trunk/arch/arm/mach-ep93xx/include/mach/dma.h | 111 +- trunk/arch/arm/mach-kirkwood/common.c | 7 +- trunk/arch/arm/mach-kirkwood/d2net_v2-setup.c | 2 +- .../arch/arm/mach-kirkwood/lacie_v2-common.c | 14 + .../arch/arm/mach-kirkwood/lacie_v2-common.h | 2 + trunk/arch/arm/mach-kirkwood/mpp.c | 4 +- .../arm/mach-kirkwood/netspace_v2-setup.c | 6 +- .../arch/arm/mach-kirkwood/netxbig_v2-setup.c | 4 +- trunk/arch/arm/mach-kirkwood/ts41x-setup.c | 14 +- .../arch/arm/mach-mmp/include/mach/cputype.h | 3 +- trunk/arch/arm/mach-mv78xx0/mpp.c | 4 +- trunk/arch/arm/mach-orion5x/mpp.c | 4 +- trunk/arch/arm/mach-orion5x/ts78xx-setup.c | 2 +- trunk/arch/arm/mach-pxa/cm-x2xx.c | 2 + trunk/arch/arm/mach-pxa/saar.c | 2 +- trunk/arch/arm/mach-shmobile/Kconfig | 2 - trunk/arch/arm/mach-shmobile/board-ap4evb.c | 46 +- trunk/arch/arm/mach-shmobile/clock-sh7372.c | 102 - .../arm/mach-shmobile/include/mach/gpio.h | 4 +- .../arm/mach-shmobile/include/mach/sh7372.h | 2 - trunk/arch/arm/mach-vexpress/ct-ca9x4.c | 2 - trunk/arch/arm/mm/dma-mapping.c | 2 +- trunk/arch/arm/plat-omap/devices.c | 4 +- trunk/arch/arm/plat-orion/include/plat/pcie.h | 3 - trunk/arch/arm/plat-orion/pcie.c | 5 + trunk/arch/m68k/include/asm/irqflags.h | 2 - trunk/arch/m68k/include/asm/machdep.h | 1 - trunk/arch/powerpc/kernel/kvm.c | 2 +- trunk/arch/powerpc/kvm/booke_interrupts.S | 2 +- trunk/arch/powerpc/kvm/e500.c | 2 +- trunk/arch/powerpc/kvm/powerpc.c | 1 - trunk/arch/powerpc/kvm/timing.c | 2 + trunk/arch/sh/Kconfig | 1 - trunk/arch/sh/Makefile | 3 + trunk/arch/sh/boards/Kconfig | 7 + trunk/arch/sh/boards/Makefile | 2 - trunk/arch/sh/boards/board-edosk7705.c | 78 - trunk/arch/sh/boards/mach-edosk7705/Makefile | 5 + trunk/arch/sh/boards/mach-edosk7705/io.c | 71 + trunk/arch/sh/boards/mach-edosk7705/setup.c | 36 + trunk/arch/sh/boards/mach-microdev/io.c | 246 +- trunk/arch/sh/boards/mach-microdev/setup.c | 23 +- trunk/arch/sh/boards/mach-se/7206/Makefile | 2 +- trunk/arch/sh/boards/mach-se/7206/io.c | 104 + trunk/arch/sh/boards/mach-se/7206/irq.c | 4 +- trunk/arch/sh/boards/mach-se/7206/setup.c | 15 + trunk/arch/sh/boards/mach-se/770x/Makefile | 2 +- trunk/arch/sh/boards/mach-se/770x/io.c | 156 ++ trunk/arch/sh/boards/mach-se/770x/setup.c | 22 + trunk/arch/sh/boards/mach-se/7751/Makefile | 2 +- trunk/arch/sh/boards/mach-se/7751/io.c | 119 + trunk/arch/sh/boards/mach-se/7751/setup.c | 18 + trunk/arch/sh/boards/mach-snapgear/Makefile | 5 + trunk/arch/sh/boards/mach-snapgear/io.c | 121 + .../setup.c} | 38 +- trunk/arch/sh/boards/mach-systemh/Makefile | 13 + trunk/arch/sh/boards/mach-systemh/io.c | 158 ++ trunk/arch/sh/boards/mach-systemh/irq.c | 61 + trunk/arch/sh/boards/mach-systemh/setup.c | 57 + ...eedge5410_defconfig => snapgear_defconfig} | 0 trunk/arch/sh/configs/systemh_defconfig | 28 + trunk/arch/sh/include/asm/addrspace.h | 8 +- trunk/arch/sh/include/asm/pgtable.h | 12 + trunk/arch/sh/include/asm/system.h | 4 +- trunk/arch/sh/include/asm/system_32.h | 36 + trunk/arch/sh/include/asm/system_64.h | 3 + trunk/arch/sh/include/asm/uncached.h | 40 - .../sh/include/mach-common/mach/edosk7705.h | 7 + .../sh/include/mach-common/mach/microdev.h | 9 + .../mach/{secureedge5410.h => snapgear.h} | 22 + .../sh/include/mach-common/mach/systemh7751.h | 71 + trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 6 +- trunk/arch/sh/mm/Kconfig | 2 +- trunk/arch/sh/mm/consistent.c | 15 +- trunk/arch/sh/mm/uncached.c | 2 +- trunk/arch/sh/tools/mach-types | 1 + trunk/arch/tile/include/asm/highmem.h | 1 + trunk/arch/tile/include/asm/kmap_types.h | 34 +- trunk/arch/tile/include/asm/pgtable.h | 6 +- trunk/arch/tile/include/asm/stat.h | 3 - trunk/arch/tile/include/asm/unistd.h | 1 - trunk/arch/tile/kernel/compat.c | 10 +- trunk/arch/tile/kernel/early_printk.c | 2 +- trunk/arch/tile/kernel/hardwall.c | 6 +- trunk/arch/tile/kernel/irq.c | 4 +- trunk/arch/tile/kernel/machine_kexec.c | 6 +- trunk/arch/tile/kernel/messaging.c | 2 +- trunk/arch/tile/kernel/ptrace.c | 39 +- trunk/arch/tile/kernel/reboot.c | 6 +- trunk/arch/tile/kernel/setup.c | 8 +- trunk/arch/tile/kernel/signal.c | 9 +- trunk/arch/tile/kernel/smp.c | 2 +- trunk/arch/tile/kernel/time.c | 8 +- trunk/arch/tile/lib/memcpy_tile64.c | 11 +- trunk/arch/tile/mm/highmem.c | 2 +- trunk/arch/tile/mm/init.c | 8 +- trunk/arch/tile/mm/pgtable.c | 4 +- trunk/arch/um/include/asm/ptrace-generic.h | 4 +- trunk/arch/um/kernel/ptrace.c | 2 +- trunk/arch/x86/include/asm/apic.h | 10 +- trunk/arch/x86/include/asm/uv/uv_mmrs.h | 189 +- trunk/arch/x86/kernel/apic/apic.c | 1 + trunk/arch/x86/kernel/apic/x2apic_uv_x.c | 12 +- trunk/arch/x86/kernel/cpu/perf_event_amd.c | 4 +- trunk/arch/x86/kernel/microcode_amd.c | 2 +- trunk/arch/x86/kernel/mmconf-fam10h_64.c | 7 +- trunk/arch/x86/kernel/pvclock.c | 38 + trunk/arch/x86/kvm/mmu.c | 9 +- trunk/arch/x86/kvm/x86.c | 16 +- trunk/arch/x86/mm/tlb.c | 2 +- trunk/arch/x86/pci/xen.c | 8 +- trunk/arch/x86/platform/uv/tlb_uv.c | 13 +- trunk/arch/x86/xen/mmu.c | 2 +- trunk/arch/x86/xen/setup.c | 18 +- trunk/block/blk-core.c | 11 +- trunk/block/blk-ioc.c | 14 + trunk/block/blk-map.c | 2 - trunk/block/compat_ioctl.c | 4 +- trunk/block/elevator.c | 4 +- trunk/block/ioctl.c | 7 +- trunk/block/scsi_ioctl.c | 34 +- trunk/crypto/pcrypt.c | 1 + trunk/drivers/Makefile | 1 - trunk/drivers/ata/libata-scsi.c | 5 +- trunk/drivers/ata/pata_legacy.c | 2 +- trunk/drivers/ata/pata_octeon_cf.c | 2 + trunk/drivers/atm/fore200e.c | 2 +- trunk/drivers/atm/solos-attrlist.c | 1 - trunk/drivers/atm/solos-pci.c | 8 - trunk/drivers/block/aoe/aoeblk.c | 3 + trunk/drivers/block/aoe/aoecmd.c | 6 +- trunk/drivers/block/cciss.c | 131 +- trunk/drivers/block/cciss.h | 4 - trunk/drivers/block/drbd/drbd_actlog.c | 42 +- trunk/drivers/block/drbd/drbd_int.h | 52 +- trunk/drivers/block/drbd/drbd_main.c | 148 +- trunk/drivers/block/drbd/drbd_nl.c | 25 +- trunk/drivers/block/drbd/drbd_proc.c | 1 + trunk/drivers/block/drbd/drbd_receiver.c | 217 +- trunk/drivers/block/drbd/drbd_req.c | 38 +- trunk/drivers/block/drbd/drbd_worker.c | 23 +- trunk/drivers/block/floppy.c | 4 +- trunk/drivers/block/loop.c | 6 + trunk/drivers/block/xen-blkfront.c | 2 + trunk/drivers/bluetooth/btusb.c | 5 - trunk/drivers/{tty/vt => char}/.gitignore | 0 trunk/drivers/char/Makefile | 44 +- trunk/drivers/char/agp/intel-gtt.c | 6 +- trunk/drivers/char/amiserial.c | 1 + trunk/drivers/{tty/vt => char}/consolemap.c | 0 trunk/drivers/{tty/vt => char}/cp437.uni | 0 .../{tty/vt => char}/defkeymap.c_shipped | 0 trunk/drivers/{tty/vt => char}/defkeymap.map | 0 trunk/drivers/{tty/vt => char}/keyboard.c | 0 trunk/drivers/{tty => char}/n_gsm.c | 5 +- trunk/drivers/{tty => char}/n_hdlc.c | 0 trunk/drivers/{tty => char}/n_r3964.c | 0 trunk/drivers/{tty => char}/n_tty.c | 0 trunk/drivers/char/nozomi.c | 1 + trunk/drivers/char/pcmcia/synclink_cs.c | 1 - trunk/drivers/{tty => char}/pty.c | 0 trunk/drivers/{tty/vt => char}/selection.c | 0 trunk/drivers/{tty => char}/sysrq.c | 0 trunk/drivers/{tty => char}/tty_audit.c | 0 trunk/drivers/{tty => char}/tty_buffer.c | 14 +- trunk/drivers/{tty => char}/tty_io.c | 0 trunk/drivers/{tty => char}/tty_ioctl.c | 0 trunk/drivers/{tty => char}/tty_ldisc.c | 49 +- trunk/drivers/{tty => char}/tty_mutex.c | 0 trunk/drivers/{tty => char}/tty_port.c | 0 trunk/drivers/{tty/vt => char}/vc_screen.c | 6 +- trunk/drivers/{tty/vt => char}/vt.c | 0 trunk/drivers/{tty/vt => char}/vt_ioctl.c | 0 trunk/drivers/clocksource/sh_cmt.c | 10 +- trunk/drivers/clocksource/sh_mtu2.c | 10 +- trunk/drivers/clocksource/sh_tmu.c | 10 +- trunk/drivers/firewire/ohci.c | 88 +- trunk/drivers/gpu/drm/drm_crtc_helper.c | 2 +- trunk/drivers/gpu/drm/drm_edid.c | 26 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 2 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 1 - trunk/drivers/gpu/drm/i915/i915_gem.c | 118 +- trunk/drivers/gpu/drm/i915/i915_gem_evict.c | 8 +- trunk/drivers/gpu/drm/i915/i915_suspend.c | 4 +- trunk/drivers/gpu/drm/i915/intel_display.c | 70 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 2 +- trunk/drivers/gpu/drm/i915/intel_drv.h | 1 - trunk/drivers/gpu/drm/i915/intel_lvds.c | 16 +- trunk/drivers/gpu/drm/i915/intel_opregion.c | 2 +- trunk/drivers/gpu/drm/i915/intel_overlay.c | 4 +- trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 129 +- trunk/drivers/gpu/drm/i915/intel_ringbuffer.h | 3 - trunk/drivers/gpu/drm/radeon/evergreen.c | 8 +- trunk/drivers/gpu/drm/radeon/r100.c | 4 +- trunk/drivers/gpu/drm/radeon/r300.c | 2 +- trunk/drivers/gpu/drm/radeon/r600.c | 12 +- .../drivers/gpu/drm/radeon/radeon_atombios.c | 27 +- .../gpu/drm/radeon/radeon_connectors.c | 16 +- trunk/drivers/gpu/drm/radeon/radeon_display.c | 18 +- .../drivers/gpu/drm/radeon/radeon_encoders.c | 26 - trunk/drivers/gpu/drm/radeon/radeon_fence.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_i2c.c | 41 +- trunk/drivers/gpu/drm/radeon/radeon_mode.h | 17 +- trunk/drivers/gpu/drm/radeon/radeon_object.c | 4 +- trunk/drivers/gpu/drm/radeon/radeon_ttm.c | 3 +- trunk/drivers/gpu/drm/radeon/rs400.c | 2 +- trunk/drivers/gpu/drm/radeon/rs600.c | 4 +- trunk/drivers/gpu/drm/ttm/ttm_bo.c | 86 +- trunk/drivers/gpu/drm/ttm/ttm_bo_manager.c | 81 +- trunk/drivers/gpu/drm/ttm/ttm_tt.c | 4 +- trunk/drivers/gpu/drm/via/via_dmablit.c | 4 +- trunk/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 1 - trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 5 - trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 2 +- trunk/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 2 +- trunk/drivers/gpu/stub/Kconfig | 3 - trunk/drivers/hwmon/ad7414.c | 6 +- trunk/drivers/hwmon/adt7470.c | 4 +- trunk/drivers/hwmon/gpio-fan.c | 8 +- trunk/drivers/hwmon/ltc4261.c | 5 +- trunk/drivers/infiniband/core/addr.c | 14 +- trunk/drivers/infiniband/hw/mlx4/main.c | 6 +- trunk/drivers/input/input.c | 87 +- trunk/drivers/input/keyboard/adp5588-keys.c | 74 +- trunk/drivers/input/keyboard/atkbd.c | 12 +- trunk/drivers/input/misc/pcf8574_keypad.c | 23 +- trunk/drivers/input/serio/i8042-x86ia64io.h | 11 - trunk/drivers/input/tablet/acecad.c | 3 +- .../isdn/hardware/mISDN/mISDNinfineon.c | 4 +- trunk/drivers/isdn/hardware/mISDN/mISDNisar.c | 2 +- trunk/drivers/isdn/hisax/avm_pci.c | 2 +- trunk/drivers/isdn/hisax/callc.c | 4 +- trunk/drivers/isdn/hisax/hfc_2bds0.c | 4 +- trunk/drivers/isdn/hisax/hfc_2bs0.c | 2 +- trunk/drivers/isdn/hisax/hfc_pci.c | 4 +- trunk/drivers/isdn/hisax/hfc_sx.c | 6 +- trunk/drivers/isdn/hisax/hisax.h | 2 - trunk/drivers/isdn/hisax/ipacx.c | 2 +- trunk/drivers/isdn/hisax/isar.c | 10 +- trunk/drivers/isdn/hisax/isdnl1.h | 1 - trunk/drivers/isdn/hisax/isdnl3.c | 2 +- trunk/drivers/isdn/hisax/netjet.c | 10 +- trunk/drivers/isdn/hisax/st5481_d.c | 6 +- trunk/drivers/isdn/i4l/isdn_concap.c | 2 +- trunk/drivers/isdn/i4l/isdn_net.c | 20 +- trunk/drivers/isdn/i4l/isdn_ppp.c | 26 +- trunk/drivers/isdn/mISDN/layer1.c | 10 +- trunk/drivers/isdn/mISDN/layer2.c | 12 +- trunk/drivers/isdn/mISDN/tei.c | 23 +- trunk/drivers/leds/Kconfig | 20 +- trunk/drivers/leds/Makefile | 2 - trunk/drivers/leds/led-class.c | 105 +- trunk/drivers/leds/led-triggers.c | 2 +- trunk/drivers/leds/leds-gpio.c | 2 +- trunk/drivers/leds/leds-lp5521.c | 821 ------- trunk/drivers/leds/leds-lp5523.c | 1065 --------- trunk/drivers/leds/leds-net5501.c | 2 - trunk/drivers/leds/ledtrig-timer.c | 124 +- trunk/drivers/macintosh/adb-iop.c | 4 +- trunk/drivers/md/md.c | 20 +- trunk/drivers/misc/apds9802als.c | 2 +- trunk/drivers/misc/bh1770glc.c | 8 +- trunk/drivers/misc/isl29020.c | 4 +- trunk/drivers/net/3c507.c | 2 +- trunk/drivers/net/3c515.c | 2 +- trunk/drivers/net/3c59x.c | 6 +- trunk/drivers/net/8139cp.c | 10 +- trunk/drivers/net/82596.c | 2 +- trunk/drivers/net/Kconfig | 255 +- trunk/drivers/net/arm/w90p910_ether.c | 2 +- trunk/drivers/net/at1700.c | 2 +- trunk/drivers/net/atarilance.c | 2 +- trunk/drivers/net/atlx/atl1.c | 1 + trunk/drivers/net/ax88796.c | 8 +- trunk/drivers/net/benet/be.h | 35 +- trunk/drivers/net/benet/be_cmds.c | 96 +- trunk/drivers/net/benet/be_cmds.h | 42 +- trunk/drivers/net/benet/be_hw.h | 39 +- trunk/drivers/net/benet/be_main.c | 187 +- trunk/drivers/net/bnx2.c | 54 +- trunk/drivers/net/bnx2.h | 2 - trunk/drivers/net/bnx2x/bnx2x.h | 4 +- trunk/drivers/net/bnx2x/bnx2x_cmn.c | 11 +- trunk/drivers/net/bnx2x/bnx2x_ethtool.c | 9 +- trunk/drivers/net/bnx2x/bnx2x_hsi.h | 9 +- trunk/drivers/net/bnx2x/bnx2x_link.c | 61 +- trunk/drivers/net/bnx2x/bnx2x_main.c | 16 +- trunk/drivers/net/bonding/bond_3ad.c | 3 +- trunk/drivers/net/bonding/bond_main.c | 16 +- trunk/drivers/net/bonding/bonding.h | 2 +- trunk/drivers/net/caif/caif_spi.c | 61 +- trunk/drivers/net/caif/caif_spi_slave.c | 13 +- trunk/drivers/net/can/mscan/mscan.c | 2 +- trunk/drivers/net/can/pch_can.c | 410 ++-- .../net/can/sja1000/sja1000_of_platform.c | 8 +- trunk/drivers/net/cnic.c | 2 +- trunk/drivers/net/cxgb3/cxgb3_main.c | 4 +- trunk/drivers/net/cxgb3/cxgb3_offload.c | 6 +- trunk/drivers/net/cxgb4/cxgb4_main.c | 7 +- trunk/drivers/net/cxgb4vf/adapter.h | 2 +- trunk/drivers/net/cxgb4vf/cxgb4vf_main.c | 75 +- trunk/drivers/net/cxgb4vf/sge.c | 131 +- trunk/drivers/net/cxgb4vf/t4vf_common.h | 1 - trunk/drivers/net/cxgb4vf/t4vf_hw.c | 24 +- trunk/drivers/net/dm9000.c | 2 +- trunk/drivers/net/e1000/e1000_main.c | 6 +- trunk/drivers/net/e1000e/82571.c | 143 +- trunk/drivers/net/e1000e/defines.h | 1 - trunk/drivers/net/e1000e/netdev.c | 57 +- trunk/drivers/net/eepro.c | 2 +- trunk/drivers/net/ehea/ehea_main.c | 4 +- trunk/drivers/net/enic/enic.h | 2 +- trunk/drivers/net/enic/enic_main.c | 4 +- trunk/drivers/net/ethoc.c | 160 +- trunk/drivers/net/fec_mpc52xx.c | 19 +- trunk/drivers/net/forcedeth.c | 326 +-- trunk/drivers/net/gianfar.c | 7 +- trunk/drivers/net/gianfar_ethtool.c | 5 +- trunk/drivers/net/ibm_newemac/core.c | 1 + trunk/drivers/net/igb/igb_main.c | 6 +- trunk/drivers/net/igbvf/Makefile | 2 +- trunk/drivers/net/igbvf/defines.h | 2 +- trunk/drivers/net/igbvf/ethtool.c | 2 +- trunk/drivers/net/igbvf/igbvf.h | 3 +- trunk/drivers/net/igbvf/mbx.c | 2 +- trunk/drivers/net/igbvf/mbx.h | 2 +- trunk/drivers/net/igbvf/netdev.c | 17 +- trunk/drivers/net/igbvf/regs.h | 2 +- trunk/drivers/net/igbvf/vf.c | 2 +- trunk/drivers/net/igbvf/vf.h | 2 +- trunk/drivers/net/ipg.c | 6 +- trunk/drivers/net/iseries_veth.c | 2 +- trunk/drivers/net/ixgb/ixgb_main.c | 6 +- trunk/drivers/net/ixgbe/Makefile | 2 +- trunk/drivers/net/ixgbe/ixgbe.h | 122 +- trunk/drivers/net/ixgbe/ixgbe_82598.c | 58 +- trunk/drivers/net/ixgbe/ixgbe_82599.c | 94 +- trunk/drivers/net/ixgbe/ixgbe_common.c | 98 +- trunk/drivers/net/ixgbe/ixgbe_common.h | 5 +- trunk/drivers/net/ixgbe/ixgbe_dcb.c | 17 +- trunk/drivers/net/ixgbe/ixgbe_dcb.h | 3 +- trunk/drivers/net/ixgbe/ixgbe_dcb_82598.c | 12 +- trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c | 12 +- trunk/drivers/net/ixgbe/ixgbe_dcb_nl.c | 55 +- trunk/drivers/net/ixgbe/ixgbe_ethtool.c | 255 +- trunk/drivers/net/ixgbe/ixgbe_fcoe.c | 15 +- trunk/drivers/net/ixgbe/ixgbe_main.c | 2051 +++++++---------- trunk/drivers/net/ixgbe/ixgbe_mbx.c | 40 +- trunk/drivers/net/ixgbe/ixgbe_mbx.h | 2 +- trunk/drivers/net/ixgbe/ixgbe_phy.c | 52 - trunk/drivers/net/ixgbe/ixgbe_phy.h | 5 - trunk/drivers/net/ixgbe/ixgbe_sriov.c | 5 +- trunk/drivers/net/ixgbe/ixgbe_type.h | 20 - trunk/drivers/net/ixgbe/ixgbe_x540.c | 722 ------ trunk/drivers/net/ixgbevf/Makefile | 2 +- trunk/drivers/net/ixgbevf/defines.h | 2 +- trunk/drivers/net/ixgbevf/ixgbevf.h | 2 +- trunk/drivers/net/ixgbevf/ixgbevf_main.c | 19 +- trunk/drivers/net/ixgbevf/mbx.c | 2 +- trunk/drivers/net/ixgbevf/mbx.h | 2 +- trunk/drivers/net/ixgbevf/regs.h | 2 +- trunk/drivers/net/ixgbevf/vf.c | 2 +- trunk/drivers/net/ixgbevf/vf.h | 2 +- trunk/drivers/net/jme.c | 4 + trunk/drivers/net/ks8851.c | 33 - trunk/drivers/net/lance.c | 2 +- trunk/drivers/net/lib82596.c | 2 +- trunk/drivers/net/lib8390.c | 24 +- trunk/drivers/net/macvlan.c | 113 +- trunk/drivers/net/ne-h8300.c | 12 +- trunk/drivers/net/netxen/netxen_nic_init.c | 7 +- trunk/drivers/net/netxen/netxen_nic_main.c | 9 +- trunk/drivers/net/pch_gbe/pch_gbe_main.c | 6 +- trunk/drivers/net/pcmcia/axnet_cs.c | 48 +- trunk/drivers/net/phy/phy.c | 4 +- trunk/drivers/net/ppp_generic.c | 12 +- trunk/drivers/net/pptp.c | 3 +- trunk/drivers/net/qla3xxx.c | 8 +- trunk/drivers/net/qlcnic/qlcnic.h | 12 +- trunk/drivers/net/qlcnic/qlcnic_ctx.c | 5 - trunk/drivers/net/qlcnic/qlcnic_ethtool.c | 3 +- trunk/drivers/net/qlcnic/qlcnic_hdr.h | 2 +- trunk/drivers/net/qlcnic/qlcnic_init.c | 7 +- trunk/drivers/net/qlcnic/qlcnic_main.c | 6 +- trunk/drivers/net/qlge/qlge.h | 4 +- trunk/drivers/net/qlge/qlge_dbg.c | 21 +- trunk/drivers/net/qlge/qlge_ethtool.c | 19 +- trunk/drivers/net/qlge/qlge_main.c | 8 +- trunk/drivers/net/qlge/qlge_mpi.c | 2 +- trunk/drivers/net/r8169.c | 12 +- trunk/drivers/net/s2io.c | 3 +- trunk/drivers/net/sfc/filter.c | 3 +- trunk/drivers/net/sh_eth.c | 244 +- trunk/drivers/net/skge.c | 1 + trunk/drivers/net/smsc911x.h | 2 +- trunk/drivers/net/stmmac/stmmac.h | 40 +- trunk/drivers/net/stmmac/stmmac_ethtool.c | 4 +- trunk/drivers/net/stmmac/stmmac_main.c | 218 +- trunk/drivers/net/stmmac/stmmac_mdio.c | 8 +- trunk/drivers/net/tg3.c | 195 +- trunk/drivers/net/tg3.h | 19 +- trunk/drivers/net/tulip/de2104x.c | 1 + trunk/drivers/net/ucc_geth.c | 25 +- trunk/drivers/net/usb/hso.c | 1 + trunk/drivers/net/usb/ipheth.c | 2 +- trunk/drivers/net/usb/pegasus.c | 4 +- trunk/drivers/net/usb/usbnet.c | 11 - trunk/drivers/net/virtio_net.c | 12 +- trunk/drivers/net/vmxnet3/vmxnet3_drv.c | 951 ++------ trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c | 174 +- trunk/drivers/net/vmxnet3/vmxnet3_int.h | 73 +- trunk/drivers/net/vxge/vxge-config.c | 1498 ++++++------ trunk/drivers/net/vxge/vxge-config.h | 135 +- trunk/drivers/net/vxge/vxge-ethtool.c | 110 +- trunk/drivers/net/vxge/vxge-main.c | 567 +---- trunk/drivers/net/vxge/vxge-main.h | 81 +- trunk/drivers/net/vxge/vxge-reg.h | 33 +- trunk/drivers/net/vxge/vxge-traffic.h | 28 + trunk/drivers/net/vxge/vxge-version.h | 31 +- .../net/wireless/ath/ath9k/ar9002_hw.c | 3 - trunk/drivers/net/wireless/ath/ath9k/ath9k.h | 1 - .../net/wireless/ath/ath9k/eeprom_9287.c | 2 +- .../drivers/net/wireless/ath/ath9k/hif_usb.c | 40 +- .../net/wireless/ath/ath9k/htc_drv_init.c | 2 - .../net/wireless/ath/ath9k/htc_drv_txrx.c | 2 +- trunk/drivers/net/wireless/ath/ath9k/hw.c | 15 +- trunk/drivers/net/wireless/ath/ath9k/hw.h | 1 - trunk/drivers/net/wireless/ath/ath9k/init.c | 7 - trunk/drivers/net/wireless/ath/ath9k/main.c | 29 +- trunk/drivers/net/wireless/ath/ath9k/recv.c | 4 +- trunk/drivers/net/wireless/ath/ath9k/reg.h | 9 +- trunk/drivers/net/wireless/ath/carl9170/usb.c | 8 +- .../net/wireless/ipw2x00/libipw_module.c | 9 +- .../net/wireless/iwlwifi/iwl3945-base.c | 3 +- trunk/drivers/net/wireless/libertas/cfg.c | 5 +- trunk/drivers/net/wireless/libertas/dev.h | 1 - trunk/drivers/net/wireless/libertas/if_usb.c | 6 - trunk/drivers/net/wireless/libertas/main.c | 7 - trunk/drivers/net/wireless/rt2x00/Kconfig | 3 + trunk/drivers/net/wireless/zd1211rw/zd_chip.c | 1 - trunk/drivers/net/xilinx_emaclite.c | 20 +- trunk/drivers/net/znet.c | 2 +- trunk/drivers/pci/xen-pcifront.c | 6 +- trunk/drivers/rapidio/rio.c | 4 +- trunk/drivers/rtc/rtc-ds1302.c | 2 +- trunk/drivers/s390/net/lcs.c | 10 +- trunk/drivers/s390/net/qeth_core.h | 9 + trunk/drivers/s390/net/qeth_core_main.c | 55 +- trunk/drivers/s390/net/qeth_core_sys.c | 2 +- trunk/drivers/s390/net/qeth_l2_main.c | 11 +- trunk/drivers/s390/net/qeth_l3_main.c | 23 +- trunk/drivers/scsi/scsi_error.c | 18 +- trunk/drivers/serial/8250.c | 5 +- trunk/drivers/serial/8250_pci.c | 5 - trunk/drivers/serial/bfin_5xx.c | 31 +- trunk/drivers/serial/kgdboc.c | 59 - trunk/drivers/sh/clk/core.c | 96 +- trunk/drivers/sh/intc/core.c | 2 +- trunk/drivers/sh/intc/dynamic.c | 2 +- trunk/drivers/staging/ath6kl/Kconfig | 2 +- .../hif/sdio/linux_sdio/src/hif_scatter.c | 4 +- .../staging/ath6kl/os/linux/ar6000_drv.c | 5 +- .../staging/ath6kl/os/linux/cfg80211.c | 7 +- .../os/linux/include/athendpack_linux.h | 0 .../os/linux/include/athstartpack_linux.h | 0 .../staging/batman-adv/hard-interface.c | 15 +- trunk/drivers/staging/batman-adv/routing.c | 12 +- trunk/drivers/staging/batman-adv/routing.h | 4 +- trunk/drivers/staging/batman-adv/unicast.c | 2 +- trunk/drivers/staging/bcm/Bcmchar.c | 49 +- trunk/drivers/staging/brcm80211/README | 2 +- trunk/drivers/staging/brcm80211/TODO | 2 +- .../staging/brcm80211/brcmfmac/dhd_linux.c | 2 + .../staging/brcm80211/brcmfmac/wl_cfg80211.c | 12 +- trunk/drivers/staging/cpia/cpia.c | 6 +- .../staging/ft1000/ft1000-usb/ft1000_chdev.c | 1 + trunk/drivers/staging/hv/hv_utils.c | 3 + .../intel_sst/intel_sst_app_interface.c | 284 +-- .../staging/intel_sst/intel_sst_common.h | 4 +- trunk/drivers/staging/keucr/init.c | 18 +- trunk/drivers/staging/keucr/ms.c | 14 +- trunk/drivers/staging/keucr/msscsi.c | 6 +- trunk/drivers/staging/keucr/sdscsi.c | 4 +- trunk/drivers/staging/keucr/smilsub.c | 18 +- trunk/drivers/staging/keucr/transport.c | 2 +- trunk/drivers/staging/rt2860/common/cmm_aes.c | 2 + trunk/drivers/staging/rt2860/usb_main_dev.c | 1 - trunk/drivers/staging/rtl8192e/r8192E_core.c | 3 - .../staging/solo6x10/solo6010-v4l2-enc.c | 2 +- .../drivers/staging/solo6x10/solo6010-v4l2.c | 2 +- trunk/drivers/staging/stradis/stradis.c | 11 +- trunk/drivers/staging/tidspbridge/Kconfig | 1 + trunk/drivers/staging/tidspbridge/Makefile | 7 +- trunk/drivers/staging/tidspbridge/core/_deh.h | 5 +- .../staging/tidspbridge/core/_tiomap.h | 19 +- .../staging/tidspbridge/core/dsp-mmu.c | 317 +++ .../drivers/staging/tidspbridge/core/io_sm.c | 180 +- .../staging/tidspbridge/core/tiomap3430.c | 1083 +-------- .../staging/tidspbridge/core/tiomap3430_pwr.c | 4 - .../staging/tidspbridge/core/tiomap_io.c | 17 +- .../drivers/staging/tidspbridge/core/ue_deh.c | 115 +- .../staging/tidspbridge/hw/EasiGlobal.h | 41 - .../staging/tidspbridge/hw/MMUAccInt.h | 76 - .../staging/tidspbridge/hw/MMURegAcM.h | 225 -- .../drivers/staging/tidspbridge/hw/hw_defs.h | 58 - trunk/drivers/staging/tidspbridge/hw/hw_mmu.c | 562 ----- trunk/drivers/staging/tidspbridge/hw/hw_mmu.h | 163 -- .../tidspbridge/include/dspbridge/cfgdefs.h | 1 - .../tidspbridge/include/dspbridge/dev.h | 24 - .../tidspbridge/include/dspbridge/dmm.h | 75 - .../tidspbridge/include/dspbridge/drv.h | 10 - .../tidspbridge/include/dspbridge/dsp-mmu.h | 67 + .../tidspbridge/include/dspbridge/dspdefs.h | 44 - .../tidspbridge/include/dspbridge/dspioctl.h | 7 - .../tidspbridge/include/dspbridge/proc.h | 46 - trunk/drivers/staging/tidspbridge/pmgr/dev.c | 63 +- trunk/drivers/staging/tidspbridge/pmgr/dmm.c | 533 ----- .../drivers/staging/tidspbridge/pmgr/dspapi.c | 34 +- trunk/drivers/staging/tidspbridge/rmgr/drv.c | 15 - .../staging/tidspbridge/rmgr/drv_interface.c | 2 - trunk/drivers/staging/tidspbridge/rmgr/node.c | 48 +- trunk/drivers/staging/tidspbridge/rmgr/proc.c | 197 +- trunk/drivers/staging/udlfb/udlfb.c | 2 +- trunk/drivers/staging/vt6656/main_usb.c | 3 +- .../westbridge/astoria/api/src/cyasusb.c | 1 + trunk/drivers/staging/wlan-ng/cfg80211.c | 6 +- trunk/drivers/staging/wlan-ng/p80211netdev.c | 2 +- trunk/drivers/tty/Makefile | 11 - trunk/drivers/tty/vt/Makefile | 34 - trunk/drivers/usb/core/devio.c | 7 +- trunk/drivers/usb/gadget/Kconfig | 2 +- trunk/drivers/usb/gadget/goku_udc.h | 3 +- trunk/drivers/usb/gadget/u_ether.c | 1 + trunk/drivers/usb/gadget/u_serial.c | 54 +- trunk/drivers/usb/host/Kconfig | 2 +- trunk/drivers/usb/host/ehci-mxc.c | 14 +- trunk/drivers/usb/host/ohci-jz4740.c | 2 +- trunk/drivers/usb/misc/iowarrior.c | 1 - trunk/drivers/usb/misc/sisusbvga/sisusb.c | 1 - trunk/drivers/usb/musb/blackfin.c | 80 +- trunk/drivers/usb/musb/musb_core.c | 41 +- trunk/drivers/usb/musb/musb_core.h | 2 +- trunk/drivers/usb/musb/musb_gadget.c | 41 +- trunk/drivers/usb/musb/musb_regs.h | 3 +- trunk/drivers/usb/musb/musbhsdma.c | 14 - trunk/drivers/usb/serial/ftdi_sio.c | 2 - trunk/drivers/usb/serial/ftdi_sio_ids.h | 7 - trunk/drivers/usb/serial/option.c | 2 +- trunk/drivers/usb/storage/uas.c | 5 +- trunk/drivers/uwb/allocator.c | 3 +- trunk/drivers/video/backlight/adp8860_bl.c | 8 +- trunk/drivers/video/backlight/l4f00242t03.c | 2 +- trunk/drivers/video/backlight/lms283gf05.c | 2 +- trunk/drivers/video/backlight/mbp_nvidia_bl.c | 18 - trunk/drivers/video/backlight/pwm_bl.c | 7 +- trunk/drivers/video/backlight/s6e63m0.c | 7 +- trunk/drivers/xen/events.c | 25 +- trunk/fs/bio.c | 23 +- trunk/fs/cifs/TODO | 2 +- trunk/fs/cifs/cifs_fs_sb.h | 6 +- trunk/fs/cifs/cifsfs.c | 5 +- trunk/fs/cifs/cifsglob.h | 3 +- trunk/fs/cifs/cifsproto.h | 1 - trunk/fs/cifs/connect.c | 195 +- trunk/fs/cifs/file.c | 72 +- trunk/fs/cifs/inode.c | 1 + trunk/fs/cifs/ioctl.c | 16 +- trunk/fs/cifs/misc.c | 25 +- trunk/fs/ext4/ext4.h | 4 +- trunk/fs/ext4/inode.c | 5 +- trunk/fs/ext4/mballoc.c | 2 + trunk/fs/ext4/page-io.c | 97 +- trunk/fs/ext4/super.c | 102 +- trunk/fs/hugetlbfs/inode.c | 3 +- trunk/fs/ioprio.c | 18 +- trunk/fs/locks.c | 19 +- trunk/fs/logfs/logfs.h | 2 +- trunk/fs/nfsd/nfs4state.c | 16 +- trunk/fs/openpromfs/inode.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_aops.c | 7 +- trunk/fs/xfs/linux-2.6/xfs_buf.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_iops.c | 3 +- trunk/fs/xfs/linux-2.6/xfs_super.c | 3 + trunk/fs/xfs/linux-2.6/xfs_sync.c | 1 - trunk/fs/xfs/xfs_filestream.c | 8 +- trunk/fs/xfs/xfs_mount.c | 1 - trunk/fs/xfs/xfs_quota.h | 20 +- trunk/include/asm-generic/stat.h | 14 +- trunk/include/drm/ttm/ttm_bo_api.h | 4 - trunk/include/drm/ttm/ttm_bo_driver.h | 79 +- trunk/include/linux/atomic.h | 37 - trunk/include/linux/bio.h | 4 + trunk/include/linux/blk_types.h | 6 +- trunk/include/linux/blkdev.h | 3 +- trunk/include/linux/dccp.h | 2 - trunk/include/linux/drbd.h | 2 +- trunk/include/linux/filter.h | 50 +- trunk/include/linux/hardirq.h | 8 +- trunk/include/linux/highmem.h | 1 - trunk/include/linux/i2c/adp5588.h | 15 +- trunk/include/linux/if_bridge.h | 4 +- trunk/include/linux/if_link.h | 28 - trunk/include/linux/if_macvlan.h | 34 +- trunk/include/linux/if_vlan.h | 25 - trunk/include/linux/igmp.h | 14 +- trunk/include/linux/inetdevice.h | 13 +- trunk/include/linux/input.h | 4 +- trunk/include/linux/iocontext.h | 1 + trunk/include/linux/ipv6.h | 2 +- trunk/include/linux/kernel.h | 3 +- trunk/include/linux/leds-lp5521.h | 47 - trunk/include/linux/leds-lp5523.h | 47 - trunk/include/linux/leds.h | 47 +- trunk/include/linux/mmc/sh_mmcif.h | 18 +- trunk/include/linux/netdevice.h | 61 +- trunk/include/linux/netfilter.h | 4 +- trunk/include/linux/perf_event.h | 10 - trunk/include/linux/pwm_backlight.h | 1 - trunk/include/linux/radix-tree.h | 39 +- trunk/include/linux/resource.h | 1 - trunk/include/linux/rtnetlink.h | 2 +- trunk/include/linux/sh_clk.h | 4 - trunk/include/linux/sh_timer.h | 1 + trunk/include/linux/skbuff.h | 3 +- trunk/include/linux/stmmac.h | 6 +- trunk/include/linux/sunrpc/svc_xprt.h | 18 +- trunk/include/linux/tty.h | 2 +- trunk/include/linux/usb.h | 2 +- trunk/include/linux/usb/musb.h | 2 - trunk/include/net/caif/caif_dev.h | 4 +- trunk/include/net/caif/caif_spi.h | 2 - trunk/include/net/caif/cfcnfg.h | 8 +- trunk/include/net/caif/cfctrl.h | 2 +- trunk/include/net/cfg80211.h | 2 +- trunk/include/net/dn.h | 2 +- trunk/include/net/dn_dev.h | 27 +- trunk/include/net/dn_route.h | 10 - trunk/include/net/dst.h | 8 +- trunk/include/net/dst_ops.h | 1 - trunk/include/net/flow.h | 2 - trunk/include/net/if_inet6.h | 3 +- trunk/include/net/inet_sock.h | 2 +- trunk/include/net/neighbour.h | 12 +- trunk/include/net/netlink.h | 23 +- trunk/include/net/netns/generic.h | 2 +- trunk/include/net/route.h | 24 +- trunk/include/net/rtnetlink.h | 35 - trunk/include/net/scm.h | 5 +- trunk/include/net/sctp/command.h | 3 + trunk/include/net/sctp/constants.h | 14 + trunk/include/net/sctp/structs.h | 2 + trunk/include/net/sock.h | 61 +- trunk/include/net/tcp.h | 6 +- trunk/include/net/udp.h | 4 +- trunk/include/net/x25.h | 2 - trunk/include/net/xfrm.h | 6 - trunk/include/trace/events/ext4.h | 97 - trunk/kernel/exit.c | 8 - trunk/kernel/latencytop.c | 17 +- trunk/kernel/perf_event.c | 42 +- trunk/kernel/printk.c | 6 - trunk/kernel/range.c | 2 +- trunk/kernel/relay.c | 15 +- trunk/kernel/sysctl.c | 9 - trunk/kernel/trace/blktrace.c | 4 + trunk/kernel/watchdog.c | 2 +- trunk/lib/nlattr.c | 22 +- trunk/lib/radix-tree.c | 83 +- trunk/mm/filemap.c | 33 +- trunk/mm/memcontrol.c | 16 +- trunk/mm/mprotect.c | 2 +- trunk/mm/vmscan.c | 2 +- trunk/mm/vmstat.c | 2 +- trunk/net/8021q/vlan.c | 13 +- trunk/net/8021q/vlan.h | 22 +- trunk/net/8021q/vlan_core.c | 4 +- trunk/net/8021q/vlan_dev.c | 197 +- trunk/net/8021q/vlan_netlink.c | 20 + trunk/net/8021q/vlanproc.c | 5 + trunk/net/Kconfig | 5 - trunk/net/atm/br2684.c | 2 +- trunk/net/atm/clip.c | 3 +- trunk/net/atm/lec.c | 3 +- trunk/net/ax25/af_ax25.c | 2 +- trunk/net/bluetooth/Makefile | 2 +- trunk/net/bluetooth/hci_event.c | 6 - trunk/net/bluetooth/hidp/Kconfig | 2 +- trunk/net/bluetooth/l2cap.c | 8 +- trunk/net/bluetooth/rfcomm/core.c | 13 +- trunk/net/bridge/br.c | 4 + trunk/net/bridge/br_fdb.c | 15 +- trunk/net/bridge/br_forward.c | 4 +- trunk/net/bridge/br_if.c | 7 +- trunk/net/bridge/br_input.c | 10 +- trunk/net/bridge/br_multicast.c | 78 +- trunk/net/bridge/br_netfilter.c | 22 +- trunk/net/bridge/br_netlink.c | 10 +- trunk/net/bridge/br_notify.c | 6 +- trunk/net/bridge/br_private.h | 21 +- trunk/net/bridge/br_stp_bpdu.c | 8 +- trunk/net/bridge/netfilter/ebtable_broute.c | 3 +- trunk/net/bridge/netfilter/ebtables.c | 11 +- trunk/net/caif/Makefile | 8 +- trunk/net/caif/caif_config_util.c | 13 +- trunk/net/caif/caif_dev.c | 2 - trunk/net/caif/caif_socket.c | 45 +- trunk/net/caif/cfcnfg.c | 17 +- trunk/net/caif/cfctrl.c | 3 +- trunk/net/caif/cfdbgl.c | 14 - trunk/net/caif/cfrfml.c | 2 +- trunk/net/can/Makefile | 6 +- trunk/net/can/bcm.c | 2 +- trunk/net/ceph/Makefile | 2 +- trunk/net/core/dev.c | 151 +- trunk/net/core/dst.c | 1 - trunk/net/core/filter.c | 373 +-- trunk/net/core/net-sysfs.c | 425 +--- trunk/net/core/net-sysfs.h | 4 +- trunk/net/core/netpoll.c | 3 +- trunk/net/core/pktgen.c | 45 +- trunk/net/core/rtnetlink.c | 175 +- trunk/net/core/scm.c | 10 +- trunk/net/core/sock.c | 14 +- trunk/net/core/timestamping.c | 2 +- trunk/net/dccp/ackvec.c | 616 ++--- trunk/net/dccp/ackvec.h | 151 +- trunk/net/dccp/ccids/ccid2.c | 143 +- trunk/net/dccp/ccids/ccid2.h | 2 - trunk/net/dccp/dccp.h | 11 +- trunk/net/dccp/input.c | 33 +- trunk/net/dccp/ipv4.c | 13 +- trunk/net/dccp/options.c | 100 +- trunk/net/dccp/output.c | 15 - trunk/net/decnet/af_decnet.c | 4 +- trunk/net/decnet/dn_dev.c | 100 +- trunk/net/decnet/dn_fib.c | 6 +- trunk/net/decnet/dn_neigh.c | 2 +- trunk/net/decnet/dn_route.c | 94 +- trunk/net/decnet/dn_rules.c | 2 +- trunk/net/decnet/sysctl_net_decnet.c | 4 +- trunk/net/dns_resolver/Makefile | 2 +- trunk/net/econet/Makefile | 2 +- trunk/net/ipv4/af_inet.c | 18 +- trunk/net/ipv4/arp.c | 12 +- trunk/net/ipv4/devinet.c | 91 - trunk/net/ipv4/fib_frontend.c | 28 +- trunk/net/ipv4/fib_lookup.h | 5 +- trunk/net/ipv4/fib_semantics.c | 8 +- trunk/net/ipv4/icmp.c | 35 +- trunk/net/ipv4/igmp.c | 286 +-- trunk/net/ipv4/inet_connection_sock.c | 15 +- trunk/net/ipv4/inet_diag.c | 27 +- trunk/net/ipv4/ip_gre.c | 43 +- trunk/net/ipv4/ip_output.c | 25 +- trunk/net/ipv4/ipconfig.c | 32 +- trunk/net/ipv4/ipip.c | 20 +- trunk/net/ipv4/ipmr.c | 20 +- trunk/net/ipv4/netfilter.c | 8 +- trunk/net/ipv4/netfilter/Makefile | 6 +- trunk/net/ipv4/netfilter/arp_tables.c | 1 - trunk/net/ipv4/netfilter/ip_tables.c | 1 - trunk/net/ipv4/netfilter/nf_nat_core.c | 40 +- trunk/net/ipv4/proc.c | 8 +- trunk/net/ipv4/raw.c | 7 +- trunk/net/ipv4/route.c | 100 +- trunk/net/ipv4/syncookies.c | 15 +- trunk/net/ipv4/sysctl_net_ipv4.c | 5 +- trunk/net/ipv4/tcp.c | 22 +- trunk/net/ipv4/tcp_input.c | 11 +- trunk/net/ipv4/tcp_ipv4.c | 8 +- trunk/net/ipv4/tcp_output.c | 10 +- trunk/net/ipv4/tcp_probe.c | 4 +- trunk/net/ipv4/udp.c | 20 +- trunk/net/ipv4/xfrm4_policy.c | 47 +- trunk/net/ipv6/addrconf.c | 160 +- trunk/net/ipv6/inet6_connection_sock.c | 22 +- trunk/net/ipv6/ip6_tunnel.c | 2 + trunk/net/ipv6/ip6mr.c | 4 +- trunk/net/ipv6/mcast.c | 77 +- trunk/net/ipv6/netfilter.c | 6 +- trunk/net/ipv6/netfilter/Makefile | 4 +- trunk/net/ipv6/netfilter/ip6_tables.c | 1 - trunk/net/ipv6/netfilter/nf_conntrack_reasm.c | 2 +- trunk/net/ipv6/reassembly.c | 32 +- trunk/net/ipv6/route.c | 34 +- trunk/net/ipv6/sit.c | 14 +- trunk/net/ipv6/udp.c | 4 +- trunk/net/irda/ircomm/Makefile | 4 +- trunk/net/irda/irlan/Makefile | 2 +- trunk/net/irda/irnet/Makefile | 2 +- trunk/net/irda/irttp.c | 30 +- trunk/net/l2tp/l2tp_debugfs.c | 2 +- trunk/net/l2tp/l2tp_ip.c | 12 +- trunk/net/lapb/Makefile | 2 +- trunk/net/mac80211/iface.c | 6 +- trunk/net/netfilter/core.c | 6 +- trunk/net/netfilter/ipvs/Kconfig | 1 - trunk/net/netfilter/ipvs/ip_vs_ctl.c | 6 +- trunk/net/netfilter/ipvs/ip_vs_xmit.c | 42 +- trunk/net/netfilter/nf_conntrack_core.c | 3 +- trunk/net/netfilter/nf_conntrack_proto.c | 6 - trunk/net/netfilter/xt_TEE.c | 12 +- trunk/net/packet/af_packet.c | 94 +- trunk/net/phonet/Makefile | 4 +- trunk/net/rds/Makefile | 8 +- trunk/net/rds/loop.c | 4 - trunk/net/rds/message.c | 4 +- trunk/net/rds/rdma.c | 2 +- trunk/net/rds/tcp.c | 6 - trunk/net/rxrpc/Makefile | 4 +- trunk/net/rxrpc/ar-peer.c | 10 +- trunk/net/sched/cls_basic.c | 4 - trunk/net/sched/cls_cgroup.c | 2 + trunk/net/sched/em_text.c | 3 +- trunk/net/sched/sch_generic.c | 8 +- trunk/net/sched/sch_teql.c | 3 +- trunk/net/sctp/protocol.c | 2 +- trunk/net/sctp/socket.c | 4 +- trunk/net/sctp/sysctl.c | 4 +- trunk/net/socket.c | 11 +- trunk/net/sunrpc/auth_gss/Makefile | 4 +- trunk/net/tipc/socket.c | 1 - trunk/net/unix/af_unix.c | 34 +- trunk/net/wanrouter/Makefile | 2 +- trunk/net/wireless/chan.c | 54 - trunk/net/wireless/nl80211.c | 4 +- trunk/net/x25/af_x25.c | 95 +- trunk/net/x25/x25_facilities.c | 20 +- trunk/net/x25/x25_in.c | 2 - trunk/net/x25/x25_link.c | 8 +- trunk/scripts/kconfig/symbol.c | 2 +- trunk/security/Kconfig | 12 - trunk/security/apparmor/lsm.c | 6 +- trunk/security/apparmor/policy.c | 2 +- trunk/security/commoncap.c | 2 - trunk/security/selinux/hooks.c | 12 +- trunk/sound/pci/asihpi/hpi6000.c | 2 - trunk/sound/pci/asihpi/hpi6205.c | 2 - trunk/sound/pci/asihpi/hpicmn.c | 12 +- trunk/sound/pci/cs46xx/dsp_spos.c | 33 +- trunk/sound/pci/hda/patch_cirrus.c | 1 - trunk/sound/pci/lx6464es/lx6464es.c | 4 +- trunk/sound/pci/lx6464es/lx6464es.h | 2 +- trunk/sound/pci/lx6464es/lx_core.c | 2 +- trunk/sound/soc/codecs/Kconfig | 3 +- trunk/sound/soc/codecs/tlv320dac33.c | 36 +- trunk/sound/soc/codecs/tpa6130a2.c | 6 +- trunk/sound/soc/codecs/wm8900.c | 6 + trunk/sound/soc/codecs/wm_hubs.c | 2 +- trunk/sound/soc/pxa/tosa.c | 2 +- trunk/sound/soc/soc-core.c | 5 +- trunk/sound/usb/mixer_quirks.c | 15 +- trunk/sound/usb/pcm.c | 4 +- trunk/tools/perf/Documentation/perf-trace.txt | 57 +- trunk/tools/perf/builtin-record.c | 10 +- trunk/tools/perf/builtin-top.c | 12 +- trunk/tools/perf/builtin-trace.c | 209 +- .../scripts/perl/bin/failed-syscalls-record | 2 +- .../perf/scripts/perl/bin/rw-by-file-record | 2 +- .../perf/scripts/perl/bin/rw-by-pid-record | 2 +- .../tools/perf/scripts/perl/bin/rwtop-record | 2 +- .../scripts/perl/bin/wakeup-latency-record | 2 +- .../scripts/perl/bin/workqueue-stats-record | 2 +- .../python/bin/failed-syscalls-by-pid-record | 2 +- .../python/bin/futex-contention-record | 2 +- .../scripts/python/bin/netdev-times-record | 2 +- .../scripts/python/bin/sched-migration-record | 2 +- .../perf/scripts/python/bin/sctop-record | 2 +- .../python/bin/syscall-counts-by-pid-record | 2 +- .../scripts/python/bin/syscall-counts-record | 2 +- trunk/tools/perf/util/ui/util.c | 5 +- 893 files changed, 11051 insertions(+), 20156 deletions(-) delete mode 100644 trunk/Documentation/ABI/obsolete/proc-pid-oom_adj delete mode 100644 trunk/Documentation/leds/leds-lp5521.txt delete mode 100644 trunk/Documentation/leds/leds-lp5523.txt delete mode 100644 trunk/arch/sh/boards/board-edosk7705.c create mode 100644 trunk/arch/sh/boards/mach-edosk7705/Makefile create mode 100644 trunk/arch/sh/boards/mach-edosk7705/io.c create mode 100644 trunk/arch/sh/boards/mach-edosk7705/setup.c create mode 100644 trunk/arch/sh/boards/mach-se/7206/io.c create mode 100644 trunk/arch/sh/boards/mach-se/770x/io.c create mode 100644 trunk/arch/sh/boards/mach-se/7751/io.c create mode 100644 trunk/arch/sh/boards/mach-snapgear/Makefile create mode 100644 trunk/arch/sh/boards/mach-snapgear/io.c rename trunk/arch/sh/boards/{board-secureedge5410.c => mach-snapgear/setup.c} (70%) create mode 100644 trunk/arch/sh/boards/mach-systemh/Makefile create mode 100644 trunk/arch/sh/boards/mach-systemh/io.c create mode 100644 trunk/arch/sh/boards/mach-systemh/irq.c create mode 100644 trunk/arch/sh/boards/mach-systemh/setup.c rename trunk/arch/sh/configs/{secureedge5410_defconfig => snapgear_defconfig} (100%) create mode 100644 trunk/arch/sh/configs/systemh_defconfig create mode 100644 trunk/arch/sh/include/mach-common/mach/edosk7705.h rename trunk/arch/sh/include/mach-common/mach/{secureedge5410.h => snapgear.h} (79%) create mode 100644 trunk/arch/sh/include/mach-common/mach/systemh7751.h rename trunk/drivers/{tty/vt => char}/.gitignore (100%) rename trunk/drivers/{tty/vt => char}/consolemap.c (100%) rename trunk/drivers/{tty/vt => char}/cp437.uni (100%) rename trunk/drivers/{tty/vt => char}/defkeymap.c_shipped (100%) rename trunk/drivers/{tty/vt => char}/defkeymap.map (100%) rename trunk/drivers/{tty/vt => char}/keyboard.c (100%) rename trunk/drivers/{tty => char}/n_gsm.c (99%) rename trunk/drivers/{tty => char}/n_hdlc.c (100%) rename trunk/drivers/{tty => char}/n_r3964.c (100%) rename trunk/drivers/{tty => char}/n_tty.c (100%) rename trunk/drivers/{tty => char}/pty.c (100%) rename trunk/drivers/{tty/vt => char}/selection.c (100%) rename trunk/drivers/{tty => char}/sysrq.c (100%) rename trunk/drivers/{tty => char}/tty_audit.c (100%) rename trunk/drivers/{tty => char}/tty_buffer.c (97%) rename trunk/drivers/{tty => char}/tty_io.c (100%) rename trunk/drivers/{tty => char}/tty_ioctl.c (100%) rename trunk/drivers/{tty => char}/tty_ldisc.c (95%) rename trunk/drivers/{tty => char}/tty_mutex.c (100%) rename trunk/drivers/{tty => char}/tty_port.c (100%) rename trunk/drivers/{tty/vt => char}/vc_screen.c (99%) rename trunk/drivers/{tty/vt => char}/vt.c (100%) rename trunk/drivers/{tty/vt => char}/vt_ioctl.c (100%) delete mode 100644 trunk/drivers/leds/leds-lp5521.c delete mode 100644 trunk/drivers/leds/leds-lp5523.c delete mode 100644 trunk/drivers/net/ixgbe/ixgbe_x540.c create mode 100644 trunk/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h create mode 100644 trunk/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h create mode 100644 trunk/drivers/staging/tidspbridge/core/dsp-mmu.c delete mode 100644 trunk/drivers/staging/tidspbridge/hw/EasiGlobal.h delete mode 100644 trunk/drivers/staging/tidspbridge/hw/MMUAccInt.h delete mode 100644 trunk/drivers/staging/tidspbridge/hw/MMURegAcM.h delete mode 100644 trunk/drivers/staging/tidspbridge/hw/hw_defs.h delete mode 100644 trunk/drivers/staging/tidspbridge/hw/hw_mmu.c delete mode 100644 trunk/drivers/staging/tidspbridge/hw/hw_mmu.h delete mode 100644 trunk/drivers/staging/tidspbridge/include/dspbridge/dmm.h create mode 100644 trunk/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h delete mode 100644 trunk/drivers/staging/tidspbridge/pmgr/dmm.c delete mode 100644 trunk/drivers/tty/Makefile delete mode 100644 trunk/drivers/tty/vt/Makefile delete mode 100644 trunk/include/linux/atomic.h delete mode 100644 trunk/include/linux/leds-lp5521.h delete mode 100644 trunk/include/linux/leds-lp5523.h diff --git a/[refs] b/[refs] index 9a2944086381..060a01a322a6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a41778694806ac1ccd4b1dafed1abef8d5ba98ac +refs/heads/master: cf43298864fdfd687202db8c736473522bfceb98 diff --git a/trunk/Documentation/ABI/obsolete/proc-pid-oom_adj b/trunk/Documentation/ABI/obsolete/proc-pid-oom_adj deleted file mode 100644 index cf63f264ce0f..000000000000 --- a/trunk/Documentation/ABI/obsolete/proc-pid-oom_adj +++ /dev/null @@ -1,22 +0,0 @@ -What: /proc//oom_adj -When: August 2012 -Why: /proc//oom_adj allows userspace to influence the oom killer's - badness heuristic used to determine which task to kill when the kernel - is out of memory. - - The badness heuristic has since been rewritten since the introduction of - this tunable such that its meaning is deprecated. The value was - implemented as a bitshift on a score generated by the badness() - function that did not have any precise units of measure. With the - rewrite, the score is given as a proportion of available memory to the - task allocating pages, so using a bitshift which grows the score - exponentially is, thus, impossible to tune with fine granularity. - - A much more powerful interface, /proc//oom_score_adj, was - introduced with the oom killer rewrite that allows users to increase or - decrease the badness() score linearly. This interface will replace - /proc//oom_adj. - - A warning will be emitted to the kernel log if an application uses this - deprecated interface. After it is printed once, future warnings will be - suppressed until the kernel is rebooted. diff --git a/trunk/Documentation/block/switching-sched.txt b/trunk/Documentation/block/switching-sched.txt index 71cfbdc0f74d..d5af3f630814 100644 --- a/trunk/Documentation/block/switching-sched.txt +++ b/trunk/Documentation/block/switching-sched.txt @@ -16,7 +16,7 @@ you can do so by typing: As of the Linux 2.6.10 kernel, it is now possible to change the IO scheduler for a given block device on the fly (thus making it possible, for instance, to set the CFQ scheduler for the system default, but -set a specific device to use the deadline or noop schedulers - which +set a specific device to use the anticipatory or noop schedulers - which can improve that device's throughput). To set a specific scheduler, simply do this: @@ -31,7 +31,7 @@ a "cat /sys/block/DEV/queue/scheduler" - the list of valid names will be displayed, with the currently selected scheduler in brackets: # cat /sys/block/hda/queue/scheduler -noop deadline [cfq] -# echo deadline > /sys/block/hda/queue/scheduler +noop anticipatory deadline [cfq] +# echo anticipatory > /sys/block/hda/queue/scheduler # cat /sys/block/hda/queue/scheduler -noop [deadline] cfq +noop [anticipatory] deadline cfq diff --git a/trunk/Documentation/filesystems/xfs-delayed-logging-design.txt b/trunk/Documentation/filesystems/xfs-delayed-logging-design.txt index 7445bf335dae..96d0df28bed3 100644 --- a/trunk/Documentation/filesystems/xfs-delayed-logging-design.txt +++ b/trunk/Documentation/filesystems/xfs-delayed-logging-design.txt @@ -794,6 +794,17 @@ designed. Roadmap: +2.6.37 Remove experimental tag from mount option + => should be roughly 6 months after initial merge + => enough time to: + => gain confidence and fix problems reported by early + adopters (a.k.a. guinea pigs) + => address worst performance regressions and undesired + behaviours + => start tuning/optimising code for parallelism + => start tuning/optimising algorithms consuming + excessive CPU time + 2.6.39 Switch default mount option to use delayed logging => should be roughly 12 months after initial merge => enough time to shake out remaining problems before next round of diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 92e83e53148f..ed45e9802aa8 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -706,7 +706,7 @@ and is between 256 and 4096 characters. It is defined in the file arch/x86/kernel/cpu/cpufreq/elanfreq.c. elevator= [IOSCHED] - Format: {"cfq" | "deadline" | "noop"} + Format: {"anticipatory" | "cfq" | "deadline" | "noop"} See Documentation/block/as-iosched.txt and Documentation/block/deadline-iosched.txt for details. diff --git a/trunk/Documentation/leds-class.txt b/trunk/Documentation/leds-class.txt index 58b266bd1846..8fd5ca2ae32d 100644 --- a/trunk/Documentation/leds-class.txt +++ b/trunk/Documentation/leds-class.txt @@ -60,18 +60,15 @@ Hardware accelerated blink of LEDs Some LEDs can be programmed to blink without any CPU interaction. To support this feature, a LED driver can optionally implement the -blink_set() function (see ). To set an LED to blinking, -however, it is better to use use the API function led_blink_set(), -as it will check and implement software fallback if necessary. - -To turn off blinking again, use the API function led_brightness_set() -as that will not just set the LED brightness but also stop any software -timers that may have been required for blinking. - -The blink_set() function should choose a user friendly blinking value -if it is called with *delay_on==0 && *delay_off==0 parameters. In this -case the driver should give back the chosen value through delay_on and -delay_off parameters to the leds subsystem. +blink_set() function (see ). If implemented, triggers can +attempt to use it before falling back to software timers. The blink_set() +function should return 0 if the blink setting is supported, or -EINVAL +otherwise, which means that LED blinking will be handled by software. + +The blink_set() function should choose a user friendly blinking +value if it is called with *delay_on==0 && *delay_off==0 parameters. In +this case the driver should give back the chosen value through delay_on +and delay_off parameters to the leds subsystem. Setting the brightness to zero with brightness_set() callback function should completely turn off the LED and cancel the previously programmed diff --git a/trunk/Documentation/leds/leds-lp5521.txt b/trunk/Documentation/leds/leds-lp5521.txt deleted file mode 100644 index c4d8d151e0fe..000000000000 --- a/trunk/Documentation/leds/leds-lp5521.txt +++ /dev/null @@ -1,88 +0,0 @@ -Kernel driver for lp5521 -======================== - -* National Semiconductor LP5521 led driver chip -* Datasheet: http://www.national.com/pf/LP/LP5521.html - -Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo -Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com) - -Description ------------ - -LP5521 can drive up to 3 channels. Leds can be controlled directly via -the led class control interface. Channels have generic names: -lp5521:channelx, where x is 0 .. 2 - -All three channels can be also controlled using the engine micro programs. -More details of the instructions can be found from the public data sheet. - -Control interface for the engines: -x is 1 .. 3 -enginex_mode : disabled, load, run -enginex_load : store program (visible only in engine load mode) - -Example (start to blink the channel 2 led): -cd /sys/class/leds/lp5521:channel2/device -echo "load" > engine3_mode -echo "037f4d0003ff6000" > engine3_load -echo "run" > engine3_mode - -stop the engine: -echo "disabled" > engine3_mode - -sysfs contains a selftest entry. -The test communicates with the chip and checks that -the clock mode is automatically set to the requested one. - -Each channel has its own led current settings. -/sys/class/leds/lp5521:channel0/led_current - RW -/sys/class/leds/lp5521:channel0/max_current - RO -Format: 10x mA i.e 10 means 1.0 mA - -example platform data: - -Note: chan_nr can have values between 0 and 2. - -static struct lp5521_led_config lp5521_led_config[] = { - { - .chan_nr = 0, - .led_current = 50, - .max_current = 130, - }, { - .chan_nr = 1, - .led_current = 0, - .max_current = 130, - }, { - .chan_nr = 2, - .led_current = 0, - .max_current = 130, - } -}; - -static int lp5521_setup(void) -{ - /* setup HW resources */ -} - -static void lp5521_release(void) -{ - /* Release HW resources */ -} - -static void lp5521_enable(bool state) -{ - /* Control of chip enable signal */ -} - -static struct lp5521_platform_data lp5521_platform_data = { - .led_config = lp5521_led_config, - .num_channels = ARRAY_SIZE(lp5521_led_config), - .clock_mode = LP5521_CLOCK_EXT, - .setup_resources = lp5521_setup, - .release_resources = lp5521_release, - .enable = lp5521_enable, -}; - -If the current is set to 0 in the platform data, that channel is -disabled and it is not visible in the sysfs. diff --git a/trunk/Documentation/leds/leds-lp5523.txt b/trunk/Documentation/leds/leds-lp5523.txt deleted file mode 100644 index fad2feb8b7ce..000000000000 --- a/trunk/Documentation/leds/leds-lp5523.txt +++ /dev/null @@ -1,83 +0,0 @@ -Kernel driver for lp5523 -======================== - -* National Semiconductor LP5523 led driver chip -* Datasheet: http://www.national.com/pf/LP/LP5523.html - -Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo -Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com) - -Description ------------ -LP5523 can drive up to 9 channels. Leds can be controlled directly via -the led class control interface. Channels have generic names: -lp5523:channelx where x is 0...8 - -The chip provides 3 engines. Each engine can control channels without -interaction from the main CPU. Details of the micro engine code can be found -from the public data sheet. Leds can be muxed to different channels. - -Control interface for the engines: -x is 1 .. 3 -enginex_mode : disabled, load, run -enginex_load : microcode load (visible only in load mode) -enginex_leds : led mux control (visible only in load mode) - -cd /sys/class/leds/lp5523:channel2/device -echo "load" > engine3_mode -echo "9d80400004ff05ff437f0000" > engine3_load -echo "111111111" > engine3_leds -echo "run" > engine3_mode - -sysfs contains a selftest entry. It measures each channel -voltage level and checks if it looks reasonable. If the level is too high, -the led is missing; if the level is too low, there is a short circuit. - -Selftest uses always the current from the platform data. - -Each channel contains led current settings. -/sys/class/leds/lp5523:channel2/led_current - RW -/sys/class/leds/lp5523:channel2/max_current - RO -Format: 10x mA i.e 10 means 1.0 mA - -Example platform data: - -Note - chan_nr can have values between 0 and 8. - -static struct lp5523_led_config lp5523_led_config[] = { - { - .chan_nr = 0, - .led_current = 50, - .max_current = 130, - }, -... - }, { - .chan_nr = 8, - .led_current = 50, - .max_current = 130, - } -}; - -static int lp5523_setup(void) -{ - /* Setup HW resources */ -} - -static void lp5523_release(void) -{ - /* Release HW resources */ -} - -static void lp5523_enable(bool state) -{ - /* Control chip enable signal */ -} - -static struct lp5523_platform_data lp5523_platform_data = { - .led_config = lp5523_led_config, - .num_channels = ARRAY_SIZE(lp5523_led_config), - .clock_mode = LP5523_CLOCK_EXT, - .setup_resources = lp5523_setup, - .release_resources = lp5523_release, - .enable = lp5523_enable, -}; diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index ae5522703d16..c7165f4cb792 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -20,15 +20,6 @@ ip_no_pmtu_disc - BOOLEAN min_pmtu - INTEGER default 562 - minimum discovered Path MTU -route/max_size - INTEGER - Maximum number of routes allowed in the kernel. Increase - this when using large numbers of interfaces and/or routes. - -neigh/default/gc_thresh3 - INTEGER - Maximum number of neighbor entries allowed. Increase this - when using large numbers of interfaces and when communicating - with large numbers of directly-connected peers. - mtu_expires - INTEGER Time, in seconds, that cached PMTU information is kept. @@ -707,28 +698,10 @@ igmp_max_memberships - INTEGER Change the maximum number of multicast groups we can subscribe to. Default: 20 - Theoretical maximum value is bounded by having to send a membership - report in a single datagram (i.e. the report can't span multiple - datagrams, or risk confusing the switch and leaving groups you don't - intend to). - - The number of supported groups 'M' is bounded by the number of group - report entries you can fit into a single datagram of 65535 bytes. - - M = 65536-sizeof (ip header)/(sizeof(Group record)) - - Group records are variable length, with a minimum of 12 bytes. - So net.ipv4.igmp_max_memberships should not be set higher than: - - (65536-24) / 12 = 5459 - - The value 5459 assumes no IP header options, so in practice - this number may be lower. - - conf/interface/* changes special settings per interface (where - "interface" is the name of your network interface) +conf/interface/* changes special settings per interface (where "interface" is + the name of your network interface) +conf/all/* is special, changes the settings for all interfaces - conf/all/* is special, changes the settings for all interfaces log_martians - BOOLEAN Log packets with impossible addresses to kernel log. diff --git a/trunk/Documentation/networking/stmmac.txt b/trunk/Documentation/networking/stmmac.txt index 80a7a3454902..7ee770b5ef5f 100644 --- a/trunk/Documentation/networking/stmmac.txt +++ b/trunk/Documentation/networking/stmmac.txt @@ -7,7 +7,7 @@ This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers (Synopsys IP blocks); it has been fully tested on STLinux platforms. Currently this network device driver is for all STM embedded MAC/GMAC -(7xxx SoCs). Other platforms start using it i.e. ARM SPEAr. +(7xxx SoCs). DWC Ether MAC 10/100/1000 Universal version 3.41a and DWC Ether MAC 10/100 Universal version 4.0 have been used for developing the first code @@ -95,14 +95,9 @@ Several information came from the platform; please refer to the driver's Header file in include/linux directory. struct plat_stmmacenet_data { - int bus_id; - int pbl; - int clk_csr; - int has_gmac; - int enh_desc; - int tx_coe; - int bugged_jumbo; - int pmt; + int bus_id; + int pbl; + int has_gmac; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(unsigned long ioaddr); #ifdef CONFIG_STM_DRIVERS @@ -119,12 +114,6 @@ Where: registers (on STM platforms); - has_gmac: GMAC core is on board (get it at run-time in the next step); - bus_id: bus identifier. -- tx_coe: core is able to perform the tx csum in HW. -- enh_desc: if sets the MAC will use the enhanced descriptor structure. -- clk_csr: CSR Clock range selection. -- bugged_jumbo: some HWs are not able to perform the csum in HW for - over-sized frames due to limited buffer sizes. Setting this - flag the csum will be done in SW on JUMBO frames. struct plat_stmmacphy_data { int bus_id; @@ -142,28 +131,13 @@ Where: - interface: physical MII interface mode; - phy_reset: hook to reset HW function. -SOURCES: -- Kconfig -- Makefile -- stmmac_main.c: main network device driver; -- stmmac_mdio.c: mdio functions; -- stmmac_ethtool.c: ethtool support; -- stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts - Only tested on ST40 platforms based. -- stmmac.h: private driver structure; -- common.h: common definitions and VFTs; -- descs.h: descriptor structure definitions; -- dwmac1000_core.c: GMAC core functions; -- dwmac1000_dma.c: dma functions for the GMAC chip; -- dwmac1000.h: specific header file for the GMAC; -- dwmac100_core: MAC 100 core and dma code; -- dwmac100_dma.c: dma funtions for the MAC chip; -- dwmac1000.h: specific header file for the MAC; -- dwmac_lib.c: generic DMA functions shared among chips -- enh_desc.c: functions for handling enhanced descriptors -- norm_desc.c: functions for handling normal descriptors - TODO: -- XGMAC controller is not supported. +- Continue to make the driver more generic and suitable for other Synopsys + Ethernet controllers used on other architectures (i.e. ARM). +- 10G controllers are not supported. +- MAC uses Normal descriptors and GMAC uses enhanced ones. + This is a limit that should be reviewed. MAC could want to + use the enhanced structure. +- Checksumming: Rx/Tx csum is done in HW in case of GMAC only. - Review the timer optimisation code to use an embedded device that seems to be available in new chip generations. diff --git a/trunk/Documentation/rbtree.txt b/trunk/Documentation/rbtree.txt index 19f8278c3854..221f38be98f4 100644 --- a/trunk/Documentation/rbtree.txt +++ b/trunk/Documentation/rbtree.txt @@ -21,8 +21,8 @@ three rotations, respectively, to balance the tree), with slightly slower To quote Linux Weekly News: There are a number of red-black trees in use in the kernel. - The deadline and CFQ I/O schedulers employ rbtrees to - track requests; the packet CD/DVD driver does the same. + The anticipatory, deadline, and CFQ I/O schedulers all employ + rbtrees to track requests; the packet CD/DVD driver does the same. The high-resolution timer code uses an rbtree to organize outstanding timer requests. The ext3 filesystem tracks directory entries in a red-black tree. Virtual memory areas (VMAs) are tracked with red-black diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt index 209e1584c3dc..3894eaa23486 100644 --- a/trunk/Documentation/sysctl/kernel.txt +++ b/trunk/Documentation/sysctl/kernel.txt @@ -28,7 +28,6 @@ show up in /proc/sys/kernel: - core_uses_pid - ctrl-alt-del - dentry-state -- dmesg_restrict - domainname - hostname - hotplug @@ -214,19 +213,6 @@ to decide what to do with it. ============================================================== -dmesg_restrict: - -This toggle indicates whether unprivileged users are prevented from using -dmesg(8) to view messages from the kernel's log buffer. When -dmesg_restrict is set to (0) there are no restrictions. When -dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use -dmesg(8). - -The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default -value of dmesg_restrict. - -============================================================== - domainname & hostname: These files can be used to set the NIS/YP domainname and the diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 8b6ca96435ee..0094224ca79b 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -161,7 +161,7 @@ M: Greg Kroah-Hartman L: linux-serial@vger.kernel.org W: http://serial.sourceforge.net S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git +T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ F: drivers/serial/8250* F: include/linux/serial_8250.h @@ -1829,13 +1829,6 @@ W: http://www.chelsio.com S: Supported F: drivers/net/cxgb4vf/ -STMMAC ETHERNET DRIVER -M: Giuseppe Cavallaro -L: netdev@vger.kernel.org -W: http://www.stlinux.com -S: Supported -F: drivers/net/stmmac/ - CYBERPRO FB DRIVER M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -5683,7 +5676,7 @@ S: Maintained STAGING SUBSYSTEM M: Greg Kroah-Hartman -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-next-2.6.git L: devel@driverdev.osuosl.org S: Maintained F: drivers/staging/ @@ -5917,7 +5910,7 @@ S: Maintained TTY LAYER M: Greg Kroah-Hartman S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git +T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ F: drivers/char/tty_* F: drivers/serial/serial_core.c F: include/linux/serial_core.h @@ -6240,7 +6233,7 @@ USB SUBSYSTEM M: Greg Kroah-Hartman L: linux-usb@vger.kernel.org W: http://www.linux-usb.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git +T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ S: Supported F: Documentation/usb/ F: drivers/net/usb/ @@ -6605,14 +6598,14 @@ F: drivers/platform/x86 XEN PCI SUBSYSTEM M: Konrad Rzeszutek Wilk -L: xen-devel@lists.xensource.com (moderated for non-subscribers) +L: xen-devel@lists.xensource.com S: Supported F: arch/x86/pci/*xen* F: drivers/pci/*xen* XEN SWIOTLB SUBSYSTEM M: Konrad Rzeszutek Wilk -L: xen-devel@lists.xensource.com (moderated for non-subscribers) +L: xen-devel@lists.xensource.com S: Supported F: arch/x86/xen/*swiotlb* F: drivers/xen/*swiotlb* @@ -6620,7 +6613,7 @@ F: drivers/xen/*swiotlb* XEN HYPERVISOR INTERFACE M: Jeremy Fitzhardinge M: Konrad Rzeszutek Wilk -L: xen-devel@lists.xensource.com (moderated for non-subscribers) +L: xen-devel@lists.xen.org L: virtualization@lists.osdl.org S: Supported F: arch/x86/xen/ diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 8ae3d48d504c..a19a5266d5fc 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -6,7 +6,7 @@ config ARM select HAVE_MEMBLOCK select RTC_LIB select SYS_SUPPORTS_APM_EMULATION - select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI) + select GENERIC_ATOMIC64 if (!CPU_32v6K) select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_ARCH_KGDB select HAVE_KPROBES if (!XIP_KERNEL) diff --git a/trunk/arch/arm/common/gic.c b/trunk/arch/arm/common/gic.c index 772f95f1aecd..ada6359160eb 100644 --- a/trunk/arch/arm/common/gic.c +++ b/trunk/arch/arm/common/gic.c @@ -251,16 +251,15 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); /* - * Set priority on all global interrupts. + * Set priority on all interrupts. */ - for (i = 32; i < max_irq; i += 4) + for (i = 0; i < max_irq; i += 4) writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); /* - * Disable all interrupts. Leave the PPI and SGIs alone - * as these enables are banked registers. + * Disable all interrupts. */ - for (i = 32; i < max_irq; i += 32) + for (i = 0; i < max_irq; i += 32) writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); /* @@ -278,30 +277,11 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) { - void __iomem *dist_base; - int i; - if (gic_nr >= MAX_GIC_NR) BUG(); - dist_base = gic_data[gic_nr].dist_base; - BUG_ON(!dist_base); - gic_data[gic_nr].cpu_base = base; - /* - * Deal with the banked PPI and SGI interrupts - disable all - * PPI interrupts, ensure all SGI interrupts are enabled. - */ - writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); - writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); - - /* - * Set priority on PPI and SGI interrupts - */ - for (i = 0; i < 32; i += 4) - writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); - writel(0xf0, base + GIC_CPU_PRIMASK); writel(1, base + GIC_CPU_CTRL); } diff --git a/trunk/arch/arm/include/asm/hardware/it8152.h b/trunk/arch/arm/include/asm/hardware/it8152.h index 21fa272301f8..6700c7fc7ebd 100644 --- a/trunk/arch/arm/include/asm/hardware/it8152.h +++ b/trunk/arch/arm/include/asm/hardware/it8152.h @@ -75,7 +75,7 @@ extern unsigned long it8152_base_address; IT8152_PD_IRQ(1) USB (USBR) IT8152_PD_IRQ(0) Audio controller (ACR) */ -#define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) +#define IT8152_IRQ(x) (IRQ_BOARD_END + (x)) /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ #define IT8152_LD_IRQ_COUNT 9 diff --git a/trunk/arch/arm/kernel/hw_breakpoint.c b/trunk/arch/arm/kernel/hw_breakpoint.c index 21e3a4ab3b8c..54593b0c241b 100644 --- a/trunk/arch/arm/kernel/hw_breakpoint.c +++ b/trunk/arch/arm/kernel/hw_breakpoint.c @@ -748,7 +748,8 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, breakpoint_handler(addr, regs); break; case ARM_ENTRY_ASYNC_WATCHPOINT: - WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n"); + WARN_ON("Asynchronous watchpoint exception taken. " + "Debugging results may be unreliable"); case ARM_ENTRY_SYNC_WATCHPOINT: watchpoint_handler(addr, regs); break; diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 07a50357492a..49643b1467e6 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -1749,7 +1749,7 @@ static inline int armv7_pmnc_has_overflowed(unsigned long pmnc) static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, enum armv7_counters counter) { - int ret = 0; + int ret; if (counter == ARMV7_CYCLE_COUNTER) ret = pmnc & ARMV7_FLAG_C; diff --git a/trunk/arch/arm/kernel/stacktrace.c b/trunk/arch/arm/kernel/stacktrace.c index c2e112e1a05f..20b7411e47fd 100644 --- a/trunk/arch/arm/kernel/stacktrace.c +++ b/trunk/arch/arm/kernel/stacktrace.c @@ -28,7 +28,7 @@ int notrace unwind_frame(struct stackframe *frame) /* only go to a higher address on the stack */ low = frame->sp; - high = ALIGN(low, THREAD_SIZE); + high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE; /* check current frame pointer is within bounds */ if (fp < (low + 12) || fp + 4 >= high) diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 446aee97436f..cda78d59aa31 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -53,7 +53,10 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long); void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS - printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); + char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN]; + sprint_symbol(sym1, where); + sprint_symbol(sym2, from); + printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2); #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif diff --git a/trunk/arch/arm/kernel/unwind.c b/trunk/arch/arm/kernel/unwind.c index d2cb0b3c9872..2a161765f6d5 100644 --- a/trunk/arch/arm/kernel/unwind.c +++ b/trunk/arch/arm/kernel/unwind.c @@ -279,7 +279,7 @@ int unwind_frame(struct stackframe *frame) /* only go to a higher address on the stack */ low = frame->sp; - high = ALIGN(low, THREAD_SIZE); + high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE; pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, frame->pc, frame->lr, frame->sp); diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/dma.h b/trunk/arch/arm/mach-ep93xx/include/mach/dma.h index 5e31b2b25da9..3a5961d3f3b1 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/dma.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/dma.h @@ -1,13 +1,5 @@ -/** - * DOC: EP93xx DMA M2P memory to peripheral and peripheral to memory engine - * - * The EP93xx DMA M2P subsystem handles DMA transfers between memory and - * peripherals. DMA M2P channels are available for audio, UARTs and IrDA. - * See chapter 10 of the EP93xx users guide for full details on the DMA M2P - * engine. - * - * See sound/soc/ep93xx/ep93xx-pcm.c for an example use of the DMA M2P code. - * +/* + * arch/arm/mach-ep93xx/include/mach/dma.h */ #ifndef __ASM_ARCH_DMA_H @@ -16,34 +8,12 @@ #include #include -/** - * struct ep93xx_dma_buffer - Information about a buffer to be transferred - * using the DMA M2P engine - * - * @list: Entry in DMA buffer list - * @bus_addr: Physical address of the buffer - * @size: Size of the buffer in bytes - */ struct ep93xx_dma_buffer { struct list_head list; u32 bus_addr; u16 size; }; -/** - * struct ep93xx_dma_m2p_client - Information about a DMA M2P client - * - * @name: Unique name for this client - * @flags: Client flags - * @cookie: User data to pass to callback functions - * @buffer_started: Non NULL function to call when a transfer is started. - * The arguments are the user data cookie and the DMA - * buffer which is starting. - * @buffer_finished: Non NULL function to call when a transfer is completed. - * The arguments are the user data cookie, the DMA buffer - * which has completed, and a boolean flag indicating if - * the transfer had an error. - */ struct ep93xx_dma_m2p_client { char *name; u8 flags; @@ -54,11 +24,10 @@ struct ep93xx_dma_m2p_client { struct ep93xx_dma_buffer *buf, int bytes, int error); - /* private: Internal use only */ + /* Internal to the DMA code. */ void *channel; }; -/* DMA M2P ports */ #define EP93XX_DMA_M2P_PORT_I2S1 0x00 #define EP93XX_DMA_M2P_PORT_I2S2 0x01 #define EP93XX_DMA_M2P_PORT_AAC1 0x02 @@ -70,80 +39,18 @@ struct ep93xx_dma_m2p_client { #define EP93XX_DMA_M2P_PORT_UART3 0x08 #define EP93XX_DMA_M2P_PORT_IRDA 0x09 #define EP93XX_DMA_M2P_PORT_MASK 0x0f +#define EP93XX_DMA_M2P_TX 0x00 +#define EP93XX_DMA_M2P_RX 0x10 +#define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20 +#define EP93XX_DMA_M2P_IGNORE_ERROR 0x40 +#define EP93XX_DMA_M2P_ERROR_MASK 0x60 -/* DMA M2P client flags */ -#define EP93XX_DMA_M2P_TX 0x00 /* Memory to peripheral */ -#define EP93XX_DMA_M2P_RX 0x10 /* Peripheral to memory */ - -/* - * DMA M2P client error handling flags. See the EP93xx users guide - * documentation on the DMA M2P CONTROL register for more details - */ -#define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20 /* Abort on peripheral error */ -#define EP93XX_DMA_M2P_IGNORE_ERROR 0x40 /* Ignore peripheral errors */ -#define EP93XX_DMA_M2P_ERROR_MASK 0x60 /* Mask of error bits */ - -/** - * ep93xx_dma_m2p_client_register - Register a client with the DMA M2P - * subsystem - * - * @m2p: Client information to register - * returns 0 on success - * - * The DMA M2P subsystem allocates a channel and an interrupt line for the DMA - * client - */ -int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p); - -/** - * ep93xx_dma_m2p_client_unregister - Unregister a client from the DMA M2P - * subsystem - * - * @m2p: Client to unregister - * - * Any transfers currently in progress will be completed in hardware, but - * ignored in software. - */ +int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p); void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p); - -/** - * ep93xx_dma_m2p_submit - Submit a DMA M2P transfer - * - * @m2p: DMA Client to submit the transfer on - * @buf: DMA Buffer to submit - * - * If the current or next transfer positions are free on the M2P client then - * the transfer is started immediately. If not, the transfer is added to the - * list of pending transfers. This function must not be called from the - * buffer_finished callback for an M2P channel. - * - */ void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p, struct ep93xx_dma_buffer *buf); - -/** - * ep93xx_dma_m2p_submit_recursive - Put a DMA transfer on the pending list - * for an M2P channel - * - * @m2p: DMA Client to submit the transfer on - * @buf: DMA Buffer to submit - * - * This function must only be called from the buffer_finished callback for an - * M2P channel. It is commonly used to add the next transfer in a chained list - * of DMA transfers. - */ void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p, struct ep93xx_dma_buffer *buf); - -/** - * ep93xx_dma_m2p_flush - Flush all pending transfers on a DMA M2P client - * - * @m2p: DMA client to flush transfers on - * - * Any transfers currently in progress will be completed in hardware, but - * ignored in software. - * - */ void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p); #endif /* __ASM_ARCH_DMA_H */ diff --git a/trunk/arch/arm/mach-kirkwood/common.c b/trunk/arch/arm/mach-kirkwood/common.c index 3688123b5ad8..51ff23b72d3a 100644 --- a/trunk/arch/arm/mach-kirkwood/common.c +++ b/trunk/arch/arm/mach-kirkwood/common.c @@ -854,9 +854,10 @@ int __init kirkwood_find_tclk(void) kirkwood_pcie_id(&dev, &rev); - if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID) - if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0) - return 200000000; + if ((dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 || + rev == MV88F6281_REV_A1)) || + (dev == MV88F6282_DEV_ID)) + return 200000000; return 166666667; } diff --git a/trunk/arch/arm/mach-kirkwood/d2net_v2-setup.c b/trunk/arch/arm/mach-kirkwood/d2net_v2-setup.c index a31c9499ab36..4aa86e4a152c 100644 --- a/trunk/arch/arm/mach-kirkwood/d2net_v2-setup.c +++ b/trunk/arch/arm/mach-kirkwood/d2net_v2-setup.c @@ -225,5 +225,5 @@ MACHINE_START(D2NET_V2, "LaCie d2 Network v2") .init_machine = d2net_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-kirkwood/lacie_v2-common.c b/trunk/arch/arm/mach-kirkwood/lacie_v2-common.c index 285edab776e9..d3ea1b6c8a02 100644 --- a/trunk/arch/arm/mach-kirkwood/lacie_v2-common.c +++ b/trunk/arch/arm/mach-kirkwood/lacie_v2-common.c @@ -111,3 +111,17 @@ void __init lacie_v2_hdd_power_init(int hdd_num) pr_err("Failed to power up HDD%d\n", i + 1); } } + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static void lacie_v2_timer_init(void) +{ + kirkwood_tclk = 166666667; + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +struct sys_timer lacie_v2_timer = { + .init = lacie_v2_timer_init, +}; diff --git a/trunk/arch/arm/mach-kirkwood/lacie_v2-common.h b/trunk/arch/arm/mach-kirkwood/lacie_v2-common.h index fc64f578536e..af521315b87b 100644 --- a/trunk/arch/arm/mach-kirkwood/lacie_v2-common.h +++ b/trunk/arch/arm/mach-kirkwood/lacie_v2-common.h @@ -13,4 +13,6 @@ void lacie_v2_register_flash(void); void lacie_v2_register_i2c_devices(void); void lacie_v2_hdd_power_init(int hdd_num); +extern struct sys_timer lacie_v2_timer; + #endif diff --git a/trunk/arch/arm/mach-kirkwood/mpp.c b/trunk/arch/arm/mach-kirkwood/mpp.c index 27901f702feb..065187d177c6 100644 --- a/trunk/arch/arm/mach-kirkwood/mpp.c +++ b/trunk/arch/arm/mach-kirkwood/mpp.c @@ -59,7 +59,7 @@ void __init kirkwood_mpp_conf(unsigned int *mpp_list) } printk("\n"); - for ( ; *mpp_list; mpp_list++) { + while (*mpp_list) { unsigned int num = MPP_NUM(*mpp_list); unsigned int sel = MPP_SEL(*mpp_list); int shift, gpio_mode; @@ -88,6 +88,8 @@ void __init kirkwood_mpp_conf(unsigned int *mpp_list) if (sel != 0) gpio_mode = 0; orion_gpio_set_valid(num, gpio_mode); + + mpp_list++; } printk(KERN_DEBUG " final MPP regs:"); diff --git a/trunk/arch/arm/mach-kirkwood/netspace_v2-setup.c b/trunk/arch/arm/mach-kirkwood/netspace_v2-setup.c index 65ee21fd2f3b..5ea66f1f4178 100644 --- a/trunk/arch/arm/mach-kirkwood/netspace_v2-setup.c +++ b/trunk/arch/arm/mach-kirkwood/netspace_v2-setup.c @@ -262,7 +262,7 @@ MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -272,7 +272,7 @@ MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -282,6 +282,6 @@ MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif diff --git a/trunk/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/trunk/arch/arm/mach-kirkwood/netxbig_v2-setup.c index 93afd3c8bfd8..a1b45d501aef 100644 --- a/trunk/arch/arm/mach-kirkwood/netxbig_v2-setup.c +++ b/trunk/arch/arm/mach-kirkwood/netxbig_v2-setup.c @@ -403,7 +403,7 @@ MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") .init_machine = netxbig_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -413,6 +413,6 @@ MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") .init_machine = netxbig_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &kirkwood_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif diff --git a/trunk/arch/arm/mach-kirkwood/ts41x-setup.c b/trunk/arch/arm/mach-kirkwood/ts41x-setup.c index 3587a281d993..8be09a0ce4ac 100644 --- a/trunk/arch/arm/mach-kirkwood/ts41x-setup.c +++ b/trunk/arch/arm/mach-kirkwood/ts41x-setup.c @@ -27,10 +27,6 @@ #include "mpp.h" #include "tsx1x-common.h" -/* for the PCIe reset workaround */ -#include - - #define QNAP_TS41X_JUMPER_JP1 45 static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = { @@ -144,16 +140,8 @@ static void __init qnap_ts41x_init(void) static int __init ts41x_pci_init(void) { - if (machine_is_ts41x()) { - /* - * Without this explicit reset, the PCIe SATA controller - * (Marvell 88sx7042/sata_mv) is known to stop working - * after a few minutes. - */ - orion_pcie_reset((void __iomem *)PCIE_VIRT_BASE); - + if (machine_is_ts41x()) kirkwood_pcie_init(KW_PCIE0); - } return 0; } diff --git a/trunk/arch/arm/mach-mmp/include/mach/cputype.h b/trunk/arch/arm/mach-mmp/include/mach/cputype.h index 8a3b56dfd35d..f43a68b213f1 100644 --- a/trunk/arch/arm/mach-mmp/include/mach/cputype.h +++ b/trunk/arch/arm/mach-mmp/include/mach/cputype.h @@ -46,8 +46,7 @@ static inline int cpu_is_pxa910(void) #ifdef CONFIG_CPU_MMP2 static inline int cpu_is_mmp2(void) { - return (((read_cpuid_id() >> 8) & 0xff) == 0x58); -} + return (((cpu_readid_id() >> 8) & 0xff) == 0x58); #else #define cpu_is_mmp2() (0) #endif diff --git a/trunk/arch/arm/mach-mv78xx0/mpp.c b/trunk/arch/arm/mach-mv78xx0/mpp.c index 84db2dfc475c..354ac514eb89 100644 --- a/trunk/arch/arm/mach-mv78xx0/mpp.c +++ b/trunk/arch/arm/mach-mv78xx0/mpp.c @@ -54,7 +54,7 @@ void __init mv78xx0_mpp_conf(unsigned int *mpp_list) } printk("\n"); - for ( ; *mpp_list; mpp_list++) { + while (*mpp_list) { unsigned int num = MPP_NUM(*mpp_list); unsigned int sel = MPP_SEL(*mpp_list); int shift, gpio_mode; @@ -83,6 +83,8 @@ void __init mv78xx0_mpp_conf(unsigned int *mpp_list) if (sel != 0) gpio_mode = 0; orion_gpio_set_valid(num, gpio_mode); + + mpp_list++; } printk(KERN_DEBUG " final MPP regs:"); diff --git a/trunk/arch/arm/mach-orion5x/mpp.c b/trunk/arch/arm/mach-orion5x/mpp.c index db485d3b8144..bc4c3b9aaf83 100644 --- a/trunk/arch/arm/mach-orion5x/mpp.c +++ b/trunk/arch/arm/mach-orion5x/mpp.c @@ -127,7 +127,7 @@ void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) /* Initialize gpiolib. */ orion_gpio_init(); - for ( ; mode->mpp >= 0; mode++) { + while (mode->mpp >= 0) { u32 *reg; int num_type; int shift; @@ -160,6 +160,8 @@ void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode) orion_gpio_set_unused(mode->mpp); orion_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO)); + + mode++; } writel(mpp_0_7_ctrl, MPP_0_7_CTRL); diff --git a/trunk/arch/arm/mach-orion5x/ts78xx-setup.c b/trunk/arch/arm/mach-orion5x/ts78xx-setup.c index c1c1cd04bdde..16f1bd5324be 100644 --- a/trunk/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/trunk/arch/arm/mach-orion5x/ts78xx-setup.c @@ -239,7 +239,7 @@ static struct platform_nand_data ts78xx_ts_nand_data = { static struct resource ts78xx_ts_nand_resources = { .start = TS_NAND_DATA, .end = TS_NAND_DATA + 4, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_IO, }; static struct platform_device ts78xx_ts_nand_device = { diff --git a/trunk/arch/arm/mach-pxa/cm-x2xx.c b/trunk/arch/arm/mach-pxa/cm-x2xx.c index d34b99febeb9..ac5598ce9724 100644 --- a/trunk/arch/arm/mach-pxa/cm-x2xx.c +++ b/trunk/arch/arm/mach-pxa/cm-x2xx.c @@ -476,6 +476,8 @@ static void __init cmx2xx_init(void) static void __init cmx2xx_init_irq(void) { + pxa27x_init_irq(); + if (cpu_is_pxa25x()) { pxa25x_init_irq(); cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ); diff --git a/trunk/arch/arm/mach-pxa/saar.c b/trunk/arch/arm/mach-pxa/saar.c index ffa50e633ee6..4b521e045d75 100644 --- a/trunk/arch/arm/mach-pxa/saar.c +++ b/trunk/arch/arm/mach-pxa/saar.c @@ -116,7 +116,7 @@ static struct platform_device smc91x_device = { }, }; -#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULE) static uint16_t lcd_power_on[] = { /* single frame */ SMART_CMD_NOOP, diff --git a/trunk/arch/arm/mach-shmobile/Kconfig b/trunk/arch/arm/mach-shmobile/Kconfig index 51dcd59eda6a..54b479c35ee0 100644 --- a/trunk/arch/arm/mach-shmobile/Kconfig +++ b/trunk/arch/arm/mach-shmobile/Kconfig @@ -116,6 +116,4 @@ endmenu config SH_CLK_CPG bool -source "drivers/sh/Kconfig" - endif diff --git a/trunk/arch/arm/mach-shmobile/board-ap4evb.c b/trunk/arch/arm/mach-shmobile/board-ap4evb.c index 32d9e2816e56..46ca4d4abf91 100644 --- a/trunk/arch/arm/mach-shmobile/board-ap4evb.c +++ b/trunk/arch/arm/mach-shmobile/board-ap4evb.c @@ -565,50 +565,12 @@ static struct platform_device *qhd_devices[] __initdata = { /* FSI */ #define IRQ_FSI evt2irq(0x1840) - -static int fsi_set_rate(int is_porta, int rate) -{ - struct clk *fsib_clk; - struct clk *fdiv_clk = &sh7372_fsidivb_clk; - int ret; - - /* set_rate is not needed if port A */ - if (is_porta) - return 0; - - fsib_clk = clk_get(NULL, "fsib_clk"); - if (IS_ERR(fsib_clk)) - return -EINVAL; - - switch (rate) { - case 48000: - clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); - clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); - ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; - break; - default: - pr_err("unsupported rate in FSI2 port B\n"); - ret = -EINVAL; - break; - } - - clk_put(fsib_clk); - - return ret; -} - static struct sh_fsi_platform_info fsi_info = { .porta_flags = SH_FSI_BRS_INV | SH_FSI_OUT_SLAVE_MODE | SH_FSI_IN_SLAVE_MODE | SH_FSI_OFMT(PCM) | SH_FSI_IFMT(PCM), - - .portb_flags = SH_FSI_BRS_INV | - SH_FSI_BRM_INV | - SH_FSI_LRS_INV | - SH_FSI_OFMT(SPDIF), - .set_rate = fsi_set_rate, }; static struct resource fsi_resources[] = { @@ -672,7 +634,6 @@ static struct platform_device lcdc1_device = { static struct sh_mobile_hdmi_info hdmi_info = { .lcd_chan = &sh_mobile_lcdc1_info.ch[0], .lcd_dev = &lcdc1_device.dev, - .flags = HDMI_SND_SRC_SPDIF, }; static struct resource hdmi_resources[] = { @@ -1031,7 +992,6 @@ static void __init ap4evb_map_io(void) #define GPIO_PORT9CR 0xE6051009 #define GPIO_PORT10CR 0xE605100A -#define USCCR1 0xE6058144 static void __init ap4evb_init(void) { u32 srcr4; @@ -1102,7 +1062,7 @@ static void __init ap4evb_init(void) /* setup USB phy */ __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ - /* enable FSI2 port A (ak4643) */ + /* enable FSI2 */ gpio_request(GPIO_FN_FSIAIBT, NULL); gpio_request(GPIO_FN_FSIAILR, NULL); gpio_request(GPIO_FN_FSIAISLD, NULL); @@ -1119,10 +1079,6 @@ static void __init ap4evb_init(void) gpio_request(GPIO_PORT41, NULL); gpio_direction_input(GPIO_PORT41); - /* setup FSI2 port B (HDMI) */ - gpio_request(GPIO_FN_FSIBCK, NULL); - __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */ - /* set SPU2 clock to 119.6 MHz */ clk = clk_get(NULL, "spu_clk"); if (!IS_ERR(clk)) { diff --git a/trunk/arch/arm/mach-shmobile/clock-sh7372.c b/trunk/arch/arm/mach-shmobile/clock-sh7372.c index 7db31e6c6bf2..8565aefa21fd 100644 --- a/trunk/arch/arm/mach-shmobile/clock-sh7372.c +++ b/trunk/arch/arm/mach-shmobile/clock-sh7372.c @@ -50,9 +50,6 @@ #define SMSTPCR3 0xe615013c #define SMSTPCR4 0xe6150140 -#define FSIDIVA 0xFE1F8000 -#define FSIDIVB 0xFE1F8008 - /* Platforms must set frequency on their DV_CLKI pin */ struct clk sh7372_dv_clki_clk = { }; @@ -291,7 +288,6 @@ struct clk sh7372_pllc2_clk = { .ops = &pllc2_clk_ops, .parent = &extal1_div2_clk, .freq_table = pllc2_freq_table, - .nr_freqs = ARRAY_SIZE(pllc2_freq_table) - 1, .parent_table = pllc2_parent, .parent_num = ARRAY_SIZE(pllc2_parent), }; @@ -421,101 +417,6 @@ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2), }; -/* FSI DIV */ -static unsigned long fsidiv_recalc(struct clk *clk) -{ - unsigned long value; - - value = __raw_readl(clk->mapping->base); - - if ((value & 0x3) != 0x3) - return 0; - - value >>= 16; - if (value < 2) - return 0; - - return clk->parent->rate / value; -} - -static long fsidiv_round_rate(struct clk *clk, unsigned long rate) -{ - return clk_rate_div_range_round(clk, 2, 0xffff, rate); -} - -static void fsidiv_disable(struct clk *clk) -{ - __raw_writel(0, clk->mapping->base); -} - -static int fsidiv_enable(struct clk *clk) -{ - unsigned long value; - - value = __raw_readl(clk->mapping->base) >> 16; - if (value < 2) { - fsidiv_disable(clk); - return -ENOENT; - } - - __raw_writel((value << 16) | 0x3, clk->mapping->base); - - return 0; -} - -static int fsidiv_set_rate(struct clk *clk, - unsigned long rate, int algo_id) -{ - int idx; - - if (clk->parent->rate == rate) { - fsidiv_disable(clk); - return 0; - } - - idx = (clk->parent->rate / rate) & 0xffff; - if (idx < 2) - return -ENOENT; - - __raw_writel(idx << 16, clk->mapping->base); - return fsidiv_enable(clk); -} - -static struct clk_ops fsidiv_clk_ops = { - .recalc = fsidiv_recalc, - .round_rate = fsidiv_round_rate, - .set_rate = fsidiv_set_rate, - .enable = fsidiv_enable, - .disable = fsidiv_disable, -}; - -static struct clk_mapping sh7372_fsidiva_clk_mapping = { - .phys = FSIDIVA, - .len = 8, -}; - -struct clk sh7372_fsidiva_clk = { - .ops = &fsidiv_clk_ops, - .parent = &div6_reparent_clks[DIV6_FSIA], /* late install */ - .mapping = &sh7372_fsidiva_clk_mapping, -}; - -static struct clk_mapping sh7372_fsidivb_clk_mapping = { - .phys = FSIDIVB, - .len = 8, -}; - -struct clk sh7372_fsidivb_clk = { - .ops = &fsidiv_clk_ops, - .parent = &div6_reparent_clks[DIV6_FSIB], /* late install */ - .mapping = &sh7372_fsidivb_clk_mapping, -}; - -static struct clk *late_main_clks[] = { - &sh7372_fsidiva_clk, - &sh7372_fsidivb_clk, -}; - enum { MSTP001, MSTP131, MSTP130, MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, @@ -684,9 +585,6 @@ void __init sh7372_clock_init(void) if (!ret) ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); - for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) - ret = clk_register(late_main_clks[k]); - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); if (!ret) diff --git a/trunk/arch/arm/mach-shmobile/include/mach/gpio.h b/trunk/arch/arm/mach-shmobile/include/mach/gpio.h index 2b1bb9e43dda..5bc6bd444d72 100644 --- a/trunk/arch/arm/mach-shmobile/include/mach/gpio.h +++ b/trunk/arch/arm/mach-shmobile/include/mach/gpio.h @@ -35,12 +35,12 @@ static inline int gpio_cansleep(unsigned gpio) static inline int gpio_to_irq(unsigned gpio) { - return __gpio_to_irq(gpio); + return -ENOSYS; } static inline int irq_to_gpio(unsigned int irq) { - return -ENOSYS; + return -EINVAL; } #endif /* CONFIG_GPIOLIB */ diff --git a/trunk/arch/arm/mach-shmobile/include/mach/sh7372.h b/trunk/arch/arm/mach-shmobile/include/mach/sh7372.h index e4f9004e7103..147775a94bce 100644 --- a/trunk/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/trunk/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -464,7 +464,5 @@ extern struct clk sh7372_dv_clki_div2_clk; extern struct clk sh7372_pllc2_clk; extern struct clk sh7372_fsiack_clk; extern struct clk sh7372_fsibck_clk; -extern struct clk sh7372_fsidiva_clk; -extern struct clk sh7372_fsidivb_clk; #endif /* __ASM_SH7372_H__ */ diff --git a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c index fd25ccd7272f..c2e405a9e025 100644 --- a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c @@ -54,9 +54,7 @@ static struct map_desc ct_ca9x4_io_desc[] __initdata = { static void __init ct_ca9x4_map_io(void) { -#ifdef CONFIG_LOCAL_TIMERS twd_base = MMIO_P2V(A9_MPCORE_TWD); -#endif v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); } diff --git a/trunk/arch/arm/mm/dma-mapping.c b/trunk/arch/arm/mm/dma-mapping.c index ac6a36142fcd..e4dd0646e859 100644 --- a/trunk/arch/arm/mm/dma-mapping.c +++ b/trunk/arch/arm/mm/dma-mapping.c @@ -198,7 +198,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) * fragmentation of the DMA space, and also prevents allocations * smaller than a section from crossing a section boundary. */ - bit = fls(size - 1); + bit = fls(size - 1) + 1; if (bit > SECTION_SHIFT) bit = SECTION_SHIFT; align = 1 << bit; diff --git a/trunk/arch/arm/plat-omap/devices.c b/trunk/arch/arm/plat-omap/devices.c index fc819120978d..6f42a18b8aa4 100644 --- a/trunk/arch/arm/plat-omap/devices.c +++ b/trunk/arch/arm/plat-omap/devices.c @@ -284,14 +284,12 @@ void __init omap_dsp_reserve_sdram_memblock(void) if (!size) return; - paddr = memblock_alloc(size, SZ_1M); + paddr = __memblock_alloc_base(size, SZ_1M, MEMBLOCK_REAL_LIMIT); if (!paddr) { pr_err("%s: failed to reserve %x bytes\n", __func__, size); return; } - memblock_free(paddr, size); - memblock_remove(paddr, size); omap_dsp_phys_mempool_base = paddr; } diff --git a/trunk/arch/arm/plat-orion/include/plat/pcie.h b/trunk/arch/arm/plat-orion/include/plat/pcie.h index cc99163e73fd..3ebfef72b4e7 100644 --- a/trunk/arch/arm/plat-orion/include/plat/pcie.h +++ b/trunk/arch/arm/plat-orion/include/plat/pcie.h @@ -11,15 +11,12 @@ #ifndef __PLAT_PCIE_H #define __PLAT_PCIE_H -struct pci_bus; - u32 orion_pcie_dev_id(void __iomem *base); u32 orion_pcie_rev(void __iomem *base); int orion_pcie_link_up(void __iomem *base); int orion_pcie_x4_mode(void __iomem *base); int orion_pcie_get_local_bus_nr(void __iomem *base); void orion_pcie_set_local_bus_nr(void __iomem *base, int nr); -void orion_pcie_reset(void __iomem *base); void orion_pcie_setup(void __iomem *base, struct mbus_dram_target_info *dram); int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus, diff --git a/trunk/arch/arm/plat-orion/pcie.c b/trunk/arch/arm/plat-orion/pcie.c index af2d733c50b5..779553a1595e 100644 --- a/trunk/arch/arm/plat-orion/pcie.c +++ b/trunk/arch/arm/plat-orion/pcie.c @@ -181,6 +181,11 @@ void __init orion_pcie_setup(void __iomem *base, u16 cmd; u32 mask; + /* + * soft reset PCIe unit + */ + orion_pcie_reset(base); + /* * Point PCIe unit MBUS decode windows to DRAM space. */ diff --git a/trunk/arch/m68k/include/asm/irqflags.h b/trunk/arch/m68k/include/asm/irqflags.h index 7ef4115b8c4a..4a5b284a1550 100644 --- a/trunk/arch/m68k/include/asm/irqflags.h +++ b/trunk/arch/m68k/include/asm/irqflags.h @@ -2,9 +2,7 @@ #define _M68K_IRQFLAGS_H #include -#ifdef CONFIG_MMU #include -#endif #include #include #include diff --git a/trunk/arch/m68k/include/asm/machdep.h b/trunk/arch/m68k/include/asm/machdep.h index 415d5484916c..789f3b2de0e9 100644 --- a/trunk/arch/m68k/include/asm/machdep.h +++ b/trunk/arch/m68k/include/asm/machdep.h @@ -40,6 +40,5 @@ extern unsigned long hw_timer_offset(void); extern irqreturn_t arch_timer_interrupt(int irq, void *dummy); extern void config_BSP(char *command, int len); -extern void do_IRQ(int irq, struct pt_regs *fp); #endif /* _M68K_MACHDEP_H */ diff --git a/trunk/arch/powerpc/kernel/kvm.c b/trunk/arch/powerpc/kernel/kvm.c index b06bdae04064..428d0e538aec 100644 --- a/trunk/arch/powerpc/kernel/kvm.c +++ b/trunk/arch/powerpc/kernel/kvm.c @@ -127,7 +127,7 @@ static void kvm_patch_ins_nop(u32 *inst) static void kvm_patch_ins_b(u32 *inst, int addr) { -#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC_BOOK3S) +#ifdef CONFIG_RELOCATABLE /* On relocatable kernels interrupts handlers and our code can be in different regions, so we don't patch them */ diff --git a/trunk/arch/powerpc/kvm/booke_interrupts.S b/trunk/arch/powerpc/kvm/booke_interrupts.S index 1cc471faac2d..049846911ce4 100644 --- a/trunk/arch/powerpc/kvm/booke_interrupts.S +++ b/trunk/arch/powerpc/kvm/booke_interrupts.S @@ -416,7 +416,7 @@ lightweight_exit: lwz r3, VCPU_PC(r4) mtsrr0 r3 lwz r3, VCPU_SHARED(r4) - lwz r3, (VCPU_SHARED_MSR + 4)(r3) + lwz r3, VCPU_SHARED_MSR(r3) oris r3, r3, KVMPPC_MSR_MASK@h ori r3, r3, KVMPPC_MSR_MASK@l mtsrr1 r3 diff --git a/trunk/arch/powerpc/kvm/e500.c b/trunk/arch/powerpc/kvm/e500.c index e3768ee9b595..71750f2dd5d3 100644 --- a/trunk/arch/powerpc/kvm/e500.c +++ b/trunk/arch/powerpc/kvm/e500.c @@ -138,8 +138,8 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); free_page((unsigned long)vcpu->arch.shared); - kvm_vcpu_uninit(vcpu); kvmppc_e500_tlb_uninit(vcpu_e500); + kvm_vcpu_uninit(vcpu); kmem_cache_free(kvm_vcpu_cache, vcpu_e500); } diff --git a/trunk/arch/powerpc/kvm/powerpc.c b/trunk/arch/powerpc/kvm/powerpc.c index 38f756f25053..2f87a1627f6c 100644 --- a/trunk/arch/powerpc/kvm/powerpc.c +++ b/trunk/arch/powerpc/kvm/powerpc.c @@ -617,7 +617,6 @@ long kvm_arch_vm_ioctl(struct file *filp, switch (ioctl) { case KVM_PPC_GET_PVINFO: { struct kvm_ppc_pvinfo pvinfo; - memset(&pvinfo, 0, sizeof(pvinfo)); r = kvm_vm_ioctl_get_pvinfo(&pvinfo); if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) { r = -EFAULT; diff --git a/trunk/arch/powerpc/kvm/timing.c b/trunk/arch/powerpc/kvm/timing.c index a021f5827a33..46fa04f12a9b 100644 --- a/trunk/arch/powerpc/kvm/timing.c +++ b/trunk/arch/powerpc/kvm/timing.c @@ -35,6 +35,7 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) int i; /* pause guest execution to avoid concurrent updates */ + local_irq_disable(); mutex_lock(&vcpu->mutex); vcpu->arch.last_exit_type = 0xDEAD; @@ -50,6 +51,7 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) vcpu->arch.timing_last_enter.tv64 = 0; mutex_unlock(&vcpu->mutex); + local_irq_enable(); } static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type) diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 7f217b3a50a8..5c075f562eba 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -193,7 +193,6 @@ config CPU_SH2 config CPU_SH2A bool select CPU_SH2 - select UNCACHED_MAPPING config CPU_SH3 bool diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index 9c8c6e1a2a15..307b3a4a790b 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -133,7 +133,10 @@ machdir-$(CONFIG_SOLUTION_ENGINE) += mach-se machdir-$(CONFIG_SH_HP6XX) += mach-hp6xx machdir-$(CONFIG_SH_DREAMCAST) += mach-dreamcast machdir-$(CONFIG_SH_SH03) += mach-sh03 +machdir-$(CONFIG_SH_SECUREEDGE5410) += mach-snapgear machdir-$(CONFIG_SH_RTS7751R2D) += mach-r2d +machdir-$(CONFIG_SH_7751_SYSTEMH) += mach-systemh +machdir-$(CONFIG_SH_EDOSK7705) += mach-edosk7705 machdir-$(CONFIG_SH_HIGHLANDER) += mach-highlander machdir-$(CONFIG_SH_MIGOR) += mach-migor machdir-$(CONFIG_SH_AP325RXA) += mach-ap325rxa diff --git a/trunk/arch/sh/boards/Kconfig b/trunk/arch/sh/boards/Kconfig index 2018c7ea4c93..9c94711aa6ca 100644 --- a/trunk/arch/sh/boards/Kconfig +++ b/trunk/arch/sh/boards/Kconfig @@ -81,6 +81,13 @@ config SH_7343_SOLUTION_ENGINE Select 7343 SolutionEngine if configuring for a Hitachi SH7343 (SH-Mobile 3AS) evaluation board. +config SH_7751_SYSTEMH + bool "SystemH7751R" + depends on CPU_SUBTYPE_SH7751R + help + Select SystemH if you are configuring for a Renesas SystemH + 7751R evaluation board. + config SH_HP6XX bool "HP6XX" select SYS_SUPPORTS_APM_EMULATION diff --git a/trunk/arch/sh/boards/Makefile b/trunk/arch/sh/boards/Makefile index be7d11d04b26..38ef655cc0f0 100644 --- a/trunk/arch/sh/boards/Makefile +++ b/trunk/arch/sh/boards/Makefile @@ -2,12 +2,10 @@ # Specific board support, not covered by a mach group. # obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o -obj-$(CONFIG_SH_SECUREEDGE5410) += board-secureedge5410.o obj-$(CONFIG_SH_SH2007) += board-sh2007.o obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o obj-$(CONFIG_SH_URQUELL) += board-urquell.o obj-$(CONFIG_SH_SHMIN) += board-shmin.o -obj-$(CONFIG_SH_EDOSK7705) += board-edosk7705.o obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o obj-$(CONFIG_SH_ESPT) += board-espt.o obj-$(CONFIG_SH_POLARIS) += board-polaris.o diff --git a/trunk/arch/sh/boards/board-edosk7705.c b/trunk/arch/sh/boards/board-edosk7705.c deleted file mode 100644 index 4cb3bb74c36f..000000000000 --- a/trunk/arch/sh/boards/board-edosk7705.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * arch/sh/boards/renesas/edosk7705/setup.c - * - * Copyright (C) 2000 Kazumoto Kojima - * - * Hitachi SolutionEngine Support. - * - * Modified for edosk7705 development - * board by S. Dunn, 2003. - */ -#include -#include -#include -#include -#include -#include -#include - -#define SMC_IOBASE 0xA2000000 -#define SMC_IO_OFFSET 0x300 -#define SMC_IOADDR (SMC_IOBASE + SMC_IO_OFFSET) - -#define ETHERNET_IRQ 0x09 - -static void __init sh_edosk7705_init_irq(void) -{ - make_imask_irq(ETHERNET_IRQ); -} - -/* eth initialization functions */ -static struct smc91x_platdata smc91x_info = { - .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL, -}; - -static struct resource smc91x_res[] = { - [0] = { - .start = SMC_IOADDR, - .end = SMC_IOADDR + SZ_32 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = ETHERNET_IRQ, - .end = ETHERNET_IRQ, - .flags = IORESOURCE_IRQ , - } -}; - -static struct platform_device smc91x_dev = { - .name = "smc91x", - .id = -1, - .num_resources = ARRAY_SIZE(smc91x_res), - .resource = smc91x_res, - - .dev = { - .platform_data = &smc91x_info, - }, -}; - -/* platform init code */ -static struct platform_device *edosk7705_devices[] __initdata = { - &smc91x_dev, -}; - -static int __init init_edosk7705_devices(void) -{ - return platform_add_devices(edosk7705_devices, - ARRAY_SIZE(edosk7705_devices)); -} -__initcall(init_edosk7705_devices); - -/* - * The Machine Vector - */ -static struct sh_machine_vector mv_edosk7705 __initmv = { - .mv_name = "EDOSK7705", - .mv_nr_irqs = 80, - .mv_init_irq = sh_edosk7705_init_irq, -}; diff --git a/trunk/arch/sh/boards/mach-edosk7705/Makefile b/trunk/arch/sh/boards/mach-edosk7705/Makefile new file mode 100644 index 000000000000..cd54acb51499 --- /dev/null +++ b/trunk/arch/sh/boards/mach-edosk7705/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the EDOSK7705 specific parts of the kernel +# + +obj-y := setup.o io.o diff --git a/trunk/arch/sh/boards/mach-edosk7705/io.c b/trunk/arch/sh/boards/mach-edosk7705/io.c new file mode 100644 index 000000000000..5b9c57c43241 --- /dev/null +++ b/trunk/arch/sh/boards/mach-edosk7705/io.c @@ -0,0 +1,71 @@ +/* + * arch/sh/boards/renesas/edosk7705/io.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routines for Hitachi EDOSK7705 board. + * + */ + +#include +#include +#include +#include +#include + +#define SMC_IOADDR 0xA2000000 + +/* Map the Ethernet addresses as if it is at 0x300 - 0x320 */ +static unsigned long sh_edosk7705_isa_port2addr(unsigned long port) +{ + /* + * SMC91C96 registers are 4 byte aligned rather than the + * usual 2 byte! + */ + if (port >= 0x300 && port < 0x320) + return SMC_IOADDR + ((port - 0x300) * 2); + + maybebadio(port); + return port; +} + +/* Trying to read / write bytes on odd-byte boundaries to the Ethernet + * registers causes problems. So we bit-shift the value and read / write + * in 2 byte chunks. Setting the low byte to 0 does not cause problems + * now as odd byte writes are only made on the bit mask / interrupt + * register. This may not be the case in future Mar-2003 SJD + */ +unsigned char sh_edosk7705_inb(unsigned long port) +{ + if (port >= 0x300 && port < 0x320 && port & 0x01) + return __raw_readw(port - 1) >> 8; + + return __raw_readb(sh_edosk7705_isa_port2addr(port)); +} + +void sh_edosk7705_outb(unsigned char value, unsigned long port) +{ + if (port >= 0x300 && port < 0x320 && port & 0x01) { + __raw_writew(((unsigned short)value << 8), port - 1); + return; + } + + __raw_writeb(value, sh_edosk7705_isa_port2addr(port)); +} + +void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count) +{ + unsigned char *p = addr; + + while (count--) + *p++ = sh_edosk7705_inb(port); +} + +void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count) +{ + unsigned char *p = (unsigned char *)addr; + + while (count--) + sh_edosk7705_outb(*p++, port); +} diff --git a/trunk/arch/sh/boards/mach-edosk7705/setup.c b/trunk/arch/sh/boards/mach-edosk7705/setup.c new file mode 100644 index 000000000000..d59225e26fb9 --- /dev/null +++ b/trunk/arch/sh/boards/mach-edosk7705/setup.c @@ -0,0 +1,36 @@ +/* + * arch/sh/boards/renesas/edosk7705/setup.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Hitachi SolutionEngine Support. + * + * Modified for edosk7705 development + * board by S. Dunn, 2003. + */ +#include +#include +#include +#include + +static void __init sh_edosk7705_init_irq(void) +{ + /* This is the Ethernet interrupt */ + make_imask_irq(0x09); +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_edosk7705 __initmv = { + .mv_name = "EDOSK7705", + .mv_nr_irqs = 80, + + .mv_inb = sh_edosk7705_inb, + .mv_outb = sh_edosk7705_outb, + + .mv_insb = sh_edosk7705_insb, + .mv_outsb = sh_edosk7705_outsb, + + .mv_init_irq = sh_edosk7705_init_irq, +}; diff --git a/trunk/arch/sh/boards/mach-microdev/io.c b/trunk/arch/sh/boards/mach-microdev/io.c index acdafb0c6404..2960c659020e 100644 --- a/trunk/arch/sh/boards/mach-microdev/io.c +++ b/trunk/arch/sh/boards/mach-microdev/io.c @@ -54,7 +54,7 @@ /* * map I/O ports to memory-mapped addresses */ -void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len) +static unsigned long microdev_isa_port2addr(unsigned long offset) { unsigned long result; @@ -72,6 +72,16 @@ void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len) * Configuration Registers */ result = IO_SUPERIO_PHYS + (offset << 1); +#if 0 + } else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG || + offset == KBD_STATUS_REG) { + /* + * SMSC FDC37C93xAPM SuperIO chip + * + * PS/2 Keyboard + Mouse (ports 0x60 and 0x64). + */ + result = IO_SUPERIO_PHYS + (offset << 1); +#endif } else if (((offset >= IO_IDE1_BASE) && (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || (offset == IO_IDE1_MISC)) { @@ -121,5 +131,237 @@ void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len) result = PVR; } - return (void __iomem *)result; + return result; +} + +#define PORT2ADDR(x) (microdev_isa_port2addr(x)) + +static inline void delay(void) +{ +#if defined(CONFIG_PCI) + /* System board present, just make a dummy SRAM access. (CS0 will be + mapped to PCI memory, probably good to avoid it.) */ + __raw_readw(0xa6800000); +#else + /* CS0 will be mapped to flash, ROM etc so safe to access it. */ + __raw_readw(0xa0000000); +#endif +} + +unsigned char microdev_inb(unsigned long port) +{ +#ifdef CONFIG_PCI + if (port >= PCIBIOS_MIN_IO) + return microdev_pci_inb(port); +#endif + return *(volatile unsigned char*)PORT2ADDR(port); +} + +unsigned short microdev_inw(unsigned long port) +{ +#ifdef CONFIG_PCI + if (port >= PCIBIOS_MIN_IO) + return microdev_pci_inw(port); +#endif + return *(volatile unsigned short*)PORT2ADDR(port); +} + +unsigned int microdev_inl(unsigned long port) +{ +#ifdef CONFIG_PCI + if (port >= PCIBIOS_MIN_IO) + return microdev_pci_inl(port); +#endif + return *(volatile unsigned int*)PORT2ADDR(port); +} + +void microdev_outw(unsigned short b, unsigned long port) +{ +#ifdef CONFIG_PCI + if (port >= PCIBIOS_MIN_IO) { + microdev_pci_outw(b, port); + return; + } +#endif + *(volatile unsigned short*)PORT2ADDR(port) = b; +} + +void microdev_outb(unsigned char b, unsigned long port) +{ +#ifdef CONFIG_PCI + if (port >= PCIBIOS_MIN_IO) { + microdev_pci_outb(b, port); + return; + } +#endif + + /* + * There is a board feature with the current SH4-202 MicroDev in + * that the 2 byte enables (nBE0 and nBE1) are tied together (and + * to the Chip Select Line (Ethernet_CS)). Due to this connectivity, + * it is not possible to safely perform 8-bit writes to the + * Ethernet registers, as 16-bits will be consumed from the Data + * lines (corrupting the other byte). Hence, this function is + * written to implement 16-bit read/modify/write for all byte-wide + * accesses. + * + * Note: there is no problem with byte READS (even or odd). + * + * Sean McGoogan - 16th June 2003. + */ + if ((port >= IO_LAN91C111_BASE) && + (port < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) { + /* + * Then are trying to perform a byte-write to the + * LAN91C111. This needs special care. + */ + if (port % 2 == 1) { /* is the port odd ? */ + /* unset bit-0, i.e. make even */ + const unsigned long evenPort = port-1; + unsigned short word; + + /* + * do a 16-bit read/write to write to 'port', + * preserving even byte. + * + * Even addresses are bits 0-7 + * Odd addresses are bits 8-15 + */ + word = microdev_inw(evenPort); + word = (word & 0xffu) | (b << 8); + microdev_outw(word, evenPort); + } else { + /* else, we are trying to do an even byte write */ + unsigned short word; + + /* + * do a 16-bit read/write to write to 'port', + * preserving odd byte. + * + * Even addresses are bits 0-7 + * Odd addresses are bits 8-15 + */ + word = microdev_inw(port); + word = (word & 0xff00u) | (b); + microdev_outw(word, port); + } + } else { + *(volatile unsigned char*)PORT2ADDR(port) = b; + } +} + +void microdev_outl(unsigned int b, unsigned long port) +{ +#ifdef CONFIG_PCI + if (port >= PCIBIOS_MIN_IO) { + microdev_pci_outl(b, port); + return; + } +#endif + *(volatile unsigned int*)PORT2ADDR(port) = b; +} + +unsigned char microdev_inb_p(unsigned long port) +{ + unsigned char v = microdev_inb(port); + delay(); + return v; +} + +unsigned short microdev_inw_p(unsigned long port) +{ + unsigned short v = microdev_inw(port); + delay(); + return v; +} + +unsigned int microdev_inl_p(unsigned long port) +{ + unsigned int v = microdev_inl(port); + delay(); + return v; +} + +void microdev_outb_p(unsigned char b, unsigned long port) +{ + microdev_outb(b, port); + delay(); +} + +void microdev_outw_p(unsigned short b, unsigned long port) +{ + microdev_outw(b, port); + delay(); +} + +void microdev_outl_p(unsigned int b, unsigned long port) +{ + microdev_outl(b, port); + delay(); +} + +void microdev_insb(unsigned long port, void *buffer, unsigned long count) +{ + volatile unsigned char *port_addr; + unsigned char *buf = buffer; + + port_addr = (volatile unsigned char *)PORT2ADDR(port); + + while (count--) + *buf++ = *port_addr; +} + +void microdev_insw(unsigned long port, void *buffer, unsigned long count) +{ + volatile unsigned short *port_addr; + unsigned short *buf = buffer; + + port_addr = (volatile unsigned short *)PORT2ADDR(port); + + while (count--) + *buf++ = *port_addr; +} + +void microdev_insl(unsigned long port, void *buffer, unsigned long count) +{ + volatile unsigned long *port_addr; + unsigned int *buf = buffer; + + port_addr = (volatile unsigned long *)PORT2ADDR(port); + + while (count--) + *buf++ = *port_addr; +} + +void microdev_outsb(unsigned long port, const void *buffer, unsigned long count) +{ + volatile unsigned char *port_addr; + const unsigned char *buf = buffer; + + port_addr = (volatile unsigned char *)PORT2ADDR(port); + + while (count--) + *port_addr = *buf++; +} + +void microdev_outsw(unsigned long port, const void *buffer, unsigned long count) +{ + volatile unsigned short *port_addr; + const unsigned short *buf = buffer; + + port_addr = (volatile unsigned short *)PORT2ADDR(port); + + while (count--) + *port_addr = *buf++; +} + +void microdev_outsl(unsigned long port, const void *buffer, unsigned long count) +{ + volatile unsigned long *port_addr; + const unsigned int *buf = buffer; + + port_addr = (volatile unsigned long *)PORT2ADDR(port); + + while (count--) + *port_addr = *buf++; } diff --git a/trunk/arch/sh/boards/mach-microdev/setup.c b/trunk/arch/sh/boards/mach-microdev/setup.c index d8a747291e03..d1df2a4fb9b8 100644 --- a/trunk/arch/sh/boards/mach-microdev/setup.c +++ b/trunk/arch/sh/boards/mach-microdev/setup.c @@ -195,6 +195,27 @@ device_initcall(microdev_devices_setup); static struct sh_machine_vector mv_sh4202_microdev __initmv = { .mv_name = "SH4-202 MicroDev", .mv_nr_irqs = 72, - .mv_ioport_map = microdev_ioport_map, + + .mv_inb = microdev_inb, + .mv_inw = microdev_inw, + .mv_inl = microdev_inl, + .mv_outb = microdev_outb, + .mv_outw = microdev_outw, + .mv_outl = microdev_outl, + + .mv_inb_p = microdev_inb_p, + .mv_inw_p = microdev_inw_p, + .mv_inl_p = microdev_inl_p, + .mv_outb_p = microdev_outb_p, + .mv_outw_p = microdev_outw_p, + .mv_outl_p = microdev_outl_p, + + .mv_insb = microdev_insb, + .mv_insw = microdev_insw, + .mv_insl = microdev_insl, + .mv_outsb = microdev_outsb, + .mv_outsw = microdev_outsw, + .mv_outsl = microdev_outsl, + .mv_init_irq = init_microdev_irq, }; diff --git a/trunk/arch/sh/boards/mach-se/7206/Makefile b/trunk/arch/sh/boards/mach-se/7206/Makefile index 5c9eaa0535b9..63e7ed699f39 100644 --- a/trunk/arch/sh/boards/mach-se/7206/Makefile +++ b/trunk/arch/sh/boards/mach-se/7206/Makefile @@ -2,4 +2,4 @@ # Makefile for the 7206 SolutionEngine specific parts of the kernel # -obj-y := setup.o irq.o +obj-y := setup.o io.o irq.o diff --git a/trunk/arch/sh/boards/mach-se/7206/io.c b/trunk/arch/sh/boards/mach-se/7206/io.c new file mode 100644 index 000000000000..adadc77532ee --- /dev/null +++ b/trunk/arch/sh/boards/mach-se/7206/io.c @@ -0,0 +1,104 @@ +/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ + * + * linux/arch/sh/boards/se/7206/io.c + * + * Copyright (C) 2006 Yoshinori Sato + * + * I/O routine for Hitachi 7206 SolutionEngine. + * + */ + +#include +#include +#include +#include + + +static inline void delay(void) +{ + __raw_readw(0x20000000); /* P2 ROM Area */ +} + +/* MS7750 requires special versions of in*, out* routines, since + PC-like io ports are located at upper half byte of 16-bit word which + can be accessed only with 16-bit wide. */ + +static inline volatile __u16 * +port2adr(unsigned int port) +{ + if (port >= 0x2000 && port < 0x2020) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); + else if (port >= 0x300 && port < 0x310) + return (volatile __u16 *) (PA_SMSC + (port - 0x300)); + + return (volatile __u16 *)port; +} + +unsigned char se7206_inb(unsigned long port) +{ + return (*port2adr(port)) & 0xff; +} + +unsigned char se7206_inb_p(unsigned long port) +{ + unsigned long v; + + v = (*port2adr(port)) & 0xff; + delay(); + return v; +} + +unsigned short se7206_inw(unsigned long port) +{ + return *port2adr(port); +} + +void se7206_outb(unsigned char value, unsigned long port) +{ + *(port2adr(port)) = value; +} + +void se7206_outb_p(unsigned char value, unsigned long port) +{ + *(port2adr(port)) = value; + delay(); +} + +void se7206_outw(unsigned short value, unsigned long port) +{ + *port2adr(port) = value; +} + +void se7206_insb(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + __u8 *ap = addr; + + while (count--) + *ap++ = *p; +} + +void se7206_insw(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + __u16 *ap = addr; + while (count--) + *ap++ = *p; +} + +void se7206_outsb(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + const __u8 *ap = addr; + + while (count--) + *p = *ap++; +} + +void se7206_outsw(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + const __u16 *ap = addr; + while (count--) + *p = *ap++; +} diff --git a/trunk/arch/sh/boards/mach-se/7206/irq.c b/trunk/arch/sh/boards/mach-se/7206/irq.c index d961949600fd..883b21eacaa6 100644 --- a/trunk/arch/sh/boards/mach-se/7206/irq.c +++ b/trunk/arch/sh/boards/mach-se/7206/irq.c @@ -139,13 +139,11 @@ void __init init_se7206_IRQ(void) make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */ make_se7206_irq(IRQ1_IRQ); /* ATA */ make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ - - __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */ + __raw_writew(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */ /* FPGA System register setup*/ __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */ - /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ __raw_writew(0x0001,INTSEL); } diff --git a/trunk/arch/sh/boards/mach-se/7206/setup.c b/trunk/arch/sh/boards/mach-se/7206/setup.c index 7f4871c71a01..8f5c65d43d1d 100644 --- a/trunk/arch/sh/boards/mach-se/7206/setup.c +++ b/trunk/arch/sh/boards/mach-se/7206/setup.c @@ -86,5 +86,20 @@ __initcall(se7206_devices_setup); static struct sh_machine_vector mv_se __initmv = { .mv_name = "SolutionEngine", .mv_nr_irqs = 256, + .mv_inb = se7206_inb, + .mv_inw = se7206_inw, + .mv_outb = se7206_outb, + .mv_outw = se7206_outw, + + .mv_inb_p = se7206_inb_p, + .mv_inw_p = se7206_inw, + .mv_outb_p = se7206_outb_p, + .mv_outw_p = se7206_outw, + + .mv_insb = se7206_insb, + .mv_insw = se7206_insw, + .mv_outsb = se7206_outsb, + .mv_outsw = se7206_outsw, + .mv_init_irq = init_se7206_IRQ, }; diff --git a/trunk/arch/sh/boards/mach-se/770x/Makefile b/trunk/arch/sh/boards/mach-se/770x/Makefile index 43ea14feef51..8e624b06d5ea 100644 --- a/trunk/arch/sh/boards/mach-se/770x/Makefile +++ b/trunk/arch/sh/boards/mach-se/770x/Makefile @@ -2,4 +2,4 @@ # Makefile for the 770x SolutionEngine specific parts of the kernel # -obj-y := setup.o irq.o +obj-y := setup.o io.o irq.o diff --git a/trunk/arch/sh/boards/mach-se/770x/io.c b/trunk/arch/sh/boards/mach-se/770x/io.c new file mode 100644 index 000000000000..28833c8786ea --- /dev/null +++ b/trunk/arch/sh/boards/mach-se/770x/io.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2000 Kazumoto Kojima + * + * I/O routine for Hitachi SolutionEngine. + */ +#include +#include +#include +#include + +/* MS7750 requires special versions of in*, out* routines, since + PC-like io ports are located at upper half byte of 16-bit word which + can be accessed only with 16-bit wide. */ + +static inline volatile __u16 * +port2adr(unsigned int port) +{ + if (port & 0xff000000) + return ( volatile __u16 *) port; + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); + else if (port >= 0x1000) + return (volatile __u16 *) (PA_83902 + (port << 1)); + else + return (volatile __u16 *) (PA_SUPERIO + (port << 1)); +} + +static inline int +shifted_port(unsigned long port) +{ + /* For IDE registers, value is not shifted */ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + return 0; + else + return 1; +} + +unsigned char se_inb(unsigned long port) +{ + if (shifted_port(port)) + return (*port2adr(port) >> 8); + else + return (*port2adr(port))&0xff; +} + +unsigned char se_inb_p(unsigned long port) +{ + unsigned long v; + + if (shifted_port(port)) + v = (*port2adr(port) >> 8); + else + v = (*port2adr(port))&0xff; + ctrl_delay(); + return v; +} + +unsigned short se_inw(unsigned long port) +{ + if (port >= 0x2000) + return *port2adr(port); + else + maybebadio(port); + return 0; +} + +unsigned int se_inl(unsigned long port) +{ + maybebadio(port); + return 0; +} + +void se_outb(unsigned char value, unsigned long port) +{ + if (shifted_port(port)) + *(port2adr(port)) = value << 8; + else + *(port2adr(port)) = value; +} + +void se_outb_p(unsigned char value, unsigned long port) +{ + if (shifted_port(port)) + *(port2adr(port)) = value << 8; + else + *(port2adr(port)) = value; + ctrl_delay(); +} + +void se_outw(unsigned short value, unsigned long port) +{ + if (port >= 0x2000) + *port2adr(port) = value; + else + maybebadio(port); +} + +void se_outl(unsigned int value, unsigned long port) +{ + maybebadio(port); +} + +void se_insb(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + __u8 *ap = addr; + + if (shifted_port(port)) { + while (count--) + *ap++ = *p >> 8; + } else { + while (count--) + *ap++ = *p; + } +} + +void se_insw(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + __u16 *ap = addr; + while (count--) + *ap++ = *p; +} + +void se_insl(unsigned long port, void *addr, unsigned long count) +{ + maybebadio(port); +} + +void se_outsb(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + const __u8 *ap = addr; + + if (shifted_port(port)) { + while (count--) + *p = *ap++ << 8; + } else { + while (count--) + *p = *ap++; + } +} + +void se_outsw(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + const __u16 *ap = addr; + + while (count--) + *p = *ap++; +} + +void se_outsl(unsigned long port, const void *addr, unsigned long count) +{ + maybebadio(port); +} diff --git a/trunk/arch/sh/boards/mach-se/770x/setup.c b/trunk/arch/sh/boards/mach-se/770x/setup.c index 31330c65c0ce..66d39d1b0901 100644 --- a/trunk/arch/sh/boards/mach-se/770x/setup.c +++ b/trunk/arch/sh/boards/mach-se/770x/setup.c @@ -195,5 +195,27 @@ static struct sh_machine_vector mv_se __initmv = { #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) .mv_nr_irqs = 104, #endif + + .mv_inb = se_inb, + .mv_inw = se_inw, + .mv_inl = se_inl, + .mv_outb = se_outb, + .mv_outw = se_outw, + .mv_outl = se_outl, + + .mv_inb_p = se_inb_p, + .mv_inw_p = se_inw, + .mv_inl_p = se_inl, + .mv_outb_p = se_outb_p, + .mv_outw_p = se_outw, + .mv_outl_p = se_outl, + + .mv_insb = se_insb, + .mv_insw = se_insw, + .mv_insl = se_insl, + .mv_outsb = se_outsb, + .mv_outsw = se_outsw, + .mv_outsl = se_outsl, + .mv_init_irq = init_se_IRQ, }; diff --git a/trunk/arch/sh/boards/mach-se/7751/Makefile b/trunk/arch/sh/boards/mach-se/7751/Makefile index a338fd9d5039..e6f4341bfe6e 100644 --- a/trunk/arch/sh/boards/mach-se/7751/Makefile +++ b/trunk/arch/sh/boards/mach-se/7751/Makefile @@ -2,4 +2,4 @@ # Makefile for the 7751 SolutionEngine specific parts of the kernel # -obj-y := setup.o irq.o +obj-y := setup.o io.o irq.o diff --git a/trunk/arch/sh/boards/mach-se/7751/io.c b/trunk/arch/sh/boards/mach-se/7751/io.c new file mode 100644 index 000000000000..6e75bd4459e5 --- /dev/null +++ b/trunk/arch/sh/boards/mach-se/7751/io.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Hitachi 7751 SolutionEngine. + * + * Initial version only to support LAN access; some + * placeholder code from io_se.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ +#include +#include +#include +#include +#include +#include + +static inline volatile u16 *port2adr(unsigned int port) +{ + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); + maybebadio((unsigned long)port); + return (volatile __u16*)port; +} + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +unsigned char sh7751se_inb(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned char *)port; + else + return (*port2adr(port)) & 0xff; +} + +unsigned char sh7751se_inb_p(unsigned long port) +{ + unsigned char v; + + if (PXSEG(port)) + v = *(volatile unsigned char *)port; + else + v = (*port2adr(port)) & 0xff; + ctrl_delay(); + return v; +} + +unsigned short sh7751se_inw(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (port >= 0x2000) + return *port2adr(port); + else + maybebadio(port); + return 0; +} + +unsigned int sh7751se_inl(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (port >= 0x2000) + return *port2adr(port); + else + maybebadio(port); + return 0; +} + +void sh7751se_outb(unsigned char value, unsigned long port) +{ + + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else + *(port2adr(port)) = value; +} + +void sh7751se_outb_p(unsigned char value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else + *(port2adr(port)) = value; + ctrl_delay(); +} + +void sh7751se_outw(unsigned short value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (port >= 0x2000) + *port2adr(port) = value; + else + maybebadio(port); +} + +void sh7751se_outl(unsigned int value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else + maybebadio(port); +} + +void sh7751se_insl(unsigned long port, void *addr, unsigned long count) +{ + maybebadio(port); +} + +void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count) +{ + maybebadio(port); +} diff --git a/trunk/arch/sh/boards/mach-se/7751/setup.c b/trunk/arch/sh/boards/mach-se/7751/setup.c index 9fbc51beb181..50572512e3e8 100644 --- a/trunk/arch/sh/boards/mach-se/7751/setup.c +++ b/trunk/arch/sh/boards/mach-se/7751/setup.c @@ -56,5 +56,23 @@ __initcall(se7751_devices_setup); static struct sh_machine_vector mv_7751se __initmv = { .mv_name = "7751 SolutionEngine", .mv_nr_irqs = 72, + + .mv_inb = sh7751se_inb, + .mv_inw = sh7751se_inw, + .mv_inl = sh7751se_inl, + .mv_outb = sh7751se_outb, + .mv_outw = sh7751se_outw, + .mv_outl = sh7751se_outl, + + .mv_inb_p = sh7751se_inb_p, + .mv_inw_p = sh7751se_inw, + .mv_inl_p = sh7751se_inl, + .mv_outb_p = sh7751se_outb_p, + .mv_outw_p = sh7751se_outw, + .mv_outl_p = sh7751se_outl, + + .mv_insl = sh7751se_insl, + .mv_outsl = sh7751se_outsl, + .mv_init_irq = init_7751se_IRQ, }; diff --git a/trunk/arch/sh/boards/mach-snapgear/Makefile b/trunk/arch/sh/boards/mach-snapgear/Makefile new file mode 100644 index 000000000000..d2d2f4b6a502 --- /dev/null +++ b/trunk/arch/sh/boards/mach-snapgear/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the SnapGear specific parts of the kernel +# + +obj-y := setup.o io.o diff --git a/trunk/arch/sh/boards/mach-snapgear/io.c b/trunk/arch/sh/boards/mach-snapgear/io.c new file mode 100644 index 000000000000..476650e42dbc --- /dev/null +++ b/trunk/arch/sh/boards/mach-snapgear/io.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2002 David McCullough + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Hitachi 7751 SolutionEngine. + * + * Initial version only to support LAN access; some + * placeholder code from io_se.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ +#include +#include +#include +#include +#include + +#ifdef CONFIG_SH_SECUREEDGE5410 +unsigned short secureedge5410_ioport; +#endif + +static inline volatile __u16 *port2adr(unsigned int port) +{ + maybebadio((unsigned long)port); + return (volatile __u16*)port; +} + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +unsigned char snapgear_inb(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned char *)port; + else + return (*port2adr(port)) & 0xff; +} + +unsigned char snapgear_inb_p(unsigned long port) +{ + unsigned char v; + + if (PXSEG(port)) + v = *(volatile unsigned char *)port; + else + v = (*port2adr(port))&0xff; + ctrl_delay(); + return v; +} + +unsigned short snapgear_inw(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (port >= 0x2000) + return *port2adr(port); + else + maybebadio(port); + return 0; +} + +unsigned int snapgear_inl(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (port >= 0x2000) + return *port2adr(port); + else + maybebadio(port); + return 0; +} + +void snapgear_outb(unsigned char value, unsigned long port) +{ + + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else + *(port2adr(port)) = value; +} + +void snapgear_outb_p(unsigned char value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else + *(port2adr(port)) = value; + ctrl_delay(); +} + +void snapgear_outw(unsigned short value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (port >= 0x2000) + *port2adr(port) = value; + else + maybebadio(port); +} + +void snapgear_outl(unsigned int value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else + maybebadio(port); +} + +void snapgear_insl(unsigned long port, void *addr, unsigned long count) +{ + maybebadio(port); +} + +void snapgear_outsl(unsigned long port, const void *addr, unsigned long count) +{ + maybebadio(port); +} diff --git a/trunk/arch/sh/boards/board-secureedge5410.c b/trunk/arch/sh/boards/mach-snapgear/setup.c similarity index 70% rename from trunk/arch/sh/boards/board-secureedge5410.c rename to trunk/arch/sh/boards/mach-snapgear/setup.c index 32f875e8493d..331745dee379 100644 --- a/trunk/arch/sh/boards/board-secureedge5410.c +++ b/trunk/arch/sh/boards/mach-snapgear/setup.c @@ -1,4 +1,6 @@ /* + * linux/arch/sh/boards/snapgear/setup.c + * * Copyright (C) 2002 David McCullough * Copyright (C) 2003 Paul Mundt * @@ -17,19 +19,18 @@ #include #include #include -#include +#include #include #include #include -unsigned short secureedge5410_ioport; - /* * EraseConfig handling functions */ + static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) { - ctrl_delay(); /* dummy read */ + (void)__raw_readb(0xb8000000); /* dummy read */ printk("SnapGear: erase switch interrupt!\n"); @@ -38,22 +39,21 @@ static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) static int __init eraseconfig_init(void) { - unsigned int irq = evt2irq(0x240); - printk("SnapGear: EraseConfig init\n"); - /* Setup "EraseConfig" switch on external IRQ 0 */ - if (request_irq(irq, eraseconfig_interrupt, IRQF_DISABLED, + if (request_irq(IRL0_IRQ, eraseconfig_interrupt, IRQF_DISABLED, "Erase Config", NULL)) printk("SnapGear: failed to register IRQ%d for Reset witch\n", - irq); + IRL0_IRQ); else printk("SnapGear: registered EraseConfig switch on IRQ%d\n", - irq); - return 0; + IRL0_IRQ); + return(0); } + module_init(eraseconfig_init); +/****************************************************************************/ /* * Initialize IRQ setting * @@ -62,6 +62,7 @@ module_init(eraseconfig_init); * IRL2 = eth1 * IRL3 = crypto */ + static void __init init_snapgear_IRQ(void) { printk("Setup SnapGear IRQ/IPR ...\n"); @@ -75,5 +76,20 @@ static void __init init_snapgear_IRQ(void) static struct sh_machine_vector mv_snapgear __initmv = { .mv_name = "SnapGear SecureEdge5410", .mv_nr_irqs = 72, + + .mv_inb = snapgear_inb, + .mv_inw = snapgear_inw, + .mv_inl = snapgear_inl, + .mv_outb = snapgear_outb, + .mv_outw = snapgear_outw, + .mv_outl = snapgear_outl, + + .mv_inb_p = snapgear_inb_p, + .mv_inw_p = snapgear_inw, + .mv_inl_p = snapgear_inl, + .mv_outb_p = snapgear_outb_p, + .mv_outw_p = snapgear_outw, + .mv_outl_p = snapgear_outl, + .mv_init_irq = init_snapgear_IRQ, }; diff --git a/trunk/arch/sh/boards/mach-systemh/Makefile b/trunk/arch/sh/boards/mach-systemh/Makefile new file mode 100644 index 000000000000..2cc6a23d9d39 --- /dev/null +++ b/trunk/arch/sh/boards/mach-systemh/Makefile @@ -0,0 +1,13 @@ +# +# Makefile for the SystemH specific parts of the kernel +# + +obj-y := setup.o irq.o io.o + +# XXX: This wants to be consolidated in arch/sh/drivers/pci, and more +# importantly, with the generic sh7751_pcic_init() code. For now, we'll +# just abuse the hell out of kbuild, because we can.. + +obj-$(CONFIG_PCI) += pci.o +pci-y := ../../se/7751/pci.o + diff --git a/trunk/arch/sh/boards/mach-systemh/io.c b/trunk/arch/sh/boards/mach-systemh/io.c new file mode 100644 index 000000000000..15577ff1f715 --- /dev/null +++ b/trunk/arch/sh/boards/mach-systemh/io.c @@ -0,0 +1,158 @@ +/* + * linux/arch/sh/boards/renesas/systemh/io.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for Hitachi 7751 Systemh. + */ +#include +#include +#include +#include +#include +#include + +#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area + of smc lan chip*/ +static inline volatile __u16 * +port2adr(unsigned int port) +{ + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); + maybebadio((unsigned long)port); + return (volatile __u16*)port; +} + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +unsigned char sh7751systemh_inb(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned char *)port; + else if (port <= 0x3F1) + return *(volatile unsigned char *)ETHER_IOMAP(port); + else + return (*port2adr(port))&0xff; +} + +unsigned char sh7751systemh_inb_p(unsigned long port) +{ + unsigned char v; + + if (PXSEG(port)) + v = *(volatile unsigned char *)port; + else if (port <= 0x3F1) + v = *(volatile unsigned char *)ETHER_IOMAP(port); + else + v = (*port2adr(port))&0xff; + ctrl_delay(); + return v; +} + +unsigned short sh7751systemh_inw(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned short *)port; + else if (port >= 0x2000) + return *port2adr(port); + else if (port <= 0x3F1) + return *(volatile unsigned int *)ETHER_IOMAP(port); + else + maybebadio(port); + return 0; +} + +unsigned int sh7751systemh_inl(unsigned long port) +{ + if (PXSEG(port)) + return *(volatile unsigned long *)port; + else if (port >= 0x2000) + return *port2adr(port); + else if (port <= 0x3F1) + return *(volatile unsigned int *)ETHER_IOMAP(port); + else + maybebadio(port); + return 0; +} + +void sh7751systemh_outb(unsigned char value, unsigned long port) +{ + + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (port <= 0x3F1) + *(volatile unsigned char *)ETHER_IOMAP(port) = value; + else + *(port2adr(port)) = value; +} + +void sh7751systemh_outb_p(unsigned char value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned char *)port = value; + else if (port <= 0x3F1) + *(volatile unsigned char *)ETHER_IOMAP(port) = value; + else + *(port2adr(port)) = value; + ctrl_delay(); +} + +void sh7751systemh_outw(unsigned short value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned short *)port = value; + else if (port >= 0x2000) + *port2adr(port) = value; + else if (port <= 0x3F1) + *(volatile unsigned short *)ETHER_IOMAP(port) = value; + else + maybebadio(port); +} + +void sh7751systemh_outl(unsigned int value, unsigned long port) +{ + if (PXSEG(port)) + *(volatile unsigned long *)port = value; + else + maybebadio(port); +} + +void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) +{ + unsigned char *p = addr; + while (count--) *p++ = sh7751systemh_inb(port); +} + +void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) +{ + unsigned short *p = addr; + while (count--) *p++ = sh7751systemh_inw(port); +} + +void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) +{ + maybebadio(port); +} + +void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) +{ + unsigned char *p = (unsigned char*)addr; + while (count--) sh7751systemh_outb(*p++, port); +} + +void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count) +{ + unsigned short *p = (unsigned short*)addr; + while (count--) sh7751systemh_outw(*p++, port); +} + +void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) +{ + maybebadio(port); +} diff --git a/trunk/arch/sh/boards/mach-systemh/irq.c b/trunk/arch/sh/boards/mach-systemh/irq.c new file mode 100644 index 000000000000..e5ee13adeff4 --- /dev/null +++ b/trunk/arch/sh/boards/mach-systemh/irq.c @@ -0,0 +1,61 @@ +/* + * linux/arch/sh/boards/renesas/systemh/irq.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Hitachi SystemH Support. + * + * Modified for 7751 SystemH by + * Jonathan Short. + */ + +#include +#include +#include +#include + +#include +#include + +/* address of external interrupt mask register + * address must be set prior to use these (maybe in init_XXX_irq()) + * XXX : is it better to use .config than specifying it in code? */ +static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004; +static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; + +static void disable_systemh_irq(struct irq_data *data) +{ + unsigned long val, mask = 0x01 << 1; + + /* Clear the "irq"th bit in the mask and set it in the request */ + val = __raw_readl((unsigned long)systemh_irq_mask_register); + val &= ~mask; + __raw_writel(val, (unsigned long)systemh_irq_mask_register); + + val = __raw_readl((unsigned long)systemh_irq_request_register); + val |= mask; + __raw_writel(val, (unsigned long)systemh_irq_request_register); +} + +static void enable_systemh_irq(struct irq_data *data) +{ + unsigned long val, mask = 0x01 << 1; + + /* Set "irq"th bit in the mask register */ + val = __raw_readl((unsigned long)systemh_irq_mask_register); + val |= mask; + __raw_writel(val, (unsigned long)systemh_irq_mask_register); +} + +static struct irq_chip systemh_irq_type = { + .name = "SystemH Register", + .irq_unmask = enable_systemh_irq, + .irq_mask = disable_systemh_irq, +}; + +void make_systemh_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + set_irq_chip_and_handler(irq, &systemh_irq_type, handle_level_irq); + disable_systemh_irq(irq_get_irq_data(irq)); +} diff --git a/trunk/arch/sh/boards/mach-systemh/setup.c b/trunk/arch/sh/boards/mach-systemh/setup.c new file mode 100644 index 000000000000..219fd800a43f --- /dev/null +++ b/trunk/arch/sh/boards/mach-systemh/setup.c @@ -0,0 +1,57 @@ +/* + * linux/arch/sh/boards/renesas/systemh/setup.c + * + * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2003 Paul Mundt + * + * Hitachi SystemH Support. + * + * Modified for 7751 SystemH by Jonathan Short. + * + * Rewritten for 2.6 by Paul Mundt. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include + +extern void make_systemh_irq(unsigned int irq); + +/* + * Initialize IRQ setting + */ +static void __init sh7751systemh_init_irq(void) +{ + make_systemh_irq(0xb); /* Ethernet interrupt */ +} + +static struct sh_machine_vector mv_7751systemh __initmv = { + .mv_name = "7751 SystemH", + .mv_nr_irqs = 72, + + .mv_inb = sh7751systemh_inb, + .mv_inw = sh7751systemh_inw, + .mv_inl = sh7751systemh_inl, + .mv_outb = sh7751systemh_outb, + .mv_outw = sh7751systemh_outw, + .mv_outl = sh7751systemh_outl, + + .mv_inb_p = sh7751systemh_inb_p, + .mv_inw_p = sh7751systemh_inw, + .mv_inl_p = sh7751systemh_inl, + .mv_outb_p = sh7751systemh_outb_p, + .mv_outw_p = sh7751systemh_outw, + .mv_outl_p = sh7751systemh_outl, + + .mv_insb = sh7751systemh_insb, + .mv_insw = sh7751systemh_insw, + .mv_insl = sh7751systemh_insl, + .mv_outsb = sh7751systemh_outsb, + .mv_outsw = sh7751systemh_outsw, + .mv_outsl = sh7751systemh_outsl, + + .mv_init_irq = sh7751systemh_init_irq, +}; diff --git a/trunk/arch/sh/configs/secureedge5410_defconfig b/trunk/arch/sh/configs/snapgear_defconfig similarity index 100% rename from trunk/arch/sh/configs/secureedge5410_defconfig rename to trunk/arch/sh/configs/snapgear_defconfig diff --git a/trunk/arch/sh/configs/systemh_defconfig b/trunk/arch/sh/configs/systemh_defconfig new file mode 100644 index 000000000000..b58dfc505efe --- /dev/null +++ b/trunk/arch/sh/configs/systemh_defconfig @@ -0,0 +1,28 @@ +CONFIG_EXPERIMENTAL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_SYSCTL_SYSCALL is not set +# CONFIG_HOTPLUG is not set +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_CPU_SUBTYPE_SH7751R=y +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x00400000 +CONFIG_FLATMEM_MANUAL=y +CONFIG_SH_7751_SYSTEMH=y +CONFIG_PREEMPT=y +# CONFIG_STANDALONE is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=1024 +# CONFIG_INPUT is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_VT is not set +CONFIG_HW_RANDOM=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_CRAMFS=y +CONFIG_ROMFS_FS=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/trunk/arch/sh/include/asm/addrspace.h b/trunk/arch/sh/include/asm/addrspace.h index 3d1ae2bfaa6f..446b3831c214 100644 --- a/trunk/arch/sh/include/asm/addrspace.h +++ b/trunk/arch/sh/include/asm/addrspace.h @@ -44,10 +44,10 @@ /* * These will never work in 32-bit, don't even bother. */ -#define P1SEGADDR(a) ({ (void)(a); BUG(); NULL; }) -#define P2SEGADDR(a) ({ (void)(a); BUG(); NULL; }) -#define P3SEGADDR(a) ({ (void)(a); BUG(); NULL; }) -#define P4SEGADDR(a) ({ (void)(a); BUG(); NULL; }) +#define P1SEGADDR(a) __futile_remapping_attempt +#define P2SEGADDR(a) __futile_remapping_attempt +#define P3SEGADDR(a) __futile_remapping_attempt +#define P4SEGADDR(a) __futile_remapping_attempt #endif #endif /* P1SEG */ diff --git a/trunk/arch/sh/include/asm/pgtable.h b/trunk/arch/sh/include/asm/pgtable.h index 083ea068e819..a15f1058bbf4 100644 --- a/trunk/arch/sh/include/asm/pgtable.h +++ b/trunk/arch/sh/include/asm/pgtable.h @@ -66,6 +66,7 @@ static inline unsigned long long neff_sign_extend(unsigned long val) #define PHYS_ADDR_MASK29 0x1fffffff #define PHYS_ADDR_MASK32 0xffffffff +#ifdef CONFIG_PMB static inline unsigned long phys_addr_mask(void) { /* Is the MMU in 29bit mode? */ @@ -74,6 +75,17 @@ static inline unsigned long phys_addr_mask(void) return PHYS_ADDR_MASK32; } +#elif defined(CONFIG_32BIT) +static inline unsigned long phys_addr_mask(void) +{ + return PHYS_ADDR_MASK32; +} +#else +static inline unsigned long phys_addr_mask(void) +{ + return PHYS_ADDR_MASK29; +} +#endif #define PTE_PHYS_MASK (phys_addr_mask() & PAGE_MASK) #define PTE_FLAGS_MASK (~(PTE_PHYS_MASK) << PAGE_SHIFT) diff --git a/trunk/arch/sh/include/asm/system.h b/trunk/arch/sh/include/asm/system.h index 10c8b1823a18..1f1af5afff03 100644 --- a/trunk/arch/sh/include/asm/system.h +++ b/trunk/arch/sh/include/asm/system.h @@ -10,7 +10,6 @@ #include #include #include -#include #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */ @@ -138,6 +137,9 @@ extern unsigned int instruction_size(unsigned int insn); #define instruction_size(insn) (4) #endif +extern unsigned long cached_to_uncached; +extern unsigned long uncached_size; + void per_cpu_trap_init(void); void default_idle(void); void cpu_idle_wait(void); diff --git a/trunk/arch/sh/include/asm/system_32.h b/trunk/arch/sh/include/asm/system_32.h index a4ad1cd9bc4d..c941b2739405 100644 --- a/trunk/arch/sh/include/asm/system_32.h +++ b/trunk/arch/sh/include/asm/system_32.h @@ -145,6 +145,42 @@ do { \ __restore_dsp(prev); \ } while (0) +/* + * Jump to uncached area. + * When handling TLB or caches, we need to do it from an uncached area. + */ +#define jump_to_uncached() \ +do { \ + unsigned long __dummy; \ + \ + __asm__ __volatile__( \ + "mova 1f, %0\n\t" \ + "add %1, %0\n\t" \ + "jmp @%0\n\t" \ + " nop\n\t" \ + ".balign 4\n" \ + "1:" \ + : "=&z" (__dummy) \ + : "r" (cached_to_uncached)); \ +} while (0) + +/* + * Back to cached area. + */ +#define back_to_cached() \ +do { \ + unsigned long __dummy; \ + ctrl_barrier(); \ + __asm__ __volatile__( \ + "mov.l 1f, %0\n\t" \ + "jmp @%0\n\t" \ + " nop\n\t" \ + ".balign 4\n" \ + "1: .long 2f\n" \ + "2:" \ + : "=&r" (__dummy)); \ +} while (0) + #ifdef CONFIG_CPU_HAS_SR_RB #define lookup_exception_vector() \ ({ \ diff --git a/trunk/arch/sh/include/asm/system_64.h b/trunk/arch/sh/include/asm/system_64.h index 8593bc8d1a4e..36338646dfc8 100644 --- a/trunk/arch/sh/include/asm/system_64.h +++ b/trunk/arch/sh/include/asm/system_64.h @@ -34,6 +34,9 @@ do { \ &next->thread); \ } while (0) +#define jump_to_uncached() do { } while (0) +#define back_to_cached() do { } while (0) + #define __icbi(addr) __asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr)) #define __ocbp(addr) __asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr)) #define __ocbi(addr) __asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr)) diff --git a/trunk/arch/sh/include/asm/uncached.h b/trunk/arch/sh/include/asm/uncached.h index 6f8816b79cf1..e3419f96626a 100644 --- a/trunk/arch/sh/include/asm/uncached.h +++ b/trunk/arch/sh/include/asm/uncached.h @@ -4,55 +4,15 @@ #include #ifdef CONFIG_UNCACHED_MAPPING -extern unsigned long cached_to_uncached; -extern unsigned long uncached_size; extern unsigned long uncached_start, uncached_end; extern int virt_addr_uncached(unsigned long kaddr); extern void uncached_init(void); extern void uncached_resize(unsigned long size); - -/* - * Jump to uncached area. - * When handling TLB or caches, we need to do it from an uncached area. - */ -#define jump_to_uncached() \ -do { \ - unsigned long __dummy; \ - \ - __asm__ __volatile__( \ - "mova 1f, %0\n\t" \ - "add %1, %0\n\t" \ - "jmp @%0\n\t" \ - " nop\n\t" \ - ".balign 4\n" \ - "1:" \ - : "=&z" (__dummy) \ - : "r" (cached_to_uncached)); \ -} while (0) - -/* - * Back to cached area. - */ -#define back_to_cached() \ -do { \ - unsigned long __dummy; \ - ctrl_barrier(); \ - __asm__ __volatile__( \ - "mov.l 1f, %0\n\t" \ - "jmp @%0\n\t" \ - " nop\n\t" \ - ".balign 4\n" \ - "1: .long 2f\n" \ - "2:" \ - : "=&r" (__dummy)); \ -} while (0) #else #define virt_addr_uncached(kaddr) (0) #define uncached_init() do { } while (0) #define uncached_resize(size) BUG() -#define jump_to_uncached() do { } while (0) -#define back_to_cached() do { } while (0) #endif #endif /* __ASM_SH_UNCACHED_H */ diff --git a/trunk/arch/sh/include/mach-common/mach/edosk7705.h b/trunk/arch/sh/include/mach-common/mach/edosk7705.h new file mode 100644 index 000000000000..efc43b323466 --- /dev/null +++ b/trunk/arch/sh/include/mach-common/mach/edosk7705.h @@ -0,0 +1,7 @@ +#ifndef __ASM_SH_EDOSK7705_H +#define __ASM_SH_EDOSK7705_H + +#define __IO_PREFIX sh_edosk7705 +#include + +#endif /* __ASM_SH_EDOSK7705_H */ diff --git a/trunk/arch/sh/include/mach-common/mach/microdev.h b/trunk/arch/sh/include/mach-common/mach/microdev.h index dcb05fa8c164..1aed15856e11 100644 --- a/trunk/arch/sh/include/mach-common/mach/microdev.h +++ b/trunk/arch/sh/include/mach-common/mach/microdev.h @@ -68,4 +68,13 @@ extern void microdev_print_fpga_intc_status(void); #define __IO_PREFIX microdev #include +#if defined(CONFIG_PCI) +unsigned char microdev_pci_inb(unsigned long port); +unsigned short microdev_pci_inw(unsigned long port); +unsigned long microdev_pci_inl(unsigned long port); +void microdev_pci_outb(unsigned char data, unsigned long port); +void microdev_pci_outw(unsigned short data, unsigned long port); +void microdev_pci_outl(unsigned long data, unsigned long port); +#endif + #endif /* __ASM_SH_MICRODEV_H */ diff --git a/trunk/arch/sh/include/mach-common/mach/secureedge5410.h b/trunk/arch/sh/include/mach-common/mach/snapgear.h similarity index 79% rename from trunk/arch/sh/include/mach-common/mach/secureedge5410.h rename to trunk/arch/sh/include/mach-common/mach/snapgear.h index 3653b9a4bacc..042d95f51c4d 100644 --- a/trunk/arch/sh/include/mach-common/mach/secureedge5410.h +++ b/trunk/arch/sh/include/mach-common/mach/snapgear.h @@ -12,9 +12,30 @@ #ifndef _ASM_SH_IO_SNAPGEAR_H #define _ASM_SH_IO_SNAPGEAR_H +#if defined(CONFIG_CPU_SH4) +/* + * The external interrupt lines, these take up ints 0 - 15 inclusive + * depending on the priority for the interrupt. In fact the priority + * is the interrupt :-) + */ + +#define IRL0_IRQ 2 +#define IRL0_PRIORITY 13 + +#define IRL1_IRQ 5 +#define IRL1_PRIORITY 10 + +#define IRL2_IRQ 8 +#define IRL2_PRIORITY 7 + +#define IRL3_IRQ 11 +#define IRL3_PRIORITY 4 +#endif + #define __IO_PREFIX snapgear #include +#ifdef CONFIG_SH_SECUREEDGE5410 /* * We need to remember what was written to the ioport as some bits * are shared with other functions and you cannot read back what was @@ -45,5 +66,6 @@ extern unsigned short secureedge5410_ioport; ((secureedge5410_ioport & ~(mask)) | ((val) & (mask))))) #define SECUREEDGE_READ_IOPORT() \ ((*SECUREEDGE_IOPORT_ADDR&0x0817) | (secureedge5410_ioport&~0x0817)) +#endif #endif /* _ASM_SH_IO_SNAPGEAR_H */ diff --git a/trunk/arch/sh/include/mach-common/mach/systemh7751.h b/trunk/arch/sh/include/mach-common/mach/systemh7751.h new file mode 100644 index 000000000000..4161122c84ef --- /dev/null +++ b/trunk/arch/sh/include/mach-common/mach/systemh7751.h @@ -0,0 +1,71 @@ +#ifndef __ASM_SH_SYSTEMH_7751SYSTEMH_H +#define __ASM_SH_SYSTEMH_7751SYSTEMH_H + +/* + * linux/include/asm-sh/systemh/7751systemh.h + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Hitachi SystemH support + + * Modified for 7751 SystemH by + * Jonathan Short, 2002. + */ + +/* Box specific addresses. */ + +#define PA_ROM 0x00000000 /* EPROM */ +#define PA_ROM_SIZE 0x00400000 /* EPROM size 4M byte */ +#define PA_FROM 0x01000000 /* EPROM */ +#define PA_FROM_SIZE 0x00400000 /* EPROM size 4M byte */ +#define PA_EXT1 0x04000000 +#define PA_EXT1_SIZE 0x04000000 +#define PA_EXT2 0x08000000 +#define PA_EXT2_SIZE 0x04000000 +#define PA_SDRAM 0x0c000000 +#define PA_SDRAM_SIZE 0x04000000 + +#define PA_EXT4 0x12000000 +#define PA_EXT4_SIZE 0x02000000 +#define PA_EXT5 0x14000000 +#define PA_EXT5_SIZE 0x04000000 +#define PA_PCIC 0x18000000 /* MR-SHPC-01 PCMCIA */ + +#define PA_DIPSW0 0xb9000000 /* Dip switch 5,6 */ +#define PA_DIPSW1 0xb9000002 /* Dip switch 7,8 */ +#define PA_LED 0xba000000 /* LED */ +#define PA_BCR 0xbb000000 /* FPGA on the MS7751SE01 */ + +#define PA_MRSHPC 0xb83fffe0 /* MR-SHPC-01 PCMCIA controller */ +#define PA_MRSHPC_MW1 0xb8400000 /* MR-SHPC-01 memory window base */ +#define PA_MRSHPC_MW2 0xb8500000 /* MR-SHPC-01 attribute window base */ +#define PA_MRSHPC_IO 0xb8600000 /* MR-SHPC-01 I/O window base */ +#define MRSHPC_MODE (PA_MRSHPC + 4) +#define MRSHPC_OPTION (PA_MRSHPC + 6) +#define MRSHPC_CSR (PA_MRSHPC + 8) +#define MRSHPC_ISR (PA_MRSHPC + 10) +#define MRSHPC_ICR (PA_MRSHPC + 12) +#define MRSHPC_CPWCR (PA_MRSHPC + 14) +#define MRSHPC_MW0CR1 (PA_MRSHPC + 16) +#define MRSHPC_MW1CR1 (PA_MRSHPC + 18) +#define MRSHPC_IOWCR1 (PA_MRSHPC + 20) +#define MRSHPC_MW0CR2 (PA_MRSHPC + 22) +#define MRSHPC_MW1CR2 (PA_MRSHPC + 24) +#define MRSHPC_IOWCR2 (PA_MRSHPC + 26) +#define MRSHPC_CDCR (PA_MRSHPC + 28) +#define MRSHPC_PCIC_INFO (PA_MRSHPC + 30) + +#define BCR_ILCRA (PA_BCR + 0) +#define BCR_ILCRB (PA_BCR + 2) +#define BCR_ILCRC (PA_BCR + 4) +#define BCR_ILCRD (PA_BCR + 6) +#define BCR_ILCRE (PA_BCR + 8) +#define BCR_ILCRF (PA_BCR + 10) +#define BCR_ILCRG (PA_BCR + 12) + +#define IRQ_79C973 13 + +#define __IO_PREFIX sh7751systemh +#include + +#endif /* __ASM_SH_SYSTEMH_7751SYSTEMH_H */ diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 0fe2e9329cb2..2d9700c6b53a 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -48,7 +48,7 @@ static struct clk r_clk = { * Default rate for the root input clock, reset this with clk_set_rate() * from the platform code. */ -static struct clk extal_clk = { +struct clk extal_clk = { .rate = 33333333, }; @@ -111,7 +111,7 @@ static struct clk div3_clk = { .parent = &pll_clk, }; -static struct clk *main_clks[] = { +struct clk *main_clks[] = { &r_clk, &extal_clk, &fll_clk, @@ -156,7 +156,7 @@ struct clk div4_clks[DIV4_NR] = { enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR }; -static struct clk div6_clks[DIV6_NR] = { +struct clk div6_clks[DIV6_NR] = { [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0), [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0), [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0), diff --git a/trunk/arch/sh/mm/Kconfig b/trunk/arch/sh/mm/Kconfig index c3e61b366493..09370392aff1 100644 --- a/trunk/arch/sh/mm/Kconfig +++ b/trunk/arch/sh/mm/Kconfig @@ -79,7 +79,7 @@ config 29BIT config 32BIT bool - default y if CPU_SH5 || !MMU + default y if CPU_SH5 config PMB bool "Support 32-bit physical addressing through PMB" diff --git a/trunk/arch/sh/mm/consistent.c b/trunk/arch/sh/mm/consistent.c index 40733a952402..038793286990 100644 --- a/trunk/arch/sh/mm/consistent.c +++ b/trunk/arch/sh/mm/consistent.c @@ -79,20 +79,21 @@ void dma_generic_free_coherent(struct device *dev, size_t size, void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { - void *addr; - - addr = __in_29bit_mode() ? - (void *)P1SEGADDR((unsigned long)vaddr) : vaddr; +#if defined(CONFIG_CPU_SH5) || defined(CONFIG_PMB) + void *p1addr = vaddr; +#else + void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr); +#endif switch (direction) { case DMA_FROM_DEVICE: /* invalidate only */ - __flush_invalidate_region(addr, size); + __flush_invalidate_region(p1addr, size); break; case DMA_TO_DEVICE: /* writeback only */ - __flush_wback_region(addr, size); + __flush_wback_region(p1addr, size); break; case DMA_BIDIRECTIONAL: /* writeback and invalidate */ - __flush_purge_region(addr, size); + __flush_purge_region(p1addr, size); break; default: BUG(); diff --git a/trunk/arch/sh/mm/uncached.c b/trunk/arch/sh/mm/uncached.c index a7767da815e9..8a4eca551fc0 100644 --- a/trunk/arch/sh/mm/uncached.c +++ b/trunk/arch/sh/mm/uncached.c @@ -28,7 +28,7 @@ EXPORT_SYMBOL(virt_addr_uncached); void __init uncached_init(void) { -#if defined(CONFIG_29BIT) || !defined(CONFIG_MMU) +#ifdef CONFIG_29BIT uncached_start = P2SEG; #else uncached_start = memory_end; diff --git a/trunk/arch/sh/tools/mach-types b/trunk/arch/sh/tools/mach-types index 0e68465e7b50..9f56eb978024 100644 --- a/trunk/arch/sh/tools/mach-types +++ b/trunk/arch/sh/tools/mach-types @@ -26,6 +26,7 @@ HD64461 HD64461 7724SE SH_7724_SOLUTION_ENGINE 7751SE SH_7751_SOLUTION_ENGINE 7780SE SH_7780_SOLUTION_ENGINE +7751SYSTEMH SH_7751_SYSTEMH HP6XX SH_HP6XX DREAMCAST SH_DREAMCAST SNAPGEAR SH_SECUREEDGE5410 diff --git a/trunk/arch/tile/include/asm/highmem.h b/trunk/arch/tile/include/asm/highmem.h index b2a6c5de79ab..e0f7ee186721 100644 --- a/trunk/arch/tile/include/asm/highmem.h +++ b/trunk/arch/tile/include/asm/highmem.h @@ -23,6 +23,7 @@ #include #include +#include #include #include diff --git a/trunk/arch/tile/include/asm/kmap_types.h b/trunk/arch/tile/include/asm/kmap_types.h index 3d0f20246260..1480106d1c05 100644 --- a/trunk/arch/tile/include/asm/kmap_types.h +++ b/trunk/arch/tile/include/asm/kmap_types.h @@ -16,42 +16,28 @@ #define _ASM_TILE_KMAP_TYPES_H /* - * In 32-bit TILE Linux we have to balance the desire to have a lot of - * nested atomic mappings with the fact that large page sizes and many - * processors chew up address space quickly. In a typical - * 64-processor, 64KB-page layout build, making KM_TYPE_NR one larger - * adds 4MB of required address-space. For now we leave KM_TYPE_NR - * set to depth 8. + * In TILE Linux each set of four of these uses another 16MB chunk of + * address space, given 64 tiles and 64KB pages, so we only enable + * ones that are required by the kernel configuration. */ enum km_type { - KM_TYPE_NR = 8 -}; - -/* - * We provide dummy definitions of all the stray values that used to be - * required for kmap_atomic() and no longer are. - */ -enum { KM_BOUNCE_READ, KM_SKB_SUNRPC_DATA, KM_SKB_DATA_SOFTIRQ, KM_USER0, KM_USER1, KM_BIO_SRC_IRQ, - KM_BIO_DST_IRQ, - KM_PTE0, - KM_PTE1, KM_IRQ0, KM_IRQ1, KM_SOFTIRQ0, KM_SOFTIRQ1, - KM_SYNC_ICACHE, - KM_SYNC_DCACHE, - KM_UML_USERCOPY, - KM_IRQ_PTE, - KM_NMI, - KM_NMI_PTE, - KM_KDB + KM_MEMCPY0, + KM_MEMCPY1, +#if defined(CONFIG_HIGHPTE) + KM_PTE0, + KM_PTE1, +#endif + KM_TYPE_NR }; #endif /* _ASM_TILE_KMAP_TYPES_H */ diff --git a/trunk/arch/tile/include/asm/pgtable.h b/trunk/arch/tile/include/asm/pgtable.h index a6604e9485da..dc4ccdd855bc 100644 --- a/trunk/arch/tile/include/asm/pgtable.h +++ b/trunk/arch/tile/include/asm/pgtable.h @@ -344,8 +344,10 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pgd_offset_k(address) pgd_offset(&init_mm, address) #if defined(CONFIG_HIGHPTE) -extern pte_t *pte_offset_map(pmd_t *, unsigned long address); -#define pte_unmap(pte) kunmap_atomic(pte) +extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type); +#define pte_offset_map(dir, address) \ + _pte_offset_map(dir, address, KM_PTE0) +#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) #else #define pte_offset_map(dir, address) pte_offset_kernel(dir, address) #define pte_unmap(pte) do { } while (0) diff --git a/trunk/arch/tile/include/asm/stat.h b/trunk/arch/tile/include/asm/stat.h index b16e5db8f0e7..3dc90fa92c70 100644 --- a/trunk/arch/tile/include/asm/stat.h +++ b/trunk/arch/tile/include/asm/stat.h @@ -1,4 +1 @@ -#ifdef CONFIG_COMPAT -#define __ARCH_WANT_STAT64 /* Used for compat_sys_stat64() etc. */ -#endif #include diff --git a/trunk/arch/tile/include/asm/unistd.h b/trunk/arch/tile/include/asm/unistd.h index b35c2db71199..f2e3ff485333 100644 --- a/trunk/arch/tile/include/asm/unistd.h +++ b/trunk/arch/tile/include/asm/unistd.h @@ -41,7 +41,6 @@ __SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr) #ifdef CONFIG_COMPAT #define __ARCH_WANT_SYS_LLSEEK #endif -#define __ARCH_WANT_SYS_NEWFSTATAT #endif #endif /* _ASM_TILE_UNISTD_H */ diff --git a/trunk/arch/tile/kernel/compat.c b/trunk/arch/tile/kernel/compat.c index 67617a05e602..77739cdd9462 100644 --- a/trunk/arch/tile/kernel/compat.c +++ b/trunk/arch/tile/kernel/compat.c @@ -148,11 +148,11 @@ long tile_compat_sys_msgrcv(int msqid, #define compat_sys_readahead sys32_readahead #define compat_sys_sync_file_range compat_sys_sync_file_range2 -/* We leverage the "struct stat64" type for 32-bit time_t/nsec. */ -#define compat_sys_stat64 sys_stat64 -#define compat_sys_lstat64 sys_lstat64 -#define compat_sys_fstat64 sys_fstat64 -#define compat_sys_fstatat64 sys_fstatat64 +/* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */ +#define compat_sys_stat64 sys_newstat +#define compat_sys_lstat64 sys_newlstat +#define compat_sys_fstat64 sys_newfstat +#define compat_sys_fstatat64 sys_newfstatat /* The native sys_ptrace dynamically handles compat binaries. */ #define compat_sys_ptrace sys_ptrace diff --git a/trunk/arch/tile/kernel/early_printk.c b/trunk/arch/tile/kernel/early_printk.c index 493a0e66d916..2c54fd43a8a0 100644 --- a/trunk/arch/tile/kernel/early_printk.c +++ b/trunk/arch/tile/kernel/early_printk.c @@ -54,7 +54,7 @@ void early_printk(const char *fmt, ...) void early_panic(const char *fmt, ...) { va_list ap; - arch_local_irq_disable_all(); + raw_local_irq_disable_all(); va_start(ap, fmt); early_printk("Kernel panic - not syncing: "); early_vprintk(fmt, ap); diff --git a/trunk/arch/tile/kernel/hardwall.c b/trunk/arch/tile/kernel/hardwall.c index e910530436e6..1e54a7843410 100644 --- a/trunk/arch/tile/kernel/hardwall.c +++ b/trunk/arch/tile/kernel/hardwall.c @@ -151,12 +151,12 @@ enum direction_protect { static void enable_firewall_interrupts(void) { - arch_local_irq_unmask_now(INT_UDN_FIREWALL); + raw_local_irq_unmask_now(INT_UDN_FIREWALL); } static void disable_firewall_interrupts(void) { - arch_local_irq_mask_now(INT_UDN_FIREWALL); + raw_local_irq_mask_now(INT_UDN_FIREWALL); } /* Set up hardwall on this cpu based on the passed hardwall_info. */ @@ -768,13 +768,13 @@ static int hardwall_release(struct inode *inode, struct file *file) } static const struct file_operations dev_hardwall_fops = { - .open = nonseekable_open, .unlocked_ioctl = hardwall_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = hardwall_compat_ioctl, #endif .flush = hardwall_flush, .release = hardwall_release, + .llseek = noop_llseek, }; static struct cdev hardwall_dev; diff --git a/trunk/arch/tile/kernel/irq.c b/trunk/arch/tile/kernel/irq.c index 128805ef8f2c..e63917687e99 100644 --- a/trunk/arch/tile/kernel/irq.c +++ b/trunk/arch/tile/kernel/irq.c @@ -26,7 +26,7 @@ #define IS_HW_CLEARED 1 /* - * The set of interrupts we enable for arch_local_irq_enable(). + * The set of interrupts we enable for raw_local_irq_enable(). * This is initialized to have just a single interrupt that the kernel * doesn't actually use as a sentinel. During kernel init, * interrupts are added as the kernel gets prepared to support them. @@ -225,7 +225,7 @@ void __cpuinit setup_irq_regs(void) /* Enable interrupt delivery. */ unmask_irqs(~0UL); #if CHIP_HAS_IPI() - arch_local_irq_unmask(INT_IPI_K); + raw_local_irq_unmask(INT_IPI_K); #endif } diff --git a/trunk/arch/tile/kernel/machine_kexec.c b/trunk/arch/tile/kernel/machine_kexec.c index 0d8b9e933487..ba7a265d6179 100644 --- a/trunk/arch/tile/kernel/machine_kexec.c +++ b/trunk/arch/tile/kernel/machine_kexec.c @@ -182,13 +182,13 @@ static void kexec_find_and_set_command_line(struct kimage *image) if ((entry & IND_SOURCE)) { void *va = - kmap_atomic_pfn(entry >> PAGE_SHIFT); + kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0); r = kexec_bn2cl(va); if (r) { command_line = r; break; } - kunmap_atomic(va); + kunmap_atomic(va, KM_USER0); } } @@ -198,7 +198,7 @@ static void kexec_find_and_set_command_line(struct kimage *image) hverr = hv_set_command_line( (HV_VirtAddr) command_line, strlen(command_line)); - kunmap_atomic(command_line); + kunmap_atomic(command_line, KM_USER0); } else { pr_info("%s: no command line found; making empty\n", __func__); diff --git a/trunk/arch/tile/kernel/messaging.c b/trunk/arch/tile/kernel/messaging.c index 0858ee6b520f..997e3933f726 100644 --- a/trunk/arch/tile/kernel/messaging.c +++ b/trunk/arch/tile/kernel/messaging.c @@ -34,7 +34,7 @@ void __cpuinit init_messaging(void) panic("hv_register_message_state: error %d", rc); /* Make sure downcall interrupts will be enabled. */ - arch_local_irq_unmask(INT_INTCTRL_K); + raw_local_irq_unmask(INT_INTCTRL_K); } void hv_message_intr(struct pt_regs *regs, int intnum) diff --git a/trunk/arch/tile/kernel/ptrace.c b/trunk/arch/tile/kernel/ptrace.c index e92e40527d6d..9cd29884c09f 100644 --- a/trunk/arch/tile/kernel/ptrace.c +++ b/trunk/arch/tile/kernel/ptrace.c @@ -50,10 +50,10 @@ long arch_ptrace(struct task_struct *child, long request, { unsigned long __user *datap = (long __user __force *)data; unsigned long tmp; + int i; long ret = -EIO; + unsigned long *childregs; char *childreg; - struct pt_regs copyregs; - int ex1_offset; switch (request) { @@ -80,16 +80,6 @@ long arch_ptrace(struct task_struct *child, long request, if (addr >= PTREGS_SIZE) break; childreg = (char *)task_pt_regs(child) + addr; - - /* Guard against overwrites of the privilege level. */ - ex1_offset = PTREGS_OFFSET_EX1; -#if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN) - if (is_compat_task()) /* point at low word */ - ex1_offset += sizeof(compat_long_t); -#endif - if (addr == ex1_offset) - data = PL_ICS_EX1(USER_PL, EX1_ICS(data)); - #ifdef CONFIG_COMPAT if (is_compat_task()) { if (addr & (sizeof(compat_long_t)-1)) @@ -106,19 +96,26 @@ long arch_ptrace(struct task_struct *child, long request, break; case PTRACE_GETREGS: /* Get all registers from the child. */ - if (copy_to_user(datap, task_pt_regs(child), - sizeof(struct pt_regs)) == 0) { - ret = 0; + if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) + break; + childregs = (long *)task_pt_regs(child); + for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); + ++i) { + ret = __put_user(childregs[i], &datap[i]); + if (ret != 0) + break; } break; case PTRACE_SETREGS: /* Set all registers in the child. */ - if (copy_from_user(©regs, datap, - sizeof(struct pt_regs)) == 0) { - copyregs.ex1 = - PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1)); - *task_pt_regs(child) = copyregs; - ret = 0; + if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) + break; + childregs = (long *)task_pt_regs(child); + for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); + ++i) { + ret = __get_user(childregs[i], &datap[i]); + if (ret != 0) + break; } break; diff --git a/trunk/arch/tile/kernel/reboot.c b/trunk/arch/tile/kernel/reboot.c index baa3d905fee2..acd86d20beba 100644 --- a/trunk/arch/tile/kernel/reboot.c +++ b/trunk/arch/tile/kernel/reboot.c @@ -27,7 +27,7 @@ void machine_halt(void) { warn_early_printk(); - arch_local_irq_disable_all(); + raw_local_irq_disable_all(); smp_send_stop(); hv_halt(); } @@ -35,14 +35,14 @@ void machine_halt(void) void machine_power_off(void) { warn_early_printk(); - arch_local_irq_disable_all(); + raw_local_irq_disable_all(); smp_send_stop(); hv_power_off(); } void machine_restart(char *cmd) { - arch_local_irq_disable_all(); + raw_local_irq_disable_all(); smp_send_stop(); hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd); } diff --git a/trunk/arch/tile/kernel/setup.c b/trunk/arch/tile/kernel/setup.c index fb0b3cbeae14..ae51cad12da0 100644 --- a/trunk/arch/tile/kernel/setup.c +++ b/trunk/arch/tile/kernel/setup.c @@ -868,14 +868,14 @@ void __cpuinit setup_cpu(int boot) /* Allow asynchronous TLB interrupts. */ #if CHIP_HAS_TILE_DMA() - arch_local_irq_unmask(INT_DMATLB_MISS); - arch_local_irq_unmask(INT_DMATLB_ACCESS); + raw_local_irq_unmask(INT_DMATLB_MISS); + raw_local_irq_unmask(INT_DMATLB_ACCESS); #endif #if CHIP_HAS_SN_PROC() - arch_local_irq_unmask(INT_SNITLB_MISS); + raw_local_irq_unmask(INT_SNITLB_MISS); #endif #ifdef __tilegx__ - arch_local_irq_unmask(INT_SINGLE_STEP_K); + raw_local_irq_unmask(INT_SINGLE_STEP_K); #endif /* diff --git a/trunk/arch/tile/kernel/signal.c b/trunk/arch/tile/kernel/signal.c index 687719d4abd1..fb28e85ae3ae 100644 --- a/trunk/arch/tile/kernel/signal.c +++ b/trunk/arch/tile/kernel/signal.c @@ -71,9 +71,6 @@ int restore_sigcontext(struct pt_regs *regs, for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) err |= __get_user(regs->regs[i], &sc->gregs[i]); - /* Ensure that the PL is always set to USER_PL. */ - regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); - regs->faultnum = INT_SWINT_1_SIGRETURN; err |= __get_user(*pr0, &sc->gregs[0]); @@ -333,7 +330,7 @@ void do_signal(struct pt_regs *regs) current_thread_info()->status &= ~TS_RESTORE_SIGMASK; } - goto done; + return; } /* Did we come from a system call? */ @@ -361,8 +358,4 @@ void do_signal(struct pt_regs *regs) current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } - -done: - /* Avoid double syscall restart if there are nested signals. */ - regs->faultnum = INT_SWINT_1_SIGRETURN; } diff --git a/trunk/arch/tile/kernel/smp.c b/trunk/arch/tile/kernel/smp.c index 9575b37a8b75..75255d90aff3 100644 --- a/trunk/arch/tile/kernel/smp.c +++ b/trunk/arch/tile/kernel/smp.c @@ -115,7 +115,7 @@ static void smp_start_cpu_interrupt(void) static void smp_stop_cpu_interrupt(void) { set_cpu_online(smp_processor_id(), 0); - arch_local_irq_disable_all(); + raw_local_irq_disable_all(); for (;;) asm("nap"); } diff --git a/trunk/arch/tile/kernel/time.c b/trunk/arch/tile/kernel/time.c index f2e156e44692..6bed820e1421 100644 --- a/trunk/arch/tile/kernel/time.c +++ b/trunk/arch/tile/kernel/time.c @@ -132,7 +132,7 @@ static int tile_timer_set_next_event(unsigned long ticks, { BUG_ON(ticks > MAX_TICK); __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks); - arch_local_irq_unmask_now(INT_TILE_TIMER); + raw_local_irq_unmask_now(INT_TILE_TIMER); return 0; } @@ -143,7 +143,7 @@ static int tile_timer_set_next_event(unsigned long ticks, static void tile_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { - arch_local_irq_mask_now(INT_TILE_TIMER); + raw_local_irq_mask_now(INT_TILE_TIMER); } /* @@ -172,7 +172,7 @@ void __cpuinit setup_tile_timer(void) evt->cpumask = cpumask_of(smp_processor_id()); /* Start out with timer not firing. */ - arch_local_irq_mask_now(INT_TILE_TIMER); + raw_local_irq_mask_now(INT_TILE_TIMER); /* Register tile timer. */ clockevents_register_device(evt); @@ -188,7 +188,7 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num) * Mask the timer interrupt here, since we are a oneshot timer * and there are now by definition no events pending. */ - arch_local_irq_mask(INT_TILE_TIMER); + raw_local_irq_mask(INT_TILE_TIMER); /* Track time spent here in an interrupt context */ irq_enter(); diff --git a/trunk/arch/tile/lib/memcpy_tile64.c b/trunk/arch/tile/lib/memcpy_tile64.c index f7d4a6ad61e8..dfedea7b266b 100644 --- a/trunk/arch/tile/lib/memcpy_tile64.c +++ b/trunk/arch/tile/lib/memcpy_tile64.c @@ -54,7 +54,7 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long); * we must run with interrupts disabled to avoid the risk of some * other code seeing the incoherent data in our cache. (Recall that * our cache is indexed by PA, so even if the other code doesn't use - * our kmap_atomic virtual addresses, they'll still hit in cache using + * our KM_MEMCPY virtual addresses, they'll still hit in cache using * the normal VAs that aren't supposed to hit in cache.) */ static void memcpy_multicache(void *dest, const void *source, @@ -64,7 +64,6 @@ static void memcpy_multicache(void *dest, const void *source, unsigned long flags, newsrc, newdst; pmd_t *pmdp; pte_t *ptep; - int type0, type1; int cpu = get_cpu(); /* @@ -78,8 +77,7 @@ static void memcpy_multicache(void *dest, const void *source, sim_allow_multiple_caching(1); /* Set up the new dest mapping */ - type0 = kmap_atomic_idx_push(); - idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + type0; + idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0; newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1)); pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst); ptep = pte_offset_kernel(pmdp, newdst); @@ -89,8 +87,7 @@ static void memcpy_multicache(void *dest, const void *source, } /* Set up the new source mapping */ - type1 = kmap_atomic_idx_push(); - idx += (type0 - type1); + idx += (KM_MEMCPY0 - KM_MEMCPY1); src_pte = hv_pte_set_nc(src_pte); src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */ newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1)); @@ -122,8 +119,6 @@ static void memcpy_multicache(void *dest, const void *source, * We're done: notify the simulator that all is back to normal, * and re-enable interrupts and pre-emption. */ - kmap_atomic_idx_pop(); - kmap_atomic_idx_pop(); sim_allow_multiple_caching(0); local_irq_restore(flags); put_cpu(); diff --git a/trunk/arch/tile/mm/highmem.c b/trunk/arch/tile/mm/highmem.c index 31dbbd9afe47..abb57331cf6e 100644 --- a/trunk/arch/tile/mm/highmem.c +++ b/trunk/arch/tile/mm/highmem.c @@ -227,7 +227,7 @@ EXPORT_SYMBOL(kmap_atomic_prot); void *__kmap_atomic(struct page *page) { /* PAGE_NONE is a magic value that tells us to check immutability. */ - return kmap_atomic_prot(page, PAGE_NONE); + return kmap_atomic_prot(page, type, PAGE_NONE); } EXPORT_SYMBOL(__kmap_atomic); diff --git a/trunk/arch/tile/mm/init.c b/trunk/arch/tile/mm/init.c index 0b9ce69b0ee5..78e1982cb6c9 100644 --- a/trunk/arch/tile/mm/init.c +++ b/trunk/arch/tile/mm/init.c @@ -988,12 +988,8 @@ static long __write_once initfree = 1; /* Select whether to free (1) or mark unusable (0) the __init pages. */ static int __init set_initfree(char *str) { - long val; - if (strict_strtol(str, 0, &val)) { - initfree = val; - pr_info("initfree: %s free init pages\n", - initfree ? "will" : "won't"); - } + strict_strtol(str, 0, &initfree); + pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't"); return 1; } __setup("initfree=", set_initfree); diff --git a/trunk/arch/tile/mm/pgtable.c b/trunk/arch/tile/mm/pgtable.c index 1f5430c53d0d..335c24621c41 100644 --- a/trunk/arch/tile/mm/pgtable.c +++ b/trunk/arch/tile/mm/pgtable.c @@ -134,9 +134,9 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags) } #if defined(CONFIG_HIGHPTE) -pte_t *_pte_offset_map(pmd_t *dir, unsigned long address) +pte_t *_pte_offset_map(pmd_t *dir, unsigned long address, enum km_type type) { - pte_t *pte = kmap_atomic(pmd_page(*dir)) + + pte_t *pte = kmap_atomic(pmd_page(*dir), type) + (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK; return &pte[pte_index(address)]; } diff --git a/trunk/arch/um/include/asm/ptrace-generic.h b/trunk/arch/um/include/asm/ptrace-generic.h index b7c5bab9bd77..2cd899f75a3c 100644 --- a/trunk/arch/um/include/asm/ptrace-generic.h +++ b/trunk/arch/um/include/asm/ptrace-generic.h @@ -38,8 +38,8 @@ struct pt_regs { struct task_struct; -extern long subarch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data); +extern long subarch_ptrace(struct task_struct *child, long request, long addr, + long data); extern unsigned long getreg(struct task_struct *child, int regno); extern int putreg(struct task_struct *child, int regno, unsigned long value); extern int get_fpregs(struct user_i387_struct __user *buf, diff --git a/trunk/arch/um/kernel/ptrace.c b/trunk/arch/um/kernel/ptrace.c index 701b672c1122..a5e33f29bbeb 100644 --- a/trunk/arch/um/kernel/ptrace.c +++ b/trunk/arch/um/kernel/ptrace.c @@ -122,7 +122,7 @@ long arch_ptrace(struct task_struct *child, long request, break; case PTRACE_SET_THREAD_AREA: - ret = ptrace_set_thread_area(child, addr, vp); + ret = ptrace_set_thread_area(child, addr, datavp); break; case PTRACE_FAULTINFO: { diff --git a/trunk/arch/x86/include/asm/apic.h b/trunk/arch/x86/include/asm/apic.h index f6ce0bda3b98..286de34b0ed6 100644 --- a/trunk/arch/x86/include/asm/apic.h +++ b/trunk/arch/x86/include/asm/apic.h @@ -141,13 +141,13 @@ static inline void native_apic_msr_write(u32 reg, u32 v) static inline u32 native_apic_msr_read(u32 reg) { - u64 msr; + u32 low, high; if (reg == APIC_DFR) return -1; - rdmsrl(APIC_BASE_MSR + (reg >> 4), msr); - return (u32)msr; + rdmsr(APIC_BASE_MSR + (reg >> 4), low, high); + return low; } static inline void native_x2apic_wait_icr_idle(void) @@ -181,12 +181,12 @@ extern void enable_x2apic(void); extern void x2apic_icr_write(u32 low, u32 id); static inline int x2apic_enabled(void) { - u64 msr; + int msr, msr2; if (!cpu_has_x2apic) return 0; - rdmsrl(MSR_IA32_APICBASE, msr); + rdmsr(MSR_IA32_APICBASE, msr, msr2); if (msr & X2APIC_ENABLE) return 1; return 0; diff --git a/trunk/arch/x86/include/asm/uv/uv_mmrs.h b/trunk/arch/x86/include/asm/uv/uv_mmrs.h index 6d90adf4428a..b2f2d2e05cec 100644 --- a/trunk/arch/x86/include/asm/uv/uv_mmrs.h +++ b/trunk/arch/x86/include/asm/uv/uv_mmrs.h @@ -805,78 +805,6 @@ union uvh_node_present_table_u { } s; }; -/* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR 0x16000c8UL - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_alias210_overlay_config_0_mmr_u { - unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_0_mmr_s { - unsigned long rsvd_0_23: 24; /* */ - unsigned long base : 8; /* RW */ - unsigned long rsvd_32_47: 16; /* */ - unsigned long m_alias : 5; /* RW */ - unsigned long rsvd_53_62: 10; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR 0x16000d8UL - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_alias210_overlay_config_1_mmr_u { - unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_1_mmr_s { - unsigned long rsvd_0_23: 24; /* */ - unsigned long base : 8; /* RW */ - unsigned long rsvd_32_47: 16; /* */ - unsigned long m_alias : 5; /* RW */ - unsigned long rsvd_53_62: 10; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - -/* ========================================================================= */ -/* UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR 0x16000e8UL - -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_SHFT 24 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_BASE_MASK 0x00000000ff000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_SHFT 48 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_M_ALIAS_MASK 0x001f000000000000UL -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_SHFT 63 -#define UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR_ENABLE_MASK 0x8000000000000000UL - -union uvh_rh_gam_alias210_overlay_config_2_mmr_u { - unsigned long v; - struct uvh_rh_gam_alias210_overlay_config_2_mmr_s { - unsigned long rsvd_0_23: 24; /* */ - unsigned long base : 8; /* RW */ - unsigned long rsvd_32_47: 16; /* */ - unsigned long m_alias : 5; /* RW */ - unsigned long rsvd_53_62: 10; /* */ - unsigned long enable : 1; /* RW */ - } s; -}; - /* ========================================================================= */ /* UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR */ /* ========================================================================= */ @@ -928,29 +856,6 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u { } s; }; -/* ========================================================================= */ -/* UVH_RH_GAM_CONFIG_MMR */ -/* ========================================================================= */ -#define UVH_RH_GAM_CONFIG_MMR 0x1600000UL - -#define UVH_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0 -#define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL -#define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6 -#define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL -#define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12 -#define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL - -union uvh_rh_gam_config_mmr_u { - unsigned long v; - struct uvh_rh_gam_config_mmr_s { - unsigned long m_skt : 6; /* RW */ - unsigned long n_skt : 4; /* RW */ - unsigned long rsvd_10_11: 2; /* */ - unsigned long mmiol_cfg : 1; /* RW */ - unsigned long rsvd_13_63: 51; /* */ - } s; -}; - /* ========================================================================= */ /* UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR */ /* ========================================================================= */ @@ -1082,5 +987,97 @@ union uvh_rtc1_int_config_u { } s; }; +/* ========================================================================= */ +/* UVH_SI_ADDR_MAP_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ADDR_MAP_CONFIG 0xc80000UL + +#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_SHFT 0 +#define UVH_SI_ADDR_MAP_CONFIG_M_SKT_MASK 0x000000000000003fUL +#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_SHFT 8 +#define UVH_SI_ADDR_MAP_CONFIG_N_SKT_MASK 0x0000000000000f00UL + +union uvh_si_addr_map_config_u { + unsigned long v; + struct uvh_si_addr_map_config_s { + unsigned long m_skt : 6; /* RW */ + unsigned long rsvd_6_7: 2; /* */ + unsigned long n_skt : 4; /* RW */ + unsigned long rsvd_12_63: 52; /* */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS0_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS0_OVERLAY_CONFIG 0xc80008UL + +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS0_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias0_overlay_config_u { + unsigned long v; + struct uvh_si_alias0_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS1_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS1_OVERLAY_CONFIG 0xc80010UL + +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS1_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias1_overlay_config_u { + unsigned long v; + struct uvh_si_alias1_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + +/* ========================================================================= */ +/* UVH_SI_ALIAS2_OVERLAY_CONFIG */ +/* ========================================================================= */ +#define UVH_SI_ALIAS2_OVERLAY_CONFIG 0xc80018UL + +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_SHFT 24 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_BASE_MASK 0x00000000ff000000UL +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_SHFT 48 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_M_ALIAS_MASK 0x001f000000000000UL +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_SHFT 63 +#define UVH_SI_ALIAS2_OVERLAY_CONFIG_ENABLE_MASK 0x8000000000000000UL + +union uvh_si_alias2_overlay_config_u { + unsigned long v; + struct uvh_si_alias2_overlay_config_s { + unsigned long rsvd_0_23: 24; /* */ + unsigned long base : 8; /* RW */ + unsigned long rsvd_32_47: 16; /* */ + unsigned long m_alias : 5; /* RW */ + unsigned long rsvd_53_62: 10; /* */ + unsigned long enable : 1; /* RW */ + } s; +}; + -#endif /* __ASM_UV_MMRS_X86_H__ */ +#endif /* _ASM_X86_UV_UV_MMRS_H */ diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index 3f838d537392..850657d1b0ed 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -52,6 +52,7 @@ #include #include #include +#include unsigned int num_processors; diff --git a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c index 194539aea175..ed4118de249e 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c @@ -379,14 +379,14 @@ struct redir_addr { #define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT static __initdata struct redir_addr redir_addrs[] = { - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_0_MMR}, - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_1_MMR}, - {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_RH_GAM_ALIAS210_OVERLAY_CONFIG_2_MMR}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, }; static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) { - union uvh_rh_gam_alias210_overlay_config_2_mmr_u alias; + union uvh_si_alias0_overlay_config_u alias; union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; int i; @@ -660,7 +660,7 @@ void uv_nmi_init(void) void __init uv_system_init(void) { - union uvh_rh_gam_config_mmr_u m_n_config; + union uvh_si_addr_map_config_u m_n_config; union uvh_node_id_u node_id; unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size; int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val; @@ -670,7 +670,7 @@ void __init uv_system_init(void) map_low_mmrs(); - m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR ); + m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); m_val = m_n_config.s.m_skt; n_val = m_n_config.s.n_skt; mmr_base = diff --git a/trunk/arch/x86/kernel/cpu/perf_event_amd.c b/trunk/arch/x86/kernel/cpu/perf_event_amd.c index e421b8cd6944..46d58448c3af 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_amd.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_amd.c @@ -280,11 +280,11 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) struct amd_nb *nb; int i; - nb = kmalloc_node(sizeof(struct amd_nb), GFP_KERNEL | __GFP_ZERO, - cpu_to_node(cpu)); + nb = kmalloc(sizeof(struct amd_nb), GFP_KERNEL); if (!nb) return NULL; + memset(nb, 0, sizeof(*nb)); nb->nb_id = nb_id; /* diff --git a/trunk/arch/x86/kernel/microcode_amd.c b/trunk/arch/x86/kernel/microcode_amd.c index ce0cb4721c9a..e1af7c055c7d 100644 --- a/trunk/arch/x86/kernel/microcode_amd.c +++ b/trunk/arch/x86/kernel/microcode_amd.c @@ -212,7 +212,7 @@ static int install_equiv_cpu_table(const u8 *buf) return 0; } - equiv_cpu_table = vmalloc(size); + equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); if (!equiv_cpu_table) { pr_err("failed to allocate equivalent CPU table\n"); return 0; diff --git a/trunk/arch/x86/kernel/mmconf-fam10h_64.c b/trunk/arch/x86/kernel/mmconf-fam10h_64.c index 6da143c2a6b8..71825806cd44 100644 --- a/trunk/arch/x86/kernel/mmconf-fam10h_64.c +++ b/trunk/arch/x86/kernel/mmconf-fam10h_64.c @@ -217,13 +217,13 @@ void __cpuinit fam10h_check_enable_mmcfg(void) wrmsrl(address, val); } -static int __init set_check_enable_amd_mmconf(const struct dmi_system_id *d) +static int __devinit set_check_enable_amd_mmconf(const struct dmi_system_id *d) { pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF; return 0; } -static const struct dmi_system_id __initconst mmconf_dmi_table[] = { +static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = { { .callback = set_check_enable_amd_mmconf, .ident = "Sun Microsystems Machine", @@ -234,8 +234,7 @@ static const struct dmi_system_id __initconst mmconf_dmi_table[] = { {} }; -/* Called from a __cpuinit function, but only on the BSP. */ -void __ref check_enable_amd_mmconf_dmi(void) +void __cpuinit check_enable_amd_mmconf_dmi(void) { dmi_check_system(mmconf_dmi_table); } diff --git a/trunk/arch/x86/kernel/pvclock.c b/trunk/arch/x86/kernel/pvclock.c index 008b91eefa18..bab3b9e6f66d 100644 --- a/trunk/arch/x86/kernel/pvclock.c +++ b/trunk/arch/x86/kernel/pvclock.c @@ -41,6 +41,44 @@ void pvclock_set_flags(u8 flags) valid_flags = flags; } +/* + * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, + * yielding a 64-bit result. + */ +static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift) +{ + u64 product; +#ifdef __i386__ + u32 tmp1, tmp2; +#endif + + if (shift < 0) + delta >>= -shift; + else + delta <<= shift; + +#ifdef __i386__ + __asm__ ( + "mul %5 ; " + "mov %4,%%eax ; " + "mov %%edx,%4 ; " + "mul %5 ; " + "xor %5,%5 ; " + "add %4,%%eax ; " + "adc %5,%%edx ; " + : "=A" (product), "=r" (tmp1), "=r" (tmp2) + : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); +#elif defined(__x86_64__) + __asm__ ( + "mul %%rdx ; shrd $32,%%rdx,%%rax" + : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); +#else +#error implement me! +#endif + + return product; +} + static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow) { u64 delta = native_read_tsc() - shadow->tsc_timestamp; diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index fb8b376bf28c..908ea5464a51 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -720,7 +720,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) } } -static int set_spte_track_bits(u64 *sptep, u64 new_spte) +static void set_spte_track_bits(u64 *sptep, u64 new_spte) { pfn_t pfn; u64 old_spte = *sptep; @@ -731,20 +731,19 @@ static int set_spte_track_bits(u64 *sptep, u64 new_spte) old_spte = __xchg_spte(sptep, new_spte); if (!is_rmap_spte(old_spte)) - return 0; + return; pfn = spte_to_pfn(old_spte); if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) kvm_set_pfn_accessed(pfn); if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask)) kvm_set_pfn_dirty(pfn); - return 1; } static void drop_spte(struct kvm *kvm, u64 *sptep, u64 new_spte) { - if (set_spte_track_bits(sptep, new_spte)) - rmap_remove(kvm, sptep); + set_spte_track_bits(sptep, new_spte); + rmap_remove(kvm, sptep); } static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index cdac9e592aa5..2288ad829b32 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -2560,7 +2560,6 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, !kvm_exception_is_soft(vcpu->arch.exception.nr); events->exception.nr = vcpu->arch.exception.nr; events->exception.has_error_code = vcpu->arch.exception.has_error_code; - events->exception.pad = 0; events->exception.error_code = vcpu->arch.exception.error_code; events->interrupt.injected = @@ -2574,14 +2573,12 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, events->nmi.injected = vcpu->arch.nmi_injected; events->nmi.pending = vcpu->arch.nmi_pending; events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu); - events->nmi.pad = 0; events->sipi_vector = vcpu->arch.sipi_vector; events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR | KVM_VCPUEVENT_VALID_SHADOW); - memset(&events->reserved, 0, sizeof(events->reserved)); } static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, @@ -2626,7 +2623,6 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, dbgregs->dr6 = vcpu->arch.dr6; dbgregs->dr7 = vcpu->arch.dr7; dbgregs->flags = 0; - memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved)); } static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, @@ -3110,7 +3106,6 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) sizeof(ps->channels)); ps->flags = kvm->arch.vpit->pit_state.flags; mutex_unlock(&kvm->arch.vpit->pit_state.lock); - memset(&ps->reserved, 0, sizeof(ps->reserved)); return r; } @@ -3174,6 +3169,10 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_memslots *slots, *old_slots; unsigned long *dirty_bitmap; + spin_lock(&kvm->mmu_lock); + kvm_mmu_slot_remove_write_access(kvm, log->slot); + spin_unlock(&kvm->mmu_lock); + r = -ENOMEM; dirty_bitmap = vmalloc(n); if (!dirty_bitmap) @@ -3195,10 +3194,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap; kfree(old_slots); - spin_lock(&kvm->mmu_lock); - kvm_mmu_slot_remove_write_access(kvm, log->slot); - spin_unlock(&kvm->mmu_lock); - r = -EFAULT; if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) { vfree(dirty_bitmap); @@ -3491,7 +3486,6 @@ long kvm_arch_vm_ioctl(struct file *filp, user_ns.clock = kvm->arch.kvmclock_offset + now_ns; local_irq_enable(); user_ns.flags = 0; - memset(&user_ns.pad, 0, sizeof(user_ns.pad)); r = -EFAULT; if (copy_to_user(argp, &user_ns, sizeof(user_ns))) @@ -3978,10 +3972,8 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) return X86EMUL_CONTINUE; if (kvm_x86_ops->has_wbinvd_exit()) { - preempt_disable(); smp_call_function_many(vcpu->arch.wbinvd_dirty_mask, wbinvd_ipi, NULL, 1); - preempt_enable(); cpumask_clear(vcpu->arch.wbinvd_dirty_mask); } wbinvd(); diff --git a/trunk/arch/x86/mm/tlb.c b/trunk/arch/x86/mm/tlb.c index 12cdbb17ad18..49358481c733 100644 --- a/trunk/arch/x86/mm/tlb.c +++ b/trunk/arch/x86/mm/tlb.c @@ -251,7 +251,7 @@ static void __cpuinit calculate_tlb_offset(void) } } -static int __cpuinit tlb_cpuhp_notify(struct notifier_block *n, +static int tlb_cpuhp_notify(struct notifier_block *n, unsigned long action, void *hcpu) { switch (action & 0xf) { diff --git a/trunk/arch/x86/pci/xen.c b/trunk/arch/x86/pci/xen.c index d7b5109f7a9c..117f5b8daf75 100644 --- a/trunk/arch/x86/pci/xen.c +++ b/trunk/arch/x86/pci/xen.c @@ -147,10 +147,8 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) irq = xen_allocate_pirq(v[i], 0, /* not sharable */ (type == PCI_CAP_ID_MSIX) ? "pcifront-msi-x" : "pcifront-msi"); - if (irq < 0) { - ret = -1; - goto free; - } + if (irq < 0) + return -1; ret = set_irq_msi(irq, msidesc); if (ret) @@ -166,7 +164,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (ret == -ENODEV) dev_err(&dev->dev, "Xen PCI frontend has not registered" \ " MSI/MSI-X support!\n"); -free: + kfree(v); return ret; } diff --git a/trunk/arch/x86/platform/uv/tlb_uv.c b/trunk/arch/x86/platform/uv/tlb_uv.c index a318194002b5..20ea20a39e2a 100644 --- a/trunk/arch/x86/platform/uv/tlb_uv.c +++ b/trunk/arch/x86/platform/uv/tlb_uv.c @@ -1343,8 +1343,8 @@ uv_activation_descriptor_init(int node, int pnode) * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR) * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub */ - bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE - * UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); + bau_desc = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)* + UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); BUG_ON(!bau_desc); pa = uv_gpa(bau_desc); /* need the real nasid*/ @@ -1402,9 +1402,9 @@ uv_payload_queue_init(int node, int pnode) struct bau_payload_queue_entry *pqp_malloc; struct bau_control *bcp; - pqp = kmalloc_node((DEST_Q_SIZE + 1) - * sizeof(struct bau_payload_queue_entry), - GFP_KERNEL, node); + pqp = (struct bau_payload_queue_entry *) kmalloc_node( + (DEST_Q_SIZE + 1) * sizeof(struct bau_payload_queue_entry), + GFP_KERNEL, node); BUG_ON(!pqp); pqp_malloc = pqp; @@ -1520,7 +1520,8 @@ static void __init uv_init_per_cpu(int nuvhubs) timeout_us = calculate_destination_timeout(); - uvhub_descs = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); + uvhub_descs = (struct uvhub_desc *) + kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); for_each_present_cpu(cpu) { diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index 21ed8d7f75a5..c237b810b03f 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -2126,7 +2126,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, { pmd_t *kernel_pmd; - level2_kernel_pgt = extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE); + level2_kernel_pgt = extend_brk(sizeof(pmd_t *) * PTRS_PER_PMD, PAGE_SIZE); max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) + xen_start_info->nr_pt_frames * PAGE_SIZE + diff --git a/trunk/arch/x86/xen/setup.c b/trunk/arch/x86/xen/setup.c index 769c4b01fa32..b1dbdaa23ecc 100644 --- a/trunk/arch/x86/xen/setup.c +++ b/trunk/arch/x86/xen/setup.c @@ -118,18 +118,16 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, const struct e820map *e820) { phys_addr_t max_addr = PFN_PHYS(max_pfn); - phys_addr_t last_end = ISA_END_ADDRESS; + phys_addr_t last_end = 0; unsigned long released = 0; int i; - /* Free any unused memory above the low 1Mbyte. */ for (i = 0; i < e820->nr_map && last_end < max_addr; i++) { phys_addr_t end = e820->map[i].addr; end = min(max_addr, end); - if (last_end < end) - released += xen_release_chunk(last_end, end); - last_end = max(last_end, e820->map[i].addr + e820->map[i].size); + released += xen_release_chunk(last_end, end); + last_end = e820->map[i].addr + e820->map[i].size; } if (last_end < max_addr) @@ -166,7 +164,6 @@ char * __init xen_memory_setup(void) XENMEM_memory_map; rc = HYPERVISOR_memory_op(op, &memmap); if (rc == -ENOSYS) { - BUG_ON(xen_initial_domain()); memmap.nr_entries = 1; map[0].addr = 0ULL; map[0].size = mem_end; @@ -204,13 +201,12 @@ char * __init xen_memory_setup(void) } /* - * In domU, the ISA region is normal, usable memory, but we - * reserve ISA memory anyway because too many things poke + * Even though this is normal, usable memory under Xen, reserve + * ISA memory anyway because too many things think they can poke * about in there. * - * In Dom0, the host E820 information can leave gaps in the - * ISA range, which would cause us to release those pages. To - * avoid this, we unconditionally reserve them here. + * In a dom0 kernel, this region is identity mapped with the + * hardware ISA area, so it really is out of bounds. */ e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_RESERVED); diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 4ce953f1b390..f0834e2f5727 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -1194,6 +1194,13 @@ static int __make_request(struct request_queue *q, struct bio *bio) int where = ELEVATOR_INSERT_SORT; int rw_flags; + /* REQ_HARDBARRIER is no more */ + if (WARN_ONCE(bio->bi_rw & REQ_HARDBARRIER, + "block: HARDBARRIER is deprecated, use FLUSH/FUA instead\n")) { + bio_endio(bio, -EOPNOTSUPP); + return 0; + } + /* * low level driver can indicate that it wants pages above a * certain limit bounced to low memory (ie for highmem, or even @@ -1344,7 +1351,7 @@ static void handle_bad_sector(struct bio *bio) bdevname(bio->bi_bdev, b), bio->bi_rw, (unsigned long long)bio->bi_sector + bio_sectors(bio), - (long long)(i_size_read(bio->bi_bdev->bd_inode) >> 9)); + (long long)(bio->bi_bdev->bd_inode->i_size >> 9)); set_bit(BIO_EOF, &bio->bi_flags); } @@ -1397,7 +1404,7 @@ static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors) return 0; /* Test device or partition size, when known. */ - maxsector = i_size_read(bio->bi_bdev->bd_inode) >> 9; + maxsector = bio->bi_bdev->bd_inode->i_size >> 9; if (maxsector) { sector_t sector = bio->bi_sector; diff --git a/trunk/block/blk-ioc.c b/trunk/block/blk-ioc.c index 3c7a339fe381..d22c4c55c406 100644 --- a/trunk/block/blk-ioc.c +++ b/trunk/block/blk-ioc.c @@ -153,6 +153,20 @@ struct io_context *get_io_context(gfp_t gfp_flags, int node) } EXPORT_SYMBOL(get_io_context); +void copy_io_context(struct io_context **pdst, struct io_context **psrc) +{ + struct io_context *src = *psrc; + struct io_context *dst = *pdst; + + if (src) { + BUG_ON(atomic_long_read(&src->refcount) == 0); + atomic_long_inc(&src->refcount); + put_io_context(dst); + *pdst = src; + } +} +EXPORT_SYMBOL(copy_io_context); + static int __init blk_ioc_init(void) { iocontext_cachep = kmem_cache_create("blkdev_ioc", diff --git a/trunk/block/blk-map.c b/trunk/block/blk-map.c index 5d5dbe47c228..d4a586d8691e 100644 --- a/trunk/block/blk-map.c +++ b/trunk/block/blk-map.c @@ -205,8 +205,6 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, unaligned = 1; break; } - if (!iov[i].iov_len) - return -EINVAL; } if (unaligned || (q->dma_pad_mask & len) || map_data) diff --git a/trunk/block/compat_ioctl.c b/trunk/block/compat_ioctl.c index 58c6ee5b010c..119f07b74dc0 100644 --- a/trunk/block/compat_ioctl.c +++ b/trunk/block/compat_ioctl.c @@ -744,13 +744,13 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; return 0; case BLKGETSIZE: - size = i_size_read(bdev->bd_inode); + size = bdev->bd_inode->i_size; if ((size >> 9) > ~0UL) return -EFBIG; return compat_put_ulong(arg, size >> 9); case BLKGETSIZE64_32: - return compat_put_u64(arg, i_size_read(bdev->bd_inode)); + return compat_put_u64(arg, bdev->bd_inode->i_size); case BLKTRACESETUP32: case BLKTRACESTART: /* compatible */ diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 2569512830d3..282e8308f7e2 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -429,7 +429,7 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) q->nr_sorted--; boundary = q->end_sector; - stop_flags = REQ_SOFTBARRIER | REQ_STARTED; + stop_flags = REQ_SOFTBARRIER | REQ_HARDBARRIER | REQ_STARTED; list_for_each_prev(entry, &q->queue_head) { struct request *pos = list_entry_rq(entry); @@ -691,7 +691,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) void __elv_add_request(struct request_queue *q, struct request *rq, int where, int plug) { - if (rq->cmd_flags & REQ_SOFTBARRIER) { + if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { /* barriers are scheduling boundary, update end_sector */ if (rq->cmd_type == REQ_TYPE_FS || (rq->cmd_flags & REQ_DISCARD)) { diff --git a/trunk/block/ioctl.c b/trunk/block/ioctl.c index 3d866d0037f2..d724ceb1d465 100644 --- a/trunk/block/ioctl.c +++ b/trunk/block/ioctl.c @@ -125,7 +125,7 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, start >>= 9; len >>= 9; - if (start + len > (i_size_read(bdev->bd_inode) >> 9)) + if (start + len > (bdev->bd_inode->i_size >> 9)) return -EINVAL; if (secure) flags |= BLKDEV_DISCARD_SECURE; @@ -242,7 +242,6 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, * We need to set the startsect first, the driver may * want to override it. */ - memset(&geo, 0, sizeof(geo)); geo.start = get_start_sect(bdev); ret = disk->fops->getgeo(bdev, &geo); if (ret) @@ -308,12 +307,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, ret = blkdev_reread_part(bdev); break; case BLKGETSIZE: - size = i_size_read(bdev->bd_inode); + size = bdev->bd_inode->i_size; if ((size >> 9) > ~0UL) return -EFBIG; return put_ulong(arg, size >> 9); case BLKGETSIZE64: - return put_u64(arg, i_size_read(bdev->bd_inode)); + return put_u64(arg, bdev->bd_inode->i_size); case BLKTRACESTART: case BLKTRACESTOP: case BLKTRACESETUP: diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 4f4230b79bb6..a8b5a10eb5b0 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -321,47 +321,33 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, if (hdr->iovec_count) { const int size = sizeof(struct sg_iovec) * hdr->iovec_count; size_t iov_data_len; - struct sg_iovec *sg_iov; - struct iovec *iov; - int i; + struct sg_iovec *iov; - sg_iov = kmalloc(size, GFP_KERNEL); - if (!sg_iov) { + iov = kmalloc(size, GFP_KERNEL); + if (!iov) { ret = -ENOMEM; goto out; } - if (copy_from_user(sg_iov, hdr->dxferp, size)) { - kfree(sg_iov); + if (copy_from_user(iov, hdr->dxferp, size)) { + kfree(iov); ret = -EFAULT; goto out; } - /* - * Sum up the vecs, making sure they don't overflow - */ - iov = (struct iovec *) sg_iov; - iov_data_len = 0; - for (i = 0; i < hdr->iovec_count; i++) { - if (iov_data_len + iov[i].iov_len < iov_data_len) { - kfree(sg_iov); - ret = -EINVAL; - goto out; - } - iov_data_len += iov[i].iov_len; - } - /* SG_IO howto says that the shorter of the two wins */ + iov_data_len = iov_length((struct iovec *)iov, + hdr->iovec_count); if (hdr->dxfer_len < iov_data_len) { - hdr->iovec_count = iov_shorten(iov, + hdr->iovec_count = iov_shorten((struct iovec *)iov, hdr->iovec_count, hdr->dxfer_len); iov_data_len = hdr->dxfer_len; } - ret = blk_rq_map_user_iov(q, rq, NULL, sg_iov, hdr->iovec_count, + ret = blk_rq_map_user_iov(q, rq, NULL, iov, hdr->iovec_count, iov_data_len, GFP_KERNEL); - kfree(sg_iov); + kfree(iov); } else if (hdr->dxfer_len) ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, GFP_KERNEL); diff --git a/trunk/crypto/pcrypt.c b/trunk/crypto/pcrypt.c index 75586f1f86e7..de3078215fe6 100644 --- a/trunk/crypto/pcrypt.c +++ b/trunk/crypto/pcrypt.c @@ -504,6 +504,7 @@ static int pcrypt_init_padata(struct padata_pcrypt *pcrypt, static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt) { + kobject_put(&pcrypt->pinst->kobj); free_cpumask_var(pcrypt->cb_cpumask->mask); kfree(pcrypt->cb_cpumask); diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index f3ebb30f1b7f..14cf9077bb2b 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_REGULATOR) += regulator/ # char/ comes before serial/ etc so that the VT console is the boot-time # default. -obj-y += tty/ obj-y += char/ # gpu/ comes after char for AGP vs DRM startup diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 3f91c01c217f..d050e073e570 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -2552,11 +2552,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) * * If door lock fails, always clear sdev->locked to * avoid this infinite loop. - * - * This may happen before SCSI scan is complete. Make - * sure qc->dev->sdev isn't NULL before dereferencing. */ - if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev) + if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL) qc->dev->sdev->locked = 0; qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; diff --git a/trunk/drivers/ata/pata_legacy.c b/trunk/drivers/ata/pata_legacy.c index 6bd9425ba5ab..eaf194138f21 100644 --- a/trunk/drivers/ata/pata_legacy.c +++ b/trunk/drivers/ata/pata_legacy.c @@ -142,7 +142,7 @@ static int autospeed; /* Chip present which snoops speed changes */ static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ -#ifdef CONFIG_PATA_WINBOND_VLB_MODULE +#ifdef PATA_WINBOND_VLB_MODULE static int winbond = 1; /* Set to probe Winbond controllers, give I/O port if non standard */ #else diff --git a/trunk/drivers/ata/pata_octeon_cf.c b/trunk/drivers/ata/pata_octeon_cf.c index fa1b95a9a7ff..74b829817891 100644 --- a/trunk/drivers/ata/pata_octeon_cf.c +++ b/trunk/drivers/ata/pata_octeon_cf.c @@ -652,6 +652,8 @@ static irqreturn_t octeon_cf_interrupt(int irq, void *dev_instance) struct octeon_cf_data *ocd; ap = host->ports[i]; + ocd = ap->dev->platform_data; + ocd = ap->dev->platform_data; cf_port = ap->private_data; dma_int.u64 = diff --git a/trunk/drivers/atm/fore200e.c b/trunk/drivers/atm/fore200e.c index c09761959354..c8fc69c85a06 100644 --- a/trunk/drivers/atm/fore200e.c +++ b/trunk/drivers/atm/fore200e.c @@ -92,7 +92,7 @@ #define FORE200E_INDEX(virt_addr, type, index) (&((type *)(virt_addr))[ index ]) -#define FORE200E_NEXT_ENTRY(index, modulo) (index = ((index) + 1) % (modulo)) +#define FORE200E_NEXT_ENTRY(index, modulo) (index = ++(index) % (modulo)) #if 1 #define ASSERT(expr) if (!(expr)) { \ diff --git a/trunk/drivers/atm/solos-attrlist.c b/trunk/drivers/atm/solos-attrlist.c index 9a676ee30824..1a9332e4efe0 100644 --- a/trunk/drivers/atm/solos-attrlist.c +++ b/trunk/drivers/atm/solos-attrlist.c @@ -1,7 +1,6 @@ SOLOS_ATTR_RO(DriverVersion) SOLOS_ATTR_RO(APIVersion) SOLOS_ATTR_RO(FirmwareVersion) -SOLOS_ATTR_RO(Version) // SOLOS_ATTR_RO(DspVersion) // SOLOS_ATTR_RO(CommonHandshake) SOLOS_ATTR_RO(Connected) diff --git a/trunk/drivers/atm/solos-pci.c b/trunk/drivers/atm/solos-pci.c index 2e08c996fd30..f46138ab38b6 100644 --- a/trunk/drivers/atm/solos-pci.c +++ b/trunk/drivers/atm/solos-pci.c @@ -1161,14 +1161,6 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n", major_ver, minor_ver, fpga_ver); - if (fpga_ver < 37 && (fpga_upgrade || firmware_upgrade || - db_fpga_upgrade || db_firmware_upgrade)) { - dev_warn(&dev->dev, - "FPGA too old; cannot upgrade flash. Use JTAG.\n"); - fpga_upgrade = firmware_upgrade = 0; - db_fpga_upgrade = db_firmware_upgrade = 0; - } - if (card->fpga_version >= DMA_SUPPORTED){ card->using_dma = 1; } else { diff --git a/trunk/drivers/block/aoe/aoeblk.c b/trunk/drivers/block/aoe/aoeblk.c index 528f6318ded1..541e18879965 100644 --- a/trunk/drivers/block/aoe/aoeblk.c +++ b/trunk/drivers/block/aoe/aoeblk.c @@ -180,6 +180,9 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio) BUG(); bio_endio(bio, -ENXIO); return 0; + } else if (bio->bi_rw & REQ_HARDBARRIER) { + bio_endio(bio, -EOPNOTSUPP); + return 0; } else if (bio->bi_io_vec == NULL) { printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); BUG(); diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index de0435e63b02..5674bd01d96d 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -297,8 +297,8 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu struct sk_buff *skb; struct net_device *ifp; - rcu_read_lock(); - for_each_netdev_rcu(&init_net, ifp) { + read_lock(&dev_base_lock); + for_each_netdev(&init_net, ifp) { dev_hold(ifp); if (!is_aoe_netif(ifp)) goto cont; @@ -325,7 +325,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *qu cont: dev_put(ifp); } - rcu_read_unlock(); + read_unlock(&dev_base_lock); } static void diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index a67d0a611a8a..2cc4dda46279 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -113,8 +113,6 @@ static struct board_type products[] = { {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, {0x40910E11, "Smart Array 6i", &SA5_access}, {0x3225103C, "Smart Array P600", &SA5_access}, - {0x3223103C, "Smart Array P800", &SA5_access}, - {0x3234103C, "Smart Array P400", &SA5_access}, {0x3235103C, "Smart Array P400i", &SA5_access}, {0x3211103C, "Smart Array E200i", &SA5_access}, {0x3212103C, "Smart Array E200", &SA5_access}, @@ -3755,7 +3753,7 @@ static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h) for (i = 0; i < MAX_CONFIG_WAIT; i++) { if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; - usleep_range(10000, 20000); + msleep(10); } } @@ -3939,9 +3937,10 @@ static int __devinit cciss_lookup_board_id(struct pci_dev *pdev, u32 *board_id) *board_id = ((subsystem_device_id << 16) & 0xffff0000) | subsystem_vendor_id; - for (i = 0; i < ARRAY_SIZE(products); i++) + for (i = 0; i < ARRAY_SIZE(products); i++) { if (*board_id == products[i].board_id) return i; + } dev_warn(&pdev->dev, "unrecognized board ID: 0x%08x, ignoring.\n", *board_id); return -ENODEV; @@ -3972,31 +3971,18 @@ static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, return -ENODEV; } -static int __devinit cciss_wait_for_board_state(struct pci_dev *pdev, - void __iomem *vaddr, int wait_for_ready) -#define BOARD_READY 1 -#define BOARD_NOT_READY 0 +static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h) { - int i, iterations; + int i; u32 scratchpad; - if (wait_for_ready) - iterations = CCISS_BOARD_READY_ITERATIONS; - else - iterations = CCISS_BOARD_NOT_READY_ITERATIONS; - - for (i = 0; i < iterations; i++) { - scratchpad = readl(vaddr + SA5_SCRATCHPAD_OFFSET); - if (wait_for_ready) { - if (scratchpad == CCISS_FIRMWARE_READY) - return 0; - } else { - if (scratchpad != CCISS_FIRMWARE_READY) - return 0; - } + for (i = 0; i < CCISS_BOARD_READY_ITERATIONS; i++) { + scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + if (scratchpad == CCISS_FIRMWARE_READY) + return 0; msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS); } - dev_warn(&pdev->dev, "board not ready, timed out.\n"); + dev_warn(&h->pdev->dev, "board not ready, timed out.\n"); return -ENODEV; } @@ -4045,11 +4031,6 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h) static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h) { h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); - - /* Limit commands in memory limited kdump scenario. */ - if (reset_devices && h->max_commands > 32) - h->max_commands = 32; - if (h->max_commands < 16) { dev_warn(&h->pdev->dev, "Controller reports " "max supported commands of %d, an obvious lie. " @@ -4167,7 +4148,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *h) err = -ENOMEM; goto err_out_free_res; } - err = cciss_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY); + err = cciss_wait_for_board_ready(h); if (err) goto err_out_free_res; err = cciss_find_cfgtables(h); @@ -4332,6 +4313,36 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u #define cciss_soft_reset_controller(p) cciss_message(p, 1, 0) #define cciss_noop(p) cciss_message(p, 3, 0) +static __devinit int cciss_reset_msi(struct pci_dev *pdev) +{ +/* the #defines are stolen from drivers/pci/msi.h. */ +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) + + int pos; + u16 control = 0; + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSI); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSI_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI\n"); + pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); + } + } + + pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(pdev, msi_control_reg(pos), &control); + if (control & PCI_MSIX_FLAGS_ENABLE) { + dev_info(&pdev->dev, "resetting MSI-X\n"); + pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); + } + } + + return 0; +} + static int cciss_controller_hard_reset(struct pci_dev *pdev, void * __iomem vaddr, bool use_doorbell) { @@ -4386,17 +4397,17 @@ static int cciss_controller_hard_reset(struct pci_dev *pdev, * states or using the doorbell register. */ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) { + u16 saved_config_space[32]; u64 cfg_offset; u32 cfg_base_addr; u64 cfg_base_addr_index; void __iomem *vaddr; unsigned long paddr; u32 misc_fw_support, active_transport; - int rc; + int rc, i; CfgTable_struct __iomem *cfgtable; bool use_doorbell; u32 board_id; - u16 command_register; /* For controllers as old a the p600, this is very nearly * the same thing as @@ -4406,6 +4417,14 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) * pci_set_power_state(pci_dev, PCI_D0); * pci_restore_state(pci_dev); * + * but we can't use these nice canned kernel routines on + * kexec, because they also check the MSI/MSI-X state in PCI + * configuration space and do the wrong thing when it is + * set/cleared. Also, the pci_save/restore_state functions + * violate the ordering requirements for restoring the + * configuration space from the CCISS document (see the + * comment below). So we roll our own .... + * * For controllers newer than the P600, the pci power state * method of resetting doesn't work so we have another way * using the doorbell register. @@ -4424,13 +4443,8 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) return -ENODEV; } - /* Save the PCI command register */ - pci_read_config_word(pdev, 4, &command_register); - /* Turn the board off. This is so that later pci_restore_state() - * won't turn the board on before the rest of config space is ready. - */ - pci_disable_device(pdev); - pci_save_state(pdev); + for (i = 0; i < 32; i++) + pci_read_config_word(pdev, 2*i, &saved_config_space[i]); /* find the first memory BAR, so we can find the cfg table */ rc = cciss_pci_find_memory_BAR(pdev, &paddr); @@ -4465,32 +4479,26 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); if (rc) goto unmap_cfgtable; - pci_restore_state(pdev); - rc = pci_enable_device(pdev); - if (rc) { - dev_warn(&pdev->dev, "failed to enable device.\n"); - goto unmap_cfgtable; + + /* Restore the PCI configuration space. The Open CISS + * Specification says, "Restore the PCI Configuration + * Registers, offsets 00h through 60h. It is important to + * restore the command register, 16-bits at offset 04h, + * last. Do not restore the configuration status register, + * 16-bits at offset 06h." Note that the offset is 2*i. + */ + for (i = 0; i < 32; i++) { + if (i == 2 || i == 3) + continue; + pci_write_config_word(pdev, 2*i, saved_config_space[i]); } - pci_write_config_word(pdev, 4, command_register); + wmb(); + pci_write_config_word(pdev, 4, saved_config_space[2]); /* Some devices (notably the HP Smart Array 5i Controller) need a little pause here */ msleep(CCISS_POST_RESET_PAUSE_MSECS); - /* Wait for board to become not ready, then ready. */ - dev_info(&pdev->dev, "Waiting for board to become ready.\n"); - rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY); - if (rc) /* Don't bail, might be E500, etc. which can't be reset */ - dev_warn(&pdev->dev, - "failed waiting for board to become not ready\n"); - rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_READY); - if (rc) { - dev_warn(&pdev->dev, - "failed waiting for board to become ready\n"); - goto unmap_cfgtable; - } - dev_info(&pdev->dev, "board ready.\n"); - /* Controller should be in simple mode at this point. If it's not, * It means we're on one of those controllers which doesn't support * the doorbell reset method and on which the PCI power management reset @@ -4531,6 +4539,8 @@ static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) return 0; /* just try to do the kdump anyhow. */ if (rc) return -ENODEV; + if (cciss_reset_msi(pdev)) + return -ENODEV; /* Now try to get the controller to respond to a no-op */ for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { @@ -4926,8 +4936,7 @@ static void __exit cciss_cleanup(void) } } kthread_stop(cciss_scan_thread); - if (proc_cciss) - remove_proc_entry("driver/cciss", NULL); + remove_proc_entry("driver/cciss", NULL); bus_unregister(&cciss_bus_type); } diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index 4b8933d778f1..ae340ffc8f81 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -200,14 +200,10 @@ struct ctlr_info * the above. */ #define CCISS_BOARD_READY_WAIT_SECS (120) -#define CCISS_BOARD_NOT_READY_WAIT_SECS (10) #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) #define CCISS_BOARD_READY_ITERATIONS \ ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ CCISS_BOARD_READY_POLL_INTERVAL_MSECS) -#define CCISS_BOARD_NOT_READY_ITERATIONS \ - ((CCISS_BOARD_NOT_READY_WAIT_SECS * 1000) / \ - CCISS_BOARD_READY_POLL_INTERVAL_MSECS) #define CCISS_POST_RESET_PAUSE_MSECS (3000) #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) #define CCISS_POST_RESET_NOOP_RETRIES (12) diff --git a/trunk/drivers/block/drbd/drbd_actlog.c b/trunk/drivers/block/drbd/drbd_actlog.c index ba95cba192be..ac04ef97eac2 100644 --- a/trunk/drivers/block/drbd/drbd_actlog.c +++ b/trunk/drivers/block/drbd/drbd_actlog.c @@ -78,10 +78,11 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, init_completion(&md_io.event); md_io.error = 0; - if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) - rw |= REQ_FUA; + if ((rw & WRITE) && !test_bit(MD_NO_BARRIER, &mdev->flags)) + rw |= REQ_HARDBARRIER; rw |= REQ_UNPLUG | REQ_SYNC; + retry: bio = bio_alloc(GFP_NOIO, 1); bio->bi_bdev = bdev->md_bdev; bio->bi_sector = sector; @@ -99,6 +100,17 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, wait_for_completion(&md_io.event); ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0; + /* check for unsupported barrier op. + * would rather check on EOPNOTSUPP, but that is not reliable. + * don't try again for ANY return value != 0 */ + if (unlikely((bio->bi_rw & REQ_HARDBARRIER) && !ok)) { + /* Try again with no barrier */ + dev_warn(DEV, "Barriers not supported on meta data device - disabling\n"); + set_bit(MD_NO_BARRIER, &mdev->flags); + rw &= ~REQ_HARDBARRIER; + bio_put(bio); + goto retry; + } out: bio_put(bio); return ok; @@ -272,32 +284,18 @@ w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) u32 xor_sum = 0; if (!get_ldev(mdev)) { - dev_err(DEV, - "disk is %s, cannot start al transaction (-%d +%d)\n", - drbd_disk_str(mdev->state.disk), evicted, new_enr); + dev_err(DEV, "get_ldev() failed in w_al_write_transaction\n"); complete(&((struct update_al_work *)w)->event); return 1; } /* do we have to do a bitmap write, first? * TODO reduce maximum latency: * submit both bios, then wait for both, - * instead of doing two synchronous sector writes. - * For now, we must not write the transaction, - * if we cannot write out the bitmap of the evicted extent. */ + * instead of doing two synchronous sector writes. */ if (mdev->state.conn < C_CONNECTED && evicted != LC_FREE) drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); - /* The bitmap write may have failed, causing a state change. */ - if (mdev->state.disk < D_INCONSISTENT) { - dev_err(DEV, - "disk is %s, cannot write al transaction (-%d +%d)\n", - drbd_disk_str(mdev->state.disk), evicted, new_enr); - complete(&((struct update_al_work *)w)->event); - put_ldev(mdev); - return 1; - } - - mutex_lock(&mdev->md_io_mutex); /* protects md_io_buffer, al_tr_cycle, ... */ + mutex_lock(&mdev->md_io_mutex); /* protects md_io_page, al_tr_cycle, ... */ buffer = (struct al_transaction *)page_address(mdev->md_io_page); buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); @@ -741,7 +739,7 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev) unsigned int enr; unsigned long add = 0; char ppb[10]; - int i, tmp; + int i; wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); @@ -749,9 +747,7 @@ void drbd_al_apply_to_bm(struct drbd_conf *mdev) enr = lc_element_by_index(mdev->act_log, i)->lc_number; if (enr == LC_FREE) continue; - tmp = drbd_bm_ALe_set_all(mdev, enr); - dynamic_dev_dbg(DEV, "AL: set %d bits in extent %u\n", tmp, enr); - add += tmp; + add += drbd_bm_ALe_set_all(mdev, enr); } lc_unlock(mdev->act_log); diff --git a/trunk/drivers/block/drbd/drbd_int.h b/trunk/drivers/block/drbd/drbd_int.h index 1ea1a34e78b2..9bdcf4393c0a 100644 --- a/trunk/drivers/block/drbd/drbd_int.h +++ b/trunk/drivers/block/drbd/drbd_int.h @@ -114,11 +114,11 @@ struct drbd_conf; #define D_ASSERT(exp) if (!(exp)) \ dev_err(DEV, "ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__) -#define ERR_IF(exp) if (({ \ - int _b = (exp) != 0; \ - if (_b) dev_err(DEV, "ASSERT FAILED: %s: (%s) in %s:%d\n", \ - __func__, #exp, __FILE__, __LINE__); \ - _b; \ +#define ERR_IF(exp) if (({ \ + int _b = (exp) != 0; \ + if (_b) dev_err(DEV, "%s: (%s) in %s:%d\n", \ + __func__, #exp, __FILE__, __LINE__); \ + _b; \ })) /* Defines to control fault insertion */ @@ -749,12 +749,17 @@ struct drbd_epoch { /* drbd_epoch flag bits */ enum { + DE_BARRIER_IN_NEXT_EPOCH_ISSUED, + DE_BARRIER_IN_NEXT_EPOCH_DONE, + DE_CONTAINS_A_BARRIER, DE_HAVE_BARRIER_NUMBER, + DE_IS_FINISHING, }; enum epoch_event { EV_PUT, EV_GOT_BARRIER_NR, + EV_BARRIER_DONE, EV_BECAME_LAST, EV_CLEANUP = 32, /* used as flag */ }; @@ -796,6 +801,11 @@ enum { __EE_CALL_AL_COMPLETE_IO, __EE_MAY_SET_IN_SYNC, + /* This epoch entry closes an epoch using a barrier. + * On sucessful completion, the epoch is released, + * and the P_BARRIER_ACK send. */ + __EE_IS_BARRIER, + /* In case a barrier failed, * we need to resubmit without the barrier flag. */ __EE_RESUBMITTED, @@ -810,6 +820,7 @@ enum { }; #define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) #define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) +#define EE_IS_BARRIER (1<<__EE_IS_BARRIER) #define EE_RESUBMITTED (1<<__EE_RESUBMITTED) #define EE_WAS_ERROR (1<<__EE_WAS_ERROR) #define EE_HAS_DIGEST (1<<__EE_HAS_DIGEST) @@ -832,15 +843,16 @@ enum { * Gets cleared when the state.conn * goes into C_CONNECTED state. */ WRITE_BM_AFTER_RESYNC, /* A kmalloc() during resync failed */ + NO_BARRIER_SUPP, /* underlying block device doesn't implement barriers */ CONSIDER_RESYNC, - MD_NO_FUA, /* Users wants us to not use FUA/FLUSH on meta data dev */ + MD_NO_BARRIER, /* meta data device does not support barriers, + so don't even try */ SUSPEND_IO, /* suspend application io */ BITMAP_IO, /* suspend application io; once no more io in flight, start bitmap io */ BITMAP_IO_QUEUED, /* Started bitmap IO */ - GO_DISKLESS, /* Disk is being detached, on io-error or admin request. */ - WAS_IO_ERROR, /* Local disk failed returned IO error */ + GO_DISKLESS, /* Disk failed, local_cnt reached zero, we are going diskless */ RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ NET_CONGESTED, /* The data socket is congested */ @@ -935,6 +947,7 @@ enum write_ordering_e { WO_none, WO_drain_io, WO_bdev_flush, + WO_bio_barrier }; struct fifo_buffer { @@ -1268,7 +1281,6 @@ extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why); extern void drbd_go_diskless(struct drbd_conf *mdev); -extern void drbd_ldev_destroy(struct drbd_conf *mdev); /* Meta data layout @@ -1786,17 +1798,17 @@ static inline void __drbd_chk_io_error_(struct drbd_conf *mdev, int forcedetach, case EP_PASS_ON: if (!forcedetach) { if (__ratelimit(&drbd_ratelimit_state)) - dev_err(DEV, "Local IO failed in %s.\n", where); + dev_err(DEV, "Local IO failed in %s." + "Passing error on...\n", where); break; } /* NOTE fall through to detach case if forcedetach set */ case EP_DETACH: case EP_CALL_HELPER: - set_bit(WAS_IO_ERROR, &mdev->flags); if (mdev->state.disk > D_FAILED) { _drbd_set_state(_NS(mdev, disk, D_FAILED), CS_HARD, NULL); - dev_err(DEV, - "Local IO failed in %s. Detaching...\n", where); + dev_err(DEV, "Local IO failed in %s." + "Detaching...\n", where); } break; } @@ -1862,7 +1874,7 @@ static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev) static inline sector_t drbd_get_capacity(struct block_device *bdev) { /* return bdev ? get_capacity(bdev->bd_disk) : 0; */ - return bdev ? i_size_read(bdev->bd_inode) >> 9 : 0; + return bdev ? bdev->bd_inode->i_size >> 9 : 0; } /** @@ -2115,11 +2127,7 @@ static inline void put_ldev(struct drbd_conf *mdev) __release(local); D_ASSERT(i >= 0); if (i == 0) { - if (mdev->state.disk == D_DISKLESS) - /* even internal references gone, safe to destroy */ - drbd_ldev_destroy(mdev); if (mdev->state.disk == D_FAILED) - /* all application IO references gone. */ drbd_go_diskless(mdev); wake_up(&mdev->misc_wait); } @@ -2130,10 +2138,6 @@ static inline int _get_ldev_if_state(struct drbd_conf *mdev, enum drbd_disk_stat { int io_allowed; - /* never get a reference while D_DISKLESS */ - if (mdev->state.disk == D_DISKLESS) - return 0; - atomic_inc(&mdev->local_cnt); io_allowed = (mdev->state.disk >= mins); if (!io_allowed) @@ -2402,12 +2406,12 @@ static inline void drbd_md_flush(struct drbd_conf *mdev) { int r; - if (test_bit(MD_NO_FUA, &mdev->flags)) + if (test_bit(MD_NO_BARRIER, &mdev->flags)) return; r = blkdev_issue_flush(mdev->ldev->md_bdev, GFP_KERNEL, NULL); if (r) { - set_bit(MD_NO_FUA, &mdev->flags); + set_bit(MD_NO_BARRIER, &mdev->flags); dev_err(DEV, "meta data flush failed with status %d, disabling md-flushes\n", r); } } diff --git a/trunk/drivers/block/drbd/drbd_main.c b/trunk/drivers/block/drbd/drbd_main.c index 6be5401d0e88..25c7a73c5062 100644 --- a/trunk/drivers/block/drbd/drbd_main.c +++ b/trunk/drivers/block/drbd/drbd_main.c @@ -835,15 +835,6 @@ static union drbd_state sanitize_state(struct drbd_conf *mdev, union drbd_state ns.conn != C_UNCONNECTED && ns.conn != C_DISCONNECTING && ns.conn <= C_TEAR_DOWN) ns.conn = os.conn; - /* we cannot fail (again) if we already detached */ - if (ns.disk == D_FAILED && os.disk == D_DISKLESS) - ns.disk = D_DISKLESS; - - /* if we are only D_ATTACHING yet, - * we can (and should) go directly to D_DISKLESS. */ - if (ns.disk == D_FAILED && os.disk == D_ATTACHING) - ns.disk = D_DISKLESS; - /* After C_DISCONNECTING only C_STANDALONE may follow */ if (os.conn == C_DISCONNECTING && ns.conn != C_STANDALONE) ns.conn = os.conn; @@ -1065,15 +1056,7 @@ int __drbd_set_state(struct drbd_conf *mdev, !test_and_set_bit(CONFIG_PENDING, &mdev->flags)) set_bit(DEVICE_DYING, &mdev->flags); - /* if we are going -> D_FAILED or D_DISKLESS, grab one extra reference - * on the ldev here, to be sure the transition -> D_DISKLESS resp. - * drbd_ldev_destroy() won't happen before our corresponding - * after_state_ch works run, where we put_ldev again. */ - if ((os.disk != D_FAILED && ns.disk == D_FAILED) || - (os.disk != D_DISKLESS && ns.disk == D_DISKLESS)) - atomic_inc(&mdev->local_cnt); - - mdev->state = ns; + mdev->state.i = ns.i; wake_up(&mdev->misc_wait); wake_up(&mdev->state_wait); @@ -1285,6 +1268,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, if (test_bit(NEW_CUR_UUID, &mdev->flags)) { drbd_uuid_new_current(mdev); clear_bit(NEW_CUR_UUID, &mdev->flags); + drbd_md_sync(mdev); } spin_lock_irq(&mdev->req_lock); _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); @@ -1381,64 +1365,63 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, os.disk > D_INCONSISTENT && ns.disk == D_INCONSISTENT) drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); - /* first half of local IO error, failure to attach, - * or administrative detach */ - if (os.disk != D_FAILED && ns.disk == D_FAILED) { - enum drbd_io_error_p eh; - int was_io_error; - /* corresponding get_ldev was in __drbd_set_state, to serialize - * our cleanup here with the transition to D_DISKLESS, - * so it is safe to dreference ldev here. */ - eh = mdev->ldev->dc.on_io_error; - was_io_error = test_and_clear_bit(WAS_IO_ERROR, &mdev->flags); - - /* current state still has to be D_FAILED, - * there is only one way out: to D_DISKLESS, - * and that may only happen after our put_ldev below. */ - if (mdev->state.disk != D_FAILED) - dev_err(DEV, - "ASSERT FAILED: disk is %s during detach\n", - drbd_disk_str(mdev->state.disk)); + /* first half of local IO error */ + if (os.disk > D_FAILED && ns.disk == D_FAILED) { + enum drbd_io_error_p eh = EP_PASS_ON; if (drbd_send_state(mdev)) - dev_warn(DEV, "Notified peer that I am detaching my disk\n"); + dev_warn(DEV, "Notified peer that my disk is broken.\n"); else - dev_err(DEV, "Sending state for detaching disk failed\n"); + dev_err(DEV, "Sending state for drbd_io_error() failed\n"); drbd_rs_cancel_all(mdev); - /* In case we want to get something to stable storage still, - * this may be the last chance. - * Following put_ldev may transition to D_DISKLESS. */ - drbd_md_sync(mdev); - put_ldev(mdev); - - if (was_io_error && eh == EP_CALL_HELPER) + if (get_ldev_if_state(mdev, D_FAILED)) { + eh = mdev->ldev->dc.on_io_error; + put_ldev(mdev); + } + if (eh == EP_CALL_HELPER) drbd_khelper(mdev, "local-io-error"); } - /* second half of local IO error, failure to attach, - * or administrative detach, - * after local_cnt references have reached zero again */ - if (os.disk != D_DISKLESS && ns.disk == D_DISKLESS) { - /* We must still be diskless, - * re-attach has to be serialized with this! */ - if (mdev->state.disk != D_DISKLESS) - dev_err(DEV, - "ASSERT FAILED: disk is %s while going diskless\n", - drbd_disk_str(mdev->state.disk)); - mdev->rs_total = 0; - mdev->rs_failed = 0; - atomic_set(&mdev->rs_pending_cnt, 0); + /* second half of local IO error handling, + * after local_cnt references have reached zero: */ + if (os.disk == D_FAILED && ns.disk == D_DISKLESS) { + mdev->rs_total = 0; + mdev->rs_failed = 0; + atomic_set(&mdev->rs_pending_cnt, 0); + } + + if (os.disk > D_DISKLESS && ns.disk == D_DISKLESS) { + /* We must still be diskless, + * re-attach has to be serialized with this! */ + if (mdev->state.disk != D_DISKLESS) + dev_err(DEV, + "ASSERT FAILED: disk is %s while going diskless\n", + drbd_disk_str(mdev->state.disk)); + /* we cannot assert local_cnt == 0 here, as get_ldev_if_state + * will inc/dec it frequently. Since we became D_DISKLESS, no + * one has touched the protected members anymore, though, so we + * are safe to free them here. */ if (drbd_send_state(mdev)) - dev_warn(DEV, "Notified peer that I'm now diskless.\n"); + dev_warn(DEV, "Notified peer that I detached my disk.\n"); else - dev_err(DEV, "Sending state for being diskless failed\n"); - /* corresponding get_ldev in __drbd_set_state - * this may finaly trigger drbd_ldev_destroy. */ - put_ldev(mdev); + dev_err(DEV, "Sending state for detach failed\n"); + + lc_destroy(mdev->resync); + mdev->resync = NULL; + lc_destroy(mdev->act_log); + mdev->act_log = NULL; + __no_warn(local, + drbd_free_bc(mdev->ldev); + mdev->ldev = NULL;); + + if (mdev->md_io_tmpp) { + __free_page(mdev->md_io_tmpp); + mdev->md_io_tmpp = NULL; + } } /* Disks got bigger while they were detached */ @@ -2789,6 +2772,11 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) drbd_set_defaults(mdev); + /* for now, we do NOT yet support it, + * even though we start some framework + * to eventually support barriers */ + set_bit(NO_BARRIER_SUPP, &mdev->flags); + atomic_set(&mdev->ap_bio_cnt, 0); atomic_set(&mdev->ap_pending_cnt, 0); atomic_set(&mdev->rs_pending_cnt, 0); @@ -2854,7 +2842,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) drbd_thread_init(mdev, &mdev->asender, drbd_asender); mdev->agreed_pro_version = PRO_VERSION_MAX; - mdev->write_ordering = WO_bdev_flush; + mdev->write_ordering = WO_bio_barrier; mdev->resync_wenr = LC_FREE; } @@ -2911,6 +2899,7 @@ void drbd_mdev_cleanup(struct drbd_conf *mdev) D_ASSERT(list_empty(&mdev->resync_work.list)); D_ASSERT(list_empty(&mdev->unplug_work.list)); D_ASSERT(list_empty(&mdev->go_diskless.list)); + } @@ -3671,8 +3660,6 @@ void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) get_random_bytes(&val, sizeof(u64)); _drbd_uuid_set(mdev, UI_CURRENT, val); - /* get it to stable storage _now_ */ - drbd_md_sync(mdev); } void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) @@ -3769,31 +3756,19 @@ static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused) return 1; } -void drbd_ldev_destroy(struct drbd_conf *mdev) -{ - lc_destroy(mdev->resync); - mdev->resync = NULL; - lc_destroy(mdev->act_log); - mdev->act_log = NULL; - __no_warn(local, - drbd_free_bc(mdev->ldev); - mdev->ldev = NULL;); - - if (mdev->md_io_tmpp) { - __free_page(mdev->md_io_tmpp); - mdev->md_io_tmpp = NULL; - } - clear_bit(GO_DISKLESS, &mdev->flags); -} - static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused) { D_ASSERT(mdev->state.disk == D_FAILED); /* we cannot assert local_cnt == 0 here, as get_ldev_if_state will * inc/dec it frequently. Once we are D_DISKLESS, no one will touch - * the protected members anymore, though, so once put_ldev reaches zero - * again, it will be safe to free them. */ + * the protected members anymore, though, so in the after_state_ch work + * it will be safe to free them. */ drbd_force_state(mdev, NS(disk, D_DISKLESS)); + /* We need to wait for return of references checked out while we still + * have been D_FAILED, though (drbd_md_sync, bitmap io). */ + wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); + + clear_bit(GO_DISKLESS, &mdev->flags); return 1; } @@ -3802,6 +3777,9 @@ void drbd_go_diskless(struct drbd_conf *mdev) D_ASSERT(mdev->state.disk == D_FAILED); if (!test_and_set_bit(GO_DISKLESS, &mdev->flags)) drbd_queue_work(&mdev->data.work, &mdev->go_diskless); + /* don't drbd_queue_work_front, + * we need to serialize with the after_state_ch work + * of the -> D_FAILED transition. */ } /** diff --git a/trunk/drivers/block/drbd/drbd_nl.c b/trunk/drivers/block/drbd/drbd_nl.c index 29e5c70e4e26..87925e97e613 100644 --- a/trunk/drivers/block/drbd/drbd_nl.c +++ b/trunk/drivers/block/drbd/drbd_nl.c @@ -870,11 +870,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp retcode = ERR_DISK_CONFIGURED; goto fail; } - /* It may just now have detached because of IO error. Make sure - * drbd_ldev_destroy is done already, we may end up here very fast, - * e.g. if someone calls attach from the on-io-error handler, - * to realize a "hot spare" feature (not that I'd recommend that) */ - wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); /* allocation not in the IO path, cqueue thread context */ nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL); @@ -1103,9 +1098,9 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp /* Reset the "barriers don't work" bits here, then force meta data to * be written, to ensure we determine if barriers are supported. */ if (nbc->dc.no_md_flush) - set_bit(MD_NO_FUA, &mdev->flags); + set_bit(MD_NO_BARRIER, &mdev->flags); else - clear_bit(MD_NO_FUA, &mdev->flags); + clear_bit(MD_NO_BARRIER, &mdev->flags); /* Point of no return reached. * Devices and memory are no longer released by error cleanup below. @@ -1117,8 +1112,8 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp nbc = NULL; resync_lru = NULL; - mdev->write_ordering = WO_bdev_flush; - drbd_bump_write_ordering(mdev, WO_bdev_flush); + mdev->write_ordering = WO_bio_barrier; + drbd_bump_write_ordering(mdev, WO_bio_barrier); if (drbd_md_test_flag(mdev->ldev, MDF_CRASHED_PRIMARY)) set_bit(CRASHED_PRIMARY, &mdev->flags); @@ -1267,7 +1262,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp force_diskless_dec: put_ldev(mdev); force_diskless: - drbd_force_state(mdev, NS(disk, D_FAILED)); + drbd_force_state(mdev, NS(disk, D_DISKLESS)); drbd_md_sync(mdev); release_bdev2_fail: if (nbc) @@ -1290,19 +1285,10 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp return 0; } -/* Detaching the disk is a process in multiple stages. First we need to lock - * out application IO, in-flight IO, IO stuck in drbd_al_begin_io. - * Then we transition to D_DISKLESS, and wait for put_ldev() to return all - * internal references as well. - * Only then we have finally detached. */ static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, struct drbd_nl_cfg_reply *reply) { - drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */ reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS)); - if (mdev->state.disk == D_DISKLESS) - wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); - drbd_resume_io(mdev); return 0; } @@ -1967,6 +1953,7 @@ static int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp if (test_bit(NEW_CUR_UUID, &mdev->flags)) { drbd_uuid_new_current(mdev); clear_bit(NEW_CUR_UUID, &mdev->flags); + drbd_md_sync(mdev); } drbd_suspend_io(mdev); reply->ret_code = drbd_request_state(mdev, NS3(susp, 0, susp_nod, 0, susp_fen, 0)); diff --git a/trunk/drivers/block/drbd/drbd_proc.c b/trunk/drivers/block/drbd/drbd_proc.c index 7e6ac307e2de..ad325c5d0ce1 100644 --- a/trunk/drivers/block/drbd/drbd_proc.c +++ b/trunk/drivers/block/drbd/drbd_proc.c @@ -158,6 +158,7 @@ static int drbd_seq_show(struct seq_file *seq, void *v) [WO_none] = 'n', [WO_drain_io] = 'd', [WO_bdev_flush] = 'f', + [WO_bio_barrier] = 'b', }; seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n", diff --git a/trunk/drivers/block/drbd/drbd_receiver.c b/trunk/drivers/block/drbd/drbd_receiver.c index d299fe9e78c8..efd6169acf2f 100644 --- a/trunk/drivers/block/drbd/drbd_receiver.c +++ b/trunk/drivers/block/drbd/drbd_receiver.c @@ -49,6 +49,11 @@ #include "drbd_vli.h" +struct flush_work { + struct drbd_work w; + struct drbd_epoch *epoch; +}; + enum finish_epoch { FE_STILL_LIVE, FE_DESTROYED, @@ -61,6 +66,16 @@ static int drbd_do_auth(struct drbd_conf *mdev); static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event); static int e_end_block(struct drbd_conf *, struct drbd_work *, int); +static struct drbd_epoch *previous_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch) +{ + struct drbd_epoch *prev; + spin_lock(&mdev->epoch_lock); + prev = list_entry(epoch->list.prev, struct drbd_epoch, list); + if (prev == epoch || prev == mdev->current_epoch) + prev = NULL; + spin_unlock(&mdev->epoch_lock); + return prev; +} #define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN) @@ -966,7 +981,7 @@ static int drbd_recv_header(struct drbd_conf *mdev, enum drbd_packets *cmd, unsi return TRUE; } -static void drbd_flush(struct drbd_conf *mdev) +static enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch) { int rv; @@ -982,6 +997,24 @@ static void drbd_flush(struct drbd_conf *mdev) } put_ldev(mdev); } + + return drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE); +} + +static int w_flush(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct flush_work *fw = (struct flush_work *)w; + struct drbd_epoch *epoch = fw->epoch; + + kfree(w); + + if (!test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags)) + drbd_flush_after_epoch(mdev, epoch); + + drbd_may_finish_epoch(mdev, epoch, EV_PUT | + (mdev->state.conn < C_CONNECTED ? EV_CLEANUP : 0)); + + return 1; } /** @@ -994,13 +1027,15 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch, enum epoch_event ev) { - int epoch_size; + int finish, epoch_size; struct drbd_epoch *next_epoch; + int schedule_flush = 0; enum finish_epoch rv = FE_STILL_LIVE; spin_lock(&mdev->epoch_lock); do { next_epoch = NULL; + finish = 0; epoch_size = atomic_read(&epoch->epoch_size); @@ -1010,6 +1045,16 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, break; case EV_GOT_BARRIER_NR: set_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags); + + /* Special case: If we just switched from WO_bio_barrier to + WO_bdev_flush we should not finish the current epoch */ + if (test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) && epoch_size == 1 && + mdev->write_ordering != WO_bio_barrier && + epoch == mdev->current_epoch) + clear_bit(DE_CONTAINS_A_BARRIER, &epoch->flags); + break; + case EV_BARRIER_DONE: + set_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags); break; case EV_BECAME_LAST: /* nothing to do*/ @@ -1018,7 +1063,23 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, if (epoch_size != 0 && atomic_read(&epoch->active) == 0 && - test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags)) { + test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) && + epoch->list.prev == &mdev->current_epoch->list && + !test_bit(DE_IS_FINISHING, &epoch->flags)) { + /* Nearly all conditions are met to finish that epoch... */ + if (test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) || + mdev->write_ordering == WO_none || + (epoch_size == 1 && test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) || + ev & EV_CLEANUP) { + finish = 1; + set_bit(DE_IS_FINISHING, &epoch->flags); + } else if (!test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) && + mdev->write_ordering == WO_bio_barrier) { + atomic_inc(&epoch->active); + schedule_flush = 1; + } + } + if (finish) { if (!(ev & EV_CLEANUP)) { spin_unlock(&mdev->epoch_lock); drbd_send_b_ack(mdev, epoch->barrier_nr, epoch_size); @@ -1041,7 +1102,6 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, /* atomic_set(&epoch->active, 0); is already zero */ if (rv == FE_STILL_LIVE) rv = FE_RECYCLED; - wake_up(&mdev->ee_wait); } } @@ -1053,6 +1113,22 @@ static enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, spin_unlock(&mdev->epoch_lock); + if (schedule_flush) { + struct flush_work *fw; + fw = kmalloc(sizeof(*fw), GFP_ATOMIC); + if (fw) { + fw->w.cb = w_flush; + fw->epoch = epoch; + drbd_queue_work(&mdev->data.work, &fw->w); + } else { + dev_warn(DEV, "Could not kmalloc a flush_work obj\n"); + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); + /* That is not a recursion, only one level */ + drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE); + drbd_may_finish_epoch(mdev, epoch, EV_PUT); + } + } + return rv; } @@ -1068,16 +1144,19 @@ void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) [WO_none] = "none", [WO_drain_io] = "drain", [WO_bdev_flush] = "flush", + [WO_bio_barrier] = "barrier", }; pwo = mdev->write_ordering; wo = min(pwo, wo); + if (wo == WO_bio_barrier && mdev->ldev->dc.no_disk_barrier) + wo = WO_bdev_flush; if (wo == WO_bdev_flush && mdev->ldev->dc.no_disk_flush) wo = WO_drain_io; if (wo == WO_drain_io && mdev->ldev->dc.no_disk_drain) wo = WO_none; mdev->write_ordering = wo; - if (pwo != mdev->write_ordering || wo == WO_bdev_flush) + if (pwo != mdev->write_ordering || wo == WO_bio_barrier) dev_info(DEV, "Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]); } @@ -1113,7 +1192,7 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, bio->bi_sector = sector; bio->bi_bdev = mdev->ldev->backing_bdev; /* we special case some flags in the multi-bio case, see below - * (REQ_UNPLUG) */ + * (REQ_UNPLUG, REQ_HARDBARRIER) */ bio->bi_rw = rw; bio->bi_private = e; bio->bi_end_io = drbd_endio_sec; @@ -1147,6 +1226,11 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, bio->bi_rw &= ~REQ_UNPLUG; drbd_generic_make_request(mdev, fault_type, bio); + + /* strip off REQ_HARDBARRIER, + * unless it is the first or last bio */ + if (bios && bios->bi_next) + bios->bi_rw &= ~REQ_HARDBARRIER; } while (bios); maybe_kick_lo(mdev); return 0; @@ -1160,9 +1244,45 @@ int drbd_submit_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, return -ENOMEM; } +/** + * w_e_reissue() - Worker callback; Resubmit a bio, without REQ_HARDBARRIER set + * @mdev: DRBD device. + * @w: work object. + * @cancel: The connection will be closed anyways (unused in this callback) + */ +int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __releases(local) +{ + struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w; + /* We leave DE_CONTAINS_A_BARRIER and EE_IS_BARRIER in place, + (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch) + so that we can finish that epoch in drbd_may_finish_epoch(). + That is necessary if we already have a long chain of Epochs, before + we realize that REQ_HARDBARRIER is actually not supported */ + + /* As long as the -ENOTSUPP on the barrier is reported immediately + that will never trigger. If it is reported late, we will just + print that warning and continue correctly for all future requests + with WO_bdev_flush */ + if (previous_epoch(mdev, e->epoch)) + dev_warn(DEV, "Write ordering was not enforced (one time event)\n"); + + /* we still have a local reference, + * get_ldev was done in receive_Data. */ + + e->w.cb = e_end_block; + if (drbd_submit_ee(mdev, e, WRITE, DRBD_FAULT_DT_WR) != 0) { + /* drbd_submit_ee fails for one reason only: + * if was not able to allocate sufficient bios. + * requeue, try again later. */ + e->w.cb = w_e_reissue; + drbd_queue_work(&mdev->data.work, &e->w); + } + return 1; +} + static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned int data_size) { - int rv; + int rv, issue_flush; struct p_barrier *p = &mdev->data.rbuf.barrier; struct drbd_epoch *epoch; @@ -1180,40 +1300,44 @@ static int receive_Barrier(struct drbd_conf *mdev, enum drbd_packets cmd, unsign * Therefore we must send the barrier_ack after the barrier request was * completed. */ switch (mdev->write_ordering) { + case WO_bio_barrier: case WO_none: if (rv == FE_RECYCLED) return TRUE; - - /* receiver context, in the writeout path of the other node. - * avoid potential distributed deadlock */ - epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); - if (epoch) - break; - else - dev_warn(DEV, "Allocation of an epoch failed, slowing down\n"); - /* Fall through */ + break; case WO_bdev_flush: case WO_drain_io: - drbd_wait_ee_list_empty(mdev, &mdev->active_ee); - drbd_flush(mdev); - - if (atomic_read(&mdev->current_epoch->epoch_size)) { - epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); - if (epoch) - break; + if (rv == FE_STILL_LIVE) { + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags); + drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + rv = drbd_flush_after_epoch(mdev, mdev->current_epoch); } + if (rv == FE_RECYCLED) + return TRUE; + + /* The asender will send all the ACKs and barrier ACKs out, since + all EEs moved from the active_ee to the done_ee. We need to + provide a new epoch object for the EEs that come in soon */ + break; + } - epoch = mdev->current_epoch; - wait_event(mdev->ee_wait, atomic_read(&epoch->epoch_size) == 0); + /* receiver context, in the writeout path of the other node. + * avoid potential distributed deadlock */ + epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); + if (!epoch) { + dev_warn(DEV, "Allocation of an epoch failed, slowing down\n"); + issue_flush = !test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags); + drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + if (issue_flush) { + rv = drbd_flush_after_epoch(mdev, mdev->current_epoch); + if (rv == FE_RECYCLED) + return TRUE; + } - D_ASSERT(atomic_read(&epoch->active) == 0); - D_ASSERT(epoch->flags == 0); + drbd_wait_ee_list_empty(mdev, &mdev->done_ee); return TRUE; - default: - dev_err(DEV, "Strangeness in mdev->write_ordering %d\n", mdev->write_ordering); - return FALSE; } epoch->flags = 0; @@ -1528,8 +1652,15 @@ static int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int cancel) { struct drbd_epoch_entry *e = (struct drbd_epoch_entry *)w; sector_t sector = e->sector; + struct drbd_epoch *epoch; int ok = 1, pcmd; + if (e->flags & EE_IS_BARRIER) { + epoch = previous_epoch(mdev, e->epoch); + if (epoch) + drbd_may_finish_epoch(mdev, epoch, EV_BARRIER_DONE + (cancel ? EV_CLEANUP : 0)); + } + if (mdev->net_conf->wire_protocol == DRBD_PROT_C) { if (likely((e->flags & EE_WAS_ERROR) == 0)) { pcmd = (mdev->state.conn >= C_SYNC_SOURCE && @@ -1686,6 +1817,27 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned e->epoch = mdev->current_epoch; atomic_inc(&e->epoch->epoch_size); atomic_inc(&e->epoch->active); + + if (mdev->write_ordering == WO_bio_barrier && atomic_read(&e->epoch->epoch_size) == 1) { + struct drbd_epoch *epoch; + /* Issue a barrier if we start a new epoch, and the previous epoch + was not a epoch containing a single request which already was + a Barrier. */ + epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list); + if (epoch == e->epoch) { + set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); + rw |= REQ_HARDBARRIER; + e->flags |= EE_IS_BARRIER; + } else { + if (atomic_read(&epoch->epoch_size) > 1 || + !test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) { + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); + set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); + rw |= REQ_HARDBARRIER; + e->flags |= EE_IS_BARRIER; + } + } + } spin_unlock(&mdev->epoch_lock); dp_flags = be32_to_cpu(p->dp_flags); @@ -1843,11 +1995,10 @@ static int receive_Data(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned break; } - if (mdev->state.pdsk < D_INCONSISTENT) { + if (mdev->state.pdsk == D_DISKLESS) { /* In case we have the only disk of the cluster, */ drbd_set_out_of_sync(mdev, e->sector, e->size); e->flags |= EE_CALL_AL_COMPLETE_IO; - e->flags &= ~EE_MAY_SET_IN_SYNC; drbd_al_begin_io(mdev, e->sector); } @@ -3211,7 +3362,7 @@ static int receive_state(struct drbd_conf *mdev, enum drbd_packets cmd, unsigned if (ns.conn == C_MASK) { ns.conn = C_CONNECTED; if (mdev->state.disk == D_NEGOTIATING) { - drbd_force_state(mdev, NS(disk, D_FAILED)); + drbd_force_state(mdev, NS(disk, D_DISKLESS)); } else if (peer_state.disk == D_NEGOTIATING) { dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); peer_state.disk = D_DISKLESS; diff --git a/trunk/drivers/block/drbd/drbd_req.c b/trunk/drivers/block/drbd/drbd_req.c index 11a75d32a2e2..9e91a2545fc8 100644 --- a/trunk/drivers/block/drbd/drbd_req.c +++ b/trunk/drivers/block/drbd/drbd_req.c @@ -258,7 +258,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) if (!hlist_unhashed(&req->colision)) hlist_del(&req->colision); else - D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); + D_ASSERT((s & RQ_NET_MASK) == 0); /* for writes we need to do some extra housekeeping */ if (rw == WRITE) @@ -813,8 +813,7 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) mdev->state.conn >= C_CONNECTED)); if (!(local || remote) && !is_susp(mdev->state)) { - if (__ratelimit(&drbd_ratelimit_state)) - dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); + dev_err(DEV, "IO ERROR: neither local nor remote disk\n"); goto fail_free_complete; } @@ -943,21 +942,12 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) if (local) { req->private_bio->bi_bdev = mdev->ldev->backing_bdev; - /* State may have changed since we grabbed our reference on the - * mdev->ldev member. Double check, and short-circuit to endio. - * In case the last activity log transaction failed to get on - * stable storage, and this is a WRITE, we may not even submit - * this bio. */ - if (get_ldev(mdev)) { - if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR - : rw == READ ? DRBD_FAULT_DT_RD - : DRBD_FAULT_DT_RA)) - bio_endio(req->private_bio, -EIO); - else - generic_make_request(req->private_bio); - put_ldev(mdev); - } else + if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR + : rw == READ ? DRBD_FAULT_DT_RD + : DRBD_FAULT_DT_RA)) bio_endio(req->private_bio, -EIO); + else + generic_make_request(req->private_bio); } /* we need to plug ALWAYS since we possibly need to kick lo_dev. @@ -1032,6 +1022,20 @@ int drbd_make_request_26(struct request_queue *q, struct bio *bio) return 0; } + /* Reject barrier requests if we know the underlying device does + * not support them. + * XXX: Need to get this info from peer as well some how so we + * XXX: reject if EITHER side/data/metadata area does not support them. + * + * because of those XXX, this is not yet enabled, + * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit. + */ + if (unlikely(bio->bi_rw & REQ_HARDBARRIER) && test_bit(NO_BARRIER_SUPP, &mdev->flags)) { + /* dev_warn(DEV, "Rejecting barrier request as underlying device does not support\n"); */ + bio_endio(bio, -EOPNOTSUPP); + return 0; + } + /* * what we "blindly" assume: */ diff --git a/trunk/drivers/block/drbd/drbd_worker.c b/trunk/drivers/block/drbd/drbd_worker.c index b0551ba7ad0c..108d58015cd1 100644 --- a/trunk/drivers/block/drbd/drbd_worker.c +++ b/trunk/drivers/block/drbd/drbd_worker.c @@ -102,6 +102,12 @@ void drbd_endio_read_sec_final(struct drbd_epoch_entry *e) __releases(local) put_ldev(mdev); } +static int is_failed_barrier(int ee_flags) +{ + return (ee_flags & (EE_IS_BARRIER|EE_WAS_ERROR|EE_RESUBMITTED)) + == (EE_IS_BARRIER|EE_WAS_ERROR); +} + /* writes on behalf of the partner, or resync writes, * "submitted" by the receiver, final stage. */ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(local) @@ -113,6 +119,21 @@ static void drbd_endio_write_sec_final(struct drbd_epoch_entry *e) __releases(lo int is_syncer_req; int do_al_complete_io; + /* if this is a failed barrier request, disable use of barriers, + * and schedule for resubmission */ + if (is_failed_barrier(e->flags)) { + drbd_bump_write_ordering(mdev, WO_bdev_flush); + spin_lock_irqsave(&mdev->req_lock, flags); + list_del(&e->w.list); + e->flags = (e->flags & ~EE_WAS_ERROR) | EE_RESUBMITTED; + e->w.cb = w_e_reissue; + /* put_ldev actually happens below, once we come here again. */ + __release(local); + spin_unlock_irqrestore(&mdev->req_lock, flags); + drbd_queue_work(&mdev->data.work, &e->w); + return; + } + D_ASSERT(e->block_id != ID_VACANT); /* after we moved e to done_ee, @@ -904,7 +925,7 @@ int drbd_resync_finished(struct drbd_conf *mdev) drbd_md_sync(mdev); if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) { - dev_info(DEV, "Writing the whole bitmap\n"); + dev_warn(DEV, "Writing the whole bitmap, due to failed kmalloc\n"); drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished"); } diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 3951020e494a..767107cce982 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -4363,9 +4363,9 @@ static int __init floppy_init(void) out_put_disk: while (dr--) { del_timer(&motor_off_timer[dr]); + put_disk(disks[dr]); if (disks[dr]->queue) blk_cleanup_queue(disks[dr]->queue); - put_disk(disks[dr]); } return err; } @@ -4573,8 +4573,8 @@ static void __exit floppy_module_exit(void) device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); platform_device_unregister(&floppy_device[drive]); } - blk_cleanup_queue(disks[drive]->queue); put_disk(disks[drive]); + blk_cleanup_queue(disks[drive]->queue); } del_timer_sync(&fd_timeout); diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 7ea0bea2f7e3..1e5284ef65fa 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -481,6 +481,12 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) if (bio_rw(bio) == WRITE) { struct file *file = lo->lo_backing_file; + /* REQ_HARDBARRIER is deprecated */ + if (bio->bi_rw & REQ_HARDBARRIER) { + ret = -EOPNOTSUPP; + goto out; + } + if (bio->bi_rw & REQ_FLUSH) { ret = vfs_fsync(file, 0); if (unlikely(ret && ret != -EINVAL)) { diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index 255035cfc88a..06e2812ba124 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -289,6 +289,8 @@ static int blkif_queue_request(struct request *req) ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; + if (req->cmd_flags & REQ_HARDBARRIER) + ring_req->operation = BLKIF_OP_WRITE_BARRIER; ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index ab3894f742c3..d120a5c1c093 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -68,9 +68,6 @@ static struct usb_device_id btusb_table[] = { /* Apple MacBookPro6,2 */ { USB_DEVICE(0x05ac, 0x8218) }, - /* Apple MacBookAir3,1, MacBookAir3,2 */ - { USB_DEVICE(0x05ac, 0x821b) }, - /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, @@ -1032,8 +1029,6 @@ static int btusb_probe(struct usb_interface *intf, usb_set_intfdata(intf, data); - usb_enable_autosuspend(interface_to_usbdev(intf)); - return 0; } diff --git a/trunk/drivers/tty/vt/.gitignore b/trunk/drivers/char/.gitignore similarity index 100% rename from trunk/drivers/tty/vt/.gitignore rename to trunk/drivers/char/.gitignore diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index ba53ec956c95..3a9c01416839 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -2,10 +2,24 @@ # Makefile for the kernel character device drivers. # -obj-y += mem.o random.o +# +# This file contains the font map for the default (hardware) font +# +FONTMAPFILE = cp437.uni + +obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o + +obj-y += tty_mutex.o +obj-$(CONFIG_LEGACY_PTYS) += pty.o +obj-$(CONFIG_UNIX98_PTYS) += pty.o obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o obj-y += misc.o +obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o selection.o keyboard.o obj-$(CONFIG_BFIN_JTAG_COMM) += bfin_jtag_comm.o +obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o +obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o +obj-$(CONFIG_AUDIT) += tty_audit.o +obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o @@ -27,6 +41,8 @@ obj-$(CONFIG_ISI) += isicom.o obj-$(CONFIG_SYNCLINK) += synclink.o obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o +obj-$(CONFIG_N_HDLC) += n_hdlc.o +obj-$(CONFIG_N_GSM) += n_gsm.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o @@ -58,6 +74,7 @@ obj-$(CONFIG_PRINTER) += lp.o obj-$(CONFIG_APM_EMULATION) += apm-emulation.o obj-$(CONFIG_DTLK) += dtlk.o +obj-$(CONFIG_R3964) += n_r3964.o obj-$(CONFIG_APPLICOM) += applicom.o obj-$(CONFIG_SONYPI) += sonypi.o obj-$(CONFIG_RTC) += rtc.o @@ -98,3 +115,28 @@ obj-$(CONFIG_RAMOOPS) += ramoops.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o + +# Files generated that shall be removed upon make clean +clean-files := consolemap_deftbl.c defkeymap.c + +quiet_cmd_conmk = CONMK $@ + cmd_conmk = scripts/conmakehash $< > $@ + +$(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE) + $(call cmd,conmk) + +$(obj)/defkeymap.o: $(obj)/defkeymap.c + +# Uncomment if you're changing the keymap and have an appropriate +# loadkeys version for the map. By default, we'll use the shipped +# versions. +# GENERATE_KEYMAP := 1 + +ifdef GENERATE_KEYMAP + +$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map + loadkeys --mktable $< > $@.tmp + sed -e 's/^static *//' $@.tmp > $@ + rm $@.tmp + +endif diff --git a/trunk/drivers/char/agp/intel-gtt.c b/trunk/drivers/char/agp/intel-gtt.c index 9272c38dd3c6..6b6760ea2435 100644 --- a/trunk/drivers/char/agp/intel-gtt.c +++ b/trunk/drivers/char/agp/intel-gtt.c @@ -1210,14 +1210,14 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry, unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; u32 pte_flags; - if (type_mask == AGP_USER_MEMORY) + if (type_mask == AGP_USER_UNCACHED_MEMORY) pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { - pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; + pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; if (gfdt) pte_flags |= GEN6_PTE_GFDT; } else { /* set 'normal'/'cached' to LLC by default */ - pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; + pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; if (gfdt) pte_flags |= GEN6_PTE_GFDT; } diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index c0bd6f472c52..b0a70461a12c 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -1299,6 +1299,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, { struct async_struct * info = tty->driver_data; struct async_icount cprev, cnow; /* kernel counter temps */ + struct serial_icounter_struct icount; void __user *argp = (void __user *)arg; unsigned long flags; diff --git a/trunk/drivers/tty/vt/consolemap.c b/trunk/drivers/char/consolemap.c similarity index 100% rename from trunk/drivers/tty/vt/consolemap.c rename to trunk/drivers/char/consolemap.c diff --git a/trunk/drivers/tty/vt/cp437.uni b/trunk/drivers/char/cp437.uni similarity index 100% rename from trunk/drivers/tty/vt/cp437.uni rename to trunk/drivers/char/cp437.uni diff --git a/trunk/drivers/tty/vt/defkeymap.c_shipped b/trunk/drivers/char/defkeymap.c_shipped similarity index 100% rename from trunk/drivers/tty/vt/defkeymap.c_shipped rename to trunk/drivers/char/defkeymap.c_shipped diff --git a/trunk/drivers/tty/vt/defkeymap.map b/trunk/drivers/char/defkeymap.map similarity index 100% rename from trunk/drivers/tty/vt/defkeymap.map rename to trunk/drivers/char/defkeymap.map diff --git a/trunk/drivers/tty/vt/keyboard.c b/trunk/drivers/char/keyboard.c similarity index 100% rename from trunk/drivers/tty/vt/keyboard.c rename to trunk/drivers/char/keyboard.c diff --git a/trunk/drivers/tty/n_gsm.c b/trunk/drivers/char/n_gsm.c similarity index 99% rename from trunk/drivers/tty/n_gsm.c rename to trunk/drivers/char/n_gsm.c index 81b46585edf7..04ef3ef0a422 100644 --- a/trunk/drivers/tty/n_gsm.c +++ b/trunk/drivers/char/n_gsm.c @@ -716,8 +716,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) if (msg->len < 128) *--dp = (msg->len << 1) | EA; else { - *--dp = ((msg->len & 127) << 1) | EA; - *--dp = (msg->len >> 6) & 0xfe; + *--dp = (msg->len >> 6) | EA; + *--dp = (msg->len & 127) << 1; } } @@ -2375,7 +2375,6 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm, gsm->mru = c->mru; gsm->encoding = c->encapsulation; gsm->adaption = c->adaption; - gsm->n2 = c->n2; if (c->i == 1) gsm->ftype = UIH; diff --git a/trunk/drivers/tty/n_hdlc.c b/trunk/drivers/char/n_hdlc.c similarity index 100% rename from trunk/drivers/tty/n_hdlc.c rename to trunk/drivers/char/n_hdlc.c diff --git a/trunk/drivers/tty/n_r3964.c b/trunk/drivers/char/n_r3964.c similarity index 100% rename from trunk/drivers/tty/n_r3964.c rename to trunk/drivers/char/n_r3964.c diff --git a/trunk/drivers/tty/n_tty.c b/trunk/drivers/char/n_tty.c similarity index 100% rename from trunk/drivers/tty/n_tty.c rename to trunk/drivers/char/n_tty.c diff --git a/trunk/drivers/char/nozomi.c b/trunk/drivers/char/nozomi.c index 294d03e8c61a..dd3f9b1f11b4 100644 --- a/trunk/drivers/char/nozomi.c +++ b/trunk/drivers/char/nozomi.c @@ -1828,6 +1828,7 @@ static int ntty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct port *port = tty->driver_data; + void __user *argp = (void __user *)arg; int rval = -ENOIOCTLCMD; DBG1("******** IOCTL, cmd: %d", cmd); diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index eaa41992fbe2..bfc10f89d951 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -2796,7 +2796,6 @@ static const struct tty_operations mgslpc_ops = { .hangup = mgslpc_hangup, .tiocmget = tiocmget, .tiocmset = tiocmset, - .get_icount = mgslpc_get_icount, .proc_fops = &mgslpc_proc_fops, }; diff --git a/trunk/drivers/tty/pty.c b/trunk/drivers/char/pty.c similarity index 100% rename from trunk/drivers/tty/pty.c rename to trunk/drivers/char/pty.c diff --git a/trunk/drivers/tty/vt/selection.c b/trunk/drivers/char/selection.c similarity index 100% rename from trunk/drivers/tty/vt/selection.c rename to trunk/drivers/char/selection.c diff --git a/trunk/drivers/tty/sysrq.c b/trunk/drivers/char/sysrq.c similarity index 100% rename from trunk/drivers/tty/sysrq.c rename to trunk/drivers/char/sysrq.c diff --git a/trunk/drivers/tty/tty_audit.c b/trunk/drivers/char/tty_audit.c similarity index 100% rename from trunk/drivers/tty/tty_audit.c rename to trunk/drivers/char/tty_audit.c diff --git a/trunk/drivers/tty/tty_buffer.c b/trunk/drivers/char/tty_buffer.c similarity index 97% rename from trunk/drivers/tty/tty_buffer.c rename to trunk/drivers/char/tty_buffer.c index d8210ca00720..cc1e9850d655 100644 --- a/trunk/drivers/tty/tty_buffer.c +++ b/trunk/drivers/char/tty_buffer.c @@ -413,8 +413,7 @@ static void flush_to_ldisc(struct work_struct *work) spin_lock_irqsave(&tty->buf.lock, flags); if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { - struct tty_buffer *head, *tail = tty->buf.tail; - int seen_tail = 0; + struct tty_buffer *head; while ((head = tty->buf.head) != NULL) { int count; char *char_buf; @@ -424,15 +423,6 @@ static void flush_to_ldisc(struct work_struct *work) if (!count) { if (head->next == NULL) break; - /* - There's a possibility tty might get new buffer - added during the unlock window below. We could - end up spinning in here forever hogging the CPU - completely. To avoid this let's have a rest each - time we processed the tail buffer. - */ - if (tail == head) - seen_tail = 1; tty->buf.head = head->next; tty_buffer_free(tty, head); continue; @@ -442,7 +432,7 @@ static void flush_to_ldisc(struct work_struct *work) line discipline as we want to empty the queue */ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) break; - if (!tty->receive_room || seen_tail) { + if (!tty->receive_room) { schedule_delayed_work(&tty->buf.work, 1); break; } diff --git a/trunk/drivers/tty/tty_io.c b/trunk/drivers/char/tty_io.c similarity index 100% rename from trunk/drivers/tty/tty_io.c rename to trunk/drivers/char/tty_io.c diff --git a/trunk/drivers/tty/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c similarity index 100% rename from trunk/drivers/tty/tty_ioctl.c rename to trunk/drivers/char/tty_ioctl.c diff --git a/trunk/drivers/tty/tty_ldisc.c b/trunk/drivers/char/tty_ldisc.c similarity index 95% rename from trunk/drivers/tty/tty_ldisc.c rename to trunk/drivers/char/tty_ldisc.c index d8e96b005023..412f9775d19c 100644 --- a/trunk/drivers/tty/tty_ldisc.c +++ b/trunk/drivers/char/tty_ldisc.c @@ -47,7 +47,6 @@ static DEFINE_SPINLOCK(tty_ldisc_lock); static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); -static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle); /* Line disc dispatch table */ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; @@ -84,7 +83,6 @@ static void put_ldisc(struct tty_ldisc *ld) return; } local_irq_restore(flags); - wake_up(&tty_ldisc_idle); } /** @@ -532,23 +530,6 @@ static int tty_ldisc_halt(struct tty_struct *tty) return cancel_delayed_work_sync(&tty->buf.work); } -/** - * tty_ldisc_wait_idle - wait for the ldisc to become idle - * @tty: tty to wait for - * - * Wait for the line discipline to become idle. The discipline must - * have been halted for this to guarantee it remains idle. - */ -static int tty_ldisc_wait_idle(struct tty_struct *tty) -{ - int ret; - ret = wait_event_interruptible_timeout(tty_ldisc_idle, - atomic_read(&tty->ldisc->users) == 1, 5 * HZ); - if (ret < 0) - return ret; - return ret > 0 ? 0 : -EBUSY; -} - /** * tty_set_ldisc - set line discipline * @tty: the terminal to set @@ -653,17 +634,8 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) flush_scheduled_work(); - retval = tty_ldisc_wait_idle(tty); - tty_lock(); mutex_lock(&tty->ldisc_mutex); - - /* handle wait idle failure locked */ - if (retval) { - tty_ldisc_put(new_ldisc); - goto enable; - } - if (test_bit(TTY_HUPPED, &tty->flags)) { /* We were raced by the hangup method. It will have stomped the ldisc data and closed the ldisc down */ @@ -697,7 +669,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_put(o_ldisc); -enable: /* * Allow ldisc referencing to occur again */ @@ -743,12 +714,9 @@ static void tty_reset_termios(struct tty_struct *tty) * state closed */ -static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) +static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc) { - struct tty_ldisc *ld = tty_ldisc_get(ldisc); - - if (IS_ERR(ld)) - return -1; + struct tty_ldisc *ld; tty_ldisc_close(tty, tty->ldisc); tty_ldisc_put(tty->ldisc); @@ -756,10 +724,10 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) /* * Switch the line discipline back */ + ld = tty_ldisc_get(ldisc); + BUG_ON(IS_ERR(ld)); tty_ldisc_assign(tty, ld); tty_set_termios_ldisc(tty, ldisc); - - return 0; } /** @@ -834,16 +802,13 @@ void tty_ldisc_hangup(struct tty_struct *tty) a FIXME */ if (tty->ldisc) { /* Not yet closed */ if (reset == 0) { - - if (!tty_ldisc_reinit(tty, tty->termios->c_line)) - err = tty_ldisc_open(tty, tty->ldisc); - else - err = 1; + tty_ldisc_reinit(tty, tty->termios->c_line); + err = tty_ldisc_open(tty, tty->ldisc); } /* If the re-open fails or we reset then go to N_TTY. The N_TTY open cannot fail */ if (reset || err) { - BUG_ON(tty_ldisc_reinit(tty, N_TTY)); + tty_ldisc_reinit(tty, N_TTY); WARN_ON(tty_ldisc_open(tty, tty->ldisc)); } tty_ldisc_enable(tty); diff --git a/trunk/drivers/tty/tty_mutex.c b/trunk/drivers/char/tty_mutex.c similarity index 100% rename from trunk/drivers/tty/tty_mutex.c rename to trunk/drivers/char/tty_mutex.c diff --git a/trunk/drivers/tty/tty_port.c b/trunk/drivers/char/tty_port.c similarity index 100% rename from trunk/drivers/tty/tty_port.c rename to trunk/drivers/char/tty_port.c diff --git a/trunk/drivers/tty/vt/vc_screen.c b/trunk/drivers/char/vc_screen.c similarity index 99% rename from trunk/drivers/tty/vt/vc_screen.c rename to trunk/drivers/char/vc_screen.c index eab3a1ff99e4..273ab44cc91d 100644 --- a/trunk/drivers/tty/vt/vc_screen.c +++ b/trunk/drivers/char/vc_screen.c @@ -553,12 +553,12 @@ static unsigned int vcs_poll(struct file *file, poll_table *wait) { struct vcs_poll_data *poll = vcs_poll_data_get(file); - int ret = DEFAULT_POLLMASK|POLLERR|POLLPRI; + int ret = 0; if (poll) { poll_wait(file, &poll->waitq, wait); - if (poll->seen_last_update) - ret = DEFAULT_POLLMASK; + if (!poll->seen_last_update) + ret = POLLIN | POLLRDNORM; } return ret; } diff --git a/trunk/drivers/tty/vt/vt.c b/trunk/drivers/char/vt.c similarity index 100% rename from trunk/drivers/tty/vt/vt.c rename to trunk/drivers/char/vt.c diff --git a/trunk/drivers/tty/vt/vt_ioctl.c b/trunk/drivers/char/vt_ioctl.c similarity index 100% rename from trunk/drivers/tty/vt/vt_ioctl.c rename to trunk/drivers/char/vt_ioctl.c diff --git a/trunk/drivers/clocksource/sh_cmt.c b/trunk/drivers/clocksource/sh_cmt.c index d68d3aa1814b..a44611652282 100644 --- a/trunk/drivers/clocksource/sh_cmt.c +++ b/trunk/drivers/clocksource/sh_cmt.c @@ -616,9 +616,13 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) /* get hold of clock */ p->clk = clk_get(&p->pdev->dev, "cmt_fck"); if (IS_ERR(p->clk)) { - dev_err(&p->pdev->dev, "cannot get clock\n"); - ret = PTR_ERR(p->clk); - goto err1; + dev_warn(&p->pdev->dev, "using deprecated clock lookup\n"); + p->clk = clk_get(&p->pdev->dev, cfg->clk); + if (IS_ERR(p->clk)) { + dev_err(&p->pdev->dev, "cannot get clock\n"); + ret = PTR_ERR(p->clk); + goto err1; + } } if (resource_size(res) == 6) { diff --git a/trunk/drivers/clocksource/sh_mtu2.c b/trunk/drivers/clocksource/sh_mtu2.c index 40630cb98237..ef7a5be8a09f 100644 --- a/trunk/drivers/clocksource/sh_mtu2.c +++ b/trunk/drivers/clocksource/sh_mtu2.c @@ -287,9 +287,13 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) /* get hold of clock */ p->clk = clk_get(&p->pdev->dev, "mtu2_fck"); if (IS_ERR(p->clk)) { - dev_err(&p->pdev->dev, "cannot get clock\n"); - ret = PTR_ERR(p->clk); - goto err1; + dev_warn(&p->pdev->dev, "using deprecated clock lookup\n"); + p->clk = clk_get(&p->pdev->dev, cfg->clk); + if (IS_ERR(p->clk)) { + dev_err(&p->pdev->dev, "cannot get clock\n"); + ret = PTR_ERR(p->clk); + goto err1; + } } return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), diff --git a/trunk/drivers/clocksource/sh_tmu.c b/trunk/drivers/clocksource/sh_tmu.c index 36aba9923060..de715901b82a 100644 --- a/trunk/drivers/clocksource/sh_tmu.c +++ b/trunk/drivers/clocksource/sh_tmu.c @@ -393,9 +393,13 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) /* get hold of clock */ p->clk = clk_get(&p->pdev->dev, "tmu_fck"); if (IS_ERR(p->clk)) { - dev_err(&p->pdev->dev, "cannot get clock\n"); - ret = PTR_ERR(p->clk); - goto err1; + dev_warn(&p->pdev->dev, "using deprecated clock lookup\n"); + p->clk = clk_get(&p->pdev->dev, cfg->clk); + if (IS_ERR(p->clk)) { + dev_err(&p->pdev->dev, "cannot get clock\n"); + ret = PTR_ERR(p->clk); + goto err1; + } } return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), diff --git a/trunk/drivers/firewire/ohci.c b/trunk/drivers/firewire/ohci.c index 84eb607d6c03..9dcb17d51aee 100644 --- a/trunk/drivers/firewire/ohci.c +++ b/trunk/drivers/firewire/ohci.c @@ -577,11 +577,17 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, return ret; } -static void ar_context_link_page(struct ar_context *ctx, - struct ar_buffer *ab, dma_addr_t ab_bus) +static int ar_context_add_page(struct ar_context *ctx) { + struct device *dev = ctx->ohci->card.device; + struct ar_buffer *ab; + dma_addr_t uninitialized_var(ab_bus); size_t offset; + ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); + if (ab == NULL) + return -ENOMEM; + ab->next = NULL; memset(&ab->descriptor, 0, sizeof(ab->descriptor)); ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | @@ -600,19 +606,6 @@ static void ar_context_link_page(struct ar_context *ctx, reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); flush_writes(ctx->ohci); -} - -static int ar_context_add_page(struct ar_context *ctx) -{ - struct device *dev = ctx->ohci->card.device; - struct ar_buffer *ab; - dma_addr_t uninitialized_var(ab_bus); - - ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); - if (ab == NULL) - return -ENOMEM; - - ar_context_link_page(ctx, ab, ab_bus); return 0; } @@ -737,17 +730,16 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) static void ar_context_tasklet(unsigned long data) { struct ar_context *ctx = (struct ar_context *)data; + struct fw_ohci *ohci = ctx->ohci; struct ar_buffer *ab; struct descriptor *d; void *buffer, *end; - __le16 res_count; ab = ctx->current_buffer; d = &ab->descriptor; - res_count = ACCESS_ONCE(d->res_count); - if (res_count == 0) { - size_t size, size2, rest, pktsize, size3, offset; + if (d->res_count == 0) { + size_t size, rest, offset; dma_addr_t start_bus; void *start; @@ -758,63 +750,29 @@ static void ar_context_tasklet(unsigned long data) */ offset = offsetof(struct ar_buffer, data); - start = ab; + start = buffer = ab; start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; - buffer = ab->data; ab = ab->next; d = &ab->descriptor; - size = start + PAGE_SIZE - ctx->pointer; - /* valid buffer data in the next page */ + size = buffer + PAGE_SIZE - ctx->pointer; rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); - /* what actually fits in this page */ - size2 = min(rest, (size_t)PAGE_SIZE - offset - size); memmove(buffer, ctx->pointer, size); - memcpy(buffer + size, ab->data, size2); - - while (size > 0) { - void *next = handle_ar_packet(ctx, buffer); - pktsize = next - buffer; - if (pktsize >= size) { - /* - * We have handled all the data that was - * originally in this page, so we can now - * continue in the next page. - */ - buffer = next; - break; - } - /* move the next packet to the start of the buffer */ - memmove(buffer, next, size + size2 - pktsize); - size -= pktsize; - /* fill up this page again */ - size3 = min(rest - size2, - (size_t)PAGE_SIZE - offset - size - size2); - memcpy(buffer + size + size2, - (void *) ab->data + size2, size3); - size2 += size3; - } - - if (rest > 0) { - /* handle the packets that are fully in the next page */ - buffer = (void *) ab->data + - (buffer - (start + offset + size)); - end = (void *) ab->data + rest; + memcpy(buffer + size, ab->data, rest); + ctx->current_buffer = ab; + ctx->pointer = (void *) ab->data + rest; + end = buffer + size + rest; - while (buffer < end) - buffer = handle_ar_packet(ctx, buffer); - - ctx->current_buffer = ab; - ctx->pointer = end; + while (buffer < end) + buffer = handle_ar_packet(ctx, buffer); - ar_context_link_page(ctx, start, start_bus); - } else { - ctx->pointer = start + PAGE_SIZE; - } + dma_free_coherent(ohci->card.device, PAGE_SIZE, + start, start_bus); + ar_context_add_page(ctx); } else { buffer = ctx->pointer; ctx->pointer = end = - (void *) ab + PAGE_SIZE - le16_to_cpu(res_count); + (void *) ab + PAGE_SIZE - le16_to_cpu(d->res_count); while (buffer < end) buffer = handle_ar_packet(ctx, buffer); diff --git a/trunk/drivers/gpu/drm/drm_crtc_helper.c b/trunk/drivers/gpu/drm/drm_crtc_helper.c index f7af91cb273d..dcbeb98f195a 100644 --- a/trunk/drivers/gpu/drm/drm_crtc_helper.c +++ b/trunk/drivers/gpu/drm/drm_crtc_helper.c @@ -276,7 +276,7 @@ static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, struct drm_crtc *tmp; int crtc_mask = 1; - WARN(!crtc, "checking null crtc?\n"); + WARN(!crtc, "checking null crtc?"); dev = crtc->dev; diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index a245d17165ae..c1a26217a530 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -240,7 +240,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, .addr = DDC_ADDR, .flags = I2C_M_RD, .len = len, - .buf = buf, + .buf = buf + start, } }; @@ -253,7 +253,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, static u8 * drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { - int i, j = 0, valid_extensions = 0; + int i, j = 0; u8 *block, *new; if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) @@ -280,28 +280,14 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) for (j = 1; j <= block[0x7e]; j++) { for (i = 0; i < 4; i++) { - if (drm_do_probe_ddc_edid(adapter, - block + (valid_extensions + 1) * EDID_LENGTH, - j, EDID_LENGTH)) + if (drm_do_probe_ddc_edid(adapter, block, j, + EDID_LENGTH)) goto out; - if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) { - valid_extensions++; + if (drm_edid_block_valid(block + j * EDID_LENGTH)) break; - } } if (i == 4) - dev_warn(connector->dev->dev, - "%s: Ignoring invalid EDID block %d.\n", - drm_get_connector_name(connector), j); - } - - if (valid_extensions != block[0x7e]) { - block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; - block[0x7e] = valid_extensions; - new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); - if (!new) - goto out; - block = new; + goto carp; } return block; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 80745f85902c..3467dd420760 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -44,7 +44,7 @@ unsigned int i915_fbpercrtc = 0; module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); unsigned int i915_powersave = 1; -module_param_named(powersave, i915_powersave, int, 0600); +module_param_named(powersave, i915_powersave, int, 0400); unsigned int i915_lvds_downclock = 0; module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 90414ae86afc..2c2c19b6285e 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -1321,7 +1321,6 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) -#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index ef188e391406..8eb8453208b5 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -2172,7 +2172,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) static int i915_ring_idle(struct drm_device *dev, struct intel_ring_buffer *ring) { - if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) + if (list_empty(&ring->gpu_write_list)) return 0; i915_gem_flush_ring(dev, NULL, ring, @@ -2190,7 +2190,9 @@ i915_gpu_idle(struct drm_device *dev) int ret; lists_empty = (list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); + list_empty(&dev_priv->render_ring.active_list) && + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); if (lists_empty) return 0; @@ -3106,8 +3108,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, * write domain */ if (obj->write_domain && - (obj->write_domain != obj->pending_read_domains || - obj_priv->ring != ring)) { + obj->write_domain != obj->pending_read_domains) { flush_domains |= obj->write_domain; invalidate_domains |= obj->pending_read_domains & ~obj->write_domain; @@ -3496,52 +3497,6 @@ i915_gem_execbuffer_pin(struct drm_device *dev, return 0; } -static int -i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, - struct drm_file *file, - struct intel_ring_buffer *ring, - struct drm_gem_object **objects, - int count) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret, i; - - /* Zero the global flush/invalidate flags. These - * will be modified as new domains are computed - * for each object - */ - dev->invalidate_domains = 0; - dev->flush_domains = 0; - dev_priv->mm.flush_rings = 0; - for (i = 0; i < count; i++) - i915_gem_object_set_to_gpu_domain(objects[i], ring); - - if (dev->invalidate_domains | dev->flush_domains) { -#if WATCH_EXEC - DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", - __func__, - dev->invalidate_domains, - dev->flush_domains); -#endif - i915_gem_flush(dev, file, - dev->invalidate_domains, - dev->flush_domains, - dev_priv->mm.flush_rings); - } - - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = to_intel_bo(objects[i]); - /* XXX replace with semaphores */ - if (obj->ring && ring != obj->ring) { - ret = i915_gem_object_wait_rendering(&obj->base, true); - if (ret) - return ret; - } - } - - return 0; -} - /* Throttle our rendering by waiting until the ring has completed our requests * emitted over 20 msec ago. * @@ -3802,10 +3757,33 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } - ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring, - object_list, args->buffer_count); - if (ret) - goto err; + /* Zero the global flush/invalidate flags. These + * will be modified as new domains are computed + * for each object + */ + dev->invalidate_domains = 0; + dev->flush_domains = 0; + dev_priv->mm.flush_rings = 0; + + for (i = 0; i < args->buffer_count; i++) { + struct drm_gem_object *obj = object_list[i]; + + /* Compute new gpu domains and update invalidate/flush */ + i915_gem_object_set_to_gpu_domain(obj, ring); + } + + if (dev->invalidate_domains | dev->flush_domains) { +#if WATCH_EXEC + DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", + __func__, + dev->invalidate_domains, + dev->flush_domains); +#endif + i915_gem_flush(dev, file, + dev->invalidate_domains, + dev->flush_domains, + dev_priv->mm.flush_rings); + } for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; @@ -4065,7 +4043,8 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) alignment = i915_gem_get_gtt_alignment(obj); if (obj_priv->gtt_offset & (alignment - 1)) { WARN(obj_priv->pin_count, - "bo is already pinned with incorrect alignment: offset=%x, req.alignment=%x\n", + "bo is already pinned with incorrect alignment:" + " offset=%x, req.alignment=%x\n", obj_priv->gtt_offset, alignment); ret = i915_gem_object_unbind(obj); if (ret) @@ -4877,24 +4856,17 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_file *file_priv) { struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - void *vaddr = obj_priv->phys_obj->handle->vaddr + args->offset; - char __user *user_data = (char __user *) (uintptr_t) args->data_ptr; - - DRM_DEBUG_DRIVER("vaddr %p, %lld\n", vaddr, args->size); + void *obj_addr; + int ret; + char __user *user_data; - if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { - unsigned long unwritten; + user_data = (char __user *) (uintptr_t) args->data_ptr; + obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset; - /* The physical object once assigned is fixed for the lifetime - * of the obj, so we can safely drop the lock and continue - * to access vaddr. - */ - mutex_unlock(&dev->struct_mutex); - unwritten = copy_from_user(vaddr, user_data, args->size); - mutex_lock(&dev->struct_mutex); - if (unwritten) - return -EFAULT; - } + DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size); + ret = copy_from_user(obj_addr, user_data, args->size); + if (ret) + return -EFAULT; drm_agp_chipset_flush(dev); return 0; @@ -4928,7 +4900,9 @@ i915_gpu_is_active(struct drm_device *dev) int lists_empty; lists_empty = list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list); + list_empty(&dev_priv->render_ring.active_list) && + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list); return !lists_empty; } diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_evict.c b/trunk/drivers/gpu/drm/i915/i915_gem_evict.c index d8ae7d1d0cc6..43a4013f53fa 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_evict.c @@ -165,7 +165,9 @@ i915_gem_evict_everything(struct drm_device *dev) lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); + list_empty(&dev_priv->render_ring.active_list) && + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); if (lists_empty) return -ENOSPC; @@ -182,7 +184,9 @@ i915_gem_evict_everything(struct drm_device *dev) lists_empty = (list_empty(&dev_priv->mm.inactive_list) && list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->mm.active_list)); + list_empty(&dev_priv->render_ring.active_list) && + list_empty(&dev_priv->bsd_ring.active_list) && + list_empty(&dev_priv->blt_ring.active_list)); BUG_ON(!lists_empty); return 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 454c064f8ef7..989c19d2d959 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -862,10 +862,8 @@ int i915_restore_state(struct drm_device *dev) /* Clock gating state */ intel_init_clock_gating(dev); - if (HAS_PCH_SPLIT(dev)) { + if (HAS_PCH_SPLIT(dev)) ironlake_enable_drps(dev); - intel_init_emon(dev); - } /* Cache mode state */ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 48d8fd686ea9..990f065374b2 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -1681,37 +1681,6 @@ static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock) udelay(500); } -static void intel_fdi_normal_train(struct drm_crtc *crtc) -{ - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int pipe = intel_crtc->pipe; - u32 reg, temp; - - /* enable normal train */ - reg = FDI_TX_CTL(pipe); - temp = I915_READ(reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; - I915_WRITE(reg, temp); - - reg = FDI_RX_CTL(pipe); - temp = I915_READ(reg); - if (HAS_PCH_CPT(dev)) { - temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; - temp |= FDI_LINK_TRAIN_NORMAL_CPT; - } else { - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE; - } - I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); - - /* wait one idle pattern time */ - POSTING_READ(reg); - udelay(1000); -} - /* The FDI link training functions for ILK/Ibexpeak. */ static void ironlake_fdi_link_train(struct drm_crtc *crtc) { @@ -1798,6 +1767,27 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc) DRM_DEBUG_KMS("FDI train done\n"); + /* enable normal train */ + reg = FDI_TX_CTL(pipe); + temp = I915_READ(reg); + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; + I915_WRITE(reg, temp); + + reg = FDI_RX_CTL(pipe); + temp = I915_READ(reg); + if (HAS_PCH_CPT(dev)) { + temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; + temp |= FDI_LINK_TRAIN_NORMAL_CPT; + } else { + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_NONE; + } + I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); + + /* wait one idle pattern time */ + POSTING_READ(reg); + udelay(1000); } static const int const snb_b_fdi_train_param [] = { @@ -2100,8 +2090,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe))); I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe))); - intel_fdi_normal_train(crtc); - /* For PCH DP, enable TRANS_DP_CTL */ if (HAS_PCH_CPT(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { @@ -2212,10 +2200,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) udelay(100); /* Ironlake workaround, disable clock pointer after downing FDI */ - if (HAS_PCH_IBX(dev)) - I915_WRITE(FDI_RX_CHICKEN(pipe), - I915_READ(FDI_RX_CHICKEN(pipe) & - ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); + I915_WRITE(FDI_RX_CHICKEN(pipe), + I915_READ(FDI_RX_CHICKEN(pipe) & + ~FDI_RX_PHASE_SYNC_POINTER_ENABLE)); /* still set train pattern 1 */ reg = FDI_TX_CTL(pipe); @@ -5594,19 +5581,20 @@ void ironlake_enable_drps(struct drm_device *dev) fmin = (rgvmodectl & MEMMODE_FMIN_MASK); fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT; + fstart = fmax; vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT; - dev_priv->fmax = fmax; /* IPS callback will increase this */ + dev_priv->fmax = fstart; /* IPS callback will increase this */ dev_priv->fstart = fstart; - dev_priv->max_delay = fstart; + dev_priv->max_delay = fmax; dev_priv->min_delay = fmin; dev_priv->cur_delay = fstart; - DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", - fmax, fmin, fstart); + DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin, + fstart); I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index c8e005553310..891f4f1d63b1 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -1517,7 +1517,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) status = connector_status_connected; } - return status; + return bit; } /** diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 21551fe74541..9af9f86a8765 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -296,7 +296,6 @@ extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, extern void intel_init_clock_gating(struct drm_device *dev); extern void ironlake_enable_drps(struct drm_device *dev); extern void ironlake_disable_drps(struct drm_device *dev); -extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj, diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 4324a326f98e..f1a649990ea9 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -481,8 +481,11 @@ static int intel_lvds_get_modes(struct drm_connector *connector) struct drm_device *dev = connector->dev; struct drm_display_mode *mode; - if (intel_lvds->edid) + if (intel_lvds->edid) { + drm_mode_connector_update_edid_property(connector, + intel_lvds->edid); return drm_add_edid_modes(connector, intel_lvds->edid); + } mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode); if (mode == 0) @@ -936,16 +939,7 @@ void intel_lvds_init(struct drm_device *dev) */ intel_lvds->edid = drm_get_edid(connector, &dev_priv->gmbus[pin].adapter); - if (intel_lvds->edid) { - if (drm_add_edid_modes(connector, - intel_lvds->edid)) { - drm_mode_connector_update_edid_property(connector, - intel_lvds->edid); - } else { - kfree(intel_lvds->edid); - intel_lvds->edid = NULL; - } - } + if (!intel_lvds->edid) { /* Didn't get an EDID, so * Set wide sync ranges so we get all modes diff --git a/trunk/drivers/gpu/drm/i915/intel_opregion.c b/trunk/drivers/gpu/drm/i915/intel_opregion.c index 9b0d9a867aea..917c7dc3cd6b 100644 --- a/trunk/drivers/gpu/drm/i915/intel_opregion.c +++ b/trunk/drivers/gpu/drm/i915/intel_opregion.c @@ -512,6 +512,6 @@ int intel_opregion_setup(struct drm_device *dev) return 0; err_out: - iounmap(base); + iounmap(opregion->header); return err; } diff --git a/trunk/drivers/gpu/drm/i915/intel_overlay.c b/trunk/drivers/gpu/drm/i915/intel_overlay.c index 02ff0a481f47..afb96d25219a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_overlay.c +++ b/trunk/drivers/gpu/drm/i915/intel_overlay.c @@ -946,9 +946,7 @@ static int check_overlay_src(struct drm_device *dev, { int uv_hscale = uv_hsubsampling(rec->flags); int uv_vscale = uv_vsubsampling(rec->flags); - u32 stride_mask; - int depth; - u32 tmp; + u32 stride_mask, depth, tmp; /* check src dimensions */ if (IS_845G(dev) || IS_I830(dev)) { diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index b83306f9244b..09f2dc353ae2 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -177,7 +177,7 @@ static int init_ring_common(struct drm_device *dev, I915_WRITE_CTL(ring, ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) - | RING_REPORT_64K | RING_VALID); + | RING_NO_REPORT | RING_VALID); head = I915_READ_HEAD(ring) & HEAD_ADDR; /* If the head is still not zero, the ring is dead */ @@ -654,10 +654,6 @@ void intel_cleanup_ring_buffer(struct drm_device *dev, i915_gem_object_unpin(ring->gem_object); drm_gem_object_unreference(ring->gem_object); ring->gem_object = NULL; - - if (ring->cleanup) - ring->cleanup(ring); - cleanup_status_page(dev, ring); } @@ -692,17 +688,6 @@ int intel_wait_ring_buffer(struct drm_device *dev, { unsigned long end; drm_i915_private_t *dev_priv = dev->dev_private; - u32 head; - - head = intel_read_status_page(ring, 4); - if (head) { - ring->head = head & HEAD_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->size; - if (ring->space >= n) - return 0; - } trace_i915_ring_wait_begin (dev); end = jiffies + 3 * HZ; @@ -869,125 +854,19 @@ blt_ring_put_user_irq(struct drm_device *dev, /* do nothing */ } - -/* Workaround for some stepping of SNB, - * each time when BLT engine ring tail moved, - * the first command in the ring to be parsed - * should be MI_BATCH_BUFFER_START - */ -#define NEED_BLT_WORKAROUND(dev) \ - (IS_GEN6(dev) && (dev->pdev->revision < 8)) - -static inline struct drm_i915_gem_object * -to_blt_workaround(struct intel_ring_buffer *ring) -{ - return ring->private; -} - -static int blt_ring_init(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - if (NEED_BLT_WORKAROUND(dev)) { - struct drm_i915_gem_object *obj; - u32 __iomem *ptr; - int ret; - - obj = to_intel_bo(i915_gem_alloc_object(dev, 4096)); - if (obj == NULL) - return -ENOMEM; - - ret = i915_gem_object_pin(&obj->base, 4096); - if (ret) { - drm_gem_object_unreference(&obj->base); - return ret; - } - - ptr = kmap(obj->pages[0]); - iowrite32(MI_BATCH_BUFFER_END, ptr); - iowrite32(MI_NOOP, ptr+1); - kunmap(obj->pages[0]); - - ret = i915_gem_object_set_to_gtt_domain(&obj->base, false); - if (ret) { - i915_gem_object_unpin(&obj->base); - drm_gem_object_unreference(&obj->base); - return ret; - } - - ring->private = obj; - } - - return init_ring_common(dev, ring); -} - -static void blt_ring_begin(struct drm_device *dev, - struct intel_ring_buffer *ring, - int num_dwords) -{ - if (ring->private) { - intel_ring_begin(dev, ring, num_dwords+2); - intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START); - intel_ring_emit(dev, ring, to_blt_workaround(ring)->gtt_offset); - } else - intel_ring_begin(dev, ring, 4); -} - -static void blt_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) -{ - blt_ring_begin(dev, ring, 4); - intel_ring_emit(dev, ring, MI_FLUSH_DW); - intel_ring_emit(dev, ring, 0); - intel_ring_emit(dev, ring, 0); - intel_ring_emit(dev, ring, 0); - intel_ring_advance(dev, ring); -} - -static u32 -blt_ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 flush_domains) -{ - u32 seqno = i915_gem_get_seqno(dev); - - blt_ring_begin(dev, ring, 4); - intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(dev, ring, - I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(dev, ring, seqno); - intel_ring_emit(dev, ring, MI_USER_INTERRUPT); - intel_ring_advance(dev, ring); - - DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); - return seqno; -} - -static void blt_ring_cleanup(struct intel_ring_buffer *ring) -{ - if (!ring->private) - return; - - i915_gem_object_unpin(ring->private); - drm_gem_object_unreference(ring->private); - ring->private = NULL; -} - static const struct intel_ring_buffer gen6_blt_ring = { .name = "blt ring", .id = RING_BLT, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, - .init = blt_ring_init, + .init = init_ring_common, .write_tail = ring_write_tail, - .flush = blt_ring_flush, - .add_request = blt_ring_add_request, + .flush = gen6_ring_flush, + .add_request = ring_add_request, .get_seqno = ring_status_page_get_seqno, .user_irq_get = blt_ring_get_user_irq, .user_irq_put = blt_ring_put_user_irq, .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, - .cleanup = blt_ring_cleanup, }; int intel_init_render_ring_buffer(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h index 3126c2681983..a05aff0e5764 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -63,7 +63,6 @@ struct intel_ring_buffer { struct drm_i915_gem_execbuffer2 *exec, struct drm_clip_rect *cliprects, uint64_t exec_offset); - void (*cleanup)(struct intel_ring_buffer *ring); /** * List of objects currently involved in rendering from the @@ -99,8 +98,6 @@ struct intel_ring_buffer { wait_queue_head_t irq_queue; drm_local_map_t map; - - void *private; }; static inline u32 diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 488c36c8f5e6..f12a5b3ec050 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -2033,7 +2033,7 @@ int evergreen_irq_set(struct radeon_device *rdev) u32 grbm_int_cntl = 0; if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); return -EINVAL; } /* don't enable anything if the ih is disabled */ @@ -2295,7 +2295,6 @@ int evergreen_irq_process(struct radeon_device *rdev) case 0: /* D1 vblank */ if (disp_int & LB_D1_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int &= ~LB_D1_VBLANK_INTERRUPT; DRM_DEBUG("IH: D1 vblank\n"); @@ -2317,7 +2316,6 @@ int evergreen_irq_process(struct radeon_device *rdev) case 0: /* D2 vblank */ if (disp_int_cont & LB_D2_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; DRM_DEBUG("IH: D2 vblank\n"); @@ -2339,7 +2337,6 @@ int evergreen_irq_process(struct radeon_device *rdev) case 0: /* D3 vblank */ if (disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 2); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; DRM_DEBUG("IH: D3 vblank\n"); @@ -2361,7 +2358,6 @@ int evergreen_irq_process(struct radeon_device *rdev) case 0: /* D4 vblank */ if (disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 3); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; DRM_DEBUG("IH: D4 vblank\n"); @@ -2383,7 +2379,6 @@ int evergreen_irq_process(struct radeon_device *rdev) case 0: /* D5 vblank */ if (disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 4); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; DRM_DEBUG("IH: D5 vblank\n"); @@ -2405,7 +2400,6 @@ int evergreen_irq_process(struct radeon_device *rdev) case 0: /* D6 vblank */ if (disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 5); - rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; DRM_DEBUG("IH: D6 vblank\n"); diff --git a/trunk/drivers/gpu/drm/radeon/r100.c b/trunk/drivers/gpu/drm/radeon/r100.c index 8e10aa9f74b0..0e8f28a68927 100644 --- a/trunk/drivers/gpu/drm/radeon/r100.c +++ b/trunk/drivers/gpu/drm/radeon/r100.c @@ -442,7 +442,7 @@ int r100_pci_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.ram.ptr) { - WARN(1, "R100 PCI GART already initialized\n"); + WARN(1, "R100 PCI GART already initialized.\n"); return 0; } /* Initialize common gart structure */ @@ -516,7 +516,7 @@ int r100_irq_set(struct radeon_device *rdev) uint32_t tmp = 0; if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); WREG32(R_000040_GEN_INT_CNTL, 0); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/radeon/r300.c b/trunk/drivers/gpu/drm/radeon/r300.c index cde1d3480d93..34527e600fe9 100644 --- a/trunk/drivers/gpu/drm/radeon/r300.c +++ b/trunk/drivers/gpu/drm/radeon/r300.c @@ -91,7 +91,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.vram.robj) { - WARN(1, "RV370 PCIE GART already initialized\n"); + WARN(1, "RV370 PCIE GART already initialized.\n"); return 0; } /* Initialize common gart structure */ diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index 0f806cc7dc75..33952a12f0a3 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -97,8 +97,14 @@ u32 rv6xx_get_temp(struct radeon_device *rdev) { u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >> ASIC_T_SHIFT; + u32 actual_temp = 0; - return temp * 1000; + if ((temp >> 7) & 1) + actual_temp = 0; + else + actual_temp = (temp >> 1) & 0xff; + + return actual_temp * 1000; } void r600_pm_get_dynpm_state(struct radeon_device *rdev) @@ -913,7 +919,7 @@ int r600_pcie_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.vram.robj) { - WARN(1, "R600 PCIE GART already initialized\n"); + WARN(1, "R600 PCIE GART already initialized.\n"); return 0; } /* Initialize common gart structure */ @@ -2989,7 +2995,7 @@ int r600_irq_set(struct radeon_device *rdev) u32 hdmi1, hdmi2; if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); return -EINVAL; } /* don't enable anything if the ih is disabled */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index 87ead090c7d5..04cac7ec9039 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -526,6 +526,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) if (crev < 2) return false; + router.valid = false; + obj_header = (ATOM_OBJECT_HEADER *) (ctx->bios + data_offset); path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *) (ctx->bios + data_offset + @@ -622,8 +624,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) if (connector_type == DRM_MODE_CONNECTOR_Unknown) continue; - router.ddc_valid = false; - router.cd_valid = false; for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { uint8_t grph_obj_id, grph_obj_num, grph_obj_type; @@ -647,8 +647,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) usDeviceTag)); } else if (grph_obj_type == GRAPH_OBJECT_TYPE_ROUTER) { + router.valid = false; for (k = 0; k < router_obj->ucNumberOfObjects; k++) { - u16 router_obj_id = le16_to_cpu(router_obj->asObjects[k].usObjectID); + u16 router_obj_id = le16_to_cpu(router_obj->asObjects[j].usObjectID); if (le16_to_cpu(path->usGraphicObjIds[j]) == router_obj_id) { ATOM_COMMON_RECORD_HEADER *record = (ATOM_COMMON_RECORD_HEADER *) (ctx->bios + data_offset + @@ -656,7 +657,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ATOM_I2C_RECORD *i2c_record; ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; ATOM_ROUTER_DDC_PATH_SELECT_RECORD *ddc_path; - ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *cd_path; ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *router_src_dst_table = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) (ctx->bios + data_offset + @@ -690,18 +690,10 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) case ATOM_ROUTER_DDC_PATH_SELECT_RECORD_TYPE: ddc_path = (ATOM_ROUTER_DDC_PATH_SELECT_RECORD *) record; - router.ddc_valid = true; - router.ddc_mux_type = ddc_path->ucMuxType; - router.ddc_mux_control_pin = ddc_path->ucMuxControlPin; - router.ddc_mux_state = ddc_path->ucMuxState[enum_id]; - break; - case ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD_TYPE: - cd_path = (ATOM_ROUTER_DATA_CLOCK_PATH_SELECT_RECORD *) - record; - router.cd_valid = true; - router.cd_mux_type = cd_path->ucMuxType; - router.cd_mux_control_pin = cd_path->ucMuxControlPin; - router.cd_mux_state = cd_path->ucMuxState[enum_id]; + router.valid = true; + router.mux_type = ddc_path->ucMuxType; + router.mux_control_pin = ddc_path->ucMuxControlPin; + router.mux_state = ddc_path->ucMuxState[enum_id]; break; } record = (ATOM_COMMON_RECORD_HEADER *) @@ -868,8 +860,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct size_t bc_size = sizeof(*bios_connectors) * ATOM_MAX_SUPPORTED_DEVICE; struct radeon_router router; - router.ddc_valid = false; - router.cd_valid = false; + router.valid = false; bios_connectors = kzalloc(bc_size, GFP_KERNEL); if (!bios_connectors) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index fe6c74780f18..4dac4b0a02ee 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -183,13 +183,13 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, continue; if (priority == true) { - DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); - DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(connector)); + DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); + DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); conflict->status = connector_status_disconnected; radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); } else { - DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); - DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(conflict)); + DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); + DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict)); current_status = connector_status_disconnected; } break; @@ -432,13 +432,13 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, mode->vdisplay == native_mode->vdisplay) { *native_mode = *mode; drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); - DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n"); + DRM_INFO("Determined LVDS native mode details from EDID\n"); break; } } } if (!native_mode->clock) { - DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n"); + DRM_INFO("No LVDS native mode details, disabling RMX\n"); radeon_encoder->rmx_type = RMX_OFF; } } @@ -1116,7 +1116,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->shared_ddc = true; shared_ddc = true; } - if (radeon_connector->router_bus && router->ddc_valid && + if (radeon_connector->router_bus && router->valid && (radeon_connector->router.router_id == router->router_id)) { radeon_connector->shared_ddc = false; shared_ddc = false; @@ -1136,7 +1136,7 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; radeon_connector->router = *router; - if (router->ddc_valid || router->cd_valid) { + if (router->valid) { radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); if (!radeon_connector->router_bus) goto failed; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c index 1df4dc6c063c..0383631da69c 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_display.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c @@ -315,14 +315,10 @@ static void radeon_print_display_setup(struct drm_device *dev) radeon_connector->ddc_bus->rec.en_data_reg, radeon_connector->ddc_bus->rec.y_clk_reg, radeon_connector->ddc_bus->rec.y_data_reg); - if (radeon_connector->router.ddc_valid) + if (radeon_connector->router_bus) DRM_INFO(" DDC Router 0x%x/0x%x\n", - radeon_connector->router.ddc_mux_control_pin, - radeon_connector->router.ddc_mux_state); - if (radeon_connector->router.cd_valid) - DRM_INFO(" Clock/Data Router 0x%x/0x%x\n", - radeon_connector->router.cd_mux_control_pin, - radeon_connector->router.cd_mux_state); + radeon_connector->router.mux_control_pin, + radeon_connector->router.mux_state); } else { if (connector->connector_type == DRM_MODE_CONNECTOR_VGA || connector->connector_type == DRM_MODE_CONNECTOR_DVII || @@ -402,8 +398,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) int ret = 0; /* on hw with routers, select right port */ - if (radeon_connector->router.ddc_valid) - radeon_router_select_ddc_port(radeon_connector); + if (radeon_connector->router.valid) + radeon_router_select_port(radeon_connector); if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { @@ -436,8 +432,8 @@ static int radeon_ddc_dump(struct drm_connector *connector) int ret = 0; /* on hw with routers, select right port */ - if (radeon_connector->router.ddc_valid) - radeon_router_select_ddc_port(radeon_connector); + if (radeon_connector->router.valid) + radeon_router_select_port(radeon_connector); if (!radeon_connector->ddc_bus) return -1; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c index f678257c42e6..ae58b6849a2e 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1520,7 +1520,6 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); if (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { @@ -1532,13 +1531,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) radeon_atom_output_lock(encoder, true); radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); - /* select the clock/data port if it uses a router */ - if (connector) { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - if (radeon_connector->router.cd_valid) - radeon_router_select_cd_port(radeon_connector); - } - /* this is needed for the pll/ss setup to work correctly in some cases */ atombios_set_encoder_crtc_source(encoder); } @@ -1555,23 +1547,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig; - - /* check for pre-DCE3 cards with shared encoders; - * can't really use the links individually, so don't disable - * the encoder if it's in use by another connector - */ - if (!ASIC_IS_DCE3(rdev)) { - struct drm_encoder *other_encoder; - struct radeon_encoder *other_radeon_encoder; - - list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { - other_radeon_encoder = to_radeon_encoder(other_encoder); - if ((radeon_encoder->encoder_id == other_radeon_encoder->encoder_id) && - drm_helper_encoder_in_use(other_encoder)) - goto disable_done; - } - } - radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); switch (radeon_encoder->encoder_id) { @@ -1611,7 +1586,6 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) break; } -disable_done: if (radeon_encoder_is_digital(encoder)) { if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) r600_hdmi_disable(encoder); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_fence.c b/trunk/drivers/gpu/drm/radeon/radeon_fence.c index daacb281dfaf..216392d0353b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_fence.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_fence.c @@ -240,8 +240,7 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) */ if (seq == rdev->fence_drv.last_seq && radeon_gpu_is_lockup(rdev)) { /* good news we believe it's a lockup */ - WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", - fence->seq, seq); + WARN(1, "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); /* FIXME: what should we do ? marking everyone * as signaled for now */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c index 0cfbba02c4d0..6a13ee38a5b9 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c @@ -53,8 +53,8 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) }; /* on hw with routers, select right port */ - if (radeon_connector->router.ddc_valid) - radeon_router_select_ddc_port(radeon_connector); + if (radeon_connector->router.valid) + radeon_router_select_port(radeon_connector); ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); if (ret == 2) @@ -1084,51 +1084,26 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, addr, val); } -/* ddc router switching */ -void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector) +/* router switching */ +void radeon_router_select_port(struct radeon_connector *radeon_connector) { u8 val; - if (!radeon_connector->router.ddc_valid) + if (!radeon_connector->router.valid) return; radeon_i2c_get_byte(radeon_connector->router_bus, radeon_connector->router.i2c_addr, 0x3, &val); - val &= ~radeon_connector->router.ddc_mux_control_pin; + val &= radeon_connector->router.mux_control_pin; radeon_i2c_put_byte(radeon_connector->router_bus, radeon_connector->router.i2c_addr, 0x3, val); radeon_i2c_get_byte(radeon_connector->router_bus, radeon_connector->router.i2c_addr, 0x1, &val); - val &= ~radeon_connector->router.ddc_mux_control_pin; - val |= radeon_connector->router.ddc_mux_state; - radeon_i2c_put_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x1, val); -} - -/* clock/data router switching */ -void radeon_router_select_cd_port(struct radeon_connector *radeon_connector) -{ - u8 val; - - if (!radeon_connector->router.cd_valid) - return; - - radeon_i2c_get_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x3, &val); - val &= ~radeon_connector->router.cd_mux_control_pin; - radeon_i2c_put_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x3, val); - radeon_i2c_get_byte(radeon_connector->router_bus, - radeon_connector->router.i2c_addr, - 0x1, &val); - val &= ~radeon_connector->router.cd_mux_control_pin; - val |= radeon_connector->router.cd_mux_state; + val &= radeon_connector->router.mux_control_pin; + val |= radeon_connector->router.mux_state; radeon_i2c_put_byte(radeon_connector->router_bus, radeon_connector->router.i2c_addr, 0x1, val); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index 680f57644e86..92457163d070 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -401,19 +401,13 @@ struct radeon_hpd { }; struct radeon_router { + bool valid; u32 router_id; struct radeon_i2c_bus_rec i2c_info; u8 i2c_addr; - /* i2c mux */ - bool ddc_valid; - u8 ddc_mux_type; - u8 ddc_mux_control_pin; - u8 ddc_mux_state; - /* clock/data mux */ - bool cd_valid; - u8 cd_mux_type; - u8 cd_mux_control_pin; - u8 cd_mux_state; + u8 mux_type; + u8 mux_control_pin; + u8 mux_state; }; struct radeon_connector { @@ -494,8 +488,7 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, u8 slave_addr, u8 addr, u8 val); -extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); -extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); +extern void radeon_router_select_port(struct radeon_connector *radeon_connector); extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.c b/trunk/drivers/gpu/drm/radeon/radeon_object.c index 8eb183466015..d7ab91416410 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.c @@ -102,8 +102,6 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, type = ttm_bo_type_device; } *bo_ptr = NULL; - -retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) return -ENOMEM; @@ -111,6 +109,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, bo->gobj = gobj; bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); + +retry: radeon_ttm_placement_from_domain(bo, domain); /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c index 01c2c736a1da..fe95bb35317e 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c @@ -689,8 +689,7 @@ static int radeon_ttm_backend_bind(struct ttm_backend *backend, gtt = container_of(backend, struct radeon_ttm_backend, backend); gtt->offset = bo_mem->start << PAGE_SHIFT; if (!gtt->num_pages) { - WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", - gtt->num_pages, bo_mem, backend); + WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", gtt->num_pages, bo_mem, backend); } r = radeon_gart_bind(gtt->rdev, gtt->offset, gtt->num_pages, gtt->pages); diff --git a/trunk/drivers/gpu/drm/radeon/rs400.c b/trunk/drivers/gpu/drm/radeon/rs400.c index 5512e4e5e636..f683e51a2a06 100644 --- a/trunk/drivers/gpu/drm/radeon/rs400.c +++ b/trunk/drivers/gpu/drm/radeon/rs400.c @@ -78,7 +78,7 @@ int rs400_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.ram.ptr) { - WARN(1, "RS400 GART already initialized\n"); + WARN(1, "RS400 GART already initialized.\n"); return 0; } /* Check gart size */ diff --git a/trunk/drivers/gpu/drm/radeon/rs600.c b/trunk/drivers/gpu/drm/radeon/rs600.c index f1c6e02c2e6b..b091a1f6fa4e 100644 --- a/trunk/drivers/gpu/drm/radeon/rs600.c +++ b/trunk/drivers/gpu/drm/radeon/rs600.c @@ -375,7 +375,7 @@ int rs600_gart_init(struct radeon_device *rdev) int r; if (rdev->gart.table.vram.robj) { - WARN(1, "RS600 GART already initialized\n"); + WARN(1, "RS600 GART already initialized.\n"); return 0; } /* Initialize common gart structure */ @@ -505,7 +505,7 @@ int rs600_irq_set(struct radeon_device *rdev) ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); if (!rdev->irq.installed) { - WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); + WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); WREG32(R_000040_GEN_INT_CNTL, 0); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c index 3ca77dc03915..a1cb783c7131 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c @@ -27,6 +27,14 @@ /* * Authors: Thomas Hellstrom */ +/* Notes: + * + * We store bo pointer in drm_mm_node struct so we know which bo own a + * specific node. There is no protection on the pointer, thus to make + * sure things don't go berserk you have to access this pointer while + * holding the global lru lock and make sure anytime you free a node you + * reset the pointer to NULL. + */ #include "ttm/ttm_module.h" #include "ttm/ttm_bo_driver.h" @@ -37,7 +45,6 @@ #include #include #include -#include #define TTM_ASSERT_LOCKED(param) #define TTM_DEBUG(fmt, arg...) @@ -445,11 +452,6 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) ttm_bo_mem_put(bo, &bo->mem); atomic_set(&bo->reserved, 0); - - /* - * Make processes trying to reserve really pick it up. - */ - smp_mb__after_atomic_dec(); wake_up_all(&bo->event_queue); } @@ -458,7 +460,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) struct ttm_bo_device *bdev = bo->bdev; struct ttm_bo_global *glob = bo->glob; struct ttm_bo_driver *driver; - void *sync_obj = NULL; + void *sync_obj; void *sync_obj_arg; int put_count; int ret; @@ -493,20 +495,17 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) spin_lock(&glob->lru_lock); } queue: - driver = bdev->driver; - if (bo->sync_obj) - sync_obj = driver->sync_obj_ref(bo->sync_obj); + sync_obj = bo->sync_obj; sync_obj_arg = bo->sync_obj_arg; + driver = bdev->driver; kref_get(&bo->list_kref); list_add_tail(&bo->ddestroy, &bdev->ddestroy); spin_unlock(&glob->lru_lock); spin_unlock(&bo->lock); - if (sync_obj) { + if (sync_obj) driver->sync_obj_flush(sync_obj, sync_obj_arg); - driver->sync_obj_unref(&sync_obj); - } schedule_delayed_work(&bdev->wq, ((HZ / 100) < 1) ? 1 : HZ / 100); } @@ -823,6 +822,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, bool no_wait_gpu) { struct ttm_bo_device *bdev = bo->bdev; + struct ttm_bo_global *glob = bdev->glob; struct ttm_mem_type_manager *man = &bdev->man[mem_type]; int ret; @@ -832,6 +832,12 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, return ret; if (mem->mm_node) break; + spin_lock(&glob->lru_lock); + if (list_empty(&man->lru)) { + spin_unlock(&glob->lru_lock); + break; + } + spin_unlock(&glob->lru_lock); ret = ttm_mem_evict_first(bdev, mem_type, interruptible, no_wait_reserve, no_wait_gpu); if (unlikely(ret != 0)) @@ -1119,9 +1125,35 @@ EXPORT_SYMBOL(ttm_bo_validate); int ttm_bo_check_placement(struct ttm_buffer_object *bo, struct ttm_placement *placement) { - BUG_ON((placement->fpfn || placement->lpfn) && - (bo->mem.num_pages > (placement->lpfn - placement->fpfn))); + int i; + if (placement->fpfn || placement->lpfn) { + if (bo->mem.num_pages > (placement->lpfn - placement->fpfn)) { + printk(KERN_ERR TTM_PFX "Page number range to small " + "Need %lu pages, range is [%u, %u]\n", + bo->mem.num_pages, placement->fpfn, + placement->lpfn); + return -EINVAL; + } + } + for (i = 0; i < placement->num_placement; i++) { + if (!capable(CAP_SYS_ADMIN)) { + if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) { + printk(KERN_ERR TTM_PFX "Need to be root to " + "modify NO_EVICT status.\n"); + return -EINVAL; + } + } + } + for (i = 0; i < placement->num_busy_placement; i++) { + if (!capable(CAP_SYS_ADMIN)) { + if (placement->busy_placement[i] & TTM_PL_FLAG_NO_EVICT) { + printk(KERN_ERR TTM_PFX "Need to be root to " + "modify NO_EVICT status.\n"); + return -EINVAL; + } + } + } return 0; } @@ -1144,10 +1176,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; if (num_pages == 0) { printk(KERN_ERR TTM_PFX "Illegal buffer object size.\n"); - if (destroy) - (*destroy)(bo); - else - kfree(bo); return -EINVAL; } bo->destroy = destroy; @@ -1341,9 +1369,18 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, int ret = -EINVAL; struct ttm_mem_type_manager *man; - BUG_ON(type >= TTM_NUM_MEM_TYPES); + if (type >= TTM_NUM_MEM_TYPES) { + printk(KERN_ERR TTM_PFX "Illegal memory type %d\n", type); + return ret; + } + man = &bdev->man[type]; - BUG_ON(man->has_type); + if (man->has_type) { + printk(KERN_ERR TTM_PFX + "Memory manager already initialized for type %d\n", + type); + return ret; + } ret = bdev->driver->init_mem_type(bdev, type, man); if (ret) @@ -1352,6 +1389,13 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, ret = 0; if (type != TTM_PL_SYSTEM) { + if (!p_size) { + printk(KERN_ERR TTM_PFX + "Zero size memory manager type %d\n", + type); + return ret; + } + ret = (*man->func->init)(man, p_size); if (ret) return ret; diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo_manager.c b/trunk/drivers/gpu/drm/ttm/ttm_bo_manager.c index 038e947d00f9..7410c190c891 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo_manager.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo_manager.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright (c) 2007-2010 VMware, Inc., Palo Alto, CA., USA + * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -31,29 +31,20 @@ #include "ttm/ttm_module.h" #include "ttm/ttm_bo_driver.h" #include "ttm/ttm_placement.h" -#include "drm_mm.h" +#include #include -#include +#include +#include +#include #include -/** - * Currently we use a spinlock for the lock, but a mutex *may* be - * more appropriate to reduce scheduling latency if the range manager - * ends up with very fragmented allocation patterns. - */ - -struct ttm_range_manager { - struct drm_mm mm; - spinlock_t lock; -}; - static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_mem_reg *mem) { - struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; - struct drm_mm *mm = &rman->mm; + struct ttm_bo_global *glob = man->bdev->glob; + struct drm_mm *mm = man->priv; struct drm_mm_node *node = NULL; unsigned long lpfn; int ret; @@ -66,19 +57,19 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, if (unlikely(ret)) return ret; - spin_lock(&rman->lock); + spin_lock(&glob->lru_lock); node = drm_mm_search_free_in_range(mm, mem->num_pages, mem->page_alignment, placement->fpfn, lpfn, 1); if (unlikely(node == NULL)) { - spin_unlock(&rman->lock); + spin_unlock(&glob->lru_lock); return 0; } node = drm_mm_get_block_atomic_range(node, mem->num_pages, - mem->page_alignment, - placement->fpfn, - lpfn); - spin_unlock(&rman->lock); + mem->page_alignment, + placement->fpfn, + lpfn); + spin_unlock(&glob->lru_lock); } while (node == NULL); mem->mm_node = node; @@ -89,12 +80,12 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem) { - struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; + struct ttm_bo_global *glob = man->bdev->glob; if (mem->mm_node) { - spin_lock(&rman->lock); + spin_lock(&glob->lru_lock); drm_mm_put_block(mem->mm_node); - spin_unlock(&rman->lock); + spin_unlock(&glob->lru_lock); mem->mm_node = NULL; } } @@ -102,49 +93,49 @@ static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, static int ttm_bo_man_init(struct ttm_mem_type_manager *man, unsigned long p_size) { - struct ttm_range_manager *rman; + struct drm_mm *mm; int ret; - rman = kzalloc(sizeof(*rman), GFP_KERNEL); - if (!rman) + mm = kzalloc(sizeof(*mm), GFP_KERNEL); + if (!mm) return -ENOMEM; - ret = drm_mm_init(&rman->mm, 0, p_size); + ret = drm_mm_init(mm, 0, p_size); if (ret) { - kfree(rman); + kfree(mm); return ret; } - spin_lock_init(&rman->lock); - man->priv = rman; + man->priv = mm; return 0; } static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man) { - struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; - struct drm_mm *mm = &rman->mm; + struct ttm_bo_global *glob = man->bdev->glob; + struct drm_mm *mm = man->priv; + int ret = 0; - spin_lock(&rman->lock); + spin_lock(&glob->lru_lock); if (drm_mm_clean(mm)) { drm_mm_takedown(mm); - spin_unlock(&rman->lock); - kfree(rman); + kfree(mm); man->priv = NULL; - return 0; - } - spin_unlock(&rman->lock); - return -EBUSY; + } else + ret = -EBUSY; + spin_unlock(&glob->lru_lock); + return ret; } static void ttm_bo_man_debug(struct ttm_mem_type_manager *man, const char *prefix) { - struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv; + struct ttm_bo_global *glob = man->bdev->glob; + struct drm_mm *mm = man->priv; - spin_lock(&rman->lock); - drm_mm_debug_table(&rman->mm, prefix); - spin_unlock(&rman->lock); + spin_lock(&glob->lru_lock); + drm_mm_debug_table(mm, prefix); + spin_unlock(&glob->lru_lock); } const struct ttm_mem_type_manager_func ttm_bo_manager_func = { diff --git a/trunk/drivers/gpu/drm/ttm/ttm_tt.c b/trunk/drivers/gpu/drm/ttm/ttm_tt.c index af789dc869b9..a7bab87a548b 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_tt.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_tt.c @@ -440,8 +440,10 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) return ret; ret = be->func->bind(be, bo_mem); - if (unlikely(ret != 0)) + if (ret) { + printk(KERN_ERR TTM_PFX "Couldn't bind backend.\n"); return ret; + } ttm->state = tt_bound; diff --git a/trunk/drivers/gpu/drm/via/via_dmablit.c b/trunk/drivers/gpu/drm/via/via_dmablit.c index 3e038a394c51..9b5b4d9dd62c 100644 --- a/trunk/drivers/gpu/drm/via/via_dmablit.c +++ b/trunk/drivers/gpu/drm/via/via_dmablit.c @@ -235,9 +235,9 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride - 1)) - first_pfn + 1; - vsg->pages = vzalloc(sizeof(struct page *) * vsg->num_pages); - if (NULL == vsg->pages) + if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages))) return -ENOMEM; + memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages); down_read(¤t->mm->mmap_sem); ret = get_user_pages(current, current->mm, (unsigned long)xfer->mem_addr, diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 76954e3528c1..51d9f9f1d7f2 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -691,7 +691,6 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, fence_rep.error = ret; fence_rep.fence_seq = (uint64_t) sequence; - fence_rep.pad64 = 0; user_fence_rep = (struct drm_vmw_fence_rep __user *) (unsigned long)arg->fence_rep; diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index cceeb42789b6..87c6e6156d7d 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -720,8 +720,6 @@ static int vmw_surface_dmabuf_pin(struct vmw_framebuffer *vfb) &vmw_vram_ne_placement, false, &vmw_dmabuf_bo_free); vmw_overlay_resume_all(dev_priv); - if (unlikely(ret != 0)) - vfbs->buffer = NULL; return ret; } @@ -732,9 +730,6 @@ static int vmw_surface_dmabuf_unpin(struct vmw_framebuffer *vfb) struct vmw_framebuffer_surface *vfbs = vmw_framebuffer_to_vfbs(&vfb->base); - if (unlikely(vfbs->buffer == NULL)) - return 0; - bo = &vfbs->buffer->base; ttm_bo_unref(&bo); vfbs->buffer = NULL; diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 29113c9b26a8..a01c47ddb5bc 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -557,7 +557,7 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) return -EINVAL; } - dev_priv->ldu_priv = kmalloc(sizeof(*dev_priv->ldu_priv), GFP_KERNEL); + dev_priv->ldu_priv = kmalloc(GFP_KERNEL, sizeof(*dev_priv->ldu_priv)); if (!dev_priv->ldu_priv) return -ENOMEM; diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index f1a52f9e7298..df2036ed18d5 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -585,7 +585,7 @@ int vmw_overlay_init(struct vmw_private *dev_priv) return -ENOSYS; } - overlay = kmalloc(sizeof(*overlay), GFP_KERNEL); + overlay = kmalloc(GFP_KERNEL, sizeof(*overlay)); if (!overlay) return -ENOMEM; diff --git a/trunk/drivers/gpu/stub/Kconfig b/trunk/drivers/gpu/stub/Kconfig index 0e1edd7311ff..742c423567cf 100644 --- a/trunk/drivers/gpu/stub/Kconfig +++ b/trunk/drivers/gpu/stub/Kconfig @@ -3,9 +3,6 @@ config STUB_POULSBO depends on PCI # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled # but for select to work, need to select ACPI_VIDEO's dependencies, ick - select VIDEO_OUTPUT_CONTROL if ACPI - select BACKLIGHT_CLASS_DEVICE if ACPI - select INPUT if ACPI select ACPI_VIDEO if ACPI help Choose this option if you have a system that has Intel GMA500 diff --git a/trunk/drivers/hwmon/ad7414.c b/trunk/drivers/hwmon/ad7414.c index 86d822aa9bbf..1e4c21fc1a89 100644 --- a/trunk/drivers/hwmon/ad7414.c +++ b/trunk/drivers/hwmon/ad7414.c @@ -178,13 +178,11 @@ static int ad7414_probe(struct i2c_client *client, { struct ad7414_data *data; int conf; - int err; + int err = 0; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_READ_WORD_DATA)) { - err = -EOPNOTSUPP; + I2C_FUNC_SMBUS_READ_WORD_DATA)) goto exit; - } data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL); if (!data) { diff --git a/trunk/drivers/hwmon/adt7470.c b/trunk/drivers/hwmon/adt7470.c index 87d92a56a939..9e775717abb7 100644 --- a/trunk/drivers/hwmon/adt7470.c +++ b/trunk/drivers/hwmon/adt7470.c @@ -1286,10 +1286,8 @@ static int adt7470_probe(struct i2c_client *client, init_completion(&data->auto_update_stop); data->auto_update = kthread_run(adt7470_update_thread, client, dev_name(data->hwmon_dev)); - if (IS_ERR(data->auto_update)) { - err = PTR_ERR(data->auto_update); + if (IS_ERR(data->auto_update)) goto exit_unregister; - } return 0; diff --git a/trunk/drivers/hwmon/gpio-fan.c b/trunk/drivers/hwmon/gpio-fan.c index f141a1de519c..aa701a183707 100644 --- a/trunk/drivers/hwmon/gpio-fan.c +++ b/trunk/drivers/hwmon/gpio-fan.c @@ -376,6 +376,10 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, } } + err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); + if (err) + goto err_free_gpio; + fan_data->num_ctrl = num_ctrl; fan_data->ctrl = ctrl; fan_data->num_speed = pdata->num_speed; @@ -387,10 +391,6 @@ static int fan_ctrl_init(struct gpio_fan_data *fan_data, goto err_free_gpio; } - err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group); - if (err) - goto err_free_gpio; - return 0; err_free_gpio: diff --git a/trunk/drivers/hwmon/ltc4261.c b/trunk/drivers/hwmon/ltc4261.c index 4b50601027d3..267626178678 100644 --- a/trunk/drivers/hwmon/ltc4261.c +++ b/trunk/drivers/hwmon/ltc4261.c @@ -82,7 +82,7 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev) val = i2c_smbus_read_byte_data(client, i); if (unlikely(val < 0)) { dev_dbg(dev, - "Failed to read ADC value: error %d\n", + "Failed to read ADC value: error %d", val); ret = ERR_PTR(val); goto abort; @@ -230,7 +230,8 @@ static int ltc4261_probe(struct i2c_client *client, return -ENODEV; if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { - dev_err(&client->dev, "Failed to read status register\n"); + dev_err(&client->dev, "Failed to read register %d:%02x:%02x\n", + adapter->id, client->addr, LTC4261_STATUS); return -ENODEV; } diff --git a/trunk/drivers/infiniband/core/addr.c b/trunk/drivers/infiniband/core/addr.c index 8aba0ba57de5..a5ea1bce9689 100644 --- a/trunk/drivers/infiniband/core/addr.c +++ b/trunk/drivers/infiniband/core/addr.c @@ -130,8 +130,8 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: - rcu_read_lock(); - for_each_netdev_rcu(&init_net, dev) { + read_lock(&dev_base_lock); + for_each_netdev(&init_net, dev) { if (ipv6_chk_addr(&init_net, &((struct sockaddr_in6 *) addr)->sin6_addr, dev, 1)) { @@ -139,7 +139,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) break; } } - rcu_read_unlock(); + read_unlock(&dev_base_lock); break; #endif } @@ -200,7 +200,7 @@ static int addr4_resolve(struct sockaddr_in *src_in, src_in->sin_family = AF_INET; src_in->sin_addr.s_addr = rt->rt_src; - if (rt->dst.dev->flags & IFF_LOOPBACK) { + if (rt->idev->dev->flags & IFF_LOOPBACK) { ret = rdma_translate_ip((struct sockaddr *) dst_in, addr); if (!ret) memcpy(addr->dst_dev_addr, addr->src_dev_addr, MAX_ADDR_LEN); @@ -208,12 +208,12 @@ static int addr4_resolve(struct sockaddr_in *src_in, } /* If the device does ARP internally, return 'done' */ - if (rt->dst.dev->flags & IFF_NOARP) { - rdma_copy_addr(addr, rt->dst.dev, NULL); + if (rt->idev->dev->flags & IFF_NOARP) { + rdma_copy_addr(addr, rt->idev->dev, NULL); goto put; } - neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev); + neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->idev->dev); if (!neigh || !(neigh->nud_state & NUD_VALID)) { neigh_event_send(rt->dst.neighbour, NULL); ret = -ENODATA; diff --git a/trunk/drivers/infiniband/hw/mlx4/main.c b/trunk/drivers/infiniband/hw/mlx4/main.c index 4e55a28fb6d4..bf3e20cd0298 100644 --- a/trunk/drivers/infiniband/hw/mlx4/main.c +++ b/trunk/drivers/infiniband/hw/mlx4/main.c @@ -848,8 +848,8 @@ static int update_ipv6_gids(struct mlx4_ib_dev *dev, int port, int clear) goto out; } - rcu_read_lock(); - for_each_netdev_rcu(&init_net, tmp) { + read_lock(&dev_base_lock); + for_each_netdev(&init_net, tmp) { if (ndev && (tmp == ndev || rdma_vlan_dev_real_dev(tmp) == ndev)) { gid.global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL); vid = rdma_vlan_dev_vlan_id(tmp); @@ -884,7 +884,7 @@ static int update_ipv6_gids(struct mlx4_ib_dev *dev, int port, int clear) } } } - rcu_read_unlock(); + read_unlock(&dev_base_lock); for (i = 0; i < 128; ++i) if (!hits[i]) { diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index 7f26ca6ecf75..d092ef9291da 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -74,7 +74,6 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) * dev->event_lock held and interrupts disabled. */ static void input_pass_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int type, unsigned int code, int value) { struct input_handler *handler; @@ -93,15 +92,6 @@ static void input_pass_event(struct input_dev *dev, continue; handler = handle->handler; - - /* - * If this is the handler that injected this - * particular event we want to skip it to avoid - * filters firing again and again. - */ - if (handler == src_handler) - continue; - if (!handler->filter) { if (filtered) break; @@ -131,7 +121,7 @@ static void input_repeat_key(unsigned long data) if (test_bit(dev->repeat_key, dev->key) && is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { - input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2); + input_pass_event(dev, EV_KEY, dev->repeat_key, 2); if (dev->sync) { /* @@ -140,7 +130,7 @@ static void input_repeat_key(unsigned long data) * Otherwise assume that the driver will send * SYN_REPORT once it's done. */ - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } if (dev->rep[REP_PERIOD]) @@ -173,7 +163,6 @@ static void input_stop_autorepeat(struct input_dev *dev) #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) static int input_handle_abs_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int code, int *pval) { bool is_mt_event; @@ -217,15 +206,13 @@ static int input_handle_abs_event(struct input_dev *dev, /* Flush pending "slot" event */ if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); - input_pass_event(dev, src_handler, - EV_ABS, ABS_MT_SLOT, dev->slot); + input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); } return INPUT_PASS_TO_HANDLERS; } static void input_handle_event(struct input_dev *dev, - struct input_handler *src_handler, unsigned int type, unsigned int code, int value) { int disposition = INPUT_IGNORE_EVENT; @@ -278,8 +265,7 @@ static void input_handle_event(struct input_dev *dev, case EV_ABS: if (is_event_supported(code, dev->absbit, ABS_MAX)) - disposition = input_handle_abs_event(dev, src_handler, - code, &value); + disposition = input_handle_abs_event(dev, code, &value); break; @@ -337,7 +323,7 @@ static void input_handle_event(struct input_dev *dev, dev->event(dev, type, code, value); if (disposition & INPUT_PASS_TO_HANDLERS) - input_pass_event(dev, src_handler, type, code, value); + input_pass_event(dev, type, code, value); } /** @@ -366,7 +352,7 @@ void input_event(struct input_dev *dev, spin_lock_irqsave(&dev->event_lock, flags); add_input_randomness(type, code, value); - input_handle_event(dev, NULL, type, code, value); + input_handle_event(dev, type, code, value); spin_unlock_irqrestore(&dev->event_lock, flags); } } @@ -396,8 +382,7 @@ void input_inject_event(struct input_handle *handle, rcu_read_lock(); grab = rcu_dereference(dev->grab); if (!grab || grab == handle) - input_handle_event(dev, handle->handler, - type, code, value); + input_handle_event(dev, type, code, value); rcu_read_unlock(); spin_unlock_irqrestore(&dev->event_lock, flags); @@ -610,10 +595,10 @@ static void input_dev_release_keys(struct input_dev *dev) for (code = 0; code <= KEY_MAX; code++) { if (is_event_supported(code, dev->keybit, KEY_MAX) && __test_and_clear_bit(code, dev->key)) { - input_pass_event(dev, NULL, EV_KEY, code, 0); + input_pass_event(dev, EV_KEY, code, 0); } } - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } } @@ -888,9 +873,9 @@ int input_set_keycode(struct input_dev *dev, !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && __test_and_clear_bit(old_keycode, dev->key)) { - input_pass_event(dev, NULL, EV_KEY, old_keycode, 0); + input_pass_event(dev, EV_KEY, old_keycode, 0); if (dev->sync) - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); } out: @@ -1580,7 +1565,8 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) } \ } while (0) -static void input_dev_toggle(struct input_dev *dev, bool activate) +#ifdef CONFIG_PM +static void input_dev_reset(struct input_dev *dev, bool activate) { if (!dev->event) return; @@ -1594,44 +1580,12 @@ static void input_dev_toggle(struct input_dev *dev, bool activate) } } -/** - * input_reset_device() - reset/restore the state of input device - * @dev: input device whose state needs to be reset - * - * This function tries to reset the state of an opened input device and - * bring internal state and state if the hardware in sync with each other. - * We mark all keys as released, restore LED state, repeat rate, etc. - */ -void input_reset_device(struct input_dev *dev) -{ - mutex_lock(&dev->mutex); - - if (dev->users) { - input_dev_toggle(dev, true); - - /* - * Keys that have been pressed at suspend time are unlikely - * to be still pressed when we resume. - */ - spin_lock_irq(&dev->event_lock); - input_dev_release_keys(dev); - spin_unlock_irq(&dev->event_lock); - } - - mutex_unlock(&dev->mutex); -} -EXPORT_SYMBOL(input_reset_device); - -#ifdef CONFIG_PM static int input_dev_suspend(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); mutex_lock(&input_dev->mutex); - - if (input_dev->users) - input_dev_toggle(input_dev, false); - + input_dev_reset(input_dev, false); mutex_unlock(&input_dev->mutex); return 0; @@ -1641,7 +1595,18 @@ static int input_dev_resume(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - input_reset_device(input_dev); + mutex_lock(&input_dev->mutex); + input_dev_reset(input_dev, true); + + /* + * Keys that have been pressed at suspend time are unlikely + * to be still pressed when we resume. + */ + spin_lock_irq(&input_dev->event_lock); + input_dev_release_keys(input_dev); + spin_unlock_irq(&input_dev->event_lock); + + mutex_unlock(&input_dev->mutex); return 0; } diff --git a/trunk/drivers/input/keyboard/adp5588-keys.c b/trunk/drivers/input/keyboard/adp5588-keys.c index af45d275f686..b92d1cd5cba1 100644 --- a/trunk/drivers/input/keyboard/adp5588-keys.c +++ b/trunk/drivers/input/keyboard/adp5588-keys.c @@ -4,7 +4,7 @@ * I2C QWERTY Keypad and IO Expander * Bugs: Enter bugs at http://blackfin.uclinux.org/ * - * Copyright (C) 2008-2010 Analog Devices Inc. + * Copyright (C) 2008-2009 Analog Devices Inc. * Licensed under the GPL-2 or later. */ @@ -24,6 +24,29 @@ #include + /* Configuration Register1 */ +#define AUTO_INC (1 << 7) +#define GPIEM_CFG (1 << 6) +#define OVR_FLOW_M (1 << 5) +#define INT_CFG (1 << 4) +#define OVR_FLOW_IEN (1 << 3) +#define K_LCK_IM (1 << 2) +#define GPI_IEN (1 << 1) +#define KE_IEN (1 << 0) + +/* Interrupt Status Register */ +#define CMP2_INT (1 << 5) +#define CMP1_INT (1 << 4) +#define OVR_FLOW_INT (1 << 3) +#define K_LCK_INT (1 << 2) +#define GPI_INT (1 << 1) +#define KE_INT (1 << 0) + +/* Key Lock and Event Counter Register */ +#define K_LCK_EN (1 << 6) +#define LCK21 0x30 +#define KEC 0xF + /* Key Event Register xy */ #define KEY_EV_PRESSED (1 << 7) #define KEY_EV_MASK (0x7F) @@ -32,6 +55,10 @@ #define KEYP_MAX_EVENT 10 +#define MAXGPIO 18 +#define ADP_BANK(offs) ((offs) >> 3) +#define ADP_BIT(offs) (1u << ((offs) & 0x7)) + /* * Early pre 4.0 Silicon required to delay readout by at least 25ms, * since the Event Counter Register updated 25ms after the interrupt @@ -48,7 +75,7 @@ struct adp5588_kpad { const struct adp5588_gpi_map *gpimap; unsigned short gpimapsize; #ifdef CONFIG_GPIOLIB - unsigned char gpiomap[ADP5588_MAXGPIO]; + unsigned char gpiomap[MAXGPIO]; bool export_gpio; struct gpio_chip gc; struct mutex gpio_lock; /* Protect cached dir, dat_out */ @@ -76,8 +103,8 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); - unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); - unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit); } @@ -86,8 +113,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, unsigned off, int val) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); - unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); - unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); mutex_lock(&kpad->gpio_lock); @@ -105,8 +132,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); - unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); - unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); int ret; mutex_lock(&kpad->gpio_lock); @@ -123,8 +150,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, unsigned off, int val) { struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); - unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); - unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); + unsigned int bank = ADP_BANK(kpad->gpiomap[off]); + unsigned int bit = ADP_BIT(kpad->gpiomap[off]); int ret; mutex_lock(&kpad->gpio_lock); @@ -149,7 +176,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, const struct adp5588_kpad_platform_data *pdata) { - bool pin_used[ADP5588_MAXGPIO]; + bool pin_used[MAXGPIO]; int n_unused = 0; int i; @@ -164,7 +191,7 @@ static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad, for (i = 0; i < kpad->gpimapsize; i++) pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true; - for (i = 0; i < ADP5588_MAXGPIO; i++) + for (i = 0; i < MAXGPIO; i++) if (!pin_used[i]) kpad->gpiomap[n_unused++] = i; @@ -207,7 +234,7 @@ static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad) return error; } - for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { + for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { kpad->dat_out[i] = adp5588_read(kpad->client, GPIO_DAT_OUT1 + i); kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i); @@ -291,11 +318,11 @@ static void adp5588_work(struct work_struct *work) status = adp5588_read(client, INT_STAT); - if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */ + if (status & OVR_FLOW_INT) /* Unlikely and should never happen */ dev_err(&client->dev, "Event Overflow Error\n"); - if (status & ADP5588_KE_INT) { - ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC; + if (status & KE_INT) { + ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; if (ev_cnt) { adp5588_report_events(kpad, ev_cnt); input_sync(kpad->input); @@ -333,7 +360,7 @@ static int __devinit adp5588_setup(struct i2c_client *client) if (pdata->en_keylock) { ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1); ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2); - ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN); + ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN); } for (i = 0; i < KEYP_MAX_EVENT; i++) @@ -357,7 +384,7 @@ static int __devinit adp5588_setup(struct i2c_client *client) } if (gpio_data) { - for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { + for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { int pull_mask = gpio_data->pullup_dis_mask; ret |= adp5588_write(client, GPIO_PULL1 + i, @@ -365,14 +392,11 @@ static int __devinit adp5588_setup(struct i2c_client *client) } } - ret |= adp5588_write(client, INT_STAT, - ADP5588_CMP2_INT | ADP5588_CMP1_INT | - ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT | - ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */ + ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | + OVR_FLOW_INT | K_LCK_INT | + GPI_INT | KE_INT); /* Status is W1C */ - ret |= adp5588_write(client, CFG, ADP5588_INT_CFG | - ADP5588_OVR_FLOW_IEN | - ADP5588_KE_IEN); + ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN); if (ret < 0) { dev_err(&client->dev, "Write Error\n"); diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index 11478eb2c27d..d358ef8623f4 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -63,10 +63,6 @@ static bool atkbd_extra; module_param_named(extra, atkbd_extra, bool, 0); MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); -static bool atkbd_terminal; -module_param_named(terminal, atkbd_terminal, bool, 0); -MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2"); - /* * Scancode to keycode tables. These are just the default setting, and * are loadable via a userland utility. @@ -140,8 +136,7 @@ static const unsigned short atkbd_unxlate_table[128] = { #define ATKBD_CMD_ENABLE 0x00f4 #define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */ #define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */ -#define ATKBD_CMD_SETALL_MB 0x00f8 /* Set all keys to give break codes */ -#define ATKBD_CMD_SETALL_MBR 0x00fa /* ... and repeat */ +#define ATKBD_CMD_SETALL_MBR 0x00fa #define ATKBD_CMD_RESET_BAT 0x02ff #define ATKBD_CMD_RESEND 0x00fe #define ATKBD_CMD_EX_ENABLE 0x10ea @@ -769,11 +764,6 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra } } - if (atkbd_terminal) { - ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MB); - return 3; - } - if (target_set != 3) return 2; diff --git a/trunk/drivers/input/misc/pcf8574_keypad.c b/trunk/drivers/input/misc/pcf8574_keypad.c index d1583aea1721..4b42ffc0532a 100644 --- a/trunk/drivers/input/misc/pcf8574_keypad.c +++ b/trunk/drivers/input/misc/pcf8574_keypad.c @@ -127,6 +127,14 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 idev->id.product = 0x0001; idev->id.version = 0x0100; + input_set_drvdata(idev, lp); + + ret = input_register_device(idev); + if (ret) { + dev_err(&client->dev, "input_register_device() failed\n"); + goto fail_register; + } + lp->laststate = read_state(lp); ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler, @@ -134,21 +142,16 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2 DRV_NAME, lp); if (ret) { dev_err(&client->dev, "IRQ %d is not free\n", client->irq); - goto fail_free_device; - } - - ret = input_register_device(idev); - if (ret) { - dev_err(&client->dev, "input_register_device() failed\n"); - goto fail_free_irq; + goto fail_irq; } i2c_set_clientdata(client, lp); return 0; - fail_free_irq: - free_irq(client->irq, lp); - fail_free_device: + fail_irq: + input_unregister_device(idev); + fail_register: + input_set_drvdata(idev, NULL); input_free_device(idev); fail_allocate: kfree(lp); diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index a5475b577086..ed7ad7416b24 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -350,17 +350,6 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), }, }, - { - /* - * Most (all?) VAIOs do not have external PS/2 ports nor - * they implement active multiplexing properly, and - * MUX discovery usually messes up keyboard/touchpad. - */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "VAIO"), - }, - }, { /* Amoi M636/A737 */ .matches = { diff --git a/trunk/drivers/input/tablet/acecad.c b/trunk/drivers/input/tablet/acecad.c index d94f7e9aa997..aea9a9399a36 100644 --- a/trunk/drivers/input/tablet/acecad.c +++ b/trunk/drivers/input/tablet/acecad.c @@ -229,13 +229,12 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ err = input_register_device(acecad->input); if (err) - goto fail3; + goto fail2; usb_set_intfdata(intf, acecad); return 0; - fail3: usb_free_urb(acecad->irq); fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma); fail1: input_free_device(input_dev); kfree(acecad); diff --git a/trunk/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/trunk/drivers/isdn/hardware/mISDN/mISDNinfineon.c index bc0529ac88a1..e90db8870b6c 100644 --- a/trunk/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/trunk/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -420,7 +420,7 @@ enable_hwirq(struct inf_hw *hw) break; case INF_NICCY: val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); - val |= NICCY_IRQ_ENABLE; + val |= NICCY_IRQ_ENABLE;; outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG); break; case INF_SCT_1: @@ -924,7 +924,7 @@ setup_instance(struct inf_hw *card) mISDNipac_init(&card->ipac, card); if (card->ipac.isac.dch.dev.Bprotocols == 0) - goto error_setup; + goto error_setup;; err = mISDN_register_device(&card->ipac.isac.dch.dev, &card->pdev->dev, card->name); diff --git a/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c b/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c index d13fa5b119f5..38eb31439a73 100644 --- a/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -264,7 +264,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size) while (noc) { val = le16_to_cpu(*sp++); *mp++ = val >> 8; - *mp++ = val & 0xFF; + *mp++ = val & 0xFF;; noc--; } spin_lock_irqsave(isar->hwlock, flags); diff --git a/trunk/drivers/isdn/hisax/avm_pci.c b/trunk/drivers/isdn/hisax/avm_pci.c index 0e66af1decd4..fcf4ed1cb4b9 100644 --- a/trunk/drivers/isdn/hisax/avm_pci.c +++ b/trunk/drivers/isdn/hisax/avm_pci.c @@ -314,7 +314,7 @@ hdlc_fill_fifo(struct BCState *bcs) bcs->hw.hdlc.ctrl.sr.cmd |= HDLC_CMD_XME; } if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hdlc_fill_fifo %d/%u", count, bcs->tx_skb->len); + debugl1(cs, "hdlc_fill_fifo %d/%ld", count, bcs->tx_skb->len); p = bcs->tx_skb->data; ptr = (u_int *)p; skb_pull(bcs->tx_skb, count); diff --git a/trunk/drivers/isdn/hisax/callc.c b/trunk/drivers/isdn/hisax/callc.c index 37e685eafd24..f150330b5a23 100644 --- a/trunk/drivers/isdn/hisax/callc.c +++ b/trunk/drivers/isdn/hisax/callc.c @@ -65,7 +65,7 @@ hisax_findcard(int driverid) return (struct IsdnCardState *) 0; } -static __attribute__((format(printf, 3, 4))) void +static void link_debug(struct Channel *chanp, int direction, char *fmt, ...) { va_list args; @@ -1068,7 +1068,7 @@ init_d_st(struct Channel *chanp) return 0; } -static __attribute__((format(printf, 2, 3))) void +static void callc_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; diff --git a/trunk/drivers/isdn/hisax/hfc_2bds0.c b/trunk/drivers/isdn/hisax/hfc_2bds0.c index a16459a1332c..7250f56a5246 100644 --- a/trunk/drivers/isdn/hisax/hfc_2bds0.c +++ b/trunk/drivers/isdn/hisax/hfc_2bds0.c @@ -292,7 +292,7 @@ hfc_fill_fifo(struct BCState *bcs) } count = GetFreeFifoBytes_B(bcs); if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo %d count(%u/%d),%lx", + debugl1(cs, "hfc_fill_fifo %d count(%ld/%d),%lx", bcs->channel, bcs->tx_skb->len, count, current->state); if (count < bcs->tx_skb->len) { @@ -719,7 +719,7 @@ hfc_fill_dfifo(struct IsdnCardState *cs) } count = GetFreeFifoBytes_D(cs); if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfc_fill_Dfifo count(%u/%d)", + debugl1(cs, "hfc_fill_Dfifo count(%ld/%d)", cs->tx_skb->len, count); if (count < cs->tx_skb->len) { if (cs->debug & L1_DEB_ISAC) diff --git a/trunk/drivers/isdn/hisax/hfc_2bs0.c b/trunk/drivers/isdn/hisax/hfc_2bs0.c index 626f85df302b..b1f6481e1193 100644 --- a/trunk/drivers/isdn/hisax/hfc_2bs0.c +++ b/trunk/drivers/isdn/hisax/hfc_2bs0.c @@ -282,7 +282,7 @@ hfc_fill_fifo(struct BCState *bcs) count += cs->hw.hfc.fifosize; } /* L1_MODE_TRANS */ if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfc_fill_fifo %d count(%u/%d)", + debugl1(cs, "hfc_fill_fifo %d count(%ld/%d)", bcs->channel, bcs->tx_skb->len, count); if (count < bcs->tx_skb->len) { diff --git a/trunk/drivers/isdn/hisax/hfc_pci.c b/trunk/drivers/isdn/hisax/hfc_pci.c index 3147020d188b..917cc84065bd 100644 --- a/trunk/drivers/isdn/hisax/hfc_pci.c +++ b/trunk/drivers/isdn/hisax/hfc_pci.c @@ -550,7 +550,7 @@ hfcpci_fill_dfifo(struct IsdnCardState *cs) count += D_FIFO_SIZE; /* count now contains available bytes */ if (cs->debug & L1_DEB_ISAC) - debugl1(cs, "hfcpci_fill_Dfifo count(%u/%d)", + debugl1(cs, "hfcpci_fill_Dfifo count(%ld/%d)", cs->tx_skb->len, count); if (count < cs->tx_skb->len) { if (cs->debug & L1_DEB_ISAC) @@ -681,7 +681,7 @@ hfcpci_fill_fifo(struct BCState *bcs) count += B_FIFO_SIZE; /* count now contains available bytes */ if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo %d count(%u/%d),%lx", + debugl1(cs, "hfcpci_fill_fifo %d count(%ld/%d),%lx", bcs->channel, bcs->tx_skb->len, count, current->state); diff --git a/trunk/drivers/isdn/hisax/hfc_sx.c b/trunk/drivers/isdn/hisax/hfc_sx.c index 1235b7131ae1..5aa138eb0b3c 100644 --- a/trunk/drivers/isdn/hisax/hfc_sx.c +++ b/trunk/drivers/isdn/hisax/hfc_sx.c @@ -179,7 +179,7 @@ write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u_char fifo, int trans count += fifo_size; /* count now contains available bytes */ if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_write_fifo %d count(%u/%d)", + debugl1(cs, "hfcsx_write_fifo %d count(%ld/%d)", fifo, skb->len, count); if (count < skb->len) { if (cs->debug & L1_DEB_ISAC_FIFO) @@ -265,7 +265,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) count++; if (cs->debug & L1_DEB_ISAC_FIFO) - debugl1(cs, "hfcsx_read_fifo %d count %u)", + debugl1(cs, "hfcsx_read_fifo %d count %ld)", fifo, count); if ((count > fifo_size) || (count < 4)) { @@ -986,7 +986,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg) default: spin_unlock_irqrestore(&cs->lock, flags); if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcsx_l1hw loop invalid %4lx", (unsigned long)arg); + debugl1(cs, "hfcsx_l1hw loop invalid %4lx", arg); return; } cs->hw.hfcsx.trm |= 0x80; /* enable IOM-loop */ diff --git a/trunk/drivers/isdn/hisax/hisax.h b/trunk/drivers/isdn/hisax/hisax.h index de1c669c7b13..32ab3924aa73 100644 --- a/trunk/drivers/isdn/hisax/hisax.h +++ b/trunk/drivers/isdn/hisax/hisax.h @@ -1286,9 +1286,7 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl * ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); -__attribute__((format(printf, 3, 4))) void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); -__attribute__((format(printf, 3, 0))) void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char * p, int cnt); diff --git a/trunk/drivers/isdn/hisax/ipacx.c b/trunk/drivers/isdn/hisax/ipacx.c index 332104103e18..751b25f2ff58 100644 --- a/trunk/drivers/isdn/hisax/ipacx.c +++ b/trunk/drivers/isdn/hisax/ipacx.c @@ -717,7 +717,7 @@ bch_mode(struct BCState *bcs, int mode, int bc) bc = bc ? 1 : 0; // in case bc is greater than 1 if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "mode_bch() switch B-%d mode %d chan %d", hscx, mode, bc); + debugl1(cs, "mode_bch() switch B-% mode %d chan %d", hscx, mode, bc); bcs->mode = mode; bcs->channel = bc; diff --git a/trunk/drivers/isdn/hisax/isar.c b/trunk/drivers/isdn/hisax/isar.c index 1be4552d94b4..40b914bded8c 100644 --- a/trunk/drivers/isdn/hisax/isar.c +++ b/trunk/drivers/isdn/hisax/isar.c @@ -953,7 +953,7 @@ isar_pump_statev_modem(struct BCState *bcs, u_char devt) { break; case PSEV_GSTN_CLR: if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "pump stev GSTN CLEAR"); + debugl1(cs, "pump stev GSTN CLEAR", devt); break; default: if (cs->debug & L1_DEB_HSCX) @@ -1268,7 +1268,7 @@ isar_int_main(struct IsdnCardState *cs) static void ftimer_handler(struct BCState *bcs) { if (bcs->cs->debug) - debugl1(bcs->cs, "ftimer flags %04lx", + debugl1(bcs->cs, "ftimer flags %04x", bcs->Flag); test_and_clear_bit(BC_FLG_FTI_RUN, &bcs->Flag); if (test_and_clear_bit(BC_FLG_LL_CONN, &bcs->Flag)) { @@ -1427,8 +1427,8 @@ modeisar(struct BCState *bcs, int mode, int bc) &bcs->hw.isar.reg->Flags)) bcs->hw.isar.dpath = 1; else { - printk(KERN_WARNING"isar modeisar analog functions only with DP1\n"); - debugl1(cs, "isar modeisar analog functions only with DP1"); + printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n"); + debugl1(cs, "isar modeisar analog funktions only with DP1"); return(1); } break; @@ -1748,7 +1748,7 @@ isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) { struct BCState *bcs; if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "isar_auxcmd cmd/ch %x/%ld", ic->command, ic->arg); + debugl1(cs, "isar_auxcmd cmd/ch %x/%d", ic->command, ic->arg); switch (ic->command) { case (ISDN_CMD_FAXCMD): bcs = cs->channel[ic->arg].bcs; diff --git a/trunk/drivers/isdn/hisax/isdnl1.h b/trunk/drivers/isdn/hisax/isdnl1.h index 425d86116f2b..172ad4c8c961 100644 --- a/trunk/drivers/isdn/hisax/isdnl1.h +++ b/trunk/drivers/isdn/hisax/isdnl1.h @@ -21,7 +21,6 @@ #define B_XMTBUFREADY 1 #define B_ACKPENDING 2 -__attribute__((format(printf, 2, 3))) void debugl1(struct IsdnCardState *cs, char *fmt, ...); void DChannel_proc_xmt(struct IsdnCardState *cs); void DChannel_proc_rcv(struct IsdnCardState *cs); diff --git a/trunk/drivers/isdn/hisax/isdnl3.c b/trunk/drivers/isdn/hisax/isdnl3.c index ad291f21b201..fd0b643ab740 100644 --- a/trunk/drivers/isdn/hisax/isdnl3.c +++ b/trunk/drivers/isdn/hisax/isdnl3.c @@ -66,7 +66,7 @@ static char *strL3Event[] = "EV_TIMEOUT", }; -static __attribute__((format(printf, 2, 3))) void +static void l3m_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; diff --git a/trunk/drivers/isdn/hisax/netjet.c b/trunk/drivers/isdn/hisax/netjet.c index 644891efc26f..5d7f0f2ff9b9 100644 --- a/trunk/drivers/isdn/hisax/netjet.c +++ b/trunk/drivers/isdn/hisax/netjet.c @@ -254,7 +254,7 @@ static int make_raw_data(struct BCState *bcs) { val >>= 1; } if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger make_raw: in %u out %d.%d", + debugl1(bcs->cs,"tiger make_raw: in %ld out %d.%d", bcs->tx_skb->len, s_cnt, bitcnt); if (bitcnt) { while (8>bitcnt++) { @@ -361,7 +361,7 @@ static int make_raw_data_56k(struct BCState *bcs) { val >>= 1; } if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger make_raw_56k: in %u out %d.%d", + debugl1(bcs->cs,"tiger make_raw_56k: in %ld out %d.%d", bcs->tx_skb->len, s_cnt, bitcnt); if (bitcnt) { while (8>bitcnt++) { @@ -612,7 +612,7 @@ void netjet_fill_dma(struct BCState *bcs) if (!bcs->tx_skb) return; if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger fill_dma1: c%d %4lx", bcs->channel, + debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel, bcs->Flag); if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) return; @@ -625,7 +625,7 @@ void netjet_fill_dma(struct BCState *bcs) return; }; if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger fill_dma2: c%d %4lx", bcs->channel, + debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel, bcs->Flag); if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); @@ -667,7 +667,7 @@ void netjet_fill_dma(struct BCState *bcs) write_raw(bcs, p, cnt); } if (bcs->cs->debug & L1_DEB_HSCX) - debugl1(bcs->cs,"tiger fill_dma3: c%d %4lx", bcs->channel, + debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel, bcs->Flag); } diff --git a/trunk/drivers/isdn/hisax/st5481_d.c b/trunk/drivers/isdn/hisax/st5481_d.c index 44082637a09f..b7876b19fe73 100644 --- a/trunk/drivers/isdn/hisax/st5481_d.c +++ b/trunk/drivers/isdn/hisax/st5481_d.c @@ -167,8 +167,7 @@ static struct FsmNode L1FnList[] __initdata = {ST_L1_F8, EV_IND_RSY, l1_ignore}, }; -static __attribute__((format(printf, 2, 3))) -void l1m_debug(struct FsmInst *fi, char *fmt, ...) +static void l1m_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; char buf[256]; @@ -270,8 +269,7 @@ static char *strDoutEvent[] = "EV_DOUT_UNDERRUN", }; -static __attribute__((format(printf, 2, 3))) -void dout_debug(struct FsmInst *fi, char *fmt, ...) +static void dout_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; char buf[256]; diff --git a/trunk/drivers/isdn/i4l/isdn_concap.c b/trunk/drivers/isdn/i4l/isdn_concap.c index d568689669f8..46048e55f241 100644 --- a/trunk/drivers/isdn/i4l/isdn_concap.c +++ b/trunk/drivers/isdn/i4l/isdn_concap.c @@ -61,7 +61,7 @@ static int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff * static int isdn_concap_dl_connect_req(struct concap_proto *concap) { struct net_device *ndev = concap -> net_dev; - isdn_net_local *lp = netdev_priv(ndev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); int ret; IX25DEBUG( "isdn_concap_dl_connect_req: %s \n", ndev -> name); diff --git a/trunk/drivers/isdn/i4l/isdn_net.c b/trunk/drivers/isdn/i4l/isdn_net.c index afeede7ee295..26d44c3ca1d8 100644 --- a/trunk/drivers/isdn/i4l/isdn_net.c +++ b/trunk/drivers/isdn/i4l/isdn_net.c @@ -827,7 +827,7 @@ isdn_net_dial(void) void isdn_net_hangup(struct net_device *d) { - isdn_net_local *lp = netdev_priv(d); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(d); isdn_ctrl cmd; #ifdef CONFIG_ISDN_X25 struct concap_proto *cprot = lp->netdev->cprot; @@ -1052,7 +1052,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) { isdn_net_dev *nd; isdn_net_local *slp; - isdn_net_local *lp = netdev_priv(ndev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); int retv = NETDEV_TX_OK; if (((isdn_net_local *) netdev_priv(ndev))->master) { @@ -1116,7 +1116,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) static void isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev) { - isdn_net_local *lp = netdev_priv(dev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); if (!skb) return; if (lp->p_encap == ISDN_NET_ENCAP_ETHER) { @@ -1131,7 +1131,7 @@ isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev) static void isdn_net_tx_timeout(struct net_device * ndev) { - isdn_net_local *lp = netdev_priv(ndev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n", ndev->name, lp->dialstate); if (!lp->dialstate){ @@ -1165,7 +1165,7 @@ static void isdn_net_tx_timeout(struct net_device * ndev) static netdev_tx_t isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) { - isdn_net_local *lp = netdev_priv(ndev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); #ifdef CONFIG_ISDN_X25 struct concap_proto * cprot = lp -> netdev -> cprot; /* At this point hard_start_xmit() passes control to the encapsulation @@ -1347,7 +1347,7 @@ isdn_net_close(struct net_device *dev) static struct net_device_stats * isdn_net_get_stats(struct net_device *dev) { - isdn_net_local *lp = netdev_priv(dev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); return &lp->stats; } @@ -1426,7 +1426,7 @@ isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len) static int isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - isdn_net_local *lp = netdev_priv(dev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); unsigned long len = 0; unsigned long expires = 0; int tmp = 0; @@ -1493,7 +1493,7 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int isdn_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - isdn_net_local *lp = netdev_priv(dev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); switch (lp->p_encap) { #ifdef CONFIG_ISDN_PPP @@ -1786,7 +1786,7 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb) static void isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) { - isdn_net_local *lp = netdev_priv(ndev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); isdn_net_local *olp = lp; /* original 'lp' */ #ifdef CONFIG_ISDN_X25 struct concap_proto *cprot = lp -> netdev -> cprot; @@ -1800,7 +1800,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) * handle master's statistics and hangup-timeout */ ndev = lp->master; - lp = netdev_priv(ndev); + lp = (isdn_net_local *) netdev_priv(ndev); lp->stats.rx_packets++; lp->stats.rx_bytes += skb->len; } diff --git a/trunk/drivers/isdn/i4l/isdn_ppp.c b/trunk/drivers/isdn/i4l/isdn_ppp.c index 9e8162c80bb0..fe824e0cbb25 100644 --- a/trunk/drivers/isdn/i4l/isdn_ppp.c +++ b/trunk/drivers/isdn/i4l/isdn_ppp.c @@ -1147,14 +1147,15 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff } if (is->pass_filter - && sk_run_filter(skb, is->pass_filter) == 0) { + && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0) { if (is->debug & 0x2) printk(KERN_DEBUG "IPPP: inbound frame filtered.\n"); kfree_skb(skb); return; } if (!(is->active_filter - && sk_run_filter(skb, is->active_filter) == 0)) { + && sk_run_filter(skb, is->active_filter, + is->active_len) == 0)) { if (is->debug & 0x2) printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n"); lp->huptimer = 0; @@ -1220,7 +1221,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) struct ippp_struct *ipt,*ipts; int slot, retval = NETDEV_TX_OK; - mlp = netdev_priv(netdev); + mlp = (isdn_net_local *) netdev_priv(netdev); nd = mlp->netdev; /* get master lp */ slot = mlp->ppp_slot; @@ -1293,14 +1294,15 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) } if (ipt->pass_filter - && sk_run_filter(skb, ipt->pass_filter) == 0) { + && sk_run_filter(skb, ipt->pass_filter, ipt->pass_len) == 0) { if (ipt->debug & 0x4) printk(KERN_DEBUG "IPPP: outbound frame filtered.\n"); kfree_skb(skb); goto unlock; } if (!(ipt->active_filter - && sk_run_filter(skb, ipt->active_filter) == 0)) { + && sk_run_filter(skb, ipt->active_filter, + ipt->active_len) == 0)) { if (ipt->debug & 0x4) printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n"); lp->huptimer = 0; @@ -1490,9 +1492,9 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp) } drop |= is->pass_filter - && sk_run_filter(skb, is->pass_filter) == 0; + && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0; drop |= is->active_filter - && sk_run_filter(skb, is->active_filter) == 0; + && sk_run_filter(skb, is->active_filter, is->active_len) == 0; skb_push(skb, IPPP_MAX_HEADER - 4); return drop; @@ -1983,7 +1985,7 @@ isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev) { struct ppp_stats __user *res = ifr->ifr_data; struct ppp_stats t; - isdn_net_local *lp = netdev_priv(dev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); if (!access_ok(VERIFY_WRITE, res, sizeof(struct ppp_stats))) return -EFAULT; @@ -2022,7 +2024,7 @@ isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int error=0; int len; - isdn_net_local *lp = netdev_priv(dev); + isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev); if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) @@ -2089,7 +2091,7 @@ isdn_ppp_dial_slave(char *name) sdev = lp->slave; while (sdev) { - isdn_net_local *mlp = netdev_priv(sdev); + isdn_net_local *mlp = (isdn_net_local *) netdev_priv(sdev); if (!(mlp->flags & ISDN_NET_CONNECTED)) break; sdev = mlp->slave; @@ -2097,7 +2099,7 @@ isdn_ppp_dial_slave(char *name) if (!sdev) return 2; - isdn_net_dial_req(netdev_priv(sdev)); + isdn_net_dial_req((isdn_net_local *) netdev_priv(sdev)); return 0; #else return -1; @@ -2120,7 +2122,7 @@ isdn_ppp_hangup_slave(char *name) sdev = lp->slave; while (sdev) { - isdn_net_local *mlp = netdev_priv(sdev); + isdn_net_local *mlp = (isdn_net_local *) netdev_priv(sdev); if (mlp->slave) { /* find last connected link in chain */ isdn_net_local *nlp = ISDN_SLAVE_PRIV(mlp); diff --git a/trunk/drivers/isdn/mISDN/layer1.c b/trunk/drivers/isdn/mISDN/layer1.c index 5cc7c001c523..ac4aa18c632b 100644 --- a/trunk/drivers/isdn/mISDN/layer1.c +++ b/trunk/drivers/isdn/mISDN/layer1.c @@ -99,16 +99,12 @@ static void l1m_debug(struct FsmInst *fi, char *fmt, ...) { struct layer1 *l1 = fi->userdata; - struct va_format vaf; va_list va; va_start(va, fmt); - - vaf.fmt = fmt; - vaf.va = &va; - - printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf); - + printk(KERN_DEBUG "%s: ", dev_name(&l1->dch->dev.dev)); + vprintk(fmt, va); + printk("\n"); va_end(va); } diff --git a/trunk/drivers/isdn/mISDN/layer2.c b/trunk/drivers/isdn/mISDN/layer2.c index 4ae75053c9d2..c97371788764 100644 --- a/trunk/drivers/isdn/mISDN/layer2.c +++ b/trunk/drivers/isdn/mISDN/layer2.c @@ -95,20 +95,14 @@ static void l2m_debug(struct FsmInst *fi, char *fmt, ...) { struct layer2 *l2 = fi->userdata; - struct va_format vaf; va_list va; if (!(*debug & DEBUG_L2_FSM)) return; - va_start(va, fmt); - - vaf.fmt = fmt; - vaf.va = &va; - - printk(KERN_DEBUG "l2 (sapi %d tei %d): %pV\n", - l2->sapi, l2->tei, &vaf); - + printk(KERN_DEBUG "l2 (sapi %d tei %d): ", l2->sapi, l2->tei); + vprintk(fmt, va); + printk("\n"); va_end(va); } diff --git a/trunk/drivers/isdn/mISDN/tei.c b/trunk/drivers/isdn/mISDN/tei.c index 687c9b6264ab..1b85d9d27496 100644 --- a/trunk/drivers/isdn/mISDN/tei.c +++ b/trunk/drivers/isdn/mISDN/tei.c @@ -79,19 +79,14 @@ static void da_debug(struct FsmInst *fi, char *fmt, ...) { struct manager *mgr = fi->userdata; - struct va_format vaf; va_list va; if (!(*debug & DEBUG_L2_TEIFSM)) return; - va_start(va, fmt); - - vaf.fmt = fmt; - vaf.va = &va; - - printk(KERN_DEBUG "mgr(%d): %pV\n", mgr->ch.st->dev->id, &vaf); - + printk(KERN_DEBUG "mgr(%d): ", mgr->ch.st->dev->id); + vprintk(fmt, va); + printk("\n"); va_end(va); } @@ -228,20 +223,14 @@ static void tei_debug(struct FsmInst *fi, char *fmt, ...) { struct teimgr *tm = fi->userdata; - struct va_format vaf; va_list va; if (!(*debug & DEBUG_L2_TEIFSM)) return; - va_start(va, fmt); - - vaf.fmt = fmt; - vaf.va = &va; - - printk(KERN_DEBUG "sapi(%d) tei(%d): %pV\n", - tm->l2->sapi, tm->l2->tei, &vaf); - + printk(KERN_DEBUG "sapi(%d) tei(%d): ", tm->l2->sapi, tm->l2->tei); + vprintk(fmt, va); + printk("\n"); va_end(va); } diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 77b8fd20cd90..cc2a88d5192f 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -10,7 +10,7 @@ menuconfig NEW_LEDS if NEW_LEDS config LEDS_CLASS - bool "LED Class Support" + tristate "LED Class Support" help This option enables the led sysfs class in /sys/class/leds. You'll need this to do anything useful with LEDs. If unsure, say N. @@ -176,24 +176,6 @@ config LEDS_LP3944 To compile this driver as a module, choose M here: the module will be called leds-lp3944. -config LEDS_LP5521 - tristate "LED Support for N.S. LP5521 LED driver chip" - depends on LEDS_CLASS && I2C - help - If you say yes here you get support for the National Semiconductor - LP5521 LED driver. It is 3 channel chip with programmable engines. - Driver provides direct control via LED class and interface for - programming the engines. - -config LEDS_LP5523 - tristate "LED Support for N.S. LP5523 LED driver chip" - depends on LEDS_CLASS && I2C - help - If you say yes here you get support for the National Semiconductor - LP5523 LED driver. It is 9 channel chip with programmable engines. - Driver provides direct control via LED class and interface for - programming the engines. - config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" depends on X86 && SERIO_I8042 && DMI diff --git a/trunk/drivers/leds/Makefile b/trunk/drivers/leds/Makefile index aae6989ff6b6..9c96db40ef6d 100644 --- a/trunk/drivers/leds/Makefile +++ b/trunk/drivers/leds/Makefile @@ -23,8 +23,6 @@ obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o -obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o -obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o obj-$(CONFIG_LEDS_FSG) += leds-fsg.o diff --git a/trunk/drivers/leds/led-class.c b/trunk/drivers/leds/led-class.c index 211e21f34bd5..260660076507 100644 --- a/trunk/drivers/leds/led-class.c +++ b/trunk/drivers/leds/led-class.c @@ -81,79 +81,6 @@ static struct device_attribute led_class_attrs[] = { __ATTR_NULL, }; -static void led_timer_function(unsigned long data) -{ - struct led_classdev *led_cdev = (void *)data; - unsigned long brightness; - unsigned long delay; - - if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { - led_set_brightness(led_cdev, LED_OFF); - return; - } - - brightness = led_get_brightness(led_cdev); - if (!brightness) { - /* Time to switch the LED on. */ - brightness = led_cdev->blink_brightness; - delay = led_cdev->blink_delay_on; - } else { - /* Store the current brightness value to be able - * to restore it when the delay_off period is over. - */ - led_cdev->blink_brightness = brightness; - brightness = LED_OFF; - delay = led_cdev->blink_delay_off; - } - - led_set_brightness(led_cdev, brightness); - - mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); -} - -static void led_stop_software_blink(struct led_classdev *led_cdev) -{ - /* deactivate previous settings */ - del_timer_sync(&led_cdev->blink_timer); - led_cdev->blink_delay_on = 0; - led_cdev->blink_delay_off = 0; -} - -static void led_set_software_blink(struct led_classdev *led_cdev, - unsigned long delay_on, - unsigned long delay_off) -{ - int current_brightness; - - current_brightness = led_get_brightness(led_cdev); - if (current_brightness) - led_cdev->blink_brightness = current_brightness; - if (!led_cdev->blink_brightness) - led_cdev->blink_brightness = led_cdev->max_brightness; - - if (delay_on == led_cdev->blink_delay_on && - delay_off == led_cdev->blink_delay_off) - return; - - led_stop_software_blink(led_cdev); - - led_cdev->blink_delay_on = delay_on; - led_cdev->blink_delay_off = delay_off; - - /* never on - don't blink */ - if (!delay_on) - return; - - /* never off - just set to brightness */ - if (!delay_off) { - led_set_brightness(led_cdev, led_cdev->blink_brightness); - return; - } - - mod_timer(&led_cdev->blink_timer, jiffies + 1); -} - - /** * led_classdev_suspend - suspend an led_classdev. * @led_cdev: the led_classdev to suspend. @@ -221,10 +148,6 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) led_update_brightness(led_cdev); - init_timer(&led_cdev->blink_timer); - led_cdev->blink_timer.function = led_timer_function; - led_cdev->blink_timer.data = (unsigned long)led_cdev; - #ifdef CONFIG_LEDS_TRIGGERS led_trigger_set_default(led_cdev); #endif @@ -234,6 +157,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) return 0; } + EXPORT_SYMBOL_GPL(led_classdev_register); /** @@ -251,9 +175,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev) up_write(&led_cdev->trigger_lock); #endif - /* Stop blinking */ - led_brightness_set(led_cdev, LED_OFF); - device_unregister(led_cdev->dev); down_write(&leds_list_lock); @@ -262,30 +183,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev) } EXPORT_SYMBOL_GPL(led_classdev_unregister); -void led_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) -{ - if (led_cdev->blink_set && - led_cdev->blink_set(led_cdev, delay_on, delay_off)) - return; - - /* blink with 1 Hz as default if nothing specified */ - if (!*delay_on && !*delay_off) - *delay_on = *delay_off = 500; - - led_set_software_blink(led_cdev, *delay_on, *delay_off); -} -EXPORT_SYMBOL(led_blink_set); - -void led_brightness_set(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - led_stop_software_blink(led_cdev); - led_cdev->brightness_set(led_cdev, brightness); -} -EXPORT_SYMBOL(led_brightness_set); - static int __init leds_init(void) { leds_class = class_create(THIS_MODULE, "leds"); diff --git a/trunk/drivers/leds/led-triggers.c b/trunk/drivers/leds/led-triggers.c index c41eb6180c9c..f1c00db88b5e 100644 --- a/trunk/drivers/leds/led-triggers.c +++ b/trunk/drivers/leds/led-triggers.c @@ -113,7 +113,7 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) if (led_cdev->trigger->deactivate) led_cdev->trigger->deactivate(led_cdev); led_cdev->trigger = NULL; - led_brightness_set(led_cdev, LED_OFF); + led_set_brightness(led_cdev, LED_OFF); } if (trigger) { write_lock_irqsave(&trigger->leddev_list_lock, flags); diff --git a/trunk/drivers/leds/leds-gpio.c b/trunk/drivers/leds/leds-gpio.c index 4d9fa38d9ff6..ea57e05d08f3 100644 --- a/trunk/drivers/leds/leds-gpio.c +++ b/trunk/drivers/leds/leds-gpio.c @@ -316,7 +316,7 @@ static struct of_platform_driver of_gpio_leds_driver = { static int __init gpio_led_init(void) { - int ret = 0; + int ret; #ifdef CONFIG_LEDS_GPIO_PLATFORM ret = platform_driver_register(&gpio_led_driver); diff --git a/trunk/drivers/leds/leds-lp5521.c b/trunk/drivers/leds/leds-lp5521.c deleted file mode 100644 index 3782f31f06d2..000000000000 --- a/trunk/drivers/leds/leds-lp5521.c +++ /dev/null @@ -1,821 +0,0 @@ -/* - * LP5521 LED chip driver. - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Samu Onkalo - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LP5521_PROGRAM_LENGTH 32 /* in bytes */ - -#define LP5521_MAX_LEDS 3 /* Maximum number of LEDs */ -#define LP5521_MAX_ENGINES 3 /* Maximum number of engines */ - -#define LP5521_ENG_MASK_BASE 0x30 /* 00110000 */ -#define LP5521_ENG_STATUS_MASK 0x07 /* 00000111 */ - -#define LP5521_CMD_LOAD 0x15 /* 00010101 */ -#define LP5521_CMD_RUN 0x2a /* 00101010 */ -#define LP5521_CMD_DIRECT 0x3f /* 00111111 */ -#define LP5521_CMD_DISABLED 0x00 /* 00000000 */ - -/* Registers */ -#define LP5521_REG_ENABLE 0x00 -#define LP5521_REG_OP_MODE 0x01 -#define LP5521_REG_R_PWM 0x02 -#define LP5521_REG_G_PWM 0x03 -#define LP5521_REG_B_PWM 0x04 -#define LP5521_REG_R_CURRENT 0x05 -#define LP5521_REG_G_CURRENT 0x06 -#define LP5521_REG_B_CURRENT 0x07 -#define LP5521_REG_CONFIG 0x08 -#define LP5521_REG_R_CHANNEL_PC 0x09 -#define LP5521_REG_G_CHANNEL_PC 0x0A -#define LP5521_REG_B_CHANNEL_PC 0x0B -#define LP5521_REG_STATUS 0x0C -#define LP5521_REG_RESET 0x0D -#define LP5521_REG_GPO 0x0E -#define LP5521_REG_R_PROG_MEM 0x10 -#define LP5521_REG_G_PROG_MEM 0x30 -#define LP5521_REG_B_PROG_MEM 0x50 - -#define LP5521_PROG_MEM_BASE LP5521_REG_R_PROG_MEM -#define LP5521_PROG_MEM_SIZE 0x20 - -/* Base register to set LED current */ -#define LP5521_REG_LED_CURRENT_BASE LP5521_REG_R_CURRENT - -/* Base register to set the brightness */ -#define LP5521_REG_LED_PWM_BASE LP5521_REG_R_PWM - -/* Bits in ENABLE register */ -#define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */ -#define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */ -#define LP5521_EXEC_RUN 0x2A - -/* Bits in CONFIG register */ -#define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */ -#define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */ -#define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */ -#define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */ -#define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */ -#define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */ -#define LP5521_R_TO_BATT 4 /* R out: 0 = CP, 1 = Vbat */ -#define LP5521_CLK_SRC_EXT 0 /* Ext-clk source (CLK_32K) */ -#define LP5521_CLK_INT 1 /* Internal clock */ -#define LP5521_CLK_AUTO 2 /* Automatic clock selection */ - -/* Status */ -#define LP5521_EXT_CLK_USED 0x08 - -struct lp5521_engine { - const struct attribute_group *attributes; - int id; - u8 mode; - u8 prog_page; - u8 engine_mask; -}; - -struct lp5521_led { - int id; - u8 chan_nr; - u8 led_current; - u8 max_current; - struct led_classdev cdev; - struct work_struct brightness_work; - u8 brightness; -}; - -struct lp5521_chip { - struct lp5521_platform_data *pdata; - struct mutex lock; /* Serialize control */ - struct i2c_client *client; - struct lp5521_engine engines[LP5521_MAX_ENGINES]; - struct lp5521_led leds[LP5521_MAX_LEDS]; - u8 num_channels; - u8 num_leds; -}; - -#define cdev_to_led(c) container_of(c, struct lp5521_led, cdev) -#define engine_to_lp5521(eng) container_of((eng), struct lp5521_chip, \ - engines[(eng)->id - 1]) -#define led_to_lp5521(led) container_of((led), struct lp5521_chip, \ - leds[(led)->id]) - -static void lp5521_led_brightness_work(struct work_struct *work); - -static inline int lp5521_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -static int lp5521_read(struct i2c_client *client, u8 reg, u8 *buf) -{ - s32 ret; - - ret = i2c_smbus_read_byte_data(client, reg); - if (ret < 0) - return -EIO; - - *buf = ret; - return 0; -} - -static int lp5521_set_engine_mode(struct lp5521_engine *engine, u8 mode) -{ - struct lp5521_chip *chip = engine_to_lp5521(engine); - struct i2c_client *client = chip->client; - int ret; - u8 engine_state; - - /* Only transition between RUN and DIRECT mode are handled here */ - if (mode == LP5521_CMD_LOAD) - return 0; - - if (mode == LP5521_CMD_DISABLED) - mode = LP5521_CMD_DIRECT; - - ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state); - - /* set mode only for this engine */ - engine_state &= ~(engine->engine_mask); - mode &= engine->engine_mask; - engine_state |= mode; - ret |= lp5521_write(client, LP5521_REG_OP_MODE, engine_state); - - return ret; -} - -static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern) -{ - struct lp5521_chip *chip = engine_to_lp5521(eng); - struct i2c_client *client = chip->client; - int ret; - int addr; - u8 mode; - - /* move current engine to direct mode and remember the state */ - ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT); - usleep_range(1000, 10000); - ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode); - - /* For loading, all the engines to load mode */ - lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); - usleep_range(1000, 10000); - lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD); - usleep_range(1000, 10000); - - addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE; - i2c_smbus_write_i2c_block_data(client, - addr, - LP5521_PROG_MEM_SIZE, - pattern); - - ret |= lp5521_write(client, LP5521_REG_OP_MODE, mode); - return ret; -} - -static int lp5521_set_led_current(struct lp5521_chip *chip, int led, u8 curr) -{ - return lp5521_write(chip->client, - LP5521_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, - curr); -} - -static void lp5521_init_engine(struct lp5521_chip *chip, - const struct attribute_group *attr_group) -{ - int i; - for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { - chip->engines[i].id = i + 1; - chip->engines[i].engine_mask = LP5521_ENG_MASK_BASE >> (i * 2); - chip->engines[i].prog_page = i; - chip->engines[i].attributes = &attr_group[i]; - } -} - -static int lp5521_configure(struct i2c_client *client, - const struct attribute_group *attr_group) -{ - struct lp5521_chip *chip = i2c_get_clientdata(client); - int ret; - - lp5521_init_engine(chip, attr_group); - - lp5521_write(client, LP5521_REG_RESET, 0xff); - - usleep_range(10000, 20000); - - /* Set all PWMs to direct control mode */ - ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F); - - /* Enable auto-powersave, set charge pump to auto, red to battery */ - ret |= lp5521_write(client, LP5521_REG_CONFIG, - LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT); - - /* Initialize all channels PWM to zero -> leds off */ - ret |= lp5521_write(client, LP5521_REG_R_PWM, 0); - ret |= lp5521_write(client, LP5521_REG_G_PWM, 0); - ret |= lp5521_write(client, LP5521_REG_B_PWM, 0); - - /* Set engines are set to run state when OP_MODE enables engines */ - ret |= lp5521_write(client, LP5521_REG_ENABLE, - LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM | - LP5521_EXEC_RUN); - /* enable takes 500us */ - usleep_range(500, 20000); - - return ret; -} - -static int lp5521_run_selftest(struct lp5521_chip *chip, char *buf) -{ - int ret; - u8 status; - - ret = lp5521_read(chip->client, LP5521_REG_STATUS, &status); - if (ret < 0) - return ret; - - /* Check that ext clock is really in use if requested */ - if (chip->pdata && chip->pdata->clock_mode == LP5521_CLOCK_EXT) - if ((status & LP5521_EXT_CLK_USED) == 0) - return -EIO; - return 0; -} - -static void lp5521_set_brightness(struct led_classdev *cdev, - enum led_brightness brightness) -{ - struct lp5521_led *led = cdev_to_led(cdev); - led->brightness = (u8)brightness; - schedule_work(&led->brightness_work); -} - -static void lp5521_led_brightness_work(struct work_struct *work) -{ - struct lp5521_led *led = container_of(work, - struct lp5521_led, - brightness_work); - struct lp5521_chip *chip = led_to_lp5521(led); - struct i2c_client *client = chip->client; - - mutex_lock(&chip->lock); - lp5521_write(client, LP5521_REG_LED_PWM_BASE + led->chan_nr, - led->brightness); - mutex_unlock(&chip->lock); -} - -/* Detect the chip by setting its ENABLE register and reading it back. */ -static int lp5521_detect(struct i2c_client *client) -{ - int ret; - u8 buf; - - ret = lp5521_write(client, LP5521_REG_ENABLE, - LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM); - if (ret) - return ret; - usleep_range(1000, 10000); - ret = lp5521_read(client, LP5521_REG_ENABLE, &buf); - if (ret) - return ret; - if (buf != (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)) - return -ENODEV; - - return 0; -} - -/* Set engine mode and create appropriate sysfs attributes, if required. */ -static int lp5521_set_mode(struct lp5521_engine *engine, u8 mode) -{ - struct lp5521_chip *chip = engine_to_lp5521(engine); - struct i2c_client *client = chip->client; - struct device *dev = &client->dev; - int ret = 0; - - /* if in that mode already do nothing, except for run */ - if (mode == engine->mode && mode != LP5521_CMD_RUN) - return 0; - - if (mode == LP5521_CMD_RUN) { - ret = lp5521_set_engine_mode(engine, LP5521_CMD_RUN); - } else if (mode == LP5521_CMD_LOAD) { - lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); - lp5521_set_engine_mode(engine, LP5521_CMD_LOAD); - - ret = sysfs_create_group(&dev->kobj, engine->attributes); - if (ret) - return ret; - } else if (mode == LP5521_CMD_DISABLED) { - lp5521_set_engine_mode(engine, LP5521_CMD_DISABLED); - } - - /* remove load attribute from sysfs if not in load mode */ - if (engine->mode == LP5521_CMD_LOAD && mode != LP5521_CMD_LOAD) - sysfs_remove_group(&dev->kobj, engine->attributes); - - engine->mode = mode; - - return ret; -} - -static int lp5521_do_store_load(struct lp5521_engine *engine, - const char *buf, size_t len) -{ - struct lp5521_chip *chip = engine_to_lp5521(engine); - struct i2c_client *client = chip->client; - int ret, nrchars, offset = 0, i = 0; - char c[3]; - unsigned cmd; - u8 pattern[LP5521_PROGRAM_LENGTH] = {0}; - - while ((offset < len - 1) && (i < LP5521_PROGRAM_LENGTH)) { - /* separate sscanfs because length is working only for %s */ - ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); - ret = sscanf(c, "%2x", &cmd); - if (ret != 1) - goto fail; - pattern[i] = (u8)cmd; - - offset += nrchars; - i++; - } - - /* Each instruction is 16bit long. Check that length is even */ - if (i % 2) - goto fail; - - mutex_lock(&chip->lock); - ret = lp5521_load_program(engine, pattern); - mutex_unlock(&chip->lock); - - if (ret) { - dev_err(&client->dev, "failed loading pattern\n"); - return ret; - } - - return len; -fail: - dev_err(&client->dev, "wrong pattern format\n"); - return -EINVAL; -} - -static ssize_t store_engine_load(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5521_chip *chip = i2c_get_clientdata(client); - return lp5521_do_store_load(&chip->engines[nr - 1], buf, len); -} - -#define store_load(nr) \ -static ssize_t store_engine##nr##_load(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_load(dev, attr, buf, len, nr); \ -} -store_load(1) -store_load(2) -store_load(3) - -static ssize_t show_engine_mode(struct device *dev, - struct device_attribute *attr, - char *buf, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5521_chip *chip = i2c_get_clientdata(client); - switch (chip->engines[nr - 1].mode) { - case LP5521_CMD_RUN: - return sprintf(buf, "run\n"); - case LP5521_CMD_LOAD: - return sprintf(buf, "load\n"); - case LP5521_CMD_DISABLED: - return sprintf(buf, "disabled\n"); - default: - return sprintf(buf, "disabled\n"); - } -} - -#define show_mode(nr) \ -static ssize_t show_engine##nr##_mode(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_engine_mode(dev, attr, buf, nr); \ -} -show_mode(1) -show_mode(2) -show_mode(3) - -static ssize_t store_engine_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5521_chip *chip = i2c_get_clientdata(client); - struct lp5521_engine *engine = &chip->engines[nr - 1]; - mutex_lock(&chip->lock); - - if (!strncmp(buf, "run", 3)) - lp5521_set_mode(engine, LP5521_CMD_RUN); - else if (!strncmp(buf, "load", 4)) - lp5521_set_mode(engine, LP5521_CMD_LOAD); - else if (!strncmp(buf, "disabled", 8)) - lp5521_set_mode(engine, LP5521_CMD_DISABLED); - - mutex_unlock(&chip->lock); - return len; -} - -#define store_mode(nr) \ -static ssize_t store_engine##nr##_mode(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_mode(dev, attr, buf, len, nr); \ -} -store_mode(1) -store_mode(2) -store_mode(3) - -static ssize_t show_max_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5521_led *led = cdev_to_led(led_cdev); - - return sprintf(buf, "%d\n", led->max_current); -} - -static ssize_t show_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5521_led *led = cdev_to_led(led_cdev); - - return sprintf(buf, "%d\n", led->led_current); -} - -static ssize_t store_current(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5521_led *led = cdev_to_led(led_cdev); - struct lp5521_chip *chip = led_to_lp5521(led); - ssize_t ret; - unsigned long curr; - - if (strict_strtoul(buf, 0, &curr)) - return -EINVAL; - - if (curr > led->max_current) - return -EINVAL; - - mutex_lock(&chip->lock); - ret = lp5521_set_led_current(chip, led->id, curr); - mutex_unlock(&chip->lock); - - if (ret < 0) - return ret; - - led->led_current = (u8)curr; - - return len; -} - -static ssize_t lp5521_selftest(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5521_chip *chip = i2c_get_clientdata(client); - int ret; - - mutex_lock(&chip->lock); - ret = lp5521_run_selftest(chip, buf); - mutex_unlock(&chip->lock); - return sprintf(buf, "%s\n", ret ? "FAIL" : "OK"); -} - -/* led class device attributes */ -static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); -static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); - -static struct attribute *lp5521_led_attributes[] = { - &dev_attr_led_current.attr, - &dev_attr_max_current.attr, - NULL, -}; - -static struct attribute_group lp5521_led_attribute_group = { - .attrs = lp5521_led_attributes -}; - -/* device attributes */ -static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, - show_engine1_mode, store_engine1_mode); -static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, - show_engine2_mode, store_engine2_mode); -static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, - show_engine3_mode, store_engine3_mode); -static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); -static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); -static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); -static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); - -static struct attribute *lp5521_attributes[] = { - &dev_attr_engine1_mode.attr, - &dev_attr_engine2_mode.attr, - &dev_attr_engine3_mode.attr, - &dev_attr_selftest.attr, - NULL -}; - -static struct attribute *lp5521_engine1_attributes[] = { - &dev_attr_engine1_load.attr, - NULL -}; - -static struct attribute *lp5521_engine2_attributes[] = { - &dev_attr_engine2_load.attr, - NULL -}; - -static struct attribute *lp5521_engine3_attributes[] = { - &dev_attr_engine3_load.attr, - NULL -}; - -static const struct attribute_group lp5521_group = { - .attrs = lp5521_attributes, -}; - -static const struct attribute_group lp5521_engine_group[] = { - {.attrs = lp5521_engine1_attributes }, - {.attrs = lp5521_engine2_attributes }, - {.attrs = lp5521_engine3_attributes }, -}; - -static int lp5521_register_sysfs(struct i2c_client *client) -{ - struct device *dev = &client->dev; - return sysfs_create_group(&dev->kobj, &lp5521_group); -} - -static void lp5521_unregister_sysfs(struct i2c_client *client) -{ - struct lp5521_chip *chip = i2c_get_clientdata(client); - struct device *dev = &client->dev; - int i; - - sysfs_remove_group(&dev->kobj, &lp5521_group); - - for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { - if (chip->engines[i].mode == LP5521_CMD_LOAD) - sysfs_remove_group(&dev->kobj, - chip->engines[i].attributes); - } - - for (i = 0; i < chip->num_leds; i++) - sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, - &lp5521_led_attribute_group); -} - -static int __init lp5521_init_led(struct lp5521_led *led, - struct i2c_client *client, - int chan, struct lp5521_platform_data *pdata) -{ - struct device *dev = &client->dev; - char name[32]; - int res; - - if (chan >= LP5521_MAX_LEDS) - return -EINVAL; - - if (pdata->led_config[chan].led_current == 0) - return 0; - - led->led_current = pdata->led_config[chan].led_current; - led->max_current = pdata->led_config[chan].max_current; - led->chan_nr = pdata->led_config[chan].chan_nr; - - if (led->chan_nr >= LP5521_MAX_LEDS) { - dev_err(dev, "Use channel numbers between 0 and %d\n", - LP5521_MAX_LEDS - 1); - return -EINVAL; - } - - snprintf(name, sizeof(name), "%s:channel%d", client->name, chan); - led->cdev.brightness_set = lp5521_set_brightness; - led->cdev.name = name; - res = led_classdev_register(dev, &led->cdev); - if (res < 0) { - dev_err(dev, "couldn't register led on channel %d\n", chan); - return res; - } - - res = sysfs_create_group(&led->cdev.dev->kobj, - &lp5521_led_attribute_group); - if (res < 0) { - dev_err(dev, "couldn't register current attribute\n"); - led_classdev_unregister(&led->cdev); - return res; - } - return 0; -} - -static int lp5521_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct lp5521_chip *chip; - struct lp5521_platform_data *pdata; - int ret, i, led; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - i2c_set_clientdata(client, chip); - chip->client = client; - - pdata = client->dev.platform_data; - - if (!pdata) { - dev_err(&client->dev, "no platform data\n"); - ret = -EINVAL; - goto fail1; - } - - mutex_init(&chip->lock); - - chip->pdata = pdata; - - if (pdata->setup_resources) { - ret = pdata->setup_resources(); - if (ret < 0) - goto fail1; - } - - if (pdata->enable) { - pdata->enable(0); - usleep_range(1000, 10000); - pdata->enable(1); - usleep_range(1000, 10000); /* Spec says min 500us */ - } - - ret = lp5521_detect(client); - - if (ret) { - dev_err(&client->dev, "Chip not found\n"); - goto fail2; - } - - dev_info(&client->dev, "%s programmable led chip found\n", id->name); - - ret = lp5521_configure(client, lp5521_engine_group); - if (ret < 0) { - dev_err(&client->dev, "error configuring chip\n"); - goto fail2; - } - - /* Initialize leds */ - chip->num_channels = pdata->num_channels; - chip->num_leds = 0; - led = 0; - for (i = 0; i < pdata->num_channels; i++) { - /* Do not initialize channels that are not connected */ - if (pdata->led_config[i].led_current == 0) - continue; - - ret = lp5521_init_led(&chip->leds[led], client, i, pdata); - if (ret) { - dev_err(&client->dev, "error initializing leds\n"); - goto fail3; - } - chip->num_leds++; - - chip->leds[led].id = led; - /* Set initial LED current */ - lp5521_set_led_current(chip, led, - chip->leds[led].led_current); - - INIT_WORK(&(chip->leds[led].brightness_work), - lp5521_led_brightness_work); - - led++; - } - - ret = lp5521_register_sysfs(client); - if (ret) { - dev_err(&client->dev, "registering sysfs failed\n"); - goto fail3; - } - return ret; -fail3: - for (i = 0; i < chip->num_leds; i++) { - led_classdev_unregister(&chip->leds[i].cdev); - cancel_work_sync(&chip->leds[i].brightness_work); - } -fail2: - if (pdata->enable) - pdata->enable(0); - if (pdata->release_resources) - pdata->release_resources(); -fail1: - kfree(chip); - return ret; -} - -static int lp5521_remove(struct i2c_client *client) -{ - struct lp5521_chip *chip = i2c_get_clientdata(client); - int i; - - lp5521_unregister_sysfs(client); - - for (i = 0; i < chip->num_leds; i++) { - led_classdev_unregister(&chip->leds[i].cdev); - cancel_work_sync(&chip->leds[i].brightness_work); - } - - if (chip->pdata->enable) - chip->pdata->enable(0); - if (chip->pdata->release_resources) - chip->pdata->release_resources(); - kfree(chip); - return 0; -} - -static const struct i2c_device_id lp5521_id[] = { - { "lp5521", 0 }, /* Three channel chip */ - { } -}; -MODULE_DEVICE_TABLE(i2c, lp5521_id); - -static struct i2c_driver lp5521_driver = { - .driver = { - .name = "lp5521", - }, - .probe = lp5521_probe, - .remove = lp5521_remove, - .id_table = lp5521_id, -}; - -static int __init lp5521_init(void) -{ - int ret; - - ret = i2c_add_driver(&lp5521_driver); - - if (ret < 0) - printk(KERN_ALERT "Adding lp5521 driver failed\n"); - - return ret; -} - -static void __exit lp5521_exit(void) -{ - i2c_del_driver(&lp5521_driver); -} - -module_init(lp5521_init); -module_exit(lp5521_exit); - -MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo"); -MODULE_DESCRIPTION("LP5521 LED engine"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/leds/leds-lp5523.c b/trunk/drivers/leds/leds-lp5523.c deleted file mode 100644 index 1e11fcc08b28..000000000000 --- a/trunk/drivers/leds/leds-lp5523.c +++ /dev/null @@ -1,1065 +0,0 @@ -/* - * lp5523.c - LP5523 LED Driver - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Samu Onkalo - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LP5523_REG_ENABLE 0x00 -#define LP5523_REG_OP_MODE 0x01 -#define LP5523_REG_RATIOMETRIC_MSB 0x02 -#define LP5523_REG_RATIOMETRIC_LSB 0x03 -#define LP5523_REG_ENABLE_LEDS_MSB 0x04 -#define LP5523_REG_ENABLE_LEDS_LSB 0x05 -#define LP5523_REG_LED_CNTRL_BASE 0x06 -#define LP5523_REG_LED_PWM_BASE 0x16 -#define LP5523_REG_LED_CURRENT_BASE 0x26 -#define LP5523_REG_CONFIG 0x36 -#define LP5523_REG_CHANNEL1_PC 0x37 -#define LP5523_REG_CHANNEL2_PC 0x38 -#define LP5523_REG_CHANNEL3_PC 0x39 -#define LP5523_REG_STATUS 0x3a -#define LP5523_REG_GPO 0x3b -#define LP5523_REG_VARIABLE 0x3c -#define LP5523_REG_RESET 0x3d -#define LP5523_REG_TEMP_CTRL 0x3e -#define LP5523_REG_TEMP_READ 0x3f -#define LP5523_REG_TEMP_WRITE 0x40 -#define LP5523_REG_LED_TEST_CTRL 0x41 -#define LP5523_REG_LED_TEST_ADC 0x42 -#define LP5523_REG_ENG1_VARIABLE 0x45 -#define LP5523_REG_ENG2_VARIABLE 0x46 -#define LP5523_REG_ENG3_VARIABLE 0x47 -#define LP5523_REG_MASTER_FADER1 0x48 -#define LP5523_REG_MASTER_FADER2 0x49 -#define LP5523_REG_MASTER_FADER3 0x4a -#define LP5523_REG_CH1_PROG_START 0x4c -#define LP5523_REG_CH2_PROG_START 0x4d -#define LP5523_REG_CH3_PROG_START 0x4e -#define LP5523_REG_PROG_PAGE_SEL 0x4f -#define LP5523_REG_PROG_MEM 0x50 - -#define LP5523_CMD_LOAD 0x15 /* 00010101 */ -#define LP5523_CMD_RUN 0x2a /* 00101010 */ -#define LP5523_CMD_DISABLED 0x00 /* 00000000 */ - -#define LP5523_ENABLE 0x40 -#define LP5523_AUTO_INC 0x40 -#define LP5523_PWR_SAVE 0x20 -#define LP5523_PWM_PWR_SAVE 0x04 -#define LP5523_CP_1 0x08 -#define LP5523_CP_1_5 0x10 -#define LP5523_CP_AUTO 0x18 -#define LP5523_INT_CLK 0x01 -#define LP5523_AUTO_CLK 0x02 -#define LP5523_EN_LEDTEST 0x80 -#define LP5523_LEDTEST_DONE 0x80 - -#define LP5523_DEFAULT_CURRENT 50 /* microAmps */ -#define LP5523_PROGRAM_LENGTH 32 /* in bytes */ -#define LP5523_PROGRAM_PAGES 6 -#define LP5523_ADC_SHORTCIRC_LIM 80 - -#define LP5523_LEDS 9 -#define LP5523_ENGINES 3 - -#define LP5523_ENG_MASK_BASE 0x30 /* 00110000 */ - -#define LP5523_ENG_STATUS_MASK 0x07 /* 00000111 */ - -#define LP5523_IRQ_FLAGS IRQF_TRIGGER_FALLING - -#define LP5523_EXT_CLK_USED 0x08 - -#define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led))) -#define SHIFT_MASK(id) (((id) - 1) * 2) - -struct lp5523_engine { - const struct attribute_group *attributes; - int id; - u8 mode; - u8 prog_page; - u8 mux_page; - u16 led_mux; - u8 engine_mask; -}; - -struct lp5523_led { - int id; - u8 chan_nr; - u8 led_current; - u8 max_current; - struct led_classdev cdev; - struct work_struct brightness_work; - u8 brightness; -}; - -struct lp5523_chip { - struct mutex lock; /* Serialize control */ - struct i2c_client *client; - struct lp5523_engine engines[LP5523_ENGINES]; - struct lp5523_led leds[LP5523_LEDS]; - struct lp5523_platform_data *pdata; - u8 num_channels; - u8 num_leds; -}; - -#define cdev_to_led(c) container_of(c, struct lp5523_led, cdev) - -static struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine) -{ - return container_of(engine, struct lp5523_chip, - engines[engine->id - 1]); -} - -static struct lp5523_chip *led_to_lp5523(struct lp5523_led *led) -{ - return container_of(led, struct lp5523_chip, - leds[led->id]); -} - -static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode); -static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode); -static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern); - -static void lp5523_led_brightness_work(struct work_struct *work); - -static int lp5523_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -static int lp5523_read(struct i2c_client *client, u8 reg, u8 *buf) -{ - s32 ret = i2c_smbus_read_byte_data(client, reg); - - if (ret < 0) - return -EIO; - - *buf = ret; - return 0; -} - -static int lp5523_detect(struct i2c_client *client) -{ - int ret; - u8 buf; - - ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40); - if (ret) - return ret; - ret = lp5523_read(client, LP5523_REG_ENABLE, &buf); - if (ret) - return ret; - if (buf == 0x40) - return 0; - else - return -ENODEV; -} - -static int lp5523_configure(struct i2c_client *client) -{ - struct lp5523_chip *chip = i2c_get_clientdata(client); - int ret = 0; - u8 status; - - /* one pattern per engine setting led mux start and stop addresses */ - u8 pattern[][LP5523_PROGRAM_LENGTH] = { - { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0}, - { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0}, - { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0}, - }; - - lp5523_write(client, LP5523_REG_RESET, 0xff); - - usleep_range(10000, 100000); - - ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE); - /* Chip startup time after reset is 500 us */ - usleep_range(1000, 10000); - - ret |= lp5523_write(client, LP5523_REG_CONFIG, - LP5523_AUTO_INC | LP5523_PWR_SAVE | - LP5523_CP_AUTO | LP5523_AUTO_CLK | - LP5523_PWM_PWR_SAVE); - - /* turn on all leds */ - ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_MSB, 0x01); - ret |= lp5523_write(client, LP5523_REG_ENABLE_LEDS_LSB, 0xff); - - /* hardcode 32 bytes of memory for each engine from program memory */ - ret |= lp5523_write(client, LP5523_REG_CH1_PROG_START, 0x00); - ret |= lp5523_write(client, LP5523_REG_CH2_PROG_START, 0x10); - ret |= lp5523_write(client, LP5523_REG_CH3_PROG_START, 0x20); - - /* write led mux address space for each channel */ - ret |= lp5523_load_program(&chip->engines[0], pattern[0]); - ret |= lp5523_load_program(&chip->engines[1], pattern[1]); - ret |= lp5523_load_program(&chip->engines[2], pattern[2]); - - if (ret) { - dev_err(&client->dev, "could not load mux programs\n"); - return -1; - } - - /* set all engines exec state and mode to run 00101010 */ - ret |= lp5523_write(client, LP5523_REG_ENABLE, - (LP5523_CMD_RUN | LP5523_ENABLE)); - - ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_RUN); - - if (ret) { - dev_err(&client->dev, "could not start mux programs\n"); - return -1; - } - - /* Wait 3ms and check the engine status */ - usleep_range(3000, 20000); - lp5523_read(client, LP5523_REG_STATUS, &status); - status &= LP5523_ENG_STATUS_MASK; - - if (status == LP5523_ENG_STATUS_MASK) { - dev_dbg(&client->dev, "all engines configured\n"); - } else { - dev_info(&client->dev, "status == %x\n", status); - dev_err(&client->dev, "cound not configure LED engine\n"); - return -1; - } - - dev_info(&client->dev, "disabling engines\n"); - - ret |= lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED); - - return ret; -} - -static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - int ret; - u8 engine_state; - - ret = lp5523_read(client, LP5523_REG_OP_MODE, &engine_state); - if (ret) - goto fail; - - engine_state &= ~(engine->engine_mask); - - /* set mode only for this engine */ - mode &= engine->engine_mask; - - engine_state |= mode; - - ret |= lp5523_write(client, LP5523_REG_OP_MODE, engine_state); -fail: - return ret; -} - -static int lp5523_load_mux(struct lp5523_engine *engine, u16 mux) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - int ret = 0; - - ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); - - ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL, engine->mux_page); - ret |= lp5523_write(client, LP5523_REG_PROG_MEM, - (u8)(mux >> 8)); - ret |= lp5523_write(client, LP5523_REG_PROG_MEM + 1, (u8)(mux)); - engine->led_mux = mux; - - return ret; -} - -static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - - int ret = 0; - - ret |= lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); - - ret |= lp5523_write(client, LP5523_REG_PROG_PAGE_SEL, - engine->prog_page); - ret |= i2c_smbus_write_i2c_block_data(client, LP5523_REG_PROG_MEM, - LP5523_PROGRAM_LENGTH, pattern); - - return ret; -} - -static int lp5523_run_program(struct lp5523_engine *engine) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - int ret; - - ret = lp5523_write(client, LP5523_REG_ENABLE, - LP5523_CMD_RUN | LP5523_ENABLE); - if (ret) - goto fail; - - ret = lp5523_set_engine_mode(engine, LP5523_CMD_RUN); -fail: - return ret; -} - -static int lp5523_mux_parse(const char *buf, u16 *mux, size_t len) -{ - int i; - u16 tmp_mux = 0; - len = len < LP5523_LEDS ? len : LP5523_LEDS; - for (i = 0; i < len; i++) { - switch (buf[i]) { - case '1': - tmp_mux |= (1 << i); - break; - case '0': - break; - case '\n': - i = len; - break; - default: - return -1; - } - } - *mux = tmp_mux; - - return 0; -} - -static void lp5523_mux_to_array(u16 led_mux, char *array) -{ - int i, pos = 0; - for (i = 0; i < LP5523_LEDS; i++) - pos += sprintf(array + pos, "%x", LED_ACTIVE(led_mux, i)); - - array[pos] = '\0'; -} - -/*--------------------------------------------------------------*/ -/* Sysfs interface */ -/*--------------------------------------------------------------*/ - -static ssize_t show_engine_leds(struct device *dev, - struct device_attribute *attr, - char *buf, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - char mux[LP5523_LEDS + 1]; - - lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux); - - return sprintf(buf, "%s\n", mux); -} - -#define show_leds(nr) \ -static ssize_t show_engine##nr##_leds(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_engine_leds(dev, attr, buf, nr); \ -} -show_leds(1) -show_leds(2) -show_leds(3) - -static ssize_t store_engine_leds(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - u16 mux = 0; - - if (lp5523_mux_parse(buf, &mux, len)) - return -EINVAL; - - if (lp5523_load_mux(&chip->engines[nr - 1], mux)) - return -EINVAL; - - return len; -} - -#define store_leds(nr) \ -static ssize_t store_engine##nr##_leds(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_leds(dev, attr, buf, len, nr); \ -} -store_leds(1) -store_leds(2) -store_leds(3) - -static ssize_t lp5523_selftest(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - int i, ret, pos = 0; - int led = 0; - u8 status, adc, vdd; - - mutex_lock(&chip->lock); - - ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); - if (ret < 0) - goto fail; - - /* Check that ext clock is really in use if requested */ - if ((chip->pdata) && (chip->pdata->clock_mode == LP5523_CLOCK_EXT)) - if ((status & LP5523_EXT_CLK_USED) == 0) - goto fail; - - /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */ - lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL, - LP5523_EN_LEDTEST | 16); - usleep_range(3000, 10000); - ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); - if (!(status & LP5523_LEDTEST_DONE)) - usleep_range(3000, 10000); - - ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd); - vdd--; /* There may be some fluctuation in measurement */ - - for (i = 0; i < LP5523_LEDS; i++) { - /* Skip non-existing channels */ - if (chip->pdata->led_config[i].led_current == 0) - continue; - - /* Set default current */ - lp5523_write(chip->client, - LP5523_REG_LED_CURRENT_BASE + i, - chip->pdata->led_config[i].led_current); - - lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff); - /* let current stabilize 2ms before measurements start */ - usleep_range(2000, 10000); - lp5523_write(chip->client, - LP5523_REG_LED_TEST_CTRL, - LP5523_EN_LEDTEST | i); - /* ledtest takes 2.7ms */ - usleep_range(3000, 10000); - ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status); - if (!(status & LP5523_LEDTEST_DONE)) - usleep_range(3000, 10000); - ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc); - - if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM) - pos += sprintf(buf + pos, "LED %d FAIL\n", i); - - lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0x00); - - /* Restore current */ - lp5523_write(chip->client, - LP5523_REG_LED_CURRENT_BASE + i, - chip->leds[led].led_current); - led++; - } - if (pos == 0) - pos = sprintf(buf, "OK\n"); - goto release_lock; -fail: - pos = sprintf(buf, "FAIL\n"); - -release_lock: - mutex_unlock(&chip->lock); - - return pos; -} - -static void lp5523_set_brightness(struct led_classdev *cdev, - enum led_brightness brightness) -{ - struct lp5523_led *led = cdev_to_led(cdev); - - led->brightness = (u8)brightness; - - schedule_work(&led->brightness_work); -} - -static void lp5523_led_brightness_work(struct work_struct *work) -{ - struct lp5523_led *led = container_of(work, - struct lp5523_led, - brightness_work); - struct lp5523_chip *chip = led_to_lp5523(led); - struct i2c_client *client = chip->client; - - mutex_lock(&chip->lock); - - lp5523_write(client, LP5523_REG_LED_PWM_BASE + led->chan_nr, - led->brightness); - - mutex_unlock(&chip->lock); -} - -static int lp5523_do_store_load(struct lp5523_engine *engine, - const char *buf, size_t len) -{ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - int ret, nrchars, offset = 0, i = 0; - char c[3]; - unsigned cmd; - u8 pattern[LP5523_PROGRAM_LENGTH] = {0}; - - while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) { - /* separate sscanfs because length is working only for %s */ - ret = sscanf(buf + offset, "%2s%n ", c, &nrchars); - ret = sscanf(c, "%2x", &cmd); - if (ret != 1) - goto fail; - pattern[i] = (u8)cmd; - - offset += nrchars; - i++; - } - - /* Each instruction is 16bit long. Check that length is even */ - if (i % 2) - goto fail; - - mutex_lock(&chip->lock); - - ret = lp5523_load_program(engine, pattern); - mutex_unlock(&chip->lock); - - if (ret) { - dev_err(&client->dev, "failed loading pattern\n"); - return ret; - } - - return len; -fail: - dev_err(&client->dev, "wrong pattern format\n"); - return -EINVAL; -} - -static ssize_t store_engine_load(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - return lp5523_do_store_load(&chip->engines[nr - 1], buf, len); -} - -#define store_load(nr) \ -static ssize_t store_engine##nr##_load(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_load(dev, attr, buf, len, nr); \ -} -store_load(1) -store_load(2) -store_load(3) - -static ssize_t show_engine_mode(struct device *dev, - struct device_attribute *attr, - char *buf, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - switch (chip->engines[nr - 1].mode) { - case LP5523_CMD_RUN: - return sprintf(buf, "run\n"); - case LP5523_CMD_LOAD: - return sprintf(buf, "load\n"); - case LP5523_CMD_DISABLED: - return sprintf(buf, "disabled\n"); - default: - return sprintf(buf, "disabled\n"); - } -} - -#define show_mode(nr) \ -static ssize_t show_engine##nr##_mode(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - return show_engine_mode(dev, attr, buf, nr); \ -} -show_mode(1) -show_mode(2) -show_mode(3) - -static ssize_t store_engine_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len, int nr) -{ - struct i2c_client *client = to_i2c_client(dev); - struct lp5523_chip *chip = i2c_get_clientdata(client); - struct lp5523_engine *engine = &chip->engines[nr - 1]; - mutex_lock(&chip->lock); - - if (!strncmp(buf, "run", 3)) - lp5523_set_mode(engine, LP5523_CMD_RUN); - else if (!strncmp(buf, "load", 4)) - lp5523_set_mode(engine, LP5523_CMD_LOAD); - else if (!strncmp(buf, "disabled", 8)) - lp5523_set_mode(engine, LP5523_CMD_DISABLED); - - mutex_unlock(&chip->lock); - return len; -} - -#define store_mode(nr) \ -static ssize_t store_engine##nr##_mode(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t len) \ -{ \ - return store_engine_mode(dev, attr, buf, len, nr); \ -} -store_mode(1) -store_mode(2) -store_mode(3) - -static ssize_t show_max_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5523_led *led = cdev_to_led(led_cdev); - - return sprintf(buf, "%d\n", led->max_current); -} - -static ssize_t show_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5523_led *led = cdev_to_led(led_cdev); - - return sprintf(buf, "%d\n", led->led_current); -} - -static ssize_t store_current(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) -{ - struct led_classdev *led_cdev = dev_get_drvdata(dev); - struct lp5523_led *led = cdev_to_led(led_cdev); - struct lp5523_chip *chip = led_to_lp5523(led); - ssize_t ret; - unsigned long curr; - - if (strict_strtoul(buf, 0, &curr)) - return -EINVAL; - - if (curr > led->max_current) - return -EINVAL; - - mutex_lock(&chip->lock); - ret = lp5523_write(chip->client, - LP5523_REG_LED_CURRENT_BASE + led->chan_nr, - (u8)curr); - mutex_unlock(&chip->lock); - - if (ret < 0) - return ret; - - led->led_current = (u8)curr; - - return len; -} - -/* led class device attributes */ -static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); -static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); - -static struct attribute *lp5523_led_attributes[] = { - &dev_attr_led_current.attr, - &dev_attr_max_current.attr, - NULL, -}; - -static struct attribute_group lp5523_led_attribute_group = { - .attrs = lp5523_led_attributes -}; - -/* device attributes */ -static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, - show_engine1_mode, store_engine1_mode); -static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, - show_engine2_mode, store_engine2_mode); -static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, - show_engine3_mode, store_engine3_mode); -static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUGO, - show_engine1_leds, store_engine1_leds); -static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUGO, - show_engine2_leds, store_engine2_leds); -static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUGO, - show_engine3_leds, store_engine3_leds); -static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); -static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); -static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); -static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL); - -static struct attribute *lp5523_attributes[] = { - &dev_attr_engine1_mode.attr, - &dev_attr_engine2_mode.attr, - &dev_attr_engine3_mode.attr, - &dev_attr_selftest.attr, - NULL -}; - -static struct attribute *lp5523_engine1_attributes[] = { - &dev_attr_engine1_load.attr, - &dev_attr_engine1_leds.attr, - NULL -}; - -static struct attribute *lp5523_engine2_attributes[] = { - &dev_attr_engine2_load.attr, - &dev_attr_engine2_leds.attr, - NULL -}; - -static struct attribute *lp5523_engine3_attributes[] = { - &dev_attr_engine3_load.attr, - &dev_attr_engine3_leds.attr, - NULL -}; - -static const struct attribute_group lp5523_group = { - .attrs = lp5523_attributes, -}; - -static const struct attribute_group lp5523_engine_group[] = { - {.attrs = lp5523_engine1_attributes }, - {.attrs = lp5523_engine2_attributes }, - {.attrs = lp5523_engine3_attributes }, -}; - -static int lp5523_register_sysfs(struct i2c_client *client) -{ - struct device *dev = &client->dev; - int ret; - - ret = sysfs_create_group(&dev->kobj, &lp5523_group); - if (ret < 0) - return ret; - - return 0; -} - -static void lp5523_unregister_sysfs(struct i2c_client *client) -{ - struct lp5523_chip *chip = i2c_get_clientdata(client); - struct device *dev = &client->dev; - int i; - - sysfs_remove_group(&dev->kobj, &lp5523_group); - - for (i = 0; i < ARRAY_SIZE(chip->engines); i++) - if (chip->engines[i].mode == LP5523_CMD_LOAD) - sysfs_remove_group(&dev->kobj, &lp5523_engine_group[i]); - - for (i = 0; i < chip->num_leds; i++) - sysfs_remove_group(&chip->leds[i].cdev.dev->kobj, - &lp5523_led_attribute_group); -} - -/*--------------------------------------------------------------*/ -/* Set chip operating mode */ -/*--------------------------------------------------------------*/ -static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode) -{ - /* engine to chip */ - struct lp5523_chip *chip = engine_to_lp5523(engine); - struct i2c_client *client = chip->client; - struct device *dev = &client->dev; - int ret = 0; - - /* if in that mode already do nothing, except for run */ - if (mode == engine->mode && mode != LP5523_CMD_RUN) - return 0; - - if (mode == LP5523_CMD_RUN) { - ret = lp5523_run_program(engine); - } else if (mode == LP5523_CMD_LOAD) { - lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); - lp5523_set_engine_mode(engine, LP5523_CMD_LOAD); - - ret = sysfs_create_group(&dev->kobj, engine->attributes); - if (ret) - return ret; - } else if (mode == LP5523_CMD_DISABLED) { - lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED); - } - - /* remove load attribute from sysfs if not in load mode */ - if (engine->mode == LP5523_CMD_LOAD && mode != LP5523_CMD_LOAD) - sysfs_remove_group(&dev->kobj, engine->attributes); - - engine->mode = mode; - - return ret; -} - -/*--------------------------------------------------------------*/ -/* Probe, Attach, Remove */ -/*--------------------------------------------------------------*/ -static int __init lp5523_init_engine(struct lp5523_engine *engine, int id) -{ - if (id < 1 || id > LP5523_ENGINES) - return -1; - engine->id = id; - engine->engine_mask = LP5523_ENG_MASK_BASE >> SHIFT_MASK(id); - engine->prog_page = id - 1; - engine->mux_page = id + 2; - engine->attributes = &lp5523_engine_group[id - 1]; - - return 0; -} - -static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev, - int chan, struct lp5523_platform_data *pdata) -{ - char name[32]; - int res; - - if (chan >= LP5523_LEDS) - return -EINVAL; - - if (pdata->led_config[chan].led_current) { - led->led_current = pdata->led_config[chan].led_current; - led->max_current = pdata->led_config[chan].max_current; - led->chan_nr = pdata->led_config[chan].chan_nr; - - if (led->chan_nr >= LP5523_LEDS) { - dev_err(dev, "Use channel numbers between 0 and %d\n", - LP5523_LEDS - 1); - return -EINVAL; - } - - snprintf(name, 32, "lp5523:channel%d", chan); - - led->cdev.name = name; - led->cdev.brightness_set = lp5523_set_brightness; - res = led_classdev_register(dev, &led->cdev); - if (res < 0) { - dev_err(dev, "couldn't register led on channel %d\n", - chan); - return res; - } - res = sysfs_create_group(&led->cdev.dev->kobj, - &lp5523_led_attribute_group); - if (res < 0) { - dev_err(dev, "couldn't register current attribute\n"); - led_classdev_unregister(&led->cdev); - return res; - } - } else { - led->led_current = 0; - } - return 0; -} - -static struct i2c_driver lp5523_driver; - -static int lp5523_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct lp5523_chip *chip; - struct lp5523_platform_data *pdata; - int ret, i, led; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - i2c_set_clientdata(client, chip); - chip->client = client; - - pdata = client->dev.platform_data; - - if (!pdata) { - dev_err(&client->dev, "no platform data\n"); - ret = -EINVAL; - goto fail1; - } - - mutex_init(&chip->lock); - - chip->pdata = pdata; - - if (pdata->setup_resources) { - ret = pdata->setup_resources(); - if (ret < 0) - goto fail1; - } - - if (pdata->enable) { - pdata->enable(0); - usleep_range(1000, 10000); - pdata->enable(1); - usleep_range(1000, 10000); /* Spec says min 500us */ - } - - ret = lp5523_detect(client); - if (ret) - goto fail2; - - dev_info(&client->dev, "LP5523 Programmable led chip found\n"); - - /* Initialize engines */ - for (i = 0; i < ARRAY_SIZE(chip->engines); i++) { - ret = lp5523_init_engine(&chip->engines[i], i + 1); - if (ret) { - dev_err(&client->dev, "error initializing engine\n"); - goto fail2; - } - } - ret = lp5523_configure(client); - if (ret < 0) { - dev_err(&client->dev, "error configuring chip\n"); - goto fail2; - } - - /* Initialize leds */ - chip->num_channels = pdata->num_channels; - chip->num_leds = 0; - led = 0; - for (i = 0; i < pdata->num_channels; i++) { - /* Do not initialize channels that are not connected */ - if (pdata->led_config[i].led_current == 0) - continue; - - ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata); - if (ret) { - dev_err(&client->dev, "error initializing leds\n"); - goto fail3; - } - chip->num_leds++; - - chip->leds[led].id = led; - /* Set LED current */ - lp5523_write(client, - LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, - chip->leds[led].led_current); - - INIT_WORK(&(chip->leds[led].brightness_work), - lp5523_led_brightness_work); - - led++; - } - - ret = lp5523_register_sysfs(client); - if (ret) { - dev_err(&client->dev, "registering sysfs failed\n"); - goto fail3; - } - return ret; -fail3: - for (i = 0; i < chip->num_leds; i++) { - led_classdev_unregister(&chip->leds[i].cdev); - cancel_work_sync(&chip->leds[i].brightness_work); - } -fail2: - if (pdata->enable) - pdata->enable(0); - if (pdata->release_resources) - pdata->release_resources(); -fail1: - kfree(chip); - return ret; -} - -static int lp5523_remove(struct i2c_client *client) -{ - struct lp5523_chip *chip = i2c_get_clientdata(client); - int i; - - lp5523_unregister_sysfs(client); - - for (i = 0; i < chip->num_leds; i++) { - led_classdev_unregister(&chip->leds[i].cdev); - cancel_work_sync(&chip->leds[i].brightness_work); - } - - if (chip->pdata->enable) - chip->pdata->enable(0); - if (chip->pdata->release_resources) - chip->pdata->release_resources(); - kfree(chip); - return 0; -} - -static const struct i2c_device_id lp5523_id[] = { - { "lp5523", 0 }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, lp5523_id); - -static struct i2c_driver lp5523_driver = { - .driver = { - .name = "lp5523", - }, - .probe = lp5523_probe, - .remove = lp5523_remove, - .id_table = lp5523_id, -}; - -static int __init lp5523_init(void) -{ - int ret; - - ret = i2c_add_driver(&lp5523_driver); - - if (ret < 0) - printk(KERN_ALERT "Adding lp5523 driver failed\n"); - - return ret; -} - -static void __exit lp5523_exit(void) -{ - i2c_del_driver(&lp5523_driver); -} - -module_init(lp5523_init); -module_exit(lp5523_exit); - -MODULE_AUTHOR("Mathias Nyman "); -MODULE_DESCRIPTION("LP5523 LED engine"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-net5501.c b/trunk/drivers/leds/leds-net5501.c index 1739557a9038..3063f591f0dc 100644 --- a/trunk/drivers/leds/leds-net5501.c +++ b/trunk/drivers/leds/leds-net5501.c @@ -92,5 +92,3 @@ static int __init soekris_init(void) } arch_initcall(soekris_init); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/ledtrig-timer.c b/trunk/drivers/leds/ledtrig-timer.c index b09bcbeade9c..82b77bd482ff 100644 --- a/trunk/drivers/leds/ledtrig-timer.c +++ b/trunk/drivers/leds/ledtrig-timer.c @@ -12,25 +12,73 @@ */ #include +#include #include #include +#include +#include #include +#include +#include #include #include +#include #include "leds.h" +struct timer_trig_data { + int brightness_on; /* LED brightness during "on" period. + * (LED_OFF < brightness_on <= LED_FULL) + */ + unsigned long delay_on; /* milliseconds on */ + unsigned long delay_off; /* milliseconds off */ + struct timer_list timer; +}; + +static void led_timer_function(unsigned long data) +{ + struct led_classdev *led_cdev = (struct led_classdev *) data; + struct timer_trig_data *timer_data = led_cdev->trigger_data; + unsigned long brightness; + unsigned long delay; + + if (!timer_data->delay_on || !timer_data->delay_off) { + led_set_brightness(led_cdev, LED_OFF); + return; + } + + brightness = led_get_brightness(led_cdev); + if (!brightness) { + /* Time to switch the LED on. */ + brightness = timer_data->brightness_on; + delay = timer_data->delay_on; + } else { + /* Store the current brightness value to be able + * to restore it when the delay_off period is over. + */ + timer_data->brightness_on = brightness; + brightness = LED_OFF; + delay = timer_data->delay_off; + } + + led_set_brightness(led_cdev, brightness); + + mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); +} + static ssize_t led_delay_on_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; - return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); + return sprintf(buf, "%lu\n", timer_data->delay_on); } static ssize_t led_delay_on_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; int ret = -EINVAL; char *after; unsigned long state = simple_strtoul(buf, &after, 10); @@ -40,7 +88,21 @@ static ssize_t led_delay_on_store(struct device *dev, count++; if (count == size) { - led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); + if (timer_data->delay_on != state) { + /* the new value differs from the previous */ + timer_data->delay_on = state; + + /* deactivate previous settings */ + del_timer_sync(&timer_data->timer); + + /* try to activate hardware acceleration, if any */ + if (!led_cdev->blink_set || + led_cdev->blink_set(led_cdev, + &timer_data->delay_on, &timer_data->delay_off)) { + /* no hardware acceleration, blink via timer */ + mod_timer(&timer_data->timer, jiffies + 1); + } + } ret = count; } @@ -51,14 +113,16 @@ static ssize_t led_delay_off_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; - return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); + return sprintf(buf, "%lu\n", timer_data->delay_off); } static ssize_t led_delay_off_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct timer_trig_data *timer_data = led_cdev->trigger_data; int ret = -EINVAL; char *after; unsigned long state = simple_strtoul(buf, &after, 10); @@ -68,7 +132,21 @@ static ssize_t led_delay_off_store(struct device *dev, count++; if (count == size) { - led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); + if (timer_data->delay_off != state) { + /* the new value differs from the previous */ + timer_data->delay_off = state; + + /* deactivate previous settings */ + del_timer_sync(&timer_data->timer); + + /* try to activate hardware acceleration, if any */ + if (!led_cdev->blink_set || + led_cdev->blink_set(led_cdev, + &timer_data->delay_on, &timer_data->delay_off)) { + /* no hardware acceleration, blink via timer */ + mod_timer(&timer_data->timer, jiffies + 1); + } + } ret = count; } @@ -80,34 +158,60 @@ static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); static void timer_trig_activate(struct led_classdev *led_cdev) { + struct timer_trig_data *timer_data; int rc; - led_cdev->trigger_data = NULL; + timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); + if (!timer_data) + return; + + timer_data->brightness_on = led_get_brightness(led_cdev); + if (timer_data->brightness_on == LED_OFF) + timer_data->brightness_on = led_cdev->max_brightness; + led_cdev->trigger_data = timer_data; + + init_timer(&timer_data->timer); + timer_data->timer.function = led_timer_function; + timer_data->timer.data = (unsigned long) led_cdev; rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); if (rc) - return; + goto err_out; rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); if (rc) goto err_out_delayon; - led_cdev->trigger_data = (void *)1; + /* If there is hardware support for blinking, start one + * user friendly blink rate chosen by the driver. + */ + if (led_cdev->blink_set) + led_cdev->blink_set(led_cdev, + &timer_data->delay_on, &timer_data->delay_off); return; err_out_delayon: device_remove_file(led_cdev->dev, &dev_attr_delay_on); +err_out: + led_cdev->trigger_data = NULL; + kfree(timer_data); } static void timer_trig_deactivate(struct led_classdev *led_cdev) { - if (led_cdev->trigger_data) { + struct timer_trig_data *timer_data = led_cdev->trigger_data; + unsigned long on = 0, off = 0; + + if (timer_data) { device_remove_file(led_cdev->dev, &dev_attr_delay_on); device_remove_file(led_cdev->dev, &dev_attr_delay_off); + del_timer_sync(&timer_data->timer); + kfree(timer_data); } - /* Stop blinking */ - led_brightness_set(led_cdev, LED_OFF); + /* If there is hardware support for blinking, stop it */ + if (led_cdev->blink_set) + led_cdev->blink_set(led_cdev, &on, &off); } static struct led_trigger timer_led_trigger = { diff --git a/trunk/drivers/macintosh/adb-iop.c b/trunk/drivers/macintosh/adb-iop.c index f5f4da3d0b67..444696625171 100644 --- a/trunk/drivers/macintosh/adb-iop.c +++ b/trunk/drivers/macintosh/adb-iop.c @@ -80,7 +80,7 @@ static void adb_iop_end_req(struct adb_request *req, int state) static void adb_iop_complete(struct iop_msg *msg) { struct adb_request *req; - unsigned long flags; + uint flags; local_irq_save(flags); @@ -103,7 +103,7 @@ static void adb_iop_listen(struct iop_msg *msg) { struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message; struct adb_request *req; - unsigned long flags; + uint flags; #ifdef DEBUG_ADB_IOP int i; #endif diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 324a3663fcda..4e957f3140a8 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -706,7 +706,7 @@ static struct mdk_personality *find_pers(int level, char *clevel) /* return the offset of the super block in 512byte sectors */ static inline sector_t calc_dev_sboffset(struct block_device *bdev) { - sector_t num_sectors = i_size_read(bdev->bd_inode) / 512; + sector_t num_sectors = bdev->bd_inode->i_size / 512; return MD_NEW_SIZE_SECTORS(num_sectors); } @@ -1386,7 +1386,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) */ switch(minor_version) { case 0: - sb_start = i_size_read(rdev->bdev->bd_inode) >> 9; + sb_start = rdev->bdev->bd_inode->i_size >> 9; sb_start -= 8*2; sb_start &= ~(sector_t)(4*2-1); break; @@ -1472,7 +1472,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) ret = 0; } if (minor_version) - rdev->sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - + rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) - le64_to_cpu(sb->data_offset); else rdev->sectors = rdev->sb_start; @@ -1680,7 +1680,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) return 0; /* component must fit device */ if (rdev->sb_start < rdev->data_offset) { /* minor versions 1 and 2; superblock before data */ - max_sectors = i_size_read(rdev->bdev->bd_inode) >> 9; + max_sectors = rdev->bdev->bd_inode->i_size >> 9; max_sectors -= rdev->data_offset; if (!num_sectors || num_sectors > max_sectors) num_sectors = max_sectors; @@ -1690,7 +1690,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) } else { /* minor version 0; superblock after data */ sector_t sb_start; - sb_start = (i_size_read(rdev->bdev->bd_inode) >> 9) - 8*2; + sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2; sb_start &= ~(sector_t)(4*2 - 1); max_sectors = rdev->sectors + sb_start - rdev->sb_start; if (!num_sectors || num_sectors > max_sectors) @@ -2584,7 +2584,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) if (!sectors) return -EBUSY; } else if (!sectors) - sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - + sectors = (rdev->bdev->bd_inode->i_size >> 9) - rdev->data_offset; } if (sectors < my_mddev->dev_sectors) @@ -2797,7 +2797,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi kobject_init(&rdev->kobj, &rdev_ktype); - size = i_size_read(rdev->bdev->bd_inode) >> BLOCK_SIZE_BITS; + size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; if (!size) { printk(KERN_WARNING "md: %s has zero or unknown size, marking faulty!\n", @@ -5235,8 +5235,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) if (!mddev->persistent) { printk(KERN_INFO "md: nonpersistent superblock ...\n"); - rdev->sb_start = i_size_read(rdev->bdev->bd_inode) / 512; - } else + rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; + } else rdev->sb_start = calc_dev_sboffset(rdev->bdev); rdev->sectors = rdev->sb_start; @@ -5306,7 +5306,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) if (mddev->persistent) rdev->sb_start = calc_dev_sboffset(rdev->bdev); else - rdev->sb_start = i_size_read(rdev->bdev->bd_inode) / 512; + rdev->sb_start = rdev->bdev->bd_inode->i_size / 512; rdev->sectors = rdev->sb_start; diff --git a/trunk/drivers/misc/apds9802als.c b/trunk/drivers/misc/apds9802als.c index 0ed09358027e..f9b91ba8900c 100644 --- a/trunk/drivers/misc/apds9802als.c +++ b/trunk/drivers/misc/apds9802als.c @@ -123,7 +123,7 @@ static ssize_t als_sensing_range_store(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); struct als_data *data = i2c_get_clientdata(client); - int ret_val; + unsigned int ret_val; unsigned long val; if (strict_strtoul(buf, 10, &val)) diff --git a/trunk/drivers/misc/bh1770glc.c b/trunk/drivers/misc/bh1770glc.c index d79a972f2c79..cee632e645e1 100644 --- a/trunk/drivers/misc/bh1770glc.c +++ b/trunk/drivers/misc/bh1770glc.c @@ -649,7 +649,7 @@ static ssize_t bh1770_power_state_store(struct device *dev, { struct bh1770_chip *chip = dev_get_drvdata(dev); unsigned long value; - ssize_t ret; + size_t ret; if (strict_strtoul(buf, 0, &value)) return -EINVAL; @@ -659,12 +659,8 @@ static ssize_t bh1770_power_state_store(struct device *dev, pm_runtime_get_sync(dev); ret = bh1770_lux_rate(chip, chip->lux_rate_index); - if (ret < 0) { - pm_runtime_put(dev); - goto leave; - } + ret |= bh1770_lux_interrupt_control(chip, BH1770_ENABLE); - ret = bh1770_lux_interrupt_control(chip, BH1770_ENABLE); if (ret < 0) { pm_runtime_put(dev); goto leave; diff --git a/trunk/drivers/misc/isl29020.c b/trunk/drivers/misc/isl29020.c index ca47e6285075..34fe835921c4 100644 --- a/trunk/drivers/misc/isl29020.c +++ b/trunk/drivers/misc/isl29020.c @@ -87,7 +87,7 @@ static ssize_t als_sensing_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); - int ret_val; + unsigned int ret_val; unsigned long val; if (strict_strtoul(buf, 10, &val)) @@ -106,8 +106,6 @@ static ssize_t als_sensing_range_store(struct device *dev, val = 4; ret_val = i2c_smbus_read_byte_data(client, 0x00); - if (ret_val < 0) - return ret_val; ret_val &= 0xFC; /*reset the bit before setting them */ ret_val |= val - 1; diff --git a/trunk/drivers/net/3c507.c b/trunk/drivers/net/3c507.c index 475a66d95b34..ea9b7a098c9b 100644 --- a/trunk/drivers/net/3c507.c +++ b/trunk/drivers/net/3c507.c @@ -201,7 +201,7 @@ struct net_local { #define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */ #define RX_BUF_END (dev->mem_end - dev->mem_start) -#define TX_TIMEOUT (HZ/20) +#define TX_TIMEOUT 5 /* That's it: only 86 bytes to set up the beast, including every extra diff --git a/trunk/drivers/net/3c515.c b/trunk/drivers/net/3c515.c index d2bb4b254c57..cdf7226a7c43 100644 --- a/trunk/drivers/net/3c515.c +++ b/trunk/drivers/net/3c515.c @@ -98,7 +98,7 @@ static int rx_nocopy, rx_copy, queued_packet; #define WAIT_TX_AVAIL 200 /* Operational parameter that usually are not changed. */ -#define TX_TIMEOUT ((4*HZ)/10) /* Time in jiffies before concluding Tx hung */ +#define TX_TIMEOUT 40 /* Time in jiffies before concluding Tx hung */ /* The size here is somewhat misleading: the Corkscrew also uses the ISA aliased registers at +0x400. diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index 0a92436f0538..e1da258bbfb7 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -699,8 +699,7 @@ DEFINE_WINDOW_IO(32) #define DEVICE_PCI(dev) NULL #endif -#define VORTEX_PCI(vp) \ - ((struct pci_dev *) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)) +#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL) #ifdef CONFIG_EISA #define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL) @@ -708,8 +707,7 @@ DEFINE_WINDOW_IO(32) #define DEVICE_EISA(dev) NULL #endif -#define VORTEX_EISA(vp) \ - ((struct eisa_device *) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)) +#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL) /* The action to take with a media selection timer tick. Note that we deviate from the 3Com order by checking 10base2 before AUI. diff --git a/trunk/drivers/net/8139cp.c b/trunk/drivers/net/8139cp.c index dd16e83933a2..ac422cd332ea 100644 --- a/trunk/drivers/net/8139cp.c +++ b/trunk/drivers/net/8139cp.c @@ -490,11 +490,13 @@ static inline unsigned int cp_rx_csum_ok (u32 status) { unsigned int protocol = (status >> 16) & 0x3; - if (((protocol == RxProtoTCP) && !(status & TCPFail)) || - ((protocol == RxProtoUDP) && !(status & UDPFail))) + if (likely((protocol == RxProtoTCP) && (!(status & TCPFail)))) return 1; - else - return 0; + else if ((protocol == RxProtoUDP) && (!(status & UDPFail))) + return 1; + else if ((protocol == RxProtoIP) && (!(status & IPFail))) + return 1; + return 0; } static int cp_rx_poll(struct napi_struct *napi, int budget) diff --git a/trunk/drivers/net/82596.c b/trunk/drivers/net/82596.c index be1f1970c842..e2c9c5b949f9 100644 --- a/trunk/drivers/net/82596.c +++ b/trunk/drivers/net/82596.c @@ -191,7 +191,7 @@ enum commands { #define RX_SUSPEND 0x0030 #define RX_ABORT 0x0040 -#define TX_TIMEOUT (HZ/20) +#define TX_TIMEOUT 5 struct i596_reg { diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index a11dc735752c..f6668cdaac85 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -1533,7 +1533,7 @@ config E100 - to identify the adapter. + to identify the adapter. For the latest Intel PRO/100 network driver for Linux, see: @@ -1786,17 +1786,17 @@ config KS8842 tristate "Micrel KSZ8841/42 with generic bus interface" depends on HAS_IOMEM && DMA_ENGINE help - This platform driver is for KSZ8841(1-port) / KS8842(2-port) - ethernet switch chip (managed, VLAN, QoS) from Micrel or - Timberdale(FPGA). + This platform driver is for KSZ8841(1-port) / KS8842(2-port) + ethernet switch chip (managed, VLAN, QoS) from Micrel or + Timberdale(FPGA). config KS8851 - tristate "Micrel KS8851 SPI" - depends on SPI - select MII + tristate "Micrel KS8851 SPI" + depends on SPI + select MII select CRC32 - help - SPI driver for Micrel KS8851 SPI attached network chip. + help + SPI driver for Micrel KS8851 SPI attached network chip. config KS8851_MLL tristate "Micrel KS8851 MLL" @@ -2133,25 +2133,25 @@ config IP1000 will be called ipg. This is recommended. config IGB - tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support" - depends on PCI - ---help--- - This driver supports Intel(R) 82575/82576 gigabit ethernet family of - adapters. For more information on how to identify your adapter, go - to the Adapter & Driver ID Guide at: + tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support" + depends on PCI + ---help--- + This driver supports Intel(R) 82575/82576 gigabit ethernet family of + adapters. For more information on how to identify your adapter, go + to the Adapter & Driver ID Guide at: - + - For general information and support, go to the Intel support - website at: + For general information and support, go to the Intel support + website at: - + - More specific information on configuring the driver is in - . + More specific information on configuring the driver is in + . - To compile this driver as a module, choose M here. The module - will be called igb. + To compile this driver as a module, choose M here. The module + will be called igb. config IGB_DCA bool "Direct Cache Access (DCA) Support" @@ -2163,25 +2163,25 @@ config IGB_DCA is used, with the intent of lessening the impact of cache misses. config IGBVF - tristate "Intel(R) 82576 Virtual Function Ethernet support" - depends on PCI - ---help--- - This driver supports Intel(R) 82576 virtual functions. For more - information on how to identify your adapter, go to the Adapter & - Driver ID Guide at: + tristate "Intel(R) 82576 Virtual Function Ethernet support" + depends on PCI + ---help--- + This driver supports Intel(R) 82576 virtual functions. For more + information on how to identify your adapter, go to the Adapter & + Driver ID Guide at: - + - For general information and support, go to the Intel support - website at: + For general information and support, go to the Intel support + website at: - + - More specific information on configuring the driver is in - . + More specific information on configuring the driver is in + . - To compile this driver as a module, choose M here. The module - will be called igbvf. + To compile this driver as a module, choose M here. The module + will be called igbvf. source "drivers/net/ixp2000/Kconfig" @@ -2300,14 +2300,14 @@ config SKGE will be called skge. This is recommended. config SKGE_DEBUG - bool "Debugging interface" - depends on SKGE && DEBUG_FS - help - This option adds the ability to dump driver state for debugging. - The file /sys/kernel/debug/skge/ethX displays the state of the internal - transmit and receive rings. + bool "Debugging interface" + depends on SKGE && DEBUG_FS + help + This option adds the ability to dump driver state for debugging. + The file /sys/kernel/debug/skge/ethX displays the state of the internal + transmit and receive rings. - If unsure, say N. + If unsure, say N. config SKY2 tristate "SysKonnect Yukon2 support" @@ -2326,14 +2326,14 @@ config SKY2 will be called sky2. This is recommended. config SKY2_DEBUG - bool "Debugging interface" - depends on SKY2 && DEBUG_FS - help - This option adds the ability to dump driver state for debugging. - The file /sys/kernel/debug/sky2/ethX displays the state of the internal - transmit and receive rings. + bool "Debugging interface" + depends on SKY2 && DEBUG_FS + help + This option adds the ability to dump driver state for debugging. + The file /sys/kernel/debug/sky2/ethX displays the state of the internal + transmit and receive rings. - If unsure, say N. + If unsure, say N. config VIA_VELOCITY tristate "VIA Velocity support" @@ -2389,12 +2389,12 @@ config SPIDER_NET Cell Processor-Based Blades from IBM. config TSI108_ETH - tristate "Tundra TSI108 gigabit Ethernet support" - depends on TSI108_BRIDGE - help - This driver supports Tundra TSI108 gigabit Ethernet ports. - To compile this driver as a module, choose M here: the module - will be called tsi108_eth. + tristate "Tundra TSI108 gigabit Ethernet support" + depends on TSI108_BRIDGE + help + This driver supports Tundra TSI108 gigabit Ethernet ports. + To compile this driver as a module, choose M here: the module + will be called tsi108_eth. config GELIC_NET tristate "PS3 Gigabit Ethernet driver" @@ -2573,32 +2573,32 @@ config MDIO tristate config CHELSIO_T1 - tristate "Chelsio 10Gb Ethernet support" - depends on PCI + tristate "Chelsio 10Gb Ethernet support" + depends on PCI select CRC32 select MDIO - help - This driver supports Chelsio gigabit and 10-gigabit - Ethernet cards. More information about adapter features and + help + This driver supports Chelsio gigabit and 10-gigabit + Ethernet cards. More information about adapter features and performance tuning is in . - For general information about Chelsio and our products, visit - our website at . + For general information about Chelsio and our products, visit + our website at . - For customer support, please visit our customer support page at - . + For customer support, please visit our customer support page at + . - Please send feedback to . + Please send feedback to . - To compile this driver as a module, choose M here: the module - will be called cxgb. + To compile this driver as a module, choose M here: the module + will be called cxgb. config CHELSIO_T1_1G - bool "Chelsio gigabit Ethernet support" - depends on CHELSIO_T1 - help - Enables support for Chelsio's gigabit Ethernet PCI cards. If you - are using only 10G cards say 'N' here. + bool "Chelsio gigabit Ethernet support" + depends on CHELSIO_T1 + help + Enables support for Chelsio's gigabit Ethernet PCI cards. If you + are using only 10G cards say 'N' here. config CHELSIO_T3_DEPENDS tristate @@ -2728,26 +2728,26 @@ config IXGBE_DCB If unsure, say N. config IXGBEVF - tristate "Intel(R) 82599 Virtual Function Ethernet support" - depends on PCI_MSI - ---help--- - This driver supports Intel(R) 82599 virtual functions. For more - information on how to identify your adapter, go to the Adapter & - Driver ID Guide at: + tristate "Intel(R) 82599 Virtual Function Ethernet support" + depends on PCI_MSI + ---help--- + This driver supports Intel(R) 82599 virtual functions. For more + information on how to identify your adapter, go to the Adapter & + Driver ID Guide at: - + - For general information and support, go to the Intel support - website at: + For general information and support, go to the Intel support + website at: - + - More specific information on configuring the driver is in - . + More specific information on configuring the driver is in + . - To compile this driver as a module, choose M here. The module - will be called ixgbevf. MSI-X interrupt support is required - for this driver to work correctly. + To compile this driver as a module, choose M here. The module + will be called ixgbevf. MSI-X interrupt support is required + for this driver to work correctly. config IXGB tristate "Intel(R) PRO/10GbE support" @@ -2772,38 +2772,29 @@ config IXGB will be called ixgb. config S2IO - tristate "Exar Xframe 10Gb Ethernet Adapter" + tristate "S2IO 10Gbe XFrame NIC" depends on PCI ---help--- - This driver supports Exar Corp's Xframe Series 10Gb Ethernet Adapters. - + This driver supports the 10Gbe XFrame NIC of S2IO. More specific information on configuring the driver is in . - To compile this driver as a module, choose M here. The module - will be called s2io. - config VXGE - tristate "Exar X3100 Series 10GbE PCIe Server Adapter" + tristate "Neterion X3100 Series 10GbE PCIe Server Adapter" depends on PCI && INET ---help--- - This driver supports Exar Corp's X3100 Series 10 GbE PCIe + This driver supports Neterion Inc's X3100 Series 10 GbE PCIe I/O Virtualized Server Adapter. - More specific information on configuring the driver is in . - To compile this driver as a module, choose M here. The module - will be called vxge. - config VXGE_DEBUG_TRACE_ALL bool "Enabling All Debug trace statments in driver" default n depends on VXGE ---help--- Say Y here if you want to enabling all the debug trace statements in - the vxge driver. By default only few debug trace statements are - enabled. + driver. By default only few debug trace statements are enabled. config MYRI10GE tristate "Myricom Myri-10G Ethernet support" @@ -2915,18 +2906,18 @@ config QLGE will be called qlge. config BNA - tristate "Brocade 1010/1020 10Gb Ethernet Driver support" - depends on PCI - ---help--- - This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet - cards. - To compile this driver as a module, choose M here: the module - will be called bna. + tristate "Brocade 1010/1020 10Gb Ethernet Driver support" + depends on PCI + ---help--- + This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet + cards. + To compile this driver as a module, choose M here: the module + will be called bna. - For general information and support, go to the Brocade support - website at: + For general information and support, go to the Brocade support + website at: - + source "drivers/net/sfc/Kconfig" @@ -3236,18 +3227,18 @@ config PPP_BSDCOMP modules once you have said "make modules". If unsure, say N. config PPP_MPPE - tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)" - depends on PPP && EXPERIMENTAL - select CRYPTO - select CRYPTO_SHA1 - select CRYPTO_ARC4 - select CRYPTO_ECB - ---help--- - Support for the MPPE Encryption protocol, as employed by the - Microsoft Point-to-Point Tunneling Protocol. - - See http://pptpclient.sourceforge.net/ for information on - configuring PPTP clients and servers to utilize this method. + tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)" + depends on PPP && EXPERIMENTAL + select CRYPTO + select CRYPTO_SHA1 + select CRYPTO_ARC4 + select CRYPTO_ECB + ---help--- + Support for the MPPE Encryption protocol, as employed by the + Microsoft Point-to-Point Tunneling Protocol. + + See http://pptpclient.sourceforge.net/ for information on + configuring PPTP clients and servers to utilize this method. config PPPOE tristate "PPP over Ethernet (EXPERIMENTAL)" @@ -3406,14 +3397,14 @@ config VIRTIO_NET depends on EXPERIMENTAL && VIRTIO ---help--- This is the virtual network driver for virtio. It can be used with - lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. + lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. config VMXNET3 - tristate "VMware VMXNET3 ethernet driver" - depends on PCI && INET - help - This driver supports VMware's vmxnet3 virtual ethernet NIC. - To compile this driver as a module, choose M here: the - module will be called vmxnet3. + tristate "VMware VMXNET3 ethernet driver" + depends on PCI && INET + help + This driver supports VMware's vmxnet3 virtual ethernet NIC. + To compile this driver as a module, choose M here: the + module will be called vmxnet3. endif # NETDEVICES diff --git a/trunk/drivers/net/arm/w90p910_ether.c b/trunk/drivers/net/arm/w90p910_ether.c index bfea499a3513..4545d5a06c24 100644 --- a/trunk/drivers/net/arm/w90p910_ether.c +++ b/trunk/drivers/net/arm/w90p910_ether.c @@ -117,7 +117,7 @@ #define TX_DESC_SIZE 10 #define MAX_RBUFF_SZ 0x600 #define MAX_TBUFF_SZ 0x600 -#define TX_TIMEOUT (HZ/2) +#define TX_TIMEOUT 50 #define DELAY 1000 #define CAM0 0x0 diff --git a/trunk/drivers/net/at1700.c b/trunk/drivers/net/at1700.c index 871b1633f543..89876897a6fe 100644 --- a/trunk/drivers/net/at1700.c +++ b/trunk/drivers/net/at1700.c @@ -150,7 +150,7 @@ struct net_local { #define PORT_OFFSET(o) (o) -#define TX_TIMEOUT (HZ/10) +#define TX_TIMEOUT 10 /* Index to functions, as function prototypes. */ diff --git a/trunk/drivers/net/atarilance.c b/trunk/drivers/net/atarilance.c index ce0091eb06f5..8cb27cb7bca1 100644 --- a/trunk/drivers/net/atarilance.c +++ b/trunk/drivers/net/atarilance.c @@ -116,7 +116,7 @@ MODULE_LICENSE("GPL"); #define RX_RING_LEN_BITS (RX_LOG_RING_SIZE << 5) #define RX_RING_MOD_MASK (RX_RING_SIZE - 1) -#define TX_TIMEOUT (HZ/5) +#define TX_TIMEOUT 20 /* The LANCE Rx and Tx ring descriptors. */ struct lance_rx_head { diff --git a/trunk/drivers/net/atlx/atl1.c b/trunk/drivers/net/atlx/atl1.c index 53363108994e..43579b3b24ac 100644 --- a/trunk/drivers/net/atlx/atl1.c +++ b/trunk/drivers/net/atlx/atl1.c @@ -3043,6 +3043,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev, atl1_pcie_patch(adapter); /* assume we have no link for now */ netif_carrier_off(netdev); + netif_stop_queue(netdev); setup_timer(&adapter->phy_config_timer, atl1_phy_config, (unsigned long)adapter); diff --git a/trunk/drivers/net/ax88796.c b/trunk/drivers/net/ax88796.c index 4bebff3faeab..b6da4cf3694b 100644 --- a/trunk/drivers/net/ax88796.c +++ b/trunk/drivers/net/ax88796.c @@ -325,7 +325,7 @@ static void ax_block_output(struct net_device *dev, int count, static void ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR; unsigned int memr; @@ -364,7 +364,7 @@ ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len) static unsigned int ax_phy_ei_inbits(struct net_device *dev, int no) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR; unsigned int memr; unsigned int result = 0; @@ -412,7 +412,7 @@ ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc) static int ax_phy_read(struct net_device *dev, int phy_addr, int reg) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned long flags; unsigned int result; @@ -435,7 +435,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg) static void ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value) { - struct ei_device *ei = netdev_priv(dev); + struct ei_device *ei = (struct ei_device *) netdev_priv(dev); struct ax_device *ax = to_ax_dev(dev); unsigned long flags; diff --git a/trunk/drivers/net/benet/be.h b/trunk/drivers/net/benet/be.h index b61a1dfebcaf..4594a28b1f66 100644 --- a/trunk/drivers/net/benet/be.h +++ b/trunk/drivers/net/benet/be.h @@ -38,17 +38,14 @@ #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" #define OC_NAME "Emulex OneConnect 10Gbps NIC" -#define OC_NAME_BE OC_NAME "(be3)" -#define OC_NAME_LANCER OC_NAME "(Lancer)" +#define OC_NAME1 "Emulex OneConnect 10Gbps NIC (be3)" #define DRV_DESC "ServerEngines BladeEngine 10Gbps NIC Driver" #define BE_VENDOR_ID 0x19a2 -#define EMULEX_VENDOR_ID 0x10df #define BE_DEVICE_ID1 0x211 #define BE_DEVICE_ID2 0x221 -#define OC_DEVICE_ID1 0x700 /* Device Id for BE2 cards */ -#define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */ -#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */ +#define OC_DEVICE_ID1 0x700 +#define OC_DEVICE_ID2 0x710 static inline char *nic_name(struct pci_dev *pdev) { @@ -56,9 +53,7 @@ static inline char *nic_name(struct pci_dev *pdev) case OC_DEVICE_ID1: return OC_NAME; case OC_DEVICE_ID2: - return OC_NAME_BE; - case OC_DEVICE_ID3: - return OC_NAME_LANCER; + return OC_NAME1; case BE_DEVICE_ID2: return BE3_NAME; default: @@ -154,7 +149,6 @@ struct be_eq_obj { u16 min_eqd; /* in usecs */ u16 max_eqd; /* in usecs */ u16 cur_eqd; /* in usecs */ - u8 msix_vec_idx; struct napi_struct napi; }; @@ -266,8 +260,6 @@ struct be_adapter { u32 num_rx_qs; u32 big_page_size; /* Compounded page size shared by rx wrbs */ - u8 msix_vec_next_idx; - struct vlan_group *vlan_grp; u16 vlans_added; u16 max_vlans; /* Number of vlans supported */ @@ -307,8 +299,8 @@ struct be_adapter { bool sriov_enabled; struct be_vf_cfg vf_cfg[BE_MAX_VF]; + u8 base_eq_id; u8 is_virtfn; - u32 sli_family; }; #define be_physfn(adapter) (!adapter->is_virtfn) @@ -317,8 +309,6 @@ struct be_adapter { #define BE_GEN2 2 #define BE_GEN3 3 -#define lancer_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID3) - extern const struct ethtool_ops be_ethtool_ops; #define tx_stats(adapter) (&adapter->tx_stats) @@ -426,17 +416,10 @@ static inline u8 is_udp_pkt(struct sk_buff *skb) static inline void be_check_sriov_fn_type(struct be_adapter *adapter) { u8 data; - u32 sli_intf; - - if (lancer_chip(adapter)) { - pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, - &sli_intf); - adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0; - } else { - pci_write_config_byte(adapter->pdev, 0xFE, 0xAA); - pci_read_config_byte(adapter->pdev, 0xFE, &data); - adapter->is_virtfn = (data != 0xAA); - } + + pci_write_config_byte(adapter->pdev, 0xFE, 0xAA); + pci_read_config_byte(adapter->pdev, 0xFE, &data); + adapter->is_virtfn = (data != 0xAA); } static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) diff --git a/trunk/drivers/net/benet/be_cmds.c b/trunk/drivers/net/benet/be_cmds.c index 3865b2bc65e6..36eca1ce75d4 100644 --- a/trunk/drivers/net/benet/be_cmds.c +++ b/trunk/drivers/net/benet/be_cmds.c @@ -323,12 +323,7 @@ static int be_mbox_notify_wait(struct be_adapter *adapter) static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) { - u32 sem; - - if (lancer_chip(adapter)) - sem = ioread32(adapter->db + MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET); - else - sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET); + u32 sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET); *stage = sem & EP_SEMAPHORE_POST_STAGE_MASK; if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK) @@ -470,25 +465,14 @@ int be_cmd_fw_init(struct be_adapter *adapter) spin_lock(&adapter->mbox_lock); wrb = (u8 *)wrb_from_mbox(adapter); - if (lancer_chip(adapter)) { - *wrb++ = 0xFF; - *wrb++ = 0x34; - *wrb++ = 0x12; - *wrb++ = 0xFF; - *wrb++ = 0xFF; - *wrb++ = 0x78; - *wrb++ = 0x56; - *wrb = 0xFF; - } else { - *wrb++ = 0xFF; - *wrb++ = 0x12; - *wrb++ = 0x34; - *wrb++ = 0xFF; - *wrb++ = 0xFF; - *wrb++ = 0x56; - *wrb++ = 0x78; - *wrb = 0xFF; - } + *wrb++ = 0xFF; + *wrb++ = 0x12; + *wrb++ = 0x34; + *wrb++ = 0xFF; + *wrb++ = 0xFF; + *wrb++ = 0x56; + *wrb++ = 0x78; + *wrb = 0xFF; status = be_mbox_notify_wait(adapter); @@ -696,36 +680,16 @@ int be_cmd_cq_create(struct be_adapter *adapter, OPCODE_COMMON_CQ_CREATE, sizeof(*req)); req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); - if (lancer_chip(adapter)) { - req->hdr.version = 1; - req->page_size = 1; /* 1 for 4K */ - AMAP_SET_BITS(struct amap_cq_context_lancer, coalescwm, ctxt, - coalesce_wm); - AMAP_SET_BITS(struct amap_cq_context_lancer, nodelay, ctxt, - no_delay); - AMAP_SET_BITS(struct amap_cq_context_lancer, count, ctxt, - __ilog2_u32(cq->len/256)); - AMAP_SET_BITS(struct amap_cq_context_lancer, valid, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context_lancer, eventable, - ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context_lancer, eqid, - ctxt, eq->id); - AMAP_SET_BITS(struct amap_cq_context_lancer, armed, ctxt, 1); - } else { - AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt, - coalesce_wm); - AMAP_SET_BITS(struct amap_cq_context_be, nodelay, - ctxt, no_delay); - AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt, - __ilog2_u32(cq->len/256)); - AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context_be, solevent, - ctxt, sol_evts); - AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id); - AMAP_SET_BITS(struct amap_cq_context_be, armed, ctxt, 1); - } + AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm); + AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay); + AMAP_SET_BITS(struct amap_cq_context, count, ctxt, + __ilog2_u32(cq->len/256)); + AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts); + AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); + AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); @@ -773,27 +737,13 @@ int be_cmd_mccq_create(struct be_adapter *adapter, OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req)); req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); - if (lancer_chip(adapter)) { - req->hdr.version = 1; - req->cq_id = cpu_to_le16(cq->id); - - AMAP_SET_BITS(struct amap_mcc_context_lancer, ring_size, ctxt, - be_encoded_q_len(mccq->len)); - AMAP_SET_BITS(struct amap_mcc_context_lancer, valid, ctxt, 1); - AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_id, - ctxt, cq->id); - AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_valid, - ctxt, 1); - - } else { - AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1); - AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt, - be_encoded_q_len(mccq->len)); - AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id); - } + AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); + AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, + be_encoded_q_len(mccq->len)); + AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id); /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */ - req->async_event_bitmap[0] = cpu_to_le32(0x00000022); + req->async_event_bitmap[0] |= 0x00000022; be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); diff --git a/trunk/drivers/net/benet/be_cmds.h b/trunk/drivers/net/benet/be_cmds.h index 83d15c8a9fa3..8469ff061f30 100644 --- a/trunk/drivers/net/benet/be_cmds.h +++ b/trunk/drivers/net/benet/be_cmds.h @@ -309,7 +309,7 @@ struct be_cmd_req_pmac_del { /******************** Create CQ ***************************/ /* Pseudo amap definition in which each bit of the actual structure is defined * as a byte: used to calculate offset/shift/mask of each field */ -struct amap_cq_context_be { +struct amap_cq_context { u8 cidx[11]; /* dword 0*/ u8 rsvd0; /* dword 0*/ u8 coalescwm[2]; /* dword 0*/ @@ -332,32 +332,14 @@ struct amap_cq_context_be { u8 rsvd5[32]; /* dword 3*/ } __packed; -struct amap_cq_context_lancer { - u8 rsvd0[12]; /* dword 0*/ - u8 coalescwm[2]; /* dword 0*/ - u8 nodelay; /* dword 0*/ - u8 rsvd1[12]; /* dword 0*/ - u8 count[2]; /* dword 0*/ - u8 valid; /* dword 0*/ - u8 rsvd2; /* dword 0*/ - u8 eventable; /* dword 0*/ - u8 eqid[16]; /* dword 1*/ - u8 rsvd3[15]; /* dword 1*/ - u8 armed; /* dword 1*/ - u8 rsvd4[32]; /* dword 2*/ - u8 rsvd5[32]; /* dword 3*/ -} __packed; - struct be_cmd_req_cq_create { struct be_cmd_req_hdr hdr; u16 num_pages; - u8 page_size; - u8 rsvd0; - u8 context[sizeof(struct amap_cq_context_be) / 8]; + u16 rsvd0; + u8 context[sizeof(struct amap_cq_context) / 8]; struct phys_addr pages[8]; } __packed; - struct be_cmd_resp_cq_create { struct be_cmd_resp_hdr hdr; u16 cq_id; @@ -367,7 +349,7 @@ struct be_cmd_resp_cq_create { /******************** Create MCCQ ***************************/ /* Pseudo amap definition in which each bit of the actual structure is defined * as a byte: used to calculate offset/shift/mask of each field */ -struct amap_mcc_context_be { +struct amap_mcc_context { u8 con_index[14]; u8 rsvd0[2]; u8 ring_size[4]; @@ -382,23 +364,12 @@ struct amap_mcc_context_be { u8 rsvd2[32]; } __packed; -struct amap_mcc_context_lancer { - u8 async_cq_id[16]; - u8 ring_size[4]; - u8 rsvd0[12]; - u8 rsvd1[31]; - u8 valid; - u8 async_cq_valid[1]; - u8 rsvd2[31]; - u8 rsvd3[32]; -} __packed; - struct be_cmd_req_mcc_create { struct be_cmd_req_hdr hdr; u16 num_pages; - u16 cq_id; + u16 rsvd0; u32 async_event_bitmap[1]; - u8 context[sizeof(struct amap_mcc_context_be) / 8]; + u8 context[sizeof(struct amap_mcc_context) / 8]; struct phys_addr pages[8]; } __packed; @@ -634,7 +605,6 @@ struct be_hw_stats { struct be_rxf_stats rxf; u32 rsvd[48]; struct be_erx_stats erx; - u32 rsvd1[6]; }; struct be_cmd_req_get_stats { diff --git a/trunk/drivers/net/benet/be_hw.h b/trunk/drivers/net/benet/be_hw.h index 4096d9778234..a2ec5df0d733 100644 --- a/trunk/drivers/net/benet/be_hw.h +++ b/trunk/drivers/net/benet/be_hw.h @@ -32,12 +32,10 @@ #define MPU_EP_CONTROL 0 /********** MPU semphore ******************/ -#define MPU_EP_SEMAPHORE_OFFSET 0xac -#define MPU_EP_SEMAPHORE_IF_TYPE2_OFFSET 0x400 -#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF -#define EP_SEMAPHORE_POST_ERR_MASK 0x1 -#define EP_SEMAPHORE_POST_ERR_SHIFT 31 - +#define MPU_EP_SEMAPHORE_OFFSET 0xac +#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF +#define EP_SEMAPHORE_POST_ERR_MASK 0x1 +#define EP_SEMAPHORE_POST_ERR_SHIFT 31 /* MPU semphore POST stage values */ #define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */ #define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */ @@ -68,28 +66,6 @@ #define PCICFG_UE_STATUS_LOW_MASK 0xA8 #define PCICFG_UE_STATUS_HI_MASK 0xAC -/******** SLI_INTF ***********************/ -#define SLI_INTF_REG_OFFSET 0x58 -#define SLI_INTF_VALID_MASK 0xE0000000 -#define SLI_INTF_VALID 0xC0000000 -#define SLI_INTF_HINT2_MASK 0x1F000000 -#define SLI_INTF_HINT2_SHIFT 24 -#define SLI_INTF_HINT1_MASK 0x00FF0000 -#define SLI_INTF_HINT1_SHIFT 16 -#define SLI_INTF_FAMILY_MASK 0x00000F00 -#define SLI_INTF_FAMILY_SHIFT 8 -#define SLI_INTF_IF_TYPE_MASK 0x0000F000 -#define SLI_INTF_IF_TYPE_SHIFT 12 -#define SLI_INTF_REV_MASK 0x000000F0 -#define SLI_INTF_REV_SHIFT 4 -#define SLI_INTF_FT_MASK 0x00000001 - - -/* SLI family */ -#define BE_SLI_FAMILY 0x0 -#define LANCER_A0_SLI_FAMILY 0xA - - /********* ISR0 Register offset **********/ #define CEV_ISR0_OFFSET 0xC18 #define CEV_ISR_SIZE 4 @@ -97,9 +73,6 @@ /********* Event Q door bell *************/ #define DB_EQ_OFFSET DB_CQ_OFFSET #define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */ -#define DB_EQ_RING_ID_EXT_MASK 0x3e00 /* bits 9-13 */ -#define DB_EQ_RING_ID_EXT_MASK_SHIFT (2) /* qid bits 9-13 placing at 11-15 */ - /* Clear the interrupt for this eq */ #define DB_EQ_CLR_SHIFT (9) /* bit 9 */ /* Must be 1 */ @@ -112,10 +85,6 @@ /********* Compl Q door bell *************/ #define DB_CQ_OFFSET 0x120 #define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */ -#define DB_CQ_RING_ID_EXT_MASK 0x7C00 /* bits 10-14 */ -#define DB_CQ_RING_ID_EXT_MASK_SHIFT (1) /* qid bits 10-14 - placing at 11-15 */ - /* Number of event entries processed */ #define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */ /* Rearm bit */ diff --git a/trunk/drivers/net/benet/be_main.c b/trunk/drivers/net/benet/be_main.c index 102567ee68c2..c36cd2ffbadc 100644 --- a/trunk/drivers/net/benet/be_main.c +++ b/trunk/drivers/net/benet/be_main.c @@ -41,7 +41,6 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, - { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)}, { 0 } }; MODULE_DEVICE_TABLE(pci, be_dev_ids); @@ -189,8 +188,6 @@ static void be_eq_notify(struct be_adapter *adapter, u16 qid, { u32 val = 0; val |= qid & DB_EQ_RING_ID_MASK; - val |= ((qid & DB_EQ_RING_ID_EXT_MASK) << - DB_EQ_RING_ID_EXT_MASK_SHIFT); if (adapter->eeh_err) return; @@ -208,8 +205,6 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped) { u32 val = 0; val |= qid & DB_CQ_RING_ID_MASK; - val |= ((qid & DB_CQ_RING_ID_EXT_MASK) << - DB_CQ_RING_ID_EXT_MASK_SHIFT); if (adapter->eeh_err) return; @@ -409,8 +404,7 @@ static void be_tx_stats_update(struct be_adapter *adapter, } /* Determine number of WRB entries needed to xmit data in an skb */ -static u32 wrb_cnt_for_skb(struct be_adapter *adapter, struct sk_buff *skb, - bool *dummy) +static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy) { int cnt = (skb->len > skb->data_len); @@ -418,13 +412,12 @@ static u32 wrb_cnt_for_skb(struct be_adapter *adapter, struct sk_buff *skb, /* to account for hdr wrb */ cnt++; - if (lancer_chip(adapter) || !(cnt & 1)) { - *dummy = false; - } else { + if (cnt & 1) { /* add a dummy to make it an even num */ cnt++; *dummy = true; - } + } else + *dummy = false; BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT); return cnt; } @@ -450,18 +443,8 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1); AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss, hdr, skb_shinfo(skb)->gso_size); - if (skb_is_gso_v6(skb) && !lancer_chip(adapter)) + if (skb_is_gso_v6(skb)) AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1); - if (lancer_chip(adapter) && adapter->sli_family == - LANCER_A0_SLI_FAMILY) { - AMAP_SET_BITS(struct amap_eth_hdr_wrb, ipcs, hdr, 1); - if (is_tcp_pkt(skb)) - AMAP_SET_BITS(struct amap_eth_hdr_wrb, - tcpcs, hdr, 1); - else if (is_udp_pkt(skb)) - AMAP_SET_BITS(struct amap_eth_hdr_wrb, - udpcs, hdr, 1); - } } else if (skb->ip_summed == CHECKSUM_PARTIAL) { if (is_tcp_pkt(skb)) AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1); @@ -583,7 +566,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, u32 start = txq->head; bool dummy_wrb, stopped = false; - wrb_cnt = wrb_cnt_for_skb(adapter, skb, &dummy_wrb); + wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb); copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb); if (copied) { @@ -1052,8 +1035,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, return; } vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); - if (!lancer_chip(adapter)) - vid = swab16(vid); + vid = swab16(vid); vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); } else { netif_receive_skb(skb); @@ -1131,8 +1113,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, napi_gro_frags(&eq_obj->napi); } else { vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); - if (!lancer_chip(adapter)) - vid = swab16(vid); + vid = swab16(vid); if (!adapter->vlan_grp || adapter->vlans_added == 0) return; @@ -1400,8 +1381,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter) sent_skb = sent_skbs[txq->tail]; end_idx = txq->tail; index_adv(&end_idx, - wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1, - txq->len); + wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len); be_tx_compl_process(adapter, end_idx); } } @@ -1496,9 +1476,7 @@ static int be_tx_queues_create(struct be_adapter *adapter) /* Ask BE to create Tx Event queue */ if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd)) goto tx_eq_free; - - adapter->tx_eq.msix_vec_idx = adapter->msix_vec_next_idx++; - + adapter->base_eq_id = adapter->tx_eq.q.id; /* Alloc TX eth compl queue */ cq = &adapter->tx_obj.cq; @@ -1590,8 +1568,6 @@ static int be_rx_queues_create(struct be_adapter *adapter) if (rc) goto err; - rxo->rx_eq.msix_vec_idx = adapter->msix_vec_next_idx++; - /* CQ */ cq = &rxo->cq; rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, @@ -1602,6 +1578,7 @@ static int be_rx_queues_create(struct be_adapter *adapter) rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); if (rc) goto err; + /* Rx Q */ q = &rxo->q; rc = be_queue_alloc(adapter, q, RX_Q_LEN, @@ -1634,45 +1611,29 @@ static int be_rx_queues_create(struct be_adapter *adapter) return -1; } -static bool event_peek(struct be_eq_obj *eq_obj) +/* There are 8 evt ids per func. Retruns the evt id's bit number */ +static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) { - struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q); - if (!eqe->evt) - return false; - else - return true; + return eq_id - adapter->base_eq_id; } static irqreturn_t be_intx(int irq, void *dev) { struct be_adapter *adapter = dev; struct be_rx_obj *rxo; - int isr, i, tx = 0 , rx = 0; - - if (lancer_chip(adapter)) { - if (event_peek(&adapter->tx_eq)) - tx = event_handle(adapter, &adapter->tx_eq); - for_all_rx_queues(adapter, rxo, i) { - if (event_peek(&rxo->rx_eq)) - rx |= event_handle(adapter, &rxo->rx_eq); - } - - if (!(tx || rx)) - return IRQ_NONE; + int isr, i; - } else { - isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + - (adapter->tx_eq.q.id / 8) * CEV_ISR_SIZE); - if (!isr) - return IRQ_NONE; + isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + + (adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE); + if (!isr) + return IRQ_NONE; - if ((1 << adapter->tx_eq.msix_vec_idx & isr)) - event_handle(adapter, &adapter->tx_eq); + if ((1 << be_evt_bit_get(adapter, adapter->tx_eq.q.id) & isr)) + event_handle(adapter, &adapter->tx_eq); - for_all_rx_queues(adapter, rxo, i) { - if ((1 << rxo->rx_eq.msix_vec_idx & isr)) - event_handle(adapter, &rxo->rx_eq); - } + for_all_rx_queues(adapter, rxo, i) { + if ((1 << be_evt_bit_get(adapter, rxo->rx_eq.q.id) & isr)) + event_handle(adapter, &rxo->rx_eq); } return IRQ_HANDLED; @@ -1869,7 +1830,8 @@ static void be_worker(struct work_struct *work) be_post_rx_frags(rxo); } } - if (!adapter->ue_detected && !lancer_chip(adapter)) + + if (!adapter->ue_detected) be_detect_dump_ue(adapter); reschedule: @@ -1948,10 +1910,10 @@ static void be_sriov_disable(struct be_adapter *adapter) #endif } -static inline int be_msix_vec_get(struct be_adapter *adapter, - struct be_eq_obj *eq_obj) +static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) { - return adapter->msix_entries[eq_obj->msix_vec_idx].vector; + return adapter->msix_entries[ + be_evt_bit_get(adapter, eq_id)].vector; } static int be_request_irq(struct be_adapter *adapter, @@ -1962,14 +1924,14 @@ static int be_request_irq(struct be_adapter *adapter, int vec; sprintf(eq_obj->desc, "%s-%s", netdev->name, desc); - vec = be_msix_vec_get(adapter, eq_obj); + vec = be_msix_vec_get(adapter, eq_obj->q.id); return request_irq(vec, handler, 0, eq_obj->desc, context); } static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj, void *context) { - int vec = be_msix_vec_get(adapter, eq_obj); + int vec = be_msix_vec_get(adapter, eq_obj->q.id); free_irq(vec, context); } @@ -2074,15 +2036,14 @@ static int be_close(struct net_device *netdev) netif_carrier_off(netdev); adapter->link_up = false; - if (!lancer_chip(adapter)) - be_intr_set(adapter, false); + be_intr_set(adapter, false); if (adapter->msix_enabled) { - vec = be_msix_vec_get(adapter, tx_eq); + vec = be_msix_vec_get(adapter, tx_eq->q.id); synchronize_irq(vec); for_all_rx_queues(adapter, rxo, i) { - vec = be_msix_vec_get(adapter, &rxo->rx_eq); + vec = be_msix_vec_get(adapter, rxo->rx_eq.q.id); synchronize_irq(vec); } } else { @@ -2121,8 +2082,7 @@ static int be_open(struct net_device *netdev) be_irq_register(adapter); - if (!lancer_chip(adapter)) - be_intr_set(adapter, true); + be_intr_set(adapter, true); /* The evt queues are created in unarmed state; arm them */ for_all_rx_queues(adapter, rxo, i) { @@ -2498,12 +2458,6 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) int status, i = 0, num_imgs = 0; const u8 *p; - if (!netif_running(adapter->netdev)) { - dev_err(&adapter->pdev->dev, - "Firmware load not allowed (interface is down)\n"); - return -EPERM; - } - strcpy(fw_file, func); status = request_firmware(&fw, fw_file, &adapter->pdev->dev); @@ -2588,9 +2542,6 @@ static void be_netdev_init(struct net_device *netdev) netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM; - if (lancer_chip(adapter)) - netdev->vlan_features |= NETIF_F_TSO6; - netdev->flags |= IFF_MULTICAST; adapter->rx_csum = true; @@ -2630,15 +2581,6 @@ static int be_map_pci_bars(struct be_adapter *adapter) u8 __iomem *addr; int pcicfg_reg, db_reg; - if (lancer_chip(adapter)) { - addr = ioremap_nocache(pci_resource_start(adapter->pdev, 0), - pci_resource_len(adapter->pdev, 0)); - if (addr == NULL) - return -ENOMEM; - adapter->db = addr; - return 0; - } - if (be_physfn(adapter)) { addr = ioremap_nocache(pci_resource_start(adapter->pdev, 2), pci_resource_len(adapter->pdev, 2)); @@ -2835,44 +2777,6 @@ static int be_get_config(struct be_adapter *adapter) return 0; } -static int be_dev_family_check(struct be_adapter *adapter) -{ - struct pci_dev *pdev = adapter->pdev; - u32 sli_intf = 0, if_type; - - switch (pdev->device) { - case BE_DEVICE_ID1: - case OC_DEVICE_ID1: - adapter->generation = BE_GEN2; - break; - case BE_DEVICE_ID2: - case OC_DEVICE_ID2: - adapter->generation = BE_GEN3; - break; - case OC_DEVICE_ID3: - pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); - if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> - SLI_INTF_IF_TYPE_SHIFT; - - if (((sli_intf & SLI_INTF_VALID_MASK) != SLI_INTF_VALID) || - if_type != 0x02) { - dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); - return -EINVAL; - } - if (num_vfs > 0) { - dev_err(&pdev->dev, "VFs not supported\n"); - return -EINVAL; - } - adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> - SLI_INTF_FAMILY_SHIFT); - adapter->generation = BE_GEN3; - break; - default: - adapter->generation = 0; - } - return 0; -} - static int __devinit be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) { @@ -2895,13 +2799,22 @@ static int __devinit be_probe(struct pci_dev *pdev, goto rel_reg; } adapter = netdev_priv(netdev); - adapter->pdev = pdev; - pci_set_drvdata(pdev, adapter); - status = be_dev_family_check(adapter); - if (!status) - goto free_netdev; + switch (pdev->device) { + case BE_DEVICE_ID1: + case OC_DEVICE_ID1: + adapter->generation = BE_GEN2; + break; + case BE_DEVICE_ID2: + case OC_DEVICE_ID2: + adapter->generation = BE_GEN3; + break; + default: + adapter->generation = 0; + } + adapter->pdev = pdev; + pci_set_drvdata(pdev, adapter); adapter->netdev = netdev; SET_NETDEV_DEV(netdev, &pdev->dev); @@ -2976,7 +2889,7 @@ static int __devinit be_probe(struct pci_dev *pdev, be_ctrl_cleanup(adapter); free_netdev: be_sriov_disable(adapter); - free_netdev(netdev); + free_netdev(adapter->netdev); pci_set_drvdata(pdev, NULL); rel_reg: pci_release_regions(pdev); diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 03209a37883e..062600be073b 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.0.20" -#define DRV_MODULE_RELDATE "Nov 24, 2010" +#define DRV_MODULE_VERSION "2.0.18" +#define DRV_MODULE_RELDATE "Oct 7, 2010" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw" @@ -766,10 +766,13 @@ bnx2_alloc_rx_mem(struct bnx2 *bp) int j; rxr->rx_buf_ring = - vzalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring); + vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring); if (rxr->rx_buf_ring == NULL) return -ENOMEM; + memset(rxr->rx_buf_ring, 0, + SW_RXBD_RING_SIZE * bp->rx_max_ring); + for (j = 0; j < bp->rx_max_ring; j++) { rxr->rx_desc_ring[j] = dma_alloc_coherent(&bp->pdev->dev, @@ -782,11 +785,13 @@ bnx2_alloc_rx_mem(struct bnx2 *bp) } if (bp->rx_pg_ring_size) { - rxr->rx_pg_ring = vzalloc(SW_RXPG_RING_SIZE * + rxr->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE * bp->rx_max_pg_ring); if (rxr->rx_pg_ring == NULL) return -ENOMEM; + memset(rxr->rx_pg_ring, 0, SW_RXPG_RING_SIZE * + bp->rx_max_pg_ring); } for (j = 0; j < bp->rx_max_pg_ring; j++) { @@ -4640,28 +4645,13 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) /* Wait for the current PCI transaction to complete before * issuing a reset. */ - if ((CHIP_NUM(bp) == CHIP_NUM_5706) || - (CHIP_NUM(bp) == CHIP_NUM_5708)) { - REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, - BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | - BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | - BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | - BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); - val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); - udelay(5); - } else { /* 5709 */ - val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); - val &= ~BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE; - REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val); - val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); - - for (i = 0; i < 100; i++) { - msleep(1); - val = REG_RD(bp, BNX2_PCICFG_DEVICE_CONTROL); - if (!(val & BNX2_PCICFG_DEVICE_STATUS_NO_PEND)) - break; - } - } + REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, + BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); + val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); + udelay(5); /* Wait for the firmware to tell us it is ok to issue a reset. */ bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1); @@ -4683,7 +4673,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; - REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val); + pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val); } else { val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | @@ -7924,15 +7914,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) goto err_out_release; } - bnx2_set_power_state(bp, PCI_D0); - /* Configure byte swap and enable write to the reg_window registers. * Rely on CPU to do target byte swapping on big endian systems * The chip's target access swapping will not swap all accesses */ - REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, - BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | - BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); + pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, + BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | + BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); + + bnx2_set_power_state(bp, PCI_D0); bp->chip_id = REG_RD(bp, BNX2_MISC_ID); diff --git a/trunk/drivers/net/bnx2.h b/trunk/drivers/net/bnx2.h index 5488a2e82fe9..bf4c3421067d 100644 --- a/trunk/drivers/net/bnx2.h +++ b/trunk/drivers/net/bnx2.h @@ -461,8 +461,6 @@ struct l2_fhdr { #define BNX2_PCICFG_MAILBOX_QUEUE_ADDR 0x00000090 #define BNX2_PCICFG_MAILBOX_QUEUE_DATA 0x00000094 -#define BNX2_PCICFG_DEVICE_CONTROL 0x000000b4 -#define BNX2_PCICFG_DEVICE_STATUS_NO_PEND ((1L<<5)<<16) /* * pci_reg definition diff --git a/trunk/drivers/net/bnx2x/bnx2x.h b/trunk/drivers/net/bnx2x/bnx2x.h index 342ab58b14b3..9eea225decaf 100644 --- a/trunk/drivers/net/bnx2x/bnx2x.h +++ b/trunk/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-5" -#define DRV_MODULE_RELDATE "2010/11/24" +#define DRV_MODULE_VERSION "1.60.00-3" +#define DRV_MODULE_RELDATE "2010/10/19" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE diff --git a/trunk/drivers/net/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/bnx2x/bnx2x_cmn.c index e20b2d378929..459614d2d7bc 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/bnx2x/bnx2x_cmn.c @@ -1680,7 +1680,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) rc = XMIT_PLAIN; else { - if (vlan_get_protocol(skb) == htons(ETH_P_IPV6)) { + if (skb->protocol == htons(ETH_P_IPV6)) { rc = XMIT_CSUM_V6; if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) rc |= XMIT_CSUM_TCP; @@ -1692,10 +1692,11 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) } } - if (skb_is_gso_v6(skb)) - rc |= XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6; - else if (skb_is_gso(skb)) - rc |= XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP; + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) + rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP); + + else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6); return rc; } diff --git a/trunk/drivers/net/bnx2x/bnx2x_ethtool.c b/trunk/drivers/net/bnx2x/bnx2x_ethtool.c index 03012787de2f..d02ffbdc9f0e 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/trunk/drivers/net/bnx2x/bnx2x_ethtool.c @@ -1499,15 +1499,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) * updates that have been performed while interrupts were * disabled. */ - if (bp->common.int_block == INT_BLOCK_IGU) { - /* Disable local BHes to prevent a dead-lock situation between - * sch_direct_xmit() and bnx2x_run_loopback() (calling - * bnx2x_tx_int()), as both are taking netif_tx_lock(). - */ - local_bh_disable(); + if (bp->common.int_block == INT_BLOCK_IGU) bnx2x_tx_int(fp_tx); - local_bh_enable(); - } rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); if (rx_idx != rx_start_idx + num_pkts) diff --git a/trunk/drivers/net/bnx2x/bnx2x_hsi.h b/trunk/drivers/net/bnx2x/bnx2x_hsi.h index 4cfd4e9b5586..18c8e23a0e82 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_hsi.h +++ b/trunk/drivers/net/bnx2x/bnx2x_hsi.h @@ -244,14 +244,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u16 xgxs_config_tx[4]; /* 0x1A0 */ - u32 Reserved1[56]; /* 0x1A8 */ - u32 default_cfg; /* 0x288 */ - /* Enable BAM on KR */ -#define PORT_HW_CFG_ENABLE_BAM_ON_KR_MASK 0x00100000 -#define PORT_HW_CFG_ENABLE_BAM_ON_KR_SHIFT 20 -#define PORT_HW_CFG_ENABLE_BAM_ON_KR_DISABLED 0x00000000 -#define PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED 0x00100000 - + u32 Reserved1[57]; /* 0x1A8 */ u32 speed_capability_mask2; /* 0x28C */ #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 diff --git a/trunk/drivers/net/bnx2x/bnx2x_link.c b/trunk/drivers/net/bnx2x/bnx2x_link.c index 38aeffef2a83..2326774df843 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/bnx2x/bnx2x_link.c @@ -610,7 +610,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, /* reset and unreset the BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - msleep(1); + udelay(10); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); @@ -3525,19 +3525,13 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); /* Enable CL37 BAM */ - if (REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_hw_config[params->port].default_cfg)) & - PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, &val); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, val | 1); - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_BAM, &val); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_BAM, val | 1); - DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); - } if (params->loopback_mode == LOOPBACK_EXT) { bnx2x_807x_force_10G(bp, phy); DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); @@ -3904,7 +3898,7 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0; + return 0;; msleep(1); } return -EINVAL; @@ -3988,7 +3982,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0; + return 0;; msleep(1); } @@ -5308,7 +5302,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 autoneg_val, an_1000_val, an_10_100_val; - + bnx2x_wait_reset_complete(bp, phy); bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); @@ -5437,7 +5431,6 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); - bnx2x_wait_reset_complete(bp, phy); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); return bnx2x_848xx_cmn_config_init(phy, params, vars); @@ -5448,7 +5441,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 port, initialize = 1; + u8 port = params->port, initialize = 1; u16 val; u16 temp; u32 actual_phy_selection; @@ -5457,16 +5450,11 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ msleep(1); - if (CHIP_IS_E2(bp)) - port = BP_PATH(bp); - else - port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); - bnx2x_wait_reset_complete(bp, phy); - /* Wait for GPHY to come out of reset */ - msleep(50); + msleep(200); /* 100 is not enough */ + /* BCM84823 requires that XGXS links up first @ 10G for normal behavior */ temp = vars->line_speed; @@ -5637,11 +5625,7 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u8 port; - if (CHIP_IS_E2(bp)) - port = BP_PATH(bp); - else - port = params->port; + u8 port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_LOW, port); @@ -6944,7 +6928,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, u8 reset_ext_phy) { struct bnx2x *bp = params->bp; - u8 phy_index, port = params->port, clear_latch_ind = 0; + u8 phy_index, port = params->port; DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); /* disable attentions */ vars->link_status = 0; @@ -6982,18 +6966,9 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, params->phy[phy_index].link_reset( ¶ms->phy[phy_index], params); - if (params->phy[phy_index].flags & - FLAGS_REARM_LATCH_SIGNAL) - clear_latch_ind = 1; } } - if (clear_latch_ind) { - /* Clear latching indication */ - bnx2x_rearm_latch_signal(bp, port, 0); - bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4, - 1 << NIG_LATCH_BC_ENABLE_MI_INT); - } if (params->phy[INT_PHY].link_reset) params->phy[INT_PHY].link_reset( ¶ms->phy[INT_PHY], params); @@ -7024,7 +6999,6 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, s8 port; s8 port_of_path = 0; - bnx2x_ext_phy_hw_reset(bp, 0); /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u32 shmem_base, shmem2_base; @@ -7047,8 +7021,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, return -EINVAL; } /* disable attentions */ - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + - port_of_path*4, + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, (NIG_MASK_XGXS0_LINK_STATUS | NIG_MASK_XGXS0_LINK10G | NIG_MASK_SERDES0_LINK_STATUS | @@ -7159,7 +7132,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); - bnx2x_ext_phy_hw_reset(bp, 0); + bnx2x_ext_phy_hw_reset(bp, 1); msleep(5); for (port = 0; port < PORT_MAX; port++) { u32 shmem_base, shmem2_base; diff --git a/trunk/drivers/net/bnx2x/bnx2x_main.c b/trunk/drivers/net/bnx2x/bnx2x_main.c index f53edfd011bf..e9ad16f00b56 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x/bnx2x_main.c @@ -8078,7 +8078,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) int port = BP_PORT(bp); u32 val, val2; u32 config; - u32 ext_phy_type, ext_phy_config; + u32 ext_phy_type, ext_phy_config;; bp->link_params.bp = bp; bp->link_params.port = port; @@ -9064,7 +9064,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, default: pr_err("Unknown board_type (%ld), aborting\n", ent->driver_data); - return -ENODEV; + return ENODEV; } cid_count += CNIC_CONTEXT_USE; @@ -9096,6 +9096,12 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* calc qm_cid_count */ bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count); + rc = register_netdev(dev); + if (rc) { + dev_err(&pdev->dev, "Cannot register net device\n"); + goto init_one_exit; + } + /* Configure interupt mode: try to enable MSI-X/MSI if * needed, set bp->num_queues appropriately. */ @@ -9104,12 +9110,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* Add all NAPI objects */ bnx2x_add_all_napi(bp); - rc = register_netdev(dev); - if (rc) { - dev_err(&pdev->dev, "Cannot register net device\n"); - goto init_one_exit; - } - bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," diff --git a/trunk/drivers/net/bonding/bond_3ad.c b/trunk/drivers/net/bonding/bond_3ad.c index 48cf24ff4e6f..881914bc4e9c 100644 --- a/trunk/drivers/net/bonding/bond_3ad.c +++ b/trunk/drivers/net/bonding/bond_3ad.c @@ -2474,7 +2474,8 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac goto out; read_lock(&bond->lock); - slave = bond_get_slave_by_dev(netdev_priv(dev), orig_dev); + slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev), + orig_dev); if (!slave) goto out_unlock; diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 0273ad0b57bb..bdb68a600382 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -873,11 +873,15 @@ static void bond_mc_del(struct bonding *bond, void *addr) static void __bond_resend_igmp_join_requests(struct net_device *dev) { struct in_device *in_dev; + struct ip_mc_list *im; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); - if (in_dev) - ip_mc_rejoin_groups(in_dev); + if (in_dev) { + for (im = in_dev->mc_list; im; im = im->next) + ip_mc_rejoin_group(im); + } + rcu_read_unlock(); } @@ -3205,7 +3209,7 @@ void bond_activebackup_arp_mon(struct work_struct *work) #ifdef CONFIG_PROC_FS static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(RCU) + __acquires(&dev_base_lock) __acquires(&bond->lock) { struct bonding *bond = seq->private; @@ -3214,7 +3218,7 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos) int i; /* make sure the bond won't be taken away */ - rcu_read_lock(); + read_lock(&dev_base_lock); read_lock(&bond->lock); if (*pos == 0) @@ -3244,12 +3248,12 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void bond_info_seq_stop(struct seq_file *seq, void *v) __releases(&bond->lock) - __releases(RCU) + __releases(&dev_base_lock) { struct bonding *bond = seq->private; read_unlock(&bond->lock); - rcu_read_unlock(); + read_unlock(&dev_base_lock); } static void bond_info_show_master(struct seq_file *seq) diff --git a/trunk/drivers/net/bonding/bonding.h b/trunk/drivers/net/bonding/bonding.h index ad3ae46a4c01..4eedb12df6ca 100644 --- a/trunk/drivers/net/bonding/bonding.h +++ b/trunk/drivers/net/bonding/bonding.h @@ -286,7 +286,7 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) return NULL; } - return netdev_priv(slave->dev->master); + return (struct bonding *)netdev_priv(slave->dev->master); } static inline bool bond_is_lb(const struct bonding *bond) diff --git a/trunk/drivers/net/caif/caif_spi.c b/trunk/drivers/net/caif/caif_spi.c index 20da1996d354..8427533fe313 100644 --- a/trunk/drivers/net/caif/caif_spi.c +++ b/trunk/drivers/net/caif/caif_spi.c @@ -33,9 +33,6 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Daniel Martensson"); MODULE_DESCRIPTION("CAIF SPI driver"); -/* Returns the number of padding bytes for alignment. */ -#define PAD_POW2(x, pow) ((((x)&((pow)-1))==0) ? 0 : (((pow)-((x)&((pow)-1))))) - static int spi_loop; module_param(spi_loop, bool, S_IRUGO); MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); @@ -44,10 +41,7 @@ MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); module_param(spi_frm_align, int, S_IRUGO); MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment."); -/* - * SPI padding options. - * Warning: must be a base of 2 (& operation used) and can not be zero ! - */ +/* SPI padding options. */ module_param(spi_up_head_align, int, S_IRUGO); MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment."); @@ -246,13 +240,15 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, static const struct file_operations dbgfs_state_fops = { .open = dbgfs_open, .read = dbgfs_state, - .owner = THIS_MODULE + .owner = THIS_MODULE, + .llseek = default_llseek, }; static const struct file_operations dbgfs_frame_fops = { .open = dbgfs_open, .read = dbgfs_frame, - .owner = THIS_MODULE + .owner = THIS_MODULE, + .llseek = default_llseek, }; static inline void dev_debugfs_add(struct cfspi *cfspi) @@ -341,9 +337,6 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) u8 *dst = buf; caif_assert(buf); - if (cfspi->slave && !cfspi->slave_talked) - cfspi->slave_talked = true; - do { struct sk_buff *skb; struct caif_payload_info *info; @@ -364,8 +357,8 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) * Compute head offset i.e. number of bytes to add to * get the start of the payload aligned. */ - if (spi_up_head_align > 1) { - spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align); + if (spi_up_head_align) { + spad = 1 + ((info->hdr_len + 1) & spi_up_head_align); *dst = (u8)(spad - 1); dst += spad; } @@ -380,7 +373,7 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) * Compute tail offset i.e. number of bytes to add to * get the complete CAIF frame aligned. */ - epad = PAD_POW2((skb->len + spad), spi_up_tail_align); + epad = (skb->len + spad) & spi_up_tail_align; dst += epad; dev_kfree_skb(skb); @@ -424,14 +417,14 @@ int cfspi_xmitlen(struct cfspi *cfspi) * Compute head offset i.e. number of bytes to add to * get the start of the payload aligned. */ - if (spi_up_head_align > 1) - spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align); + if (spi_up_head_align) + spad = 1 + ((info->hdr_len + 1) & spi_up_head_align); /* * Compute tail offset i.e. number of bytes to add to * get the complete CAIF frame aligned. */ - epad = PAD_POW2((skb->len + spad), spi_up_tail_align); + epad = (skb->len + spad) & spi_up_tail_align; if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) { skb_queue_tail(&cfspi->chead, skb); @@ -440,7 +433,6 @@ int cfspi_xmitlen(struct cfspi *cfspi) } else { /* Put back packet. */ skb_queue_head(&cfspi->qhead, skb); - break; } } while (pkts <= CAIF_MAX_SPI_PKTS); @@ -461,15 +453,6 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc) { struct cfspi *cfspi = (struct cfspi *)ifc->priv; - /* - * The slave device is the master on the link. Interrupts before the - * slave has transmitted are considered spurious. - */ - if (cfspi->slave && !cfspi->slave_talked) { - printk(KERN_WARNING "CFSPI: Spurious SS interrupt.\n"); - return; - } - if (!in_interrupt()) spin_lock(&cfspi->lock); if (assert) { @@ -482,8 +465,7 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc) spin_unlock(&cfspi->lock); /* Wake up the xfer thread. */ - if (assert) - wake_up_interruptible(&cfspi->wait); + wake_up_interruptible(&cfspi->wait); } static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc) @@ -541,7 +523,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) * Compute head offset i.e. number of bytes added to * get the start of the payload aligned. */ - if (spi_down_head_align > 1) { + if (spi_down_head_align) { spad = 1 + *src; src += spad; } @@ -582,7 +564,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) * Compute tail offset i.e. number of bytes added to * get the complete CAIF frame aligned. */ - epad = PAD_POW2((pkt_len + spad), spi_down_tail_align); + epad = (pkt_len + spad) & spi_down_tail_align; src += epad; } while ((src - buf) < len); @@ -635,28 +617,19 @@ int cfspi_spi_probe(struct platform_device *pdev) ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d", cfspi_setup); - if (!ndev) - return -ENOMEM; + if (!dev) + return -ENODEV; cfspi = netdev_priv(ndev); netif_stop_queue(ndev); cfspi->ndev = ndev; cfspi->pdev = pdev; - /* Set flow info. */ + /* Set flow info */ cfspi->flow_off_sent = 0; cfspi->qd_low_mark = LOW_WATER_MARK; cfspi->qd_high_mark = HIGH_WATER_MARK; - /* Set slave info. */ - if (!strncmp(cfspi_spi_driver.driver.name, "cfspi_sspi", 10)) { - cfspi->slave = true; - cfspi->slave_talked = false; - } else { - cfspi->slave = false; - cfspi->slave_talked = false; - } - /* Assign the SPI device. */ cfspi->dev = dev; /* Assign the device ifc to this SPI interface. */ diff --git a/trunk/drivers/net/caif/caif_spi_slave.c b/trunk/drivers/net/caif/caif_spi_slave.c index 1b9943a4edab..2111dbfea6fe 100644 --- a/trunk/drivers/net/caif/caif_spi_slave.c +++ b/trunk/drivers/net/caif/caif_spi_slave.c @@ -36,15 +36,10 @@ static inline int forward_to_spi_cmd(struct cfspi *cfspi) #endif int spi_frm_align = 2; - -/* - * SPI padding options. - * Warning: must be a base of 2 (& operation used) and can not be zero ! - */ -int spi_up_head_align = 1 << 1; -int spi_up_tail_align = 1 << 0; -int spi_down_head_align = 1 << 2; -int spi_down_tail_align = 1 << 1; +int spi_up_head_align = 1; +int spi_up_tail_align; +int spi_down_head_align = 3; +int spi_down_tail_align = 1; #ifdef CONFIG_DEBUG_FS static inline void debugfs_store_prev(struct cfspi *cfspi) diff --git a/trunk/drivers/net/can/mscan/mscan.c b/trunk/drivers/net/can/mscan/mscan.c index 74cd880c7e06..64c378cd0c34 100644 --- a/trunk/drivers/net/can/mscan/mscan.c +++ b/trunk/drivers/net/can/mscan/mscan.c @@ -182,7 +182,7 @@ static int mscan_restart(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; WARN(!(in_8(®s->canmisc) & MSCAN_BOHOLD), - "bus-off state expected\n"); + "bus-off state expected"); out_8(®s->canmisc, MSCAN_BOHOLD); /* Re-enable receive interrupts. */ out_8(®s->canrier, MSCAN_RX_INTS_ENABLE); diff --git a/trunk/drivers/net/can/pch_can.c b/trunk/drivers/net/can/pch_can.c index 238622a04bc1..672718261c68 100644 --- a/trunk/drivers/net/can/pch_can.c +++ b/trunk/drivers/net/can/pch_can.c @@ -32,57 +32,58 @@ #include #include -#define PCH_MAX_MSG_OBJ 32 -#define PCH_MSG_OBJ_RX 0 /* The receive message object flag. */ -#define PCH_MSG_OBJ_TX 1 /* The transmit message object flag. */ - -#define PCH_ENABLE 1 /* The enable flag */ -#define PCH_DISABLE 0 /* The disable flag */ -#define PCH_CTRL_INIT BIT(0) /* The INIT bit of CANCONT register. */ -#define PCH_CTRL_IE BIT(1) /* The IE bit of CAN control register */ -#define PCH_CTRL_IE_SIE_EIE (BIT(3) | BIT(2) | BIT(1)) -#define PCH_CTRL_CCE BIT(6) -#define PCH_CTRL_OPT BIT(7) /* The OPT bit of CANCONT register. */ -#define PCH_OPT_SILENT BIT(3) /* The Silent bit of CANOPT reg. */ -#define PCH_OPT_LBACK BIT(4) /* The LoopBack bit of CANOPT reg. */ - -#define PCH_CMASK_RX_TX_SET 0x00f3 -#define PCH_CMASK_RX_TX_GET 0x0073 -#define PCH_CMASK_ALL 0xff -#define PCH_CMASK_NEWDAT BIT(2) -#define PCH_CMASK_CLRINTPND BIT(3) -#define PCH_CMASK_CTRL BIT(4) -#define PCH_CMASK_ARB BIT(5) -#define PCH_CMASK_MASK BIT(6) -#define PCH_CMASK_RDWR BIT(7) -#define PCH_IF_MCONT_NEWDAT BIT(15) -#define PCH_IF_MCONT_MSGLOST BIT(14) -#define PCH_IF_MCONT_INTPND BIT(13) -#define PCH_IF_MCONT_UMASK BIT(12) -#define PCH_IF_MCONT_TXIE BIT(11) -#define PCH_IF_MCONT_RXIE BIT(10) -#define PCH_IF_MCONT_RMTEN BIT(9) -#define PCH_IF_MCONT_TXRQXT BIT(8) -#define PCH_IF_MCONT_EOB BIT(7) -#define PCH_IF_MCONT_DLC (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -#define PCH_MASK2_MDIR_MXTD (BIT(14) | BIT(15)) -#define PCH_ID2_DIR BIT(13) -#define PCH_ID2_XTD BIT(14) -#define PCH_ID_MSGVAL BIT(15) -#define PCH_IF_CREQ_BUSY BIT(15) - -#define PCH_STATUS_INT 0x8000 -#define PCH_REC 0x00007f00 -#define PCH_TEC 0x000000ff - -#define PCH_TX_OK BIT(3) -#define PCH_RX_OK BIT(4) -#define PCH_EPASSIV BIT(5) -#define PCH_EWARN BIT(6) -#define PCH_BUS_OFF BIT(7) -#define PCH_LEC0 BIT(0) -#define PCH_LEC1 BIT(1) -#define PCH_LEC2 BIT(2) +#define MAX_MSG_OBJ 32 +#define MSG_OBJ_RX 0 /* The receive message object flag. */ +#define MSG_OBJ_TX 1 /* The transmit message object flag. */ + +#define ENABLE 1 /* The enable flag */ +#define DISABLE 0 /* The disable flag */ +#define CAN_CTRL_INIT 0x0001 /* The INIT bit of CANCONT register. */ +#define CAN_CTRL_IE 0x0002 /* The IE bit of CAN control register */ +#define CAN_CTRL_IE_SIE_EIE 0x000e +#define CAN_CTRL_CCE 0x0040 +#define CAN_CTRL_OPT 0x0080 /* The OPT bit of CANCONT register. */ +#define CAN_OPT_SILENT 0x0008 /* The Silent bit of CANOPT reg. */ +#define CAN_OPT_LBACK 0x0010 /* The LoopBack bit of CANOPT reg. */ +#define CAN_CMASK_RX_TX_SET 0x00f3 +#define CAN_CMASK_RX_TX_GET 0x0073 +#define CAN_CMASK_ALL 0xff +#define CAN_CMASK_RDWR 0x80 +#define CAN_CMASK_ARB 0x20 +#define CAN_CMASK_CTRL 0x10 +#define CAN_CMASK_MASK 0x40 +#define CAN_CMASK_NEWDAT 0x04 +#define CAN_CMASK_CLRINTPND 0x08 + +#define CAN_IF_MCONT_NEWDAT 0x8000 +#define CAN_IF_MCONT_INTPND 0x2000 +#define CAN_IF_MCONT_UMASK 0x1000 +#define CAN_IF_MCONT_TXIE 0x0800 +#define CAN_IF_MCONT_RXIE 0x0400 +#define CAN_IF_MCONT_RMTEN 0x0200 +#define CAN_IF_MCONT_TXRQXT 0x0100 +#define CAN_IF_MCONT_EOB 0x0080 +#define CAN_IF_MCONT_DLC 0x000f +#define CAN_IF_MCONT_MSGLOST 0x4000 +#define CAN_MASK2_MDIR_MXTD 0xc000 +#define CAN_ID2_DIR 0x2000 +#define CAN_ID_MSGVAL 0x8000 + +#define CAN_STATUS_INT 0x8000 +#define CAN_IF_CREQ_BUSY 0x8000 +#define CAN_ID2_XTD 0x4000 + +#define CAN_REC 0x00007f00 +#define CAN_TEC 0x000000ff + +#define PCH_RX_OK 0x00000010 +#define PCH_TX_OK 0x00000008 +#define PCH_BUS_OFF 0x00000080 +#define PCH_EWARN 0x00000040 +#define PCH_EPASSIV 0x00000020 +#define PCH_LEC0 0x00000001 +#define PCH_LEC1 0x00000002 +#define PCH_LEC2 0x00000004 #define PCH_LEC_ALL (PCH_LEC0 | PCH_LEC1 | PCH_LEC2) #define PCH_STUF_ERR PCH_LEC0 #define PCH_FORM_ERR PCH_LEC1 @@ -92,15 +93,26 @@ #define PCH_CRC_ERR (PCH_LEC1 | PCH_LEC2) /* bit position of certain controller bits. */ -#define PCH_BIT_BRP 0 -#define PCH_BIT_SJW 6 -#define PCH_BIT_TSEG1 8 -#define PCH_BIT_TSEG2 12 -#define PCH_BIT_BRPE_BRPE 6 -#define PCH_MSK_BITT_BRP 0x3f -#define PCH_MSK_BRPE_BRPE 0x3c0 -#define PCH_MSK_CTRL_IE_SIE_EIE 0x07 -#define PCH_COUNTER_LIMIT 10 +#define BIT_BITT_BRP 0 +#define BIT_BITT_SJW 6 +#define BIT_BITT_TSEG1 8 +#define BIT_BITT_TSEG2 12 +#define BIT_IF1_MCONT_RXIE 10 +#define BIT_IF2_MCONT_TXIE 11 +#define BIT_BRPE_BRPE 6 +#define BIT_ES_TXERRCNT 0 +#define BIT_ES_RXERRCNT 8 +#define MSK_BITT_BRP 0x3f +#define MSK_BITT_SJW 0xc0 +#define MSK_BITT_TSEG1 0xf00 +#define MSK_BITT_TSEG2 0x7000 +#define MSK_BRPE_BRPE 0x3c0 +#define MSK_BRPE_GET 0x0f +#define MSK_CTRL_IE_SIE_EIE 0x07 +#define MSK_MCONT_TXIE 0x08 +#define MSK_MCONT_RXIE 0x10 +#define PCH_CAN_NO_TX_BUFF 1 +#define COUNTER_LIMIT 10 #define PCH_CAN_CLK 50000000 /* 50MHz */ @@ -169,14 +181,14 @@ struct pch_can_priv { struct can_priv can; unsigned int can_num; struct pci_dev *dev; - unsigned int tx_enable[PCH_MAX_MSG_OBJ]; - unsigned int rx_enable[PCH_MAX_MSG_OBJ]; - unsigned int rx_link[PCH_MAX_MSG_OBJ]; + unsigned int tx_enable[MAX_MSG_OBJ]; + unsigned int rx_enable[MAX_MSG_OBJ]; + unsigned int rx_link[MAX_MSG_OBJ]; unsigned int int_enables; unsigned int int_stat; struct net_device *ndev; spinlock_t msgif_reg_lock; /* Message Interface Registers Access Lock*/ - unsigned int msg_obj[PCH_MAX_MSG_OBJ]; + unsigned int msg_obj[MAX_MSG_OBJ]; struct pch_can_regs __iomem *regs; struct napi_struct napi; unsigned int tx_obj; /* Point next Tx Obj index */ @@ -216,11 +228,11 @@ static void pch_can_set_run_mode(struct pch_can_priv *priv, { switch (mode) { case PCH_CAN_RUN: - pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_INIT); + pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_INIT); break; case PCH_CAN_STOP: - pch_can_bit_set(&priv->regs->cont, PCH_CTRL_INIT); + pch_can_bit_set(&priv->regs->cont, CAN_CTRL_INIT); break; default: @@ -234,30 +246,30 @@ static void pch_can_set_optmode(struct pch_can_priv *priv) u32 reg_val = ioread32(&priv->regs->opt); if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) - reg_val |= PCH_OPT_SILENT; + reg_val |= CAN_OPT_SILENT; if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) - reg_val |= PCH_OPT_LBACK; + reg_val |= CAN_OPT_LBACK; - pch_can_bit_set(&priv->regs->cont, PCH_CTRL_OPT); + pch_can_bit_set(&priv->regs->cont, CAN_CTRL_OPT); iowrite32(reg_val, &priv->regs->opt); } static void pch_can_set_int_custom(struct pch_can_priv *priv) { /* Clearing the IE, SIE and EIE bits of Can control register. */ - pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); + pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE); /* Appropriately setting them. */ pch_can_bit_set(&priv->regs->cont, - ((priv->int_enables & PCH_MSK_CTRL_IE_SIE_EIE) << 1)); + ((priv->int_enables & MSK_CTRL_IE_SIE_EIE) << 1)); } /* This function retrieves interrupt enabled for the CAN device. */ static void pch_can_get_int_enables(struct pch_can_priv *priv, u32 *enables) { /* Obtaining the status of IE, SIE and EIE interrupt bits. */ - *enables = ((ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1); + *enables = ((ioread32(&priv->regs->cont) & CAN_CTRL_IE_SIE_EIE) >> 1); } static void pch_can_set_int_enables(struct pch_can_priv *priv, @@ -265,19 +277,19 @@ static void pch_can_set_int_enables(struct pch_can_priv *priv, { switch (interrupt_no) { case PCH_CAN_ENABLE: - pch_can_bit_set(&priv->regs->cont, PCH_CTRL_IE); + pch_can_bit_set(&priv->regs->cont, CAN_CTRL_IE); break; case PCH_CAN_DISABLE: - pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE); + pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE); break; case PCH_CAN_ALL: - pch_can_bit_set(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); + pch_can_bit_set(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE); break; case PCH_CAN_NONE: - pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE); + pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_IE_SIE_EIE); break; default: @@ -288,12 +300,12 @@ static void pch_can_set_int_enables(struct pch_can_priv *priv, static void pch_can_check_if_busy(u32 __iomem *creq_addr, u32 num) { - u32 counter = PCH_COUNTER_LIMIT; + u32 counter = COUNTER_LIMIT; u32 ifx_creq; iowrite32(num, creq_addr); while (counter) { - ifx_creq = ioread32(creq_addr) & PCH_IF_CREQ_BUSY; + ifx_creq = ioread32(creq_addr) & CAN_IF_CREQ_BUSY; if (!ifx_creq) break; counter--; @@ -310,22 +322,22 @@ static void pch_can_set_rx_enable(struct pch_can_priv *priv, u32 buff_num, spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the receive buffer data from RAM to Interface1 registers */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); /* Setting the IF1MASK1 register to access MsgVal and RxIE bits */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_ARB | CAN_CMASK_CTRL, &priv->regs->if1_cmask); - if (set == PCH_ENABLE) { + if (set == ENABLE) { /* Setting the MsgVal and RxIE bits */ - pch_can_bit_set(&priv->regs->if1_mcont, PCH_IF_MCONT_RXIE); - pch_can_bit_set(&priv->regs->if1_id2, PCH_ID_MSGVAL); + pch_can_bit_set(&priv->regs->if1_mcont, CAN_IF_MCONT_RXIE); + pch_can_bit_set(&priv->regs->if1_id2, CAN_ID_MSGVAL); - } else if (set == PCH_DISABLE) { + } else if (set == DISABLE) { /* Resetting the MsgVal and RxIE bits */ - pch_can_bit_clear(&priv->regs->if1_mcont, PCH_IF_MCONT_RXIE); - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID_MSGVAL); + pch_can_bit_clear(&priv->regs->if1_mcont, CAN_IF_MCONT_RXIE); + pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID_MSGVAL); } pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); @@ -338,8 +350,8 @@ static void pch_can_rx_enable_all(struct pch_can_priv *priv) /* Traversing to obtain the object configured as receivers. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) - pch_can_set_rx_enable(priv, i + 1, PCH_ENABLE); + if (priv->msg_obj[i] == MSG_OBJ_RX) + pch_can_set_rx_enable(priv, i + 1, ENABLE); } } @@ -349,8 +361,8 @@ static void pch_can_rx_disable_all(struct pch_can_priv *priv) /* Traversing to obtain the object configured as receivers. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) - pch_can_set_rx_enable(priv, i + 1, PCH_DISABLE); + if (priv->msg_obj[i] == MSG_OBJ_RX) + pch_can_set_rx_enable(priv, i + 1, DISABLE); } } @@ -361,22 +373,22 @@ static void pch_can_set_tx_enable(struct pch_can_priv *priv, u32 buff_num, spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the Msg buffer from Message RAM to Interface2 registers. */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); /* Setting the IF2CMASK register for accessing the MsgVal and TxIE bits */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL, + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_ARB | CAN_CMASK_CTRL, &priv->regs->if2_cmask); - if (set == PCH_ENABLE) { + if (set == ENABLE) { /* Setting the MsgVal and TxIE bits */ - pch_can_bit_set(&priv->regs->if2_mcont, PCH_IF_MCONT_TXIE); - pch_can_bit_set(&priv->regs->if2_id2, PCH_ID_MSGVAL); - } else if (set == PCH_DISABLE) { + pch_can_bit_set(&priv->regs->if2_mcont, CAN_IF_MCONT_TXIE); + pch_can_bit_set(&priv->regs->if2_id2, CAN_ID_MSGVAL); + } else if (set == DISABLE) { /* Resetting the MsgVal and TxIE bits. */ - pch_can_bit_clear(&priv->regs->if2_mcont, PCH_IF_MCONT_TXIE); - pch_can_bit_clear(&priv->regs->if2_id2, PCH_ID_MSGVAL); + pch_can_bit_clear(&priv->regs->if2_mcont, CAN_IF_MCONT_TXIE); + pch_can_bit_clear(&priv->regs->if2_id2, CAN_ID_MSGVAL); } pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); @@ -389,8 +401,8 @@ static void pch_can_tx_enable_all(struct pch_can_priv *priv) /* Traversing to obtain the object configured as transmit object. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) - pch_can_set_tx_enable(priv, i + 1, PCH_ENABLE); + if (priv->msg_obj[i] == MSG_OBJ_TX) + pch_can_set_tx_enable(priv, i + 1, ENABLE); } } @@ -400,8 +412,8 @@ static void pch_can_tx_disable_all(struct pch_can_priv *priv) /* Traversing to obtain the object configured as transmit object. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) - pch_can_set_tx_enable(priv, i + 1, PCH_DISABLE); + if (priv->msg_obj[i] == MSG_OBJ_TX) + pch_can_set_tx_enable(priv, i + 1, DISABLE); } } @@ -411,15 +423,15 @@ static void pch_can_get_rx_enable(struct pch_can_priv *priv, u32 buff_num, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, buff_num); - if (((ioread32(&priv->regs->if1_id2)) & PCH_ID_MSGVAL) && + if (((ioread32(&priv->regs->if1_id2)) & CAN_ID_MSGVAL) && ((ioread32(&priv->regs->if1_mcont)) & - PCH_IF_MCONT_RXIE)) - *enable = PCH_ENABLE; + CAN_IF_MCONT_RXIE)) + *enable = ENABLE; else - *enable = PCH_DISABLE; + *enable = DISABLE; spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } @@ -429,15 +441,15 @@ static void pch_can_get_tx_enable(struct pch_can_priv *priv, u32 buff_num, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, buff_num); - if (((ioread32(&priv->regs->if2_id2)) & PCH_ID_MSGVAL) && + if (((ioread32(&priv->regs->if2_id2)) & CAN_ID_MSGVAL) && ((ioread32(&priv->regs->if2_mcont)) & - PCH_IF_MCONT_TXIE)) { - *enable = PCH_ENABLE; + CAN_IF_MCONT_TXIE)) { + *enable = ENABLE; } else { - *enable = PCH_DISABLE; + *enable = DISABLE; } spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } @@ -453,13 +465,13 @@ static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, &priv->regs->if1_cmask); - if (set == PCH_ENABLE) - pch_can_bit_clear(&priv->regs->if1_mcont, PCH_IF_MCONT_EOB); + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL, &priv->regs->if1_cmask); + if (set == ENABLE) + pch_can_bit_clear(&priv->regs->if1_mcont, CAN_IF_MCONT_EOB); else - pch_can_bit_set(&priv->regs->if1_mcont, PCH_IF_MCONT_EOB); + pch_can_bit_set(&priv->regs->if1_mcont, CAN_IF_MCONT_EOB); pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); @@ -471,13 +483,13 @@ static void pch_can_get_rx_buffer_link(struct pch_can_priv *priv, unsigned long flags; spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, buffer_num); - if (ioread32(&priv->regs->if1_mcont) & PCH_IF_MCONT_EOB) - *link = PCH_DISABLE; + if (ioread32(&priv->regs->if1_mcont) & CAN_IF_MCONT_EOB) + *link = DISABLE; else - *link = PCH_ENABLE; + *link = ENABLE; spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); } @@ -486,7 +498,7 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) int i; for (i = 0; i < PCH_RX_OBJ_NUM; i++) { - iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->if1_cmask); + iowrite32(CAN_CMASK_RX_TX_SET, &priv->regs->if1_cmask); iowrite32(0xffff, &priv->regs->if1_mask1); iowrite32(0xffff, &priv->regs->if1_mask2); iowrite32(0x0, &priv->regs->if1_id1); @@ -496,14 +508,14 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(0x0, &priv->regs->if1_dataa2); iowrite32(0x0, &priv->regs->if1_datab1); iowrite32(0x0, &priv->regs->if1_datab2); - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK | + CAN_CMASK_ARB | CAN_CMASK_CTRL, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, i+1); } for (i = i; i < PCH_OBJ_NUM; i++) { - iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->if2_cmask); + iowrite32(CAN_CMASK_RX_TX_SET, &priv->regs->if2_cmask); iowrite32(0xffff, &priv->regs->if2_mask1); iowrite32(0xffff, &priv->regs->if2_mask2); iowrite32(0x0, &priv->regs->if2_id1); @@ -513,8 +525,8 @@ static void pch_can_clear_buffers(struct pch_can_priv *priv) iowrite32(0x0, &priv->regs->if2_dataa2); iowrite32(0x0, &priv->regs->if2_datab1); iowrite32(0x0, &priv->regs->if2_datab2); - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK | + CAN_CMASK_ARB | CAN_CMASK_CTRL, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, i+1); } @@ -528,8 +540,8 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) spin_lock_irqsave(&priv->msgif_reg_lock, flags); for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { - iowrite32(PCH_CMASK_RX_TX_GET, + if (priv->msg_obj[i] == MSG_OBJ_RX) { + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, i+1); @@ -537,48 +549,48 @@ static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv) iowrite32(0x0, &priv->regs->if1_id2); pch_can_bit_set(&priv->regs->if1_mcont, - PCH_IF_MCONT_UMASK); + CAN_IF_MCONT_UMASK); /* Set FIFO mode set to 0 except last Rx Obj*/ pch_can_bit_clear(&priv->regs->if1_mcont, - PCH_IF_MCONT_EOB); + CAN_IF_MCONT_EOB); /* In case FIFO mode, Last EoB of Rx Obj must be 1 */ if (i == (PCH_RX_OBJ_NUM - 1)) pch_can_bit_set(&priv->regs->if1_mcont, - PCH_IF_MCONT_EOB); + CAN_IF_MCONT_EOB); iowrite32(0, &priv->regs->if1_mask1); pch_can_bit_clear(&priv->regs->if1_mask2, - 0x1fff | PCH_MASK2_MDIR_MXTD); + 0x1fff | CAN_MASK2_MDIR_MXTD); /* Setting CMASK for writing */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK | + CAN_CMASK_ARB | CAN_CMASK_CTRL, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, i+1); - } else if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) { - iowrite32(PCH_CMASK_RX_TX_GET, + } else if (priv->msg_obj[i] == MSG_OBJ_TX) { + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, i+1); /* Resetting DIR bit for reception */ iowrite32(0x0, &priv->regs->if2_id1); iowrite32(0x0, &priv->regs->if2_id2); - pch_can_bit_set(&priv->regs->if2_id2, PCH_ID2_DIR); + pch_can_bit_set(&priv->regs->if2_id2, CAN_ID2_DIR); /* Setting EOB bit for transmitter */ - iowrite32(PCH_IF_MCONT_EOB, &priv->regs->if2_mcont); + iowrite32(CAN_IF_MCONT_EOB, &priv->regs->if2_mcont); pch_can_bit_set(&priv->regs->if2_mcont, - PCH_IF_MCONT_UMASK); + CAN_IF_MCONT_UMASK); iowrite32(0, &priv->regs->if2_mask1); pch_can_bit_clear(&priv->regs->if2_mask2, 0x1fff); /* Setting CMASK for writing */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | - PCH_CMASK_ARB | PCH_CMASK_CTRL, + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK | + CAN_CMASK_ARB | CAN_CMASK_CTRL, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, i+1); @@ -620,39 +632,39 @@ static void pch_can_release(struct pch_can_priv *priv) /* This function clears interrupt(s) from the CAN device. */ static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask) { - if (mask == PCH_STATUS_INT) { + if (mask == CAN_STATUS_INT) { ioread32(&priv->regs->stat); return; } /* Clear interrupt for transmit object */ - if (priv->msg_obj[mask - 1] == PCH_MSG_OBJ_TX) { + if (priv->msg_obj[mask - 1] == MSG_OBJ_TX) { /* Setting CMASK for clearing interrupts for frame transmission. */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL | CAN_CMASK_ARB, &priv->regs->if2_cmask); /* Resetting the ID registers. */ pch_can_bit_set(&priv->regs->if2_id2, - PCH_ID2_DIR | (0x7ff << 2)); + CAN_ID2_DIR | (0x7ff << 2)); iowrite32(0x0, &priv->regs->if2_id1); /* Claring NewDat, TxRqst & IntPnd */ pch_can_bit_clear(&priv->regs->if2_mcont, - PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | - PCH_IF_MCONT_TXRQXT); + CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND | + CAN_IF_MCONT_TXRQXT); pch_can_check_if_busy(&priv->regs->if2_creq, mask); - } else if (priv->msg_obj[mask - 1] == PCH_MSG_OBJ_RX) { + } else if (priv->msg_obj[mask - 1] == MSG_OBJ_RX) { /* Setting CMASK for clearing the reception interrupts. */ - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB, + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL | CAN_CMASK_ARB, &priv->regs->if1_cmask); /* Clearing the Dir bit. */ - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID2_DIR); + pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID2_DIR); /* Clearing NewDat & IntPnd */ pch_can_bit_clear(&priv->regs->if1_mcont, - PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND); + CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND); pch_can_check_if_busy(&priv->regs->if1_creq, mask); } @@ -700,9 +712,9 @@ static void pch_can_error(struct net_device *ndev, u32 status) priv->can.can_stats.error_warning++; cf->can_id |= CAN_ERR_CRTL; errc = ioread32(&priv->regs->errc); - if (((errc & PCH_REC) >> 8) > 96) + if (((errc & CAN_REC) >> 8) > 96) cf->data[1] |= CAN_ERR_CRTL_RX_WARNING; - if ((errc & PCH_TEC) > 96) + if ((errc & CAN_TEC) > 96) cf->data[1] |= CAN_ERR_CRTL_TX_WARNING; dev_warn(&ndev->dev, "%s -> Error Counter is more than 96.\n", __func__); @@ -713,9 +725,9 @@ static void pch_can_error(struct net_device *ndev, u32 status) state = CAN_STATE_ERROR_PASSIVE; cf->can_id |= CAN_ERR_CRTL; errc = ioread32(&priv->regs->errc); - if (((errc & PCH_REC) >> 8) > 127) + if (((errc & CAN_REC) >> 8) > 127) cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; - if ((errc & PCH_TEC) > 127) + if ((errc & CAN_TEC) > 127) cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; dev_err(&ndev->dev, "%s -> CAN controller is ERROR PASSIVE .\n", __func__); @@ -783,20 +795,20 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) struct net_device_stats *stats = &(priv->ndev->stats); /* Reading the messsage object from the Message RAM */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, int_stat); /* Reading the MCONT register. */ reg = ioread32(&priv->regs->if1_mcont); reg &= 0xffff; - for (k = int_stat; !(reg & PCH_IF_MCONT_EOB); k++) { + for (k = int_stat; !(reg & CAN_IF_MCONT_EOB); k++) { /* If MsgLost bit set. */ - if (reg & PCH_IF_MCONT_MSGLOST) { + if (reg & CAN_IF_MCONT_MSGLOST) { dev_err(&priv->ndev->dev, "Msg Obj is overwritten.\n"); pch_can_bit_clear(&priv->regs->if1_mcont, - PCH_IF_MCONT_MSGLOST); - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL, + CAN_IF_MCONT_MSGLOST); + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, k); @@ -816,7 +828,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) rcv_pkts++; goto RX_NEXT; } - if (!(reg & PCH_IF_MCONT_NEWDAT)) + if (!(reg & CAN_IF_MCONT_NEWDAT)) goto RX_NEXT; skb = alloc_can_skb(priv->ndev, &cf); @@ -824,7 +836,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) return -ENOMEM; /* Get Received data */ - ide = ((ioread32(&priv->regs->if1_id2)) & PCH_ID2_XTD) >> 14; + ide = ((ioread32(&priv->regs->if1_id2)) & CAN_ID2_XTD) >> 14; if (ide) { id = (ioread32(&priv->regs->if1_id1) & 0xffff); id |= (((ioread32(&priv->regs->if1_id2)) & @@ -836,7 +848,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) cf->can_id = (id & CAN_SFF_MASK); } - rtr = (ioread32(&priv->regs->if1_id2) & PCH_ID2_DIR); + rtr = (ioread32(&priv->regs->if1_id2) & CAN_ID2_DIR); if (rtr) { cf->can_dlc = 0; cf->can_id |= CAN_RTR_FLAG; @@ -859,15 +871,15 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) stats->rx_bytes += cf->can_dlc; if (k < PCH_FIFO_THRESH) { - iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | - PCH_CMASK_ARB, &priv->regs->if1_cmask); + iowrite32(CAN_CMASK_RDWR | CAN_CMASK_CTRL | + CAN_CMASK_ARB, &priv->regs->if1_cmask); /* Clearing the Dir bit. */ - pch_can_bit_clear(&priv->regs->if1_id2, PCH_ID2_DIR); + pch_can_bit_clear(&priv->regs->if1_id2, CAN_ID2_DIR); /* Clearing NewDat & IntPnd */ pch_can_bit_clear(&priv->regs->if1_mcont, - PCH_IF_MCONT_INTPND); + CAN_IF_MCONT_INTPND); pch_can_check_if_busy(&priv->regs->if1_creq, k); } else if (k > PCH_FIFO_THRESH) { pch_can_int_clr(priv, k); @@ -878,7 +890,7 @@ static int pch_can_rx_normal(struct net_device *ndev, u32 int_stat) } RX_NEXT: /* Reading the messsage object from the Message RAM */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if1_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if1_cmask); pch_can_check_if_busy(&priv->regs->if1_creq, k + 1); reg = ioread32(&priv->regs->if1_mcont); } @@ -901,7 +913,7 @@ static int pch_can_rx_poll(struct napi_struct *napi, int quota) return 0; INT_STAT: - if (int_stat == PCH_STATUS_INT) { + if (int_stat == CAN_STATUS_INT) { reg_stat = ioread32(&priv->regs->stat); if (reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) { if ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL) @@ -910,7 +922,7 @@ static int pch_can_rx_poll(struct napi_struct *napi, int quota) if (reg_stat & PCH_TX_OK) { spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, ioread32(&priv->regs->intr)); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); @@ -921,7 +933,7 @@ static int pch_can_rx_poll(struct napi_struct *napi, int quota) pch_can_bit_clear(&priv->regs->stat, PCH_RX_OK); int_stat = pch_can_int_pending(priv); - if (int_stat == PCH_STATUS_INT) + if (int_stat == CAN_STATUS_INT) goto INT_STAT; } @@ -933,14 +945,14 @@ static int pch_can_rx_poll(struct napi_struct *napi, int quota) if (rcv_pkts < 0) return 0; } else if ((int_stat > PCH_RX_OBJ_NUM) && (int_stat <= PCH_OBJ_NUM)) { - if (priv->msg_obj[int_stat - 1] == PCH_MSG_OBJ_TX) { + if (priv->msg_obj[int_stat - 1] == MSG_OBJ_TX) { /* Handle transmission interrupt */ can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_NUM - 1); spin_lock_irqsave(&priv->msgif_reg_lock, flags); - iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND, + iowrite32(CAN_CMASK_RX_TX_GET | CAN_CMASK_CLRINTPND, &priv->regs->if2_cmask); dlc = ioread32(&priv->regs->if2_mcont) & - PCH_IF_MCONT_DLC; + CAN_IF_MCONT_DLC; pch_can_check_if_busy(&priv->regs->if2_creq, int_stat); spin_unlock_irqrestore(&priv->msgif_reg_lock, flags); if (dlc > 8) @@ -951,7 +963,7 @@ static int pch_can_rx_poll(struct napi_struct *napi, int quota) } int_stat = pch_can_int_pending(priv); - if (int_stat == PCH_STATUS_INT) + if (int_stat == CAN_STATUS_INT) goto INT_STAT; else if (int_stat >= 1 && int_stat <= 32) goto MSG_OBJ; @@ -971,17 +983,17 @@ static int pch_set_bittiming(struct net_device *ndev) u32 brp; /* Setting the CCE bit for accessing the Can Timing register. */ - pch_can_bit_set(&priv->regs->cont, PCH_CTRL_CCE); + pch_can_bit_set(&priv->regs->cont, CAN_CTRL_CCE); brp = (bt->tq) / (1000000000/PCH_CAN_CLK) - 1; - canbit = brp & PCH_MSK_BITT_BRP; - canbit |= (bt->sjw - 1) << PCH_BIT_SJW; - canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1; - canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2; - bepe = (brp & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE; + canbit = brp & MSK_BITT_BRP; + canbit |= (bt->sjw - 1) << BIT_BITT_SJW; + canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << BIT_BITT_TSEG1; + canbit |= (bt->phase_seg2 - 1) << BIT_BITT_TSEG2; + bepe = (brp & MSK_BRPE_BRPE) >> BIT_BRPE_BRPE; iowrite32(canbit, &priv->regs->bitt); iowrite32(bepe, &priv->regs->brpe); - pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_CCE); + pch_can_bit_clear(&priv->regs->cont, CAN_CTRL_CCE); return 0; } @@ -1125,19 +1137,19 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) spin_lock_irqsave(&priv->msgif_reg_lock, flags); /* Reading the Msg Obj from the Msg RAM to the Interface register. */ - iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->if2_cmask); + iowrite32(CAN_CMASK_RX_TX_GET, &priv->regs->if2_cmask); pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail); /* Setting the CMASK register. */ - pch_can_bit_set(&priv->regs->if2_cmask, PCH_CMASK_ALL); + pch_can_bit_set(&priv->regs->if2_cmask, CAN_CMASK_ALL); /* If ID extended is set. */ pch_can_bit_clear(&priv->regs->if2_id1, 0xffff); - pch_can_bit_clear(&priv->regs->if2_id2, 0x1fff | PCH_ID2_XTD); + pch_can_bit_clear(&priv->regs->if2_id2, 0x1fff | CAN_ID2_XTD); if (cf->can_id & CAN_EFF_FLAG) { pch_can_bit_set(&priv->regs->if2_id1, cf->can_id & 0xffff); pch_can_bit_set(&priv->regs->if2_id2, - ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD); + ((cf->can_id >> 16) & 0x1fff) | CAN_ID2_XTD); } else { pch_can_bit_set(&priv->regs->if2_id1, 0); pch_can_bit_set(&priv->regs->if2_id2, @@ -1146,7 +1158,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) /* If remote frame has to be transmitted.. */ if (cf->can_id & CAN_RTR_FLAG) - pch_can_bit_clear(&priv->regs->if2_id2, PCH_ID2_DIR); + pch_can_bit_clear(&priv->regs->if2_id2, CAN_ID2_DIR); for (i = 0, j = 0; i < cf->can_dlc; j++) { iowrite32(le32_to_cpu(cf->data[i++]), @@ -1165,12 +1177,12 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) /* Clearing IntPend, NewDat & TxRqst */ pch_can_bit_clear(&priv->regs->if2_mcont, - PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND | - PCH_IF_MCONT_TXRQXT); + CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_INTPND | + CAN_IF_MCONT_TXRQXT); /* Setting NewDat, TxRqst bits */ pch_can_bit_set(&priv->regs->if2_mcont, - PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT); + CAN_IF_MCONT_NEWDAT | CAN_IF_MCONT_TXRQXT); pch_can_check_if_busy(&priv->regs->if2_creq, tx_buffer_avail); @@ -1233,7 +1245,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) /* Save Tx buffer enable state */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) + if (priv->msg_obj[i] == MSG_OBJ_TX) pch_can_get_tx_enable(priv, i + 1, &(priv->tx_enable[i])); } @@ -1243,7 +1255,7 @@ static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state) /* Save Rx buffer enable state */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { + if (priv->msg_obj[i] == MSG_OBJ_RX) { pch_can_get_rx_enable(priv, i + 1, &(priv->rx_enable[i])); pch_can_get_rx_buffer_link(priv, i + 1, @@ -1301,7 +1313,7 @@ static int pch_can_resume(struct pci_dev *pdev) /* Enabling the transmit buffer. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_TX) { + if (priv->msg_obj[i] == MSG_OBJ_TX) { pch_can_set_tx_enable(priv, i + 1, priv->tx_enable[i]); } @@ -1309,7 +1321,7 @@ static int pch_can_resume(struct pci_dev *pdev) /* Configuring the receive buffer and enabling them. */ for (i = 0; i < PCH_OBJ_NUM; i++) { - if (priv->msg_obj[i] == PCH_MSG_OBJ_RX) { + if (priv->msg_obj[i] == MSG_OBJ_RX) { /* Restore buffer link */ pch_can_set_rx_buffer_link(priv, i + 1, priv->rx_link[i]); @@ -1337,8 +1349,8 @@ static int pch_can_get_berr_counter(const struct net_device *dev, { struct pch_can_priv *priv = netdev_priv(dev); - bec->txerr = ioread32(&priv->regs->errc) & PCH_TEC; - bec->rxerr = (ioread32(&priv->regs->errc) & PCH_REC) >> 8; + bec->txerr = ioread32(&priv->regs->errc) & CAN_TEC; + bec->rxerr = (ioread32(&priv->regs->errc) & CAN_REC) >> 8; return 0; } @@ -1398,10 +1410,10 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, priv->can.clock.freq = PCH_CAN_CLK; /* Hz */ for (index = 0; index < PCH_RX_OBJ_NUM;) - priv->msg_obj[index++] = PCH_MSG_OBJ_RX; + priv->msg_obj[index++] = MSG_OBJ_RX; for (index = index; index < PCH_OBJ_NUM;) - priv->msg_obj[index++] = PCH_MSG_OBJ_TX; + priv->msg_obj[index++] = MSG_OBJ_TX; netif_napi_add(ndev, &priv->napi, pch_can_rx_poll, PCH_RX_OBJ_NUM); diff --git a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c index 09c3e9db9316..5bfccfdf3bbb 100644 --- a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c @@ -107,13 +107,17 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev, res_size = resource_size(&res); if (!request_mem_region(res.start, res_size, DRV_NAME)) { - dev_err(&ofdev->dev, "couldn't request %pR\n", &res); + dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n", + (unsigned long long)res.start, + (unsigned long long)res.end); return -EBUSY; } base = ioremap_nocache(res.start, res_size); if (!base) { - dev_err(&ofdev->dev, "couldn't ioremap %pR\n", &res); + dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n", + (unsigned long long)res.start, + (unsigned long long)res.end); err = -ENOMEM; goto exit_release_mem; } diff --git a/trunk/drivers/net/cnic.c b/trunk/drivers/net/cnic.c index 594ca9c2c10a..92bac19ad60a 100644 --- a/trunk/drivers/net/cnic.c +++ b/trunk/drivers/net/cnic.c @@ -1695,7 +1695,7 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], *work = num; return -EINVAL; } - *work = 2 + req2->num_additional_wqes; + *work = 2 + req2->num_additional_wqes;; l5_cid = req1->iscsi_conn_id; if (l5_cid >= MAX_ISCSI_TBL_SZ) diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index 386461750d0f..407d4e272075 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -3006,11 +3006,12 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { struct adapter *adapter = pci_get_drvdata(pdev); + int ret; if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - t3_adapter_error(adapter, 0, 0); + ret = t3_adapter_error(adapter, 0, 0); /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; @@ -3340,6 +3341,7 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->name = adapter->port[i]->name; __set_bit(i, &adapter->registered_device_map); + netif_tx_stop_all_queues(adapter->port[i]); } } if (!adapter->registered_device_map) { diff --git a/trunk/drivers/net/cxgb3/cxgb3_offload.c b/trunk/drivers/net/cxgb3/cxgb3_offload.c index ef02aa68c926..bcf07532953d 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_offload.c +++ b/trunk/drivers/net/cxgb3/cxgb3_offload.c @@ -1164,10 +1164,12 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) */ void *cxgb_alloc_mem(unsigned long size) { - void *p = kzalloc(size, GFP_KERNEL); + void *p = kmalloc(size, GFP_KERNEL); if (!p) - p = vzalloc(size); + p = vmalloc(size); + if (p) + memset(p, 0, size); return p; } diff --git a/trunk/drivers/net/cxgb4/cxgb4_main.c b/trunk/drivers/net/cxgb4/cxgb4_main.c index 848f89d19fb7..f17703f410b3 100644 --- a/trunk/drivers/net/cxgb4/cxgb4_main.c +++ b/trunk/drivers/net/cxgb4/cxgb4_main.c @@ -868,10 +868,12 @@ out: release_firmware(fw); */ void *t4_alloc_mem(size_t size) { - void *p = kzalloc(size, GFP_KERNEL); + void *p = kmalloc(size, GFP_KERNEL); if (!p) - p = vzalloc(size); + p = vmalloc(size); + if (p) + memset(p, 0, size); return p; } @@ -3734,6 +3736,7 @@ static int __devinit init_one(struct pci_dev *pdev, __set_bit(i, &adapter->registered_device_map); adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i; + netif_tx_stop_all_queues(adapter->port[i]); } } if (!adapter->registered_device_map) { diff --git a/trunk/drivers/net/cxgb4vf/adapter.h b/trunk/drivers/net/cxgb4vf/adapter.h index 4766b4116b41..8ea01962e045 100644 --- a/trunk/drivers/net/cxgb4vf/adapter.h +++ b/trunk/drivers/net/cxgb4vf/adapter.h @@ -60,7 +60,7 @@ enum { * MSI-X interrupt index usage. */ MSIX_FW = 0, /* MSI-X index for firmware Q */ - MSIX_IQFLINT = 1, /* MSI-X index base for Ingress Qs */ + MSIX_NIQFLINT = 1, /* MSI-X index base for Ingress Qs */ MSIX_EXTRAS = 1, MSIX_ENTRIES = MAX_ETH_QSETS + MSIX_EXTRAS, diff --git a/trunk/drivers/net/cxgb4vf/cxgb4vf_main.c b/trunk/drivers/net/cxgb4vf/cxgb4vf_main.c index 9246d2fa6cf9..555ecc5a2e93 100644 --- a/trunk/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/trunk/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -280,7 +280,9 @@ static void name_msix_vecs(struct adapter *adapter) const struct port_info *pi = netdev_priv(dev); int qs, msi; - for (qs = 0, msi = MSIX_IQFLINT; qs < pi->nqsets; qs++, msi++) { + for (qs = 0, msi = MSIX_NIQFLINT; + qs < pi->nqsets; + qs++, msi++) { snprintf(adapter->msix_info[msi].desc, namelen, "%s-%d", dev->name, qs); adapter->msix_info[msi].desc[namelen] = 0; @@ -307,7 +309,7 @@ static int request_msix_queue_irqs(struct adapter *adapter) /* * Ethernet queues. */ - msi = MSIX_IQFLINT; + msi = MSIX_NIQFLINT; for_each_ethrxq(s, rxq) { err = request_irq(adapter->msix_info[msi].vec, t4vf_sge_intr_msix, 0, @@ -335,7 +337,7 @@ static void free_msix_queue_irqs(struct adapter *adapter) int rxq, msi; free_irq(adapter->msix_info[MSIX_FW].vec, &s->fw_evtq); - msi = MSIX_IQFLINT; + msi = MSIX_NIQFLINT; for_each_ethrxq(s, rxq) free_irq(adapter->msix_info[msi++].vec, &s->ethrxq[rxq].rspq); @@ -525,7 +527,7 @@ static int setup_sge_queues(struct adapter *adapter) * brought up at which point lots of things get nailed down * permanently ... */ - msix = MSIX_IQFLINT; + msix = MSIX_NIQFLINT; for_each_port(adapter, pidx) { struct net_device *dev = adapter->port[pidx]; struct port_info *pi = netdev_priv(dev); @@ -751,9 +753,7 @@ static int cxgb4vf_open(struct net_device *dev) if (err) return err; set_bit(pi->port_id, &adapter->open_device_map); - err = link_start(dev); - if (err) - return err; + link_start(dev); netif_tx_start_all_queues(dev); return 0; } @@ -1103,6 +1103,18 @@ static int cxgb4vf_set_mac_addr(struct net_device *dev, void *_addr) return 0; } +/* + * Return a TX Queue on which to send the specified skb. + */ +static u16 cxgb4vf_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + /* + * XXX For now just use the default hash but we probably want to + * XXX look at other possibilities ... + */ + return skb_tx_hash(dev, skb); +} + #ifdef CONFIG_NET_POLL_CONTROLLER /* * Poll all of our receive queues. This is called outside of normal interrupt @@ -1346,8 +1358,6 @@ struct queue_port_stats { u64 rx_csum; u64 vlan_ex; u64 vlan_ins; - u64 lro_pkts; - u64 lro_merged; }; /* @@ -1385,8 +1395,6 @@ static const char stats_strings[][ETH_GSTRING_LEN] = { "RxCsumGood ", "VLANextractions ", "VLANinsertions ", - "GROPackets ", - "GROMerged ", }; /* @@ -1436,8 +1444,6 @@ static void collect_sge_port_stats(const struct adapter *adapter, stats->rx_csum += rxq->stats.rx_cso; stats->vlan_ex += rxq->stats.vlan_ex; stats->vlan_ins += txq->vlan_ins; - stats->lro_pkts += rxq->stats.lro_pkts; - stats->lro_merged += rxq->stats.lro_merged; } } @@ -1533,20 +1539,15 @@ static void cxgb4vf_get_wol(struct net_device *dev, memset(&wol->sopass, 0, sizeof(wol->sopass)); } -/* - * TCP Segmentation Offload flags which we support. - */ -#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) - /* * Set TCP Segmentation Offloading feature capabilities. */ static int cxgb4vf_set_tso(struct net_device *dev, u32 tso) { if (tso) - dev->features |= TSO_FLAGS; + dev->features |= NETIF_F_TSO | NETIF_F_TSO6; else - dev->features &= ~TSO_FLAGS; + dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); return 0; } @@ -2037,7 +2038,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) * Tear down the /sys/kernel/debug/cxgb4vf sub-nodes created above. We leave * it to our caller to tear down the directory (debugfs_root). */ -static void cleanup_debugfs(struct adapter *adapter) +static void __devexit cleanup_debugfs(struct adapter *adapter) { BUG_ON(adapter->debugfs_root == NULL); @@ -2055,7 +2056,7 @@ static void cleanup_debugfs(struct adapter *adapter) * adapter parameters we're going to be using and initialize basic adapter * hardware support. */ -static int __devinit adap_init0(struct adapter *adapter) +static int adap_init0(struct adapter *adapter) { struct vf_resources *vfres = &adapter->params.vfres; struct sge_params *sge_params = &adapter->params.sge; @@ -2073,22 +2074,6 @@ static int __devinit adap_init0(struct adapter *adapter) return err; } - /* - * Some environments do not properly handle PCIE FLRs -- e.g. in Linux - * 2.6.31 and later we can't call pci_reset_function() in order to - * issue an FLR because of a self- deadlock on the device semaphore. - * Meanwhile, the OS infrastructure doesn't issue FLRs in all the - * cases where they're needed -- for instance, some versions of KVM - * fail to reset "Assigned Devices" when the VM reboots. Therefore we - * use the firmware based reset in order to reset any per function - * state. - */ - err = t4vf_fw_reset(adapter); - if (err < 0) { - dev_err(adapter->pdev_dev, "FW reset failed: err=%d\n", err); - return err; - } - /* * Grab basic operational parameters. These will predominantly have * been set up by the Physical Function Driver or will be hard coded @@ -2432,6 +2417,7 @@ static const struct net_device_ops cxgb4vf_netdev_ops = { .ndo_get_stats = cxgb4vf_get_stats, .ndo_set_rx_mode = cxgb4vf_set_rxmode, .ndo_set_mac_address = cxgb4vf_set_mac_addr, + .ndo_select_queue = cxgb4vf_select_queue, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = cxgb4vf_do_ioctl, .ndo_change_mtu = cxgb4vf_change_mtu, @@ -2479,6 +2465,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, version_printed = 1; } + /* * Initialize generic PCI device state. */ @@ -2613,9 +2600,10 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, pi->xact_addr_filt = -1; pi->rx_offload = RX_CSO; netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); netdev->irq = pdev->irq; - netdev->features = (NETIF_F_SG | TSO_FLAGS | + netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_GRO); @@ -2637,6 +2625,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, netdev->do_ioctl = cxgb4vf_do_ioctl; netdev->change_mtu = cxgb4vf_change_mtu; netdev->set_mac_address = cxgb4vf_set_mac_addr; + netdev->select_queue = cxgb4vf_select_queue; #ifdef CONFIG_NET_POLL_CONTROLLER netdev->poll_controller = cxgb4vf_poll_controller; #endif @@ -2855,14 +2844,6 @@ static struct pci_device_id cxgb4vf_pci_tbl[] = { CH_DEVICE(0x4800, 0), /* T440-dbg */ CH_DEVICE(0x4801, 0), /* T420-cr */ CH_DEVICE(0x4802, 0), /* T422-cr */ - CH_DEVICE(0x4803, 0), /* T440-cr */ - CH_DEVICE(0x4804, 0), /* T420-bch */ - CH_DEVICE(0x4805, 0), /* T440-bch */ - CH_DEVICE(0x4806, 0), /* T460-ch */ - CH_DEVICE(0x4807, 0), /* T420-so */ - CH_DEVICE(0x4808, 0), /* T420-cx */ - CH_DEVICE(0x4809, 0), /* T420-bt */ - CH_DEVICE(0x480a, 0), /* T404-bt */ { 0, } }; diff --git a/trunk/drivers/net/cxgb4vf/sge.c b/trunk/drivers/net/cxgb4vf/sge.c index e0b3d1bc2fdf..f10864ddafbe 100644 --- a/trunk/drivers/net/cxgb4vf/sge.c +++ b/trunk/drivers/net/cxgb4vf/sge.c @@ -154,15 +154,14 @@ enum { */ RX_COPY_THRES = 256, RX_PULL_LEN = 128, - - /* - * Main body length for sk_buffs used for RX Ethernet packets with - * fragments. Should be >= RX_PULL_LEN but possibly bigger to give - * pskb_may_pull() some room. - */ - RX_SKB_LEN = 512, }; +/* + * Can't define this in the above enum because PKTSHIFT isn't a constant in + * the VF Driver ... + */ +#define RX_PKT_PULL_LEN (RX_PULL_LEN + PKTSHIFT) + /* * Software state per TX descriptor. */ @@ -1355,67 +1354,6 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -/** - * t4vf_pktgl_to_skb - build an sk_buff from a packet gather list - * @gl: the gather list - * @skb_len: size of sk_buff main body if it carries fragments - * @pull_len: amount of data to move to the sk_buff's main body - * - * Builds an sk_buff from the given packet gather list. Returns the - * sk_buff or %NULL if sk_buff allocation failed. - */ -struct sk_buff *t4vf_pktgl_to_skb(const struct pkt_gl *gl, - unsigned int skb_len, unsigned int pull_len) -{ - struct sk_buff *skb; - struct skb_shared_info *ssi; - - /* - * If the ingress packet is small enough, allocate an skb large enough - * for all of the data and copy it inline. Otherwise, allocate an skb - * with enough room to pull in the header and reference the rest of - * the data via the skb fragment list. - * - * Below we rely on RX_COPY_THRES being less than the smallest Rx - * buff! size, which is expected since buffers are at least - * PAGE_SIZEd. In this case packets up to RX_COPY_THRES have only one - * fragment. - */ - if (gl->tot_len <= RX_COPY_THRES) { - /* small packets have only one fragment */ - skb = alloc_skb(gl->tot_len, GFP_ATOMIC); - if (unlikely(!skb)) - goto out; - __skb_put(skb, gl->tot_len); - skb_copy_to_linear_data(skb, gl->va, gl->tot_len); - } else { - skb = alloc_skb(skb_len, GFP_ATOMIC); - if (unlikely(!skb)) - goto out; - __skb_put(skb, pull_len); - skb_copy_to_linear_data(skb, gl->va, pull_len); - - ssi = skb_shinfo(skb); - ssi->frags[0].page = gl->frags[0].page; - ssi->frags[0].page_offset = gl->frags[0].page_offset + pull_len; - ssi->frags[0].size = gl->frags[0].size - pull_len; - if (gl->nfrags > 1) - memcpy(&ssi->frags[1], &gl->frags[1], - (gl->nfrags-1) * sizeof(skb_frag_t)); - ssi->nr_frags = gl->nfrags; - - skb->len = gl->tot_len; - skb->data_len = skb->len - pull_len; - skb->truesize += skb->data_len; - - /* Get a reference for the last page, we don't own it */ - get_page(gl->frags[gl->nfrags - 1].page); - } - -out: - return skb; -} - /** * t4vf_pktgl_free - free a packet gather list * @gl: the gather list @@ -1525,8 +1463,10 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, { struct sk_buff *skb; struct port_info *pi; + struct skb_shared_info *ssi; const struct cpl_rx_pkt *pkt = (void *)&rsp[1]; bool csum_ok = pkt->csum_calc && !pkt->err_vec; + unsigned int len = be16_to_cpu(pkt->len); struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq); /* @@ -1541,14 +1481,42 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } /* - * Convert the Packet Gather List into an skb. + * If the ingress packet is small enough, allocate an skb large enough + * for all of the data and copy it inline. Otherwise, allocate an skb + * with enough room to pull in the header and reference the rest of + * the data via the skb fragment list. */ - skb = t4vf_pktgl_to_skb(gl, RX_SKB_LEN, RX_PULL_LEN); - if (unlikely(!skb)) { - t4vf_pktgl_free(gl); - rxq->stats.rx_drops++; - return 0; + if (len <= RX_COPY_THRES) { + /* small packets have only one fragment */ + skb = alloc_skb(gl->frags[0].size, GFP_ATOMIC); + if (!skb) + goto nomem; + __skb_put(skb, gl->frags[0].size); + skb_copy_to_linear_data(skb, gl->va, gl->frags[0].size); + } else { + skb = alloc_skb(RX_PKT_PULL_LEN, GFP_ATOMIC); + if (!skb) + goto nomem; + __skb_put(skb, RX_PKT_PULL_LEN); + skb_copy_to_linear_data(skb, gl->va, RX_PKT_PULL_LEN); + + ssi = skb_shinfo(skb); + ssi->frags[0].page = gl->frags[0].page; + ssi->frags[0].page_offset = (gl->frags[0].page_offset + + RX_PKT_PULL_LEN); + ssi->frags[0].size = gl->frags[0].size - RX_PKT_PULL_LEN; + if (gl->nfrags > 1) + memcpy(&ssi->frags[1], &gl->frags[1], + (gl->nfrags-1) * sizeof(skb_frag_t)); + ssi->nr_frags = gl->nfrags; + skb->len = len + PKTSHIFT; + skb->data_len = skb->len - RX_PKT_PULL_LEN; + skb->truesize += skb->data_len; + + /* Get a reference for the last page, we don't own it */ + get_page(gl->frags[gl->nfrags - 1].page); } + __skb_pull(skb, PKTSHIFT); skb->protocol = eth_type_trans(skb, rspq->netdev); skb_record_rx_queue(skb, rspq->idx); @@ -1568,9 +1536,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } else skb_checksum_none_assert(skb); - /* - * Deliver the packet to the stack. - */ if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; @@ -1584,6 +1549,11 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, netif_receive_skb(skb); return 0; + +nomem: + t4vf_pktgl_free(gl); + rxq->stats.rx_drops++; + return 0; } /** @@ -1709,7 +1679,6 @@ int process_responses(struct sge_rspq *rspq, int budget) } len = RSPD_LEN(len); } - gl.tot_len = len; /* * Gather packet fragments. @@ -2146,7 +2115,7 @@ int t4vf_sge_alloc_rxq(struct adapter *adapter, struct sge_rspq *rspq, /* * Calculate the size of the hardware free list ring plus - * Status Page (which the SGE will place after the end of the + * status page (which the SGE will place at the end of the * free list ring) in Egress Queue Units. */ flsz = (fl->size / FL_PER_EQ_UNIT + @@ -2243,8 +2212,8 @@ int t4vf_sge_alloc_eth_txq(struct adapter *adapter, struct sge_eth_txq *txq, struct port_info *pi = netdev_priv(dev); /* - * Calculate the size of the hardware TX Queue (including the Status - * Page on the end of the TX Queue) in units of TX Descriptors. + * Calculate the size of the hardware TX Queue (including the + * status age on the end) in units of TX Descriptors. */ nentries = txq->q.size + STAT_LEN / sizeof(struct tx_desc); diff --git a/trunk/drivers/net/cxgb4vf/t4vf_common.h b/trunk/drivers/net/cxgb4vf/t4vf_common.h index a65c80aed1f2..873cb7d86c57 100644 --- a/trunk/drivers/net/cxgb4vf/t4vf_common.h +++ b/trunk/drivers/net/cxgb4vf/t4vf_common.h @@ -235,7 +235,6 @@ static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd, int __devinit t4vf_wait_dev_ready(struct adapter *); int __devinit t4vf_port_init(struct adapter *, int); -int t4vf_fw_reset(struct adapter *); int t4vf_query_params(struct adapter *, unsigned int, const u32 *, u32 *); int t4vf_set_params(struct adapter *, unsigned int, const u32 *, const u32 *); diff --git a/trunk/drivers/net/cxgb4vf/t4vf_hw.c b/trunk/drivers/net/cxgb4vf/t4vf_hw.c index f7d7f976064b..ea1c123f0cb4 100644 --- a/trunk/drivers/net/cxgb4vf/t4vf_hw.c +++ b/trunk/drivers/net/cxgb4vf/t4vf_hw.c @@ -325,25 +325,6 @@ int __devinit t4vf_port_init(struct adapter *adapter, int pidx) return 0; } -/** - * t4vf_fw_reset - issue a reset to FW - * @adapter: the adapter - * - * Issues a reset command to FW. For a Physical Function this would - * result in the Firmware reseting all of its state. For a Virtual - * Function this just resets the state associated with the VF. - */ -int t4vf_fw_reset(struct adapter *adapter) -{ - struct fw_reset_cmd cmd; - - memset(&cmd, 0, sizeof(cmd)); - cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RESET_CMD) | - FW_CMD_WRITE); - cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); - return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL); -} - /** * t4vf_query_params - query FW or device parameters * @adapter: the adapter @@ -1276,7 +1257,7 @@ int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid) */ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) { - const struct fw_cmd_hdr *cmd_hdr = (const struct fw_cmd_hdr *)rpl; + struct fw_cmd_hdr *cmd_hdr = (struct fw_cmd_hdr *)rpl; u8 opcode = FW_CMD_OP_GET(be32_to_cpu(cmd_hdr->hi)); switch (opcode) { @@ -1284,8 +1265,7 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) /* * Link/module state change message. */ - const struct fw_port_cmd *port_cmd = - (const struct fw_port_cmd *)rpl; + const struct fw_port_cmd *port_cmd = (void *)rpl; u32 word; int action, port_id, link_ok, speed, fc, pidx; diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index 2d4c4fc1d900..9f6aeefa06bf 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -1675,7 +1675,7 @@ dm9000_drv_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); - dm9000_release_board(pdev, netdev_priv(ndev)); + dm9000_release_board(pdev, (board_info_t *) netdev_priv(ndev)); free_netdev(ndev); /* free device structure */ dev_dbg(&pdev->dev, "released and freed device\n"); diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index dcb7f82c2701..4686c3983fc3 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -1425,12 +1425,13 @@ static int e1000_setup_tx_resources(struct e1000_adapter *adapter, int size; size = sizeof(struct e1000_buffer) * txdr->count; - txdr->buffer_info = vzalloc(size); + txdr->buffer_info = vmalloc(size); if (!txdr->buffer_info) { e_err(probe, "Unable to allocate memory for the Tx descriptor " "ring\n"); return -ENOMEM; } + memset(txdr->buffer_info, 0, size); /* round up to nearest 4K */ @@ -1620,12 +1621,13 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, int size, desc_len; size = sizeof(struct e1000_buffer) * rxdr->count; - rxdr->buffer_info = vzalloc(size); + rxdr->buffer_info = vmalloc(size); if (!rxdr->buffer_info) { e_err(probe, "Unable to allocate memory for the Rx descriptor " "ring\n"); return -ENOMEM; } + memset(rxdr->buffer_info, 0, size); desc_len = sizeof(struct e1000_rx_desc); diff --git a/trunk/drivers/net/e1000e/82571.c b/trunk/drivers/net/e1000e/82571.c index 9333921010cc..7236f1a53ba0 100644 --- a/trunk/drivers/net/e1000e/82571.c +++ b/trunk/drivers/net/e1000e/82571.c @@ -74,9 +74,6 @@ static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); static s32 e1000_led_on_82574(struct e1000_hw *hw); static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); -static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw); -static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); -static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); /** * e1000_init_phy_params_82571 - Init PHY func ptrs. @@ -110,8 +107,6 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) case e1000_82574: case e1000_82583: phy->type = e1000_phy_bm; - phy->ops.acquire = e1000_get_hw_semaphore_82574; - phy->ops.release = e1000_put_hw_semaphore_82574; break; default: return -E1000_ERR_PHY; @@ -205,17 +200,6 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) break; } - /* Function Pointers */ - switch (hw->mac.type) { - case e1000_82574: - case e1000_82583: - nvm->ops.acquire = e1000_get_hw_semaphore_82574; - nvm->ops.release = e1000_put_hw_semaphore_82574; - break; - default: - break; - } - return 0; } @@ -558,94 +542,6 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); ew32(SWSM, swsm); } -/** - * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore - * @hw: pointer to the HW structure - * - * Acquire the HW semaphore during reset. - * - **/ -static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw) -{ - u32 extcnf_ctrl; - s32 ret_val = 0; - s32 i = 0; - - extcnf_ctrl = er32(EXTCNF_CTRL); - extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; - do { - ew32(EXTCNF_CTRL, extcnf_ctrl); - extcnf_ctrl = er32(EXTCNF_CTRL); - - if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) - break; - - extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; - - msleep(2); - i++; - } while (i < MDIO_OWNERSHIP_TIMEOUT); - - if (i == MDIO_OWNERSHIP_TIMEOUT) { - /* Release semaphores */ - e1000_put_hw_semaphore_82573(hw); - e_dbg("Driver can't access the PHY\n"); - ret_val = -E1000_ERR_PHY; - goto out; - } - -out: - return ret_val; -} - -/** - * e1000_put_hw_semaphore_82573 - Release hardware semaphore - * @hw: pointer to the HW structure - * - * Release hardware semaphore used during reset. - * - **/ -static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw) -{ - u32 extcnf_ctrl; - - extcnf_ctrl = er32(EXTCNF_CTRL); - extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; - ew32(EXTCNF_CTRL, extcnf_ctrl); -} - -static DEFINE_MUTEX(swflag_mutex); - -/** - * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore - * @hw: pointer to the HW structure - * - * Acquire the HW semaphore to access the PHY or NVM. - * - **/ -static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw) -{ - s32 ret_val; - - mutex_lock(&swflag_mutex); - ret_val = e1000_get_hw_semaphore_82573(hw); - if (ret_val) - mutex_unlock(&swflag_mutex); - return ret_val; -} - -/** - * e1000_put_hw_semaphore_82574 - Release hardware semaphore - * @hw: pointer to the HW structure - * - * Release hardware semaphore used to access the PHY or NVM - * - **/ -static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw) -{ - e1000_put_hw_semaphore_82573(hw); - mutex_unlock(&swflag_mutex); -} /** * e1000_acquire_nvm_82571 - Request for access to the EEPROM @@ -666,6 +562,8 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_82573: + case e1000_82574: + case e1000_82583: break; default: ret_val = e1000e_acquire_nvm(hw); @@ -955,8 +853,9 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) **/ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) { - u32 ctrl, ctrl_ext, icr; + u32 ctrl, extcnf_ctrl, ctrl_ext, icr; s32 ret_val; + u16 i = 0; /* * Prevent the PCI-E bus from sticking if there is no TLP connection @@ -981,33 +880,33 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) */ switch (hw->mac.type) { case e1000_82573: - ret_val = e1000_get_hw_semaphore_82573(hw); - break; case e1000_82574: case e1000_82583: - ret_val = e1000_get_hw_semaphore_82574(hw); + extcnf_ctrl = er32(EXTCNF_CTRL); + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + + do { + ew32(EXTCNF_CTRL, extcnf_ctrl); + extcnf_ctrl = er32(EXTCNF_CTRL); + + if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) + break; + + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + + msleep(2); + i++; + } while (i < MDIO_OWNERSHIP_TIMEOUT); break; default: break; } - if (ret_val) - e_dbg("Cannot acquire MDIO ownership\n"); ctrl = er32(CTRL); e_dbg("Issuing a global reset to MAC\n"); ew32(CTRL, ctrl | E1000_CTRL_RST); - /* Must release MDIO ownership and mutex after MAC reset. */ - switch (hw->mac.type) { - case e1000_82574: - case e1000_82583: - e1000_put_hw_semaphore_82574(hw); - break; - default: - break; - } - if (hw->nvm.type == e1000_nvm_flash_hw) { udelay(10); ctrl_ext = er32(CTRL_EXT); @@ -1532,10 +1431,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) * auto-negotiation in the TXCW register and disable * forced link in the Device Control register in an * attempt to auto-negotiate with our link partner. - * If the partner code word is null, stop forcing - * and restart auto negotiation. */ - if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { + if (rxcw & E1000_RXCW_C) { /* Enable autoneg, and unforce link up */ ew32(TXCW, mac->txcw); ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); diff --git a/trunk/drivers/net/e1000e/defines.h b/trunk/drivers/net/e1000e/defines.h index 016ea383145a..d3f7a9c3f973 100644 --- a/trunk/drivers/net/e1000e/defines.h +++ b/trunk/drivers/net/e1000e/defines.h @@ -516,7 +516,6 @@ #define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */ /* Receive Configuration Word */ -#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */ #define E1000_RXCW_IV 0x08000000 /* Receive config invalid */ #define E1000_RXCW_C 0x20000000 /* Receive config */ #define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 0adcb79e6386..c4ca1629f532 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -2059,9 +2059,10 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter) int err = -ENOMEM, size; size = sizeof(struct e1000_buffer) * tx_ring->count; - tx_ring->buffer_info = vzalloc(size); + tx_ring->buffer_info = vmalloc(size); if (!tx_ring->buffer_info) goto err; + memset(tx_ring->buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); @@ -2094,9 +2095,10 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter) int i, size, desc_len, err = -ENOMEM; size = sizeof(struct e1000_buffer) * rx_ring->count; - rx_ring->buffer_info = vzalloc(size); + rx_ring->buffer_info = vmalloc(size); if (!rx_ring->buffer_info) goto err; + memset(rx_ring->buffer_info, 0, size); for (i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; @@ -4593,7 +4595,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, i += tx_ring->count; i--; buffer_info = &tx_ring->buffer_info[i]; - e1000_put_txbuf(adapter, buffer_info); + e1000_put_txbuf(adapter, buffer_info);; } return 0; @@ -5463,36 +5465,6 @@ static void e1000_shutdown(struct pci_dev *pdev) } #ifdef CONFIG_NET_POLL_CONTROLLER - -static irqreturn_t e1000_intr_msix(int irq, void *data) -{ - struct net_device *netdev = data; - struct e1000_adapter *adapter = netdev_priv(netdev); - int vector, msix_irq; - - if (adapter->msix_entries) { - vector = 0; - msix_irq = adapter->msix_entries[vector].vector; - disable_irq(msix_irq); - e1000_intr_msix_rx(msix_irq, netdev); - enable_irq(msix_irq); - - vector++; - msix_irq = adapter->msix_entries[vector].vector; - disable_irq(msix_irq); - e1000_intr_msix_tx(msix_irq, netdev); - enable_irq(msix_irq); - - vector++; - msix_irq = adapter->msix_entries[vector].vector; - disable_irq(msix_irq); - e1000_msix_other(msix_irq, netdev); - enable_irq(msix_irq); - } - - return IRQ_HANDLED; -} - /* * Polling 'interrupt' - used by things like netconsole to send skbs * without having to re-enable interrupts. It's not called while @@ -5502,21 +5474,10 @@ static void e1000_netpoll(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - switch (adapter->int_mode) { - case E1000E_INT_MODE_MSIX: - e1000_intr_msix(adapter->pdev->irq, netdev); - break; - case E1000E_INT_MODE_MSI: - disable_irq(adapter->pdev->irq); - e1000_intr_msi(adapter->pdev->irq, netdev); - enable_irq(adapter->pdev->irq); - break; - default: /* E1000E_INT_MODE_LEGACY */ - disable_irq(adapter->pdev->irq); - e1000_intr(adapter->pdev->irq, netdev); - enable_irq(adapter->pdev->irq); - break; - } + disable_irq(adapter->pdev->irq); + e1000_intr(adapter->pdev->irq, netdev); + + enable_irq(adapter->pdev->irq); } #endif diff --git a/trunk/drivers/net/eepro.c b/trunk/drivers/net/eepro.c index 9e19fbc2f176..7c826319ee5a 100644 --- a/trunk/drivers/net/eepro.c +++ b/trunk/drivers/net/eepro.c @@ -302,7 +302,7 @@ struct eepro_local { #define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */ #define ee_id_eepro10p1 0x31 -#define TX_TIMEOUT ((4*HZ)/10) +#define TX_TIMEOUT 40 /* Index to functions, as function prototypes. */ diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index a84c389d3db7..182b2a7be8dc 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -1496,10 +1496,12 @@ static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries) { int arr_size = sizeof(void *) * max_q_entries; - q_skba->arr = vzalloc(arr_size); + q_skba->arr = vmalloc(arr_size); if (!q_skba->arr) return -ENOMEM; + memset(q_skba->arr, 0, arr_size); + q_skba->len = max_q_entries; q_skba->index = 0; q_skba->os_skbs = 0; diff --git a/trunk/drivers/net/enic/enic.h b/trunk/drivers/net/enic/enic.h index 70672541364e..c91d364c5527 100644 --- a/trunk/drivers/net/enic/enic.h +++ b/trunk/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.7" +#define DRV_VERSION "1.4.1.6" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 diff --git a/trunk/drivers/net/enic/enic_main.c b/trunk/drivers/net/enic/enic_main.c index 9f293fa24768..a466ef91dd43 100644 --- a/trunk/drivers/net/enic/enic_main.c +++ b/trunk/drivers/net/enic/enic_main.c @@ -2042,7 +2042,7 @@ static int enic_dev_hang_reset(struct enic *enic) static int enic_set_rsskey(struct enic *enic) { - dma_addr_t rss_key_buf_pa; + u64 rss_key_buf_pa; union vnic_rss_key *rss_key_buf_va = NULL; union vnic_rss_key rss_key = { .key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101}, @@ -2073,7 +2073,7 @@ static int enic_set_rsskey(struct enic *enic) static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits) { - dma_addr_t rss_cpu_buf_pa; + u64 rss_cpu_buf_pa; union vnic_rss_cpu *rss_cpu_buf_va = NULL; unsigned int i; int err; diff --git a/trunk/drivers/net/ethoc.c b/trunk/drivers/net/ethoc.c index b79d7e1555d5..c5a2fe099a8d 100644 --- a/trunk/drivers/net/ethoc.c +++ b/trunk/drivers/net/ethoc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include static int buffer_size = 0x8000; /* 32 KBytes */ @@ -185,6 +184,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); * @netdev: pointer to network device structure * @napi: NAPI structure * @msg_enable: device state flags + * @rx_lock: receive lock * @lock: device lock * @phy: attached PHY * @mdio: MDIO bus for PHY access @@ -209,6 +209,7 @@ struct ethoc { struct napi_struct napi; u32 msg_enable; + spinlock_t rx_lock; spinlock_t lock; struct phy_device *phy; @@ -412,21 +413,10 @@ static int ethoc_rx(struct net_device *dev, int limit) unsigned int entry; struct ethoc_bd bd; - entry = priv->num_tx + priv->cur_rx; + entry = priv->num_tx + (priv->cur_rx % priv->num_rx); ethoc_read_bd(priv, entry, &bd); - if (bd.stat & RX_BD_EMPTY) { - ethoc_ack_irq(priv, INT_MASK_RX); - /* If packet (interrupt) came in between checking - * BD_EMTPY and clearing the interrupt source, then we - * risk missing the packet as the RX interrupt won't - * trigger right away when we reenable it; hence, check - * BD_EMTPY here again to make sure there isn't such a - * packet waiting for us... - */ - ethoc_read_bd(priv, entry, &bd); - if (bd.stat & RX_BD_EMPTY) - break; - } + if (bd.stat & RX_BD_EMPTY) + break; if (ethoc_update_rx_stats(priv, &bd) == 0) { int size = bd.stat >> 16; @@ -456,14 +446,13 @@ static int ethoc_rx(struct net_device *dev, int limit) bd.stat &= ~RX_BD_STATS; bd.stat |= RX_BD_EMPTY; ethoc_write_bd(priv, entry, &bd); - if (++priv->cur_rx == priv->num_rx) - priv->cur_rx = 0; + priv->cur_rx++; } return count; } -static void ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd) +static int ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd) { struct net_device *netdev = dev->netdev; @@ -493,44 +482,32 @@ static void ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd) netdev->stats.collisions += (bd->stat >> 4) & 0xf; netdev->stats.tx_bytes += bd->stat >> 16; netdev->stats.tx_packets++; + return 0; } -static int ethoc_tx(struct net_device *dev, int limit) +static void ethoc_tx(struct net_device *dev) { struct ethoc *priv = netdev_priv(dev); - int count; - struct ethoc_bd bd; - for (count = 0; count < limit; ++count) { - unsigned int entry; + spin_lock(&priv->lock); - entry = priv->dty_tx & (priv->num_tx-1); + while (priv->dty_tx != priv->cur_tx) { + unsigned int entry = priv->dty_tx % priv->num_tx; + struct ethoc_bd bd; ethoc_read_bd(priv, entry, &bd); + if (bd.stat & TX_BD_READY) + break; - if (bd.stat & TX_BD_READY || (priv->dty_tx == priv->cur_tx)) { - ethoc_ack_irq(priv, INT_MASK_TX); - /* If interrupt came in between reading in the BD - * and clearing the interrupt source, then we risk - * missing the event as the TX interrupt won't trigger - * right away when we reenable it; hence, check - * BD_EMPTY here again to make sure there isn't such an - * event pending... - */ - ethoc_read_bd(priv, entry, &bd); - if (bd.stat & TX_BD_READY || - (priv->dty_tx == priv->cur_tx)) - break; - } - - ethoc_update_tx_stats(priv, &bd); - priv->dty_tx++; + entry = (++priv->dty_tx) % priv->num_tx; + (void)ethoc_update_tx_stats(priv, &bd); } if ((priv->cur_tx - priv->dty_tx) <= (priv->num_tx / 2)) netif_wake_queue(dev); - return count; + ethoc_ack_irq(priv, INT_MASK_TX); + spin_unlock(&priv->lock); } static irqreturn_t ethoc_interrupt(int irq, void *dev_id) @@ -538,38 +515,32 @@ static irqreturn_t ethoc_interrupt(int irq, void *dev_id) struct net_device *dev = dev_id; struct ethoc *priv = netdev_priv(dev); u32 pending; - u32 mask; - - /* Figure out what triggered the interrupt... - * The tricky bit here is that the interrupt source bits get - * set in INT_SOURCE for an event irregardless of whether that - * event is masked or not. Thus, in order to figure out what - * triggered the interrupt, we need to remove the sources - * for all events that are currently masked. This behaviour - * is not particularly well documented but reasonable... - */ - mask = ethoc_read(priv, INT_MASK); - pending = ethoc_read(priv, INT_SOURCE); - pending &= mask; + ethoc_disable_irq(priv, INT_MASK_ALL); + pending = ethoc_read(priv, INT_SOURCE); if (unlikely(pending == 0)) { + ethoc_enable_irq(priv, INT_MASK_ALL); return IRQ_NONE; } ethoc_ack_irq(priv, pending); - /* We always handle the dropped packet interrupt */ if (pending & INT_MASK_BUSY) { dev_err(&dev->dev, "packet dropped\n"); dev->stats.rx_dropped++; } - /* Handle receive/transmit event by switching to polling */ - if (pending & (INT_MASK_TX | INT_MASK_RX)) { - ethoc_disable_irq(priv, INT_MASK_TX | INT_MASK_RX); - napi_schedule(&priv->napi); + if (pending & INT_MASK_RX) { + if (napi_schedule_prep(&priv->napi)) + __napi_schedule(&priv->napi); + } else { + ethoc_enable_irq(priv, INT_MASK_RX); } + if (pending & INT_MASK_TX) + ethoc_tx(dev); + + ethoc_enable_irq(priv, INT_MASK_ALL & ~INT_MASK_RX); return IRQ_HANDLED; } @@ -595,29 +566,26 @@ static int ethoc_get_mac_address(struct net_device *dev, void *addr) static int ethoc_poll(struct napi_struct *napi, int budget) { struct ethoc *priv = container_of(napi, struct ethoc, napi); - int rx_work_done = 0; - int tx_work_done = 0; - - rx_work_done = ethoc_rx(priv->netdev, budget); - tx_work_done = ethoc_tx(priv->netdev, budget); + int work_done = 0; - if (rx_work_done < budget && tx_work_done < budget) { + work_done = ethoc_rx(priv->netdev, budget); + if (work_done < budget) { + ethoc_enable_irq(priv, INT_MASK_RX); napi_complete(napi); - ethoc_enable_irq(priv, INT_MASK_TX | INT_MASK_RX); } - return rx_work_done; + return work_done; } static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg) { + unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT; struct ethoc *priv = bus->priv; - int i; ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg)); ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ); - for (i=0; i < 5; i++) { + while (time_before(jiffies, timeout)) { u32 status = ethoc_read(priv, MIISTATUS); if (!(status & MIISTATUS_BUSY)) { u32 data = ethoc_read(priv, MIIRX_DATA); @@ -625,7 +593,8 @@ static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg) ethoc_write(priv, MIICOMMAND, 0); return data; } - usleep_range(100,200); + + schedule(); } return -EBUSY; @@ -633,21 +602,22 @@ static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg) static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) { + unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT; struct ethoc *priv = bus->priv; - int i; ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg)); ethoc_write(priv, MIITX_DATA, val); ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE); - for (i=0; i < 5; i++) { + while (time_before(jiffies, timeout)) { u32 stat = ethoc_read(priv, MIISTATUS); if (!(stat & MIISTATUS_BUSY)) { /* reset MII command register */ ethoc_write(priv, MIICOMMAND, 0); return 0; } - usleep_range(100,200); + + schedule(); } return -EBUSY; @@ -1001,17 +971,9 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* calculate the number of TX/RX buffers, maximum 128 supported */ num_bd = min_t(unsigned int, 128, (netdev->mem_end - netdev->mem_start + 1) / ETHOC_BUFSIZ); - if (num_bd < 4) { - ret = -ENODEV; - goto error; - } - /* num_tx must be a power of two */ - priv->num_tx = rounddown_pow_of_two(num_bd >> 1); + priv->num_tx = max(2, num_bd / 4); priv->num_rx = num_bd - priv->num_tx; - dev_dbg(&pdev->dev, "ethoc: num_tx: %d num_rx: %d\n", - priv->num_tx, priv->num_rx); - priv->vma = devm_kzalloc(&pdev->dev, num_bd*sizeof(void*), GFP_KERNEL); if (!priv->vma) { ret = -ENOMEM; @@ -1020,23 +982,10 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* Allow the platform setup code to pass in a MAC address. */ if (pdev->dev.platform_data) { - struct ethoc_platform_data *pdata = pdev->dev.platform_data; + struct ethoc_platform_data *pdata = + (struct ethoc_platform_data *)pdev->dev.platform_data; memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); priv->phy_id = pdata->phy_id; - } else { - priv->phy_id = -1; - -#ifdef CONFIG_OF - { - const uint8_t* mac; - - mac = of_get_property(pdev->dev.of_node, - "local-mac-address", - NULL); - if (mac) - memcpy(netdev->dev_addr, mac, IFHWADDRLEN); - } -#endif } /* Check that the given MAC address is valid. If it isn't, read the @@ -1097,6 +1046,7 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* setup NAPI */ netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); + spin_lock_init(&priv->rx_lock); spin_lock_init(&priv->lock); ret = register_netdev(netdev); @@ -1163,16 +1113,6 @@ static int ethoc_resume(struct platform_device *pdev) # define ethoc_resume NULL #endif -#ifdef CONFIG_OF -static struct of_device_id ethoc_match[] = { - { - .compatible = "opencores,ethoc", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, ethoc_match); -#endif - static struct platform_driver ethoc_driver = { .probe = ethoc_probe, .remove = __devexit_p(ethoc_remove), @@ -1180,10 +1120,6 @@ static struct platform_driver ethoc_driver = { .resume = ethoc_resume, .driver = { .name = "ethoc", - .owner = THIS_MODULE, -#ifdef CONFIG_OF - .of_match_table = ethoc_match, -#endif }, }; diff --git a/trunk/drivers/net/fec_mpc52xx.c b/trunk/drivers/net/fec_mpc52xx.c index 50c1213f61fe..e9f5d030bc26 100644 --- a/trunk/drivers/net/fec_mpc52xx.c +++ b/trunk/drivers/net/fec_mpc52xx.c @@ -366,8 +366,9 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct mpc52xx_fec_priv *priv = netdev_priv(dev); + unsigned long flags; - spin_lock(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); while (bcom_buffer_done(priv->tx_dmatsk)) { struct sk_buff *skb; struct bcom_fec_bd *bd; @@ -378,7 +379,7 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id) dev_kfree_skb_irq(skb); } - spin_unlock(&priv->lock); + spin_unlock_irqrestore(&priv->lock, flags); netif_wake_queue(dev); @@ -394,8 +395,9 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) struct bcom_fec_bd *bd; u32 status, physaddr; int length; + unsigned long flags; - spin_lock(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); while (bcom_buffer_done(priv->rx_dmatsk)) { @@ -427,7 +429,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) /* Process the received skb - Drop the spin lock while * calling into the network stack */ - spin_unlock(&priv->lock); + spin_unlock_irqrestore(&priv->lock, flags); dma_unmap_single(dev->dev.parent, physaddr, rskb->len, DMA_FROM_DEVICE); @@ -436,10 +438,10 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) rskb->protocol = eth_type_trans(rskb, dev); netif_rx(rskb); - spin_lock(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); } - spin_unlock(&priv->lock); + spin_unlock_irqrestore(&priv->lock, flags); return IRQ_HANDLED; } @@ -450,6 +452,7 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id) struct mpc52xx_fec_priv *priv = netdev_priv(dev); struct mpc52xx_fec __iomem *fec = priv->fec; u32 ievent; + unsigned long flags; ievent = in_be32(&fec->ievent); @@ -467,9 +470,9 @@ static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id) if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR)) dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n"); - spin_lock(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); mpc52xx_fec_reset(dev); - spin_unlock(&priv->lock); + spin_unlock_irqrestore(&priv->lock, flags); return IRQ_HANDLED; } diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 2fd1ae9e13b5..0fa1776563a3 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -60,10 +60,10 @@ #include #include #include -#include -#include #include +#include +#include #include #if 0 @@ -186,9 +186,9 @@ enum { NvRegSlotTime = 0x9c, #define NVREG_SLOTTIME_LEGBF_ENABLED 0x80000000 #define NVREG_SLOTTIME_10_100_FULL 0x00007f00 -#define NVREG_SLOTTIME_1000_FULL 0x0003ff00 +#define NVREG_SLOTTIME_1000_FULL 0x0003ff00 #define NVREG_SLOTTIME_HALF 0x0000ff00 -#define NVREG_SLOTTIME_DEFAULT 0x00007f00 +#define NVREG_SLOTTIME_DEFAULT 0x00007f00 #define NVREG_SLOTTIME_MASK 0x000000ff NvRegTxDeferral = 0xA0, @@ -297,7 +297,7 @@ enum { #define NVREG_WAKEUPFLAGS_ENABLE 0x1111 NvRegMgmtUnitGetVersion = 0x204, -#define NVREG_MGMTUNITGETVERSION 0x01 +#define NVREG_MGMTUNITGETVERSION 0x01 NvRegMgmtUnitVersion = 0x208, #define NVREG_MGMTUNITVERSION 0x08 NvRegPowerCap = 0x268, @@ -368,8 +368,8 @@ struct ring_desc_ex { }; union ring_type { - struct ring_desc *orig; - struct ring_desc_ex *ex; + struct ring_desc* orig; + struct ring_desc_ex* ex; }; #define FLAG_MASK_V1 0xffff0000 @@ -444,10 +444,10 @@ union ring_type { #define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) /* Miscelaneous hardware related defines: */ -#define NV_PCI_REGSZ_VER1 0x270 -#define NV_PCI_REGSZ_VER2 0x2d4 -#define NV_PCI_REGSZ_VER3 0x604 -#define NV_PCI_REGSZ_MAX 0x604 +#define NV_PCI_REGSZ_VER1 0x270 +#define NV_PCI_REGSZ_VER2 0x2d4 +#define NV_PCI_REGSZ_VER3 0x604 +#define NV_PCI_REGSZ_MAX 0x604 /* various timeout delays: all in usec */ #define NV_TXRX_RESET_DELAY 4 @@ -717,7 +717,7 @@ static const struct register_test nv_registers_test[] = { { NvRegMulticastAddrA, 0xffffffff }, { NvRegTxWatermark, 0x0ff }, { NvRegWakeUpFlags, 0x07777 }, - { 0, 0 } + { 0,0 } }; struct nv_skb_map { @@ -911,7 +911,7 @@ static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED; * Power down phy when interface is down (persists through reboot; * older Linux and other OSes may not power it up again) */ -static int phy_power_down; +static int phy_power_down = 0; static inline struct fe_priv *get_nvpriv(struct net_device *dev) { @@ -984,10 +984,12 @@ static void setup_hw_rings(struct net_device *dev, int rxtx_flags) u8 __iomem *base = get_hwbase(dev); if (!nv_optimized(np)) { - if (rxtx_flags & NV_SETUP_RX_RING) + if (rxtx_flags & NV_SETUP_RX_RING) { writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr); - if (rxtx_flags & NV_SETUP_TX_RING) + } + if (rxtx_flags & NV_SETUP_TX_RING) { writel(dma_low(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); + } } else { if (rxtx_flags & NV_SETUP_RX_RING) { writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr); @@ -1013,8 +1015,10 @@ static void free_rings(struct net_device *dev) pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (np->rx_ring_size + np->tx_ring_size), np->rx_ring.ex, np->ring_addr); } - kfree(np->rx_skb); - kfree(np->tx_skb); + if (np->rx_skb) + kfree(np->rx_skb); + if (np->tx_skb) + kfree(np->tx_skb); } static int using_multi_irqs(struct net_device *dev) @@ -1170,15 +1174,16 @@ static int phy_reset(struct net_device *dev, u32 bmcr_setup) unsigned int tries = 0; miicontrol = BMCR_RESET | bmcr_setup; - if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) + if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) { return -1; + } /* wait for 500ms */ msleep(500); /* must wait till reset is deasserted */ while (miicontrol & BMCR_RESET) { - usleep_range(10000, 20000); + msleep(10); miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); /* FIXME: 100 tries seem excessive */ if (tries++ > 100) @@ -1191,7 +1196,7 @@ static int phy_init(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); u8 __iomem *base = get_hwbase(dev); - u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000, reg; + u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg; /* phy errata for E3016 phy */ if (np->phy_model == PHY_MODEL_MARVELL_E3016) { @@ -1308,7 +1313,8 @@ static int phy_init(struct net_device *dev) printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); return PHY_ERROR; } - } else + } + else np->gigabit = 0; mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); @@ -1334,7 +1340,7 @@ static int phy_init(struct net_device *dev) } /* phy vendor specific configuration */ - if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII)) { + if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) { phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2); phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4); @@ -1495,10 +1501,12 @@ static int phy_init(struct net_device *dev) /* restart auto negotiation, power down phy */ mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); - if (phy_power_down) + if (phy_power_down) { mii_control |= BMCR_PDOWN; - if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) + } + if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { return PHY_ERROR; + } return 0; } @@ -1518,8 +1526,8 @@ static void nv_start_rx(struct net_device *dev) } writel(np->linkspeed, base + NvRegLinkSpeed); pci_push(base); - rx_ctrl |= NVREG_RCVCTL_START; - if (np->mac_in_use) + rx_ctrl |= NVREG_RCVCTL_START; + if (np->mac_in_use) rx_ctrl &= ~NVREG_RCVCTL_RX_PATH_EN; writel(rx_ctrl, base + NvRegReceiverControl); dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n", @@ -1737,7 +1745,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev) static int nv_alloc_rx(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - struct ring_desc *less_rx; + struct ring_desc* less_rx; less_rx = np->get_rx.orig; if (less_rx-- == np->first_rx.orig) @@ -1759,8 +1767,9 @@ static int nv_alloc_rx(struct net_device *dev) np->put_rx.orig = np->first_rx.orig; if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) np->put_rx_ctx = np->first_rx_ctx; - } else + } else { return 1; + } } return 0; } @@ -1768,7 +1777,7 @@ static int nv_alloc_rx(struct net_device *dev) static int nv_alloc_rx_optimized(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - struct ring_desc_ex *less_rx; + struct ring_desc_ex* less_rx; less_rx = np->get_rx.ex; if (less_rx-- == np->first_rx.ex) @@ -1791,8 +1800,9 @@ static int nv_alloc_rx_optimized(struct net_device *dev) np->put_rx.ex = np->first_rx.ex; if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) np->put_rx_ctx = np->first_rx_ctx; - } else + } else { return 1; + } } return 0; } @@ -2008,24 +2018,24 @@ static void nv_legacybackoff_reseed(struct net_device *dev) /* Known Good seed sets */ static const u32 main_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = { - {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, - {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974}, - {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, - {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974}, - {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984}, - {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984}, - {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800, 84}, - {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184} }; + {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, + {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974}, + {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874}, + {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974}, + {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984}, + {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984}, + {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800, 84}, + {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184}}; static const u32 gear_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = { - {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397}, - {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, - {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, - {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395} }; + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397}, + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375, 30, 295}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}, + {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}}; static void nv_gear_backoff_reseed(struct net_device *dev) { @@ -2073,12 +2083,13 @@ static void nv_gear_backoff_reseed(struct net_device *dev) temp = NVREG_BKOFFCTRL_DEFAULT | (0 << NVREG_BKOFFCTRL_SELECT); temp |= combinedSeed & NVREG_BKOFFCTRL_SEED_MASK; temp |= combinedSeed >> NVREG_BKOFFCTRL_GEAR; - writel(temp, base + NvRegBackOffControl); + writel(temp,base + NvRegBackOffControl); - /* Setup seeds for all gear LFSRs. */ + /* Setup seeds for all gear LFSRs. */ get_random_bytes(&seedset, sizeof(seedset)); seedset = seedset % BACKOFF_SEEDSET_ROWS; - for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; i++) { + for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; i++) + { temp = NVREG_BKOFFCTRL_DEFAULT | (i << NVREG_BKOFFCTRL_SELECT); temp |= main_seedset[seedset][i-1] & 0x3ff; temp |= ((gear_seedset[seedset][i-1] & 0x3ff) << NVREG_BKOFFCTRL_GEAR); @@ -2102,10 +2113,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 size = skb_headlen(skb); u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); u32 empty_slots; - struct ring_desc *put_tx; - struct ring_desc *start_tx; - struct ring_desc *prev_tx; - struct nv_skb_map *prev_tx_ctx; + struct ring_desc* put_tx; + struct ring_desc* start_tx; + struct ring_desc* prev_tx; + struct nv_skb_map* prev_tx_ctx; unsigned long flags; /* add fragments to entries count */ @@ -2197,10 +2208,10 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->name, entries, tx_flags_extra); { int j; - for (j = 0; j < 64; j++) { + for (j=0; j<64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char *)skb->data)[j]); + dprintk(" %02x", ((unsigned char*)skb->data)[j]); } dprintk("\n"); } @@ -2222,11 +2233,11 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, u32 size = skb_headlen(skb); u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); u32 empty_slots; - struct ring_desc_ex *put_tx; - struct ring_desc_ex *start_tx; - struct ring_desc_ex *prev_tx; - struct nv_skb_map *prev_tx_ctx; - struct nv_skb_map *start_tx_ctx; + struct ring_desc_ex* put_tx; + struct ring_desc_ex* start_tx; + struct ring_desc_ex* prev_tx; + struct nv_skb_map* prev_tx_ctx; + struct nv_skb_map* start_tx_ctx; unsigned long flags; /* add fragments to entries count */ @@ -2348,10 +2359,10 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, dev->name, entries, tx_flags_extra); { int j; - for (j = 0; j < 64; j++) { + for (j=0; j<64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char *)skb->data)[j]); + dprintk(" %02x", ((unsigned char*)skb->data)[j]); } dprintk("\n"); } @@ -2388,7 +2399,7 @@ static int nv_tx_done(struct net_device *dev, int limit) struct fe_priv *np = netdev_priv(dev); u32 flags; int tx_work = 0; - struct ring_desc *orig_get_tx = np->get_tx.orig; + struct ring_desc* orig_get_tx = np->get_tx.orig; while ((np->get_tx.orig != np->put_tx.orig) && !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) && @@ -2453,7 +2464,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) struct fe_priv *np = netdev_priv(dev); u32 flags; int tx_work = 0; - struct ring_desc_ex *orig_get_tx = np->get_tx.ex; + struct ring_desc_ex* orig_get_tx = np->get_tx.ex; while ((np->get_tx.ex != np->put_tx.ex) && !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX2_VALID) && @@ -2480,8 +2491,9 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) np->get_tx_ctx->skb = NULL; tx_work++; - if (np->tx_limit) + if (np->tx_limit) { nv_tx_flip_ownership(dev); + } } if (unlikely(np->get_tx.ex++ == np->last_tx.ex)) np->get_tx.ex = np->first_tx.ex; @@ -2520,7 +2532,7 @@ static void nv_tx_timeout(struct net_device *dev) printk(KERN_INFO "%s: Ring at %lx\n", dev->name, (unsigned long)np->ring_addr); printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); - for (i = 0; i <= np->register_size; i += 32) { + for (i=0;i<=np->register_size;i+= 32) { printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", i, readl(base + i + 0), readl(base + i + 4), @@ -2529,7 +2541,7 @@ static void nv_tx_timeout(struct net_device *dev) readl(base + i + 24), readl(base + i + 28)); } printk(KERN_INFO "%s: Dumping tx ring\n", dev->name); - for (i = 0; i < np->tx_ring_size; i += 4) { + for (i=0;itx_ring_size;i+= 4) { if (!nv_optimized(np)) { printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", i, @@ -2604,11 +2616,11 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen) int protolen; /* length as stored in the proto field */ /* 1) calculate len according to header */ - if (((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) { - protolen = ntohs(((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto); + if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) { + protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto ); hdrlen = VLAN_HLEN; } else { - protolen = ntohs(((struct ethhdr *)packet)->h_proto); + protolen = ntohs( ((struct ethhdr *)packet)->h_proto); hdrlen = ETH_HLEN; } dprintk(KERN_DEBUG "%s: nv_getlen: datalen %d, protolen %d, hdrlen %d\n", @@ -2655,7 +2667,7 @@ static int nv_rx_process(struct net_device *dev, int limit) struct sk_buff *skb; int len; - while ((np->get_rx.orig != np->put_rx.orig) && + while((np->get_rx.orig != np->put_rx.orig) && !((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) && (rx_work < limit)) { @@ -2675,11 +2687,11 @@ static int nv_rx_process(struct net_device *dev, int limit) { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).", flags); - for (j = 0; j < 64; j++) { + dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",flags); + for (j=0; j<64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char *)skb->data)[j]); + dprintk(" %02x", ((unsigned char*)skb->data)[j]); } dprintk("\n"); } @@ -2698,8 +2710,9 @@ static int nv_rx_process(struct net_device *dev, int limit) } /* framing errors are soft errors */ else if ((flags & NV_RX_ERROR_MASK) == NV_RX_FRAMINGERR) { - if (flags & NV_RX_SUBSTRACT1) + if (flags & NV_RX_SUBSTRACT1) { len--; + } } /* the rest are hard errors */ else { @@ -2732,8 +2745,9 @@ static int nv_rx_process(struct net_device *dev, int limit) } /* framing errors are soft errors */ else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) { - if (flags & NV_RX2_SUBSTRACT1) + if (flags & NV_RX2_SUBSTRACT1) { len--; + } } /* the rest are hard errors */ else { @@ -2783,7 +2797,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) struct sk_buff *skb; int len; - while ((np->get_rx.ex != np->put_rx.ex) && + while((np->get_rx.ex != np->put_rx.ex) && !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) && (rx_work < limit)) { @@ -2803,11 +2817,11 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).", flags); - for (j = 0; j < 64; j++) { + dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",flags); + for (j=0; j<64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); - dprintk(" %02x", ((unsigned char *)skb->data)[j]); + dprintk(" %02x", ((unsigned char*)skb->data)[j]); } dprintk("\n"); } @@ -2824,8 +2838,9 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) } /* framing errors are soft errors */ else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) { - if (flags & NV_RX2_SUBSTRACT1) + if (flags & NV_RX2_SUBSTRACT1) { len--; + } } /* the rest are hard errors */ else { @@ -2934,7 +2949,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) /* reinit nic view of the rx queue */ writel(np->rx_buf_sz, base + NvRegOffloadConfig); setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); - writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); pci_push(base); writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); @@ -2971,7 +2986,7 @@ static void nv_copy_mac_to_hw(struct net_device *dev) static int nv_set_mac_address(struct net_device *dev, void *addr) { struct fe_priv *np = netdev_priv(dev); - struct sockaddr *macaddr = (struct sockaddr *)addr; + struct sockaddr *macaddr = (struct sockaddr*)addr; if (!is_valid_ether_addr(macaddr->sa_data)) return -EADDRNOTAVAIL; @@ -3287,7 +3302,7 @@ static int nv_update_linkspeed(struct net_device *dev) } writel(txreg, base + NvRegTxWatermark); - writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), + writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1); pci_push(base); writel(np->linkspeed, base + NvRegLinkSpeed); @@ -3297,8 +3312,8 @@ static int nv_update_linkspeed(struct net_device *dev) /* setup pause frame */ if (np->duplex != 0) { if (np->autoneg && np->pause_flags & NV_PAUSEFRAME_AUTONEG) { - adv_pause = adv & (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); - lpa_pause = lpa & (LPA_PAUSE_CAP | LPA_PAUSE_ASYM); + adv_pause = adv & (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM); + lpa_pause = lpa & (LPA_PAUSE_CAP| LPA_PAUSE_ASYM); switch (adv_pause) { case ADVERTISE_PAUSE_CAP: @@ -3309,17 +3324,22 @@ static int nv_update_linkspeed(struct net_device *dev) } break; case ADVERTISE_PAUSE_ASYM: - if (lpa_pause == (LPA_PAUSE_CAP | LPA_PAUSE_ASYM)) + if (lpa_pause == (LPA_PAUSE_CAP| LPA_PAUSE_ASYM)) + { pause_flags |= NV_PAUSEFRAME_TX_ENABLE; + } break; - case ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM: - if (lpa_pause & LPA_PAUSE_CAP) { + case ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM: + if (lpa_pause & LPA_PAUSE_CAP) + { pause_flags |= NV_PAUSEFRAME_RX_ENABLE; if (np->pause_flags & NV_PAUSEFRAME_TX_REQ) pause_flags |= NV_PAUSEFRAME_TX_ENABLE; } if (lpa_pause == LPA_PAUSE_ASYM) + { pause_flags |= NV_PAUSEFRAME_RX_ENABLE; + } break; } } else { @@ -3494,7 +3514,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name); - for (i = 0;; i++) { + for (i=0; ; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_TX_ALL; writel(NVREG_IRQ_TX_ALL, base + NvRegMSIXIrqStatus); dprintk(KERN_DEBUG "%s: tx irq: %08x\n", dev->name, events); @@ -3533,7 +3553,7 @@ static int nv_napi_poll(struct napi_struct *napi, int budget) u8 __iomem *base = get_hwbase(dev); unsigned long flags; int retcode; - int rx_count, tx_work = 0, rx_work = 0; + int rx_count, tx_work=0, rx_work=0; do { if (!nv_optimized(np)) { @@ -3608,7 +3628,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name); - for (i = 0;; i++) { + for (i=0; ; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL; writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus); dprintk(KERN_DEBUG "%s: rx irq: %08x\n", dev->name, events); @@ -3655,7 +3675,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name); - for (i = 0;; i++) { + for (i=0; ; i++) { events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_OTHER; writel(NVREG_IRQ_OTHER, base + NvRegMSIXIrqStatus); dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); @@ -3756,15 +3776,17 @@ static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask) * the remaining 8 interrupts. */ for (i = 0; i < 8; i++) { - if ((irqmask >> i) & 0x1) + if ((irqmask >> i) & 0x1) { msixmap |= vector << (i << 2); + } } writel(readl(base + NvRegMSIXMap0) | msixmap, base + NvRegMSIXMap0); msixmap = 0; for (i = 0; i < 8; i++) { - if ((irqmask >> (i + 8)) & 0x1) + if ((irqmask >> (i + 8)) & 0x1) { msixmap |= vector << (i << 2); + } } writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1); } @@ -3787,10 +3809,10 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } if (np->msi_flags & NV_MSI_X_CAPABLE) { - for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) + for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { np->msi_x_entry[i].entry = i; - ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK)); - if (ret == 0) { + } + if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) { np->msi_flags |= NV_MSI_X_ENABLED; if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) { /* Request irq for rx handling */ @@ -3842,8 +3864,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } } if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { - ret = pci_enable_msi(np->pci_dev); - if (ret == 0) { + if ((ret = pci_enable_msi(np->pci_dev)) == 0) { np->msi_flags |= NV_MSI_ENABLED; dev->irq = np->pci_dev->irq; if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { @@ -3882,8 +3903,9 @@ static void nv_free_irq(struct net_device *dev) int i; if (np->msi_flags & NV_MSI_X_ENABLED) { - for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) + for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { free_irq(np->msi_x_entry[i].vector, dev); + } pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; } else { @@ -3953,7 +3975,7 @@ static void nv_do_nic_poll(unsigned long data) /* reinit nic view of the rx queue */ writel(np->rx_buf_sz, base + NvRegOffloadConfig); setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); - writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); pci_push(base); writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); @@ -4083,7 +4105,7 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } if (netif_carrier_ok(dev)) { - switch (np->linkspeed & (NVREG_LINKSPEED_MASK)) { + switch(np->linkspeed & (NVREG_LINKSPEED_MASK)) { case NVREG_LINKSPEED_10: ecmd->speed = SPEED_10; break; @@ -4322,7 +4344,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void regs->version = FORCEDETH_REGS_VER; spin_lock_irq(&np->lock); - for (i = 0; i <= np->register_size/sizeof(u32); i++) + for (i = 0;i <= np->register_size/sizeof(u32); i++) rbuf[i] = readl(base + i*sizeof(u32)); spin_unlock_irq(&np->lock); } @@ -4442,9 +4464,10 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (ring->rx_pending + ring->tx_pending), rxtx_ring, ring_addr); } - - kfree(rx_skbuff); - kfree(tx_skbuff); + if (rx_skbuff) + kfree(rx_skbuff); + if (tx_skbuff) + kfree(tx_skbuff); goto exit; } @@ -4468,14 +4491,14 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri np->tx_ring_size = ring->tx_pending; if (!nv_optimized(np)) { - np->rx_ring.orig = (struct ring_desc *)rxtx_ring; + np->rx_ring.orig = (struct ring_desc*)rxtx_ring; np->tx_ring.orig = &np->rx_ring.orig[np->rx_ring_size]; } else { - np->rx_ring.ex = (struct ring_desc_ex *)rxtx_ring; + np->rx_ring.ex = (struct ring_desc_ex*)rxtx_ring; np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; } - np->rx_skb = (struct nv_skb_map *)rx_skbuff; - np->tx_skb = (struct nv_skb_map *)tx_skbuff; + np->rx_skb = (struct nv_skb_map*)rx_skbuff; + np->tx_skb = (struct nv_skb_map*)tx_skbuff; np->ring_addr = ring_addr; memset(np->rx_skb, 0, sizeof(struct nv_skb_map) * np->rx_ring_size); @@ -4492,7 +4515,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri /* reinit nic view of the queues */ writel(np->rx_buf_sz, base + NvRegOffloadConfig); setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); - writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); pci_push(base); writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); @@ -4818,7 +4841,7 @@ static int nv_loopback_test(struct net_device *dev) /* reinit nic view of the rx queue */ writel(np->rx_buf_sz, base + NvRegOffloadConfig); setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); - writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); pci_push(base); @@ -4870,8 +4893,9 @@ static int nv_loopback_test(struct net_device *dev) if (flags & NV_RX_ERROR) ret = 0; } else { - if (flags & NV_RX2_ERROR) + if (flags & NV_RX2_ERROR) { ret = 0; + } } if (ret) { @@ -4934,10 +4958,11 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 netif_addr_lock(dev); spin_lock_irq(&np->lock); nv_disable_hw_interrupts(dev, np->irqmask); - if (!(np->msi_flags & NV_MSI_X_ENABLED)) + if (!(np->msi_flags & NV_MSI_X_ENABLED)) { writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); - else + } else { writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus); + } /* stop engines */ nv_stop_rxtx(dev); nv_txrx_reset(dev); @@ -4978,7 +5003,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 /* reinit nic view of the rx queue */ writel(np->rx_buf_sz, base + NvRegOffloadConfig); setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); - writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); pci_push(base); writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); @@ -5081,7 +5106,8 @@ static int nv_mgmt_acquire_sema(struct net_device *dev) ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE)) { np->mgmt_sema = 1; return 1; - } else + } + else udelay(50); } @@ -5178,7 +5204,7 @@ static int nv_open(struct net_device *dev) /* give hw rings */ setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING); - writel(((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), + writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + ((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes); writel(np->linkspeed, base + NvRegLinkSpeed); @@ -5225,7 +5251,8 @@ static int nv_open(struct net_device *dev) writel(NVREG_POLL_DEFAULT_THROUGHPUT, base + NvRegPollingInterval); else writel(NVREG_POLL_DEFAULT_CPU, base + NvRegPollingInterval); - } else + } + else writel(poll_interval & 0xFFFF, base + NvRegPollingInterval); writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING, @@ -5236,7 +5263,7 @@ static int nv_open(struct net_device *dev) writel(NVREG_WAKEUPFLAGS_ENABLE , base + NvRegWakeUpFlags); i = readl(base + NvRegPowerState); - if ((i & NVREG_POWERSTATE_POWEREDUP) == 0) + if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState); pci_push(base); @@ -5249,8 +5276,9 @@ static int nv_open(struct net_device *dev) writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); - if (nv_request_irq(dev, 0)) + if (nv_request_irq(dev, 0)) { goto out_drain; + } /* ask for interrupts */ nv_enable_hw_interrupts(dev, np->irqmask); @@ -5438,7 +5466,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i addr = 0; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { dprintk(KERN_DEBUG "%s: resource %d start %p len %ld flags 0x%08lx.\n", - pci_name(pci_dev), i, (void *)pci_resource_start(pci_dev, i), + pci_name(pci_dev), i, (void*)pci_resource_start(pci_dev, i), pci_resource_len(pci_dev, i), pci_resource_flags(pci_dev, i)); if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && @@ -5603,7 +5631,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i */ dev_printk(KERN_ERR, &pci_dev->dev, "Invalid Mac address detected: %pM\n", - dev->dev_addr); + dev->dev_addr); dev_printk(KERN_ERR, &pci_dev->dev, "Please complain to your hardware vendor. Switching to a random MAC.\n"); random_ether_addr(dev->dev_addr); @@ -5635,15 +5663,16 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i writel(powerstate, base + NvRegPowerState2); } - if (np->desc_ver == DESC_VER_1) + if (np->desc_ver == DESC_VER_1) { np->tx_flags = NV_TX_VALID; - else + } else { np->tx_flags = NV_TX2_VALID; + } np->msi_flags = 0; - if ((id->driver_data & DEV_HAS_MSI) && msi) + if ((id->driver_data & DEV_HAS_MSI) && msi) { np->msi_flags |= NV_MSI_CAPABLE; - + } if ((id->driver_data & DEV_HAS_MSI_X) && msix) { /* msix has had reported issues when modifying irqmask as in the case of napi, therefore, disable for now @@ -5706,8 +5735,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i nv_mgmt_acquire_sema(dev) && nv_mgmt_get_version(dev)) { np->mac_in_use = 1; - if (np->mgmt_version > 0) + if (np->mgmt_version > 0) { np->mac_in_use = readl(base + NvRegMgmtUnitControl) & NVREG_MGMTUNITCONTROL_INUSE; + } dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", pci_name(pci_dev), np->mac_in_use); /* management unit setup the phy already? */ @@ -5769,8 +5799,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i } else { /* see if it is a gigabit phy */ u32 mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); - if (mii_status & PHY_GIGABIT) + if (mii_status & PHY_GIGABIT) { np->gigabit = PHY_GIGABIT; + } } /* set default link speed settings */ @@ -5798,19 +5829,19 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->dev_addr[5]); dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n", - dev->features & NETIF_F_HIGHDMA ? "highdma " : "", - dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? - "csum " : "", - dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? - "vlan " : "", - id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "", - id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "", - id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "", - np->gigabit == PHY_GIGABIT ? "gbit " : "", - np->need_linktimer ? "lnktim " : "", - np->msi_flags & NV_MSI_CAPABLE ? "msi " : "", - np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "", - np->desc_ver); + dev->features & NETIF_F_HIGHDMA ? "highdma " : "", + dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? + "csum " : "", + dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? + "vlan " : "", + id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "", + id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "", + id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "", + np->gigabit == PHY_GIGABIT ? "gbit " : "", + np->need_linktimer ? "lnktim " : "", + np->msi_flags & NV_MSI_CAPABLE ? "msi " : "", + np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "", + np->desc_ver); return 0; @@ -5900,13 +5931,13 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state) int i; if (netif_running(dev)) { - /* Gross. */ + // Gross. nv_close(dev); } netif_device_detach(dev); /* save non-pci configuration space */ - for (i = 0; i <= np->register_size/sizeof(u32); i++) + for (i = 0;i <= np->register_size/sizeof(u32); i++) np->saved_config_space[i] = readl(base + i*sizeof(u32)); pci_save_state(pdev); @@ -5929,7 +5960,7 @@ static int nv_resume(struct pci_dev *pdev) pci_enable_wake(pdev, PCI_D0, 0); /* restore non-pci configuration space */ - for (i = 0; i <= np->register_size/sizeof(u32); i++) + for (i = 0;i <= np->register_size/sizeof(u32); i++) writel(np->saved_config_space[i], base+i*sizeof(u32)); if (np->driver_data & DEV_NEED_MSI_FIX) @@ -5959,8 +5990,9 @@ static void nv_shutdown(struct pci_dev *pdev) * If we really go for poweroff, we must not restore the MAC, * otherwise the MAC for WOL will be reversed at least on some boards. */ - if (system_state != SYSTEM_POWER_OFF) + if (system_state != SYSTEM_POWER_OFF) { nv_restore_mac_addr(pdev); + } pci_disable_device(pdev); /* diff --git a/trunk/drivers/net/gianfar.c b/trunk/drivers/net/gianfar.c index d1bec6269173..49e4ce1246a7 100644 --- a/trunk/drivers/net/gianfar.c +++ b/trunk/drivers/net/gianfar.c @@ -577,10 +577,11 @@ static int gfar_parse_group(struct device_node *np, irq_of_parse_and_map(np, 1); priv->gfargrp[priv->num_grps].interruptError = irq_of_parse_and_map(np,2); - if (priv->gfargrp[priv->num_grps].interruptTransmit == NO_IRQ || - priv->gfargrp[priv->num_grps].interruptReceive == NO_IRQ || - priv->gfargrp[priv->num_grps].interruptError == NO_IRQ) + if (priv->gfargrp[priv->num_grps].interruptTransmit < 0 || + priv->gfargrp[priv->num_grps].interruptReceive < 0 || + priv->gfargrp[priv->num_grps].interruptError < 0) { return -EINVAL; + } } priv->gfargrp[priv->num_grps].grp_id = priv->num_grps; diff --git a/trunk/drivers/net/gianfar_ethtool.c b/trunk/drivers/net/gianfar_ethtool.c index 3bc8e276ba4d..5c566ebc54b8 100644 --- a/trunk/drivers/net/gianfar_ethtool.c +++ b/trunk/drivers/net/gianfar_ethtool.c @@ -635,10 +635,9 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; - device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC); - spin_lock_irqsave(&priv->bflock, flags); - priv->wol_en = !!device_may_wakeup(&dev->dev); + priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0; + device_set_wakeup_enable(&dev->dev, priv->wol_en); spin_unlock_irqrestore(&priv->bflock, flags); return 0; diff --git a/trunk/drivers/net/ibm_newemac/core.c b/trunk/drivers/net/ibm_newemac/core.c index 06bb9b799458..385dc3204cb7 100644 --- a/trunk/drivers/net/ibm_newemac/core.c +++ b/trunk/drivers/net/ibm_newemac/core.c @@ -2871,6 +2871,7 @@ static int __devinit emac_probe(struct platform_device *ofdev, SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); netif_carrier_off(ndev); + netif_stop_queue(ndev); err = register_netdev(ndev); if (err) { diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index 67ea262e482a..892d196f17ac 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -2436,9 +2436,10 @@ int igb_setup_tx_resources(struct igb_ring *tx_ring) int size; size = sizeof(struct igb_buffer) * tx_ring->count; - tx_ring->buffer_info = vzalloc(size); + tx_ring->buffer_info = vmalloc(size); if (!tx_ring->buffer_info) goto err; + memset(tx_ring->buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc); @@ -2586,9 +2587,10 @@ int igb_setup_rx_resources(struct igb_ring *rx_ring) int size, desc_len; size = sizeof(struct igb_buffer) * rx_ring->count; - rx_ring->buffer_info = vzalloc(size); + rx_ring->buffer_info = vmalloc(size); if (!rx_ring->buffer_info) goto err; + memset(rx_ring->buffer_info, 0, size); desc_len = sizeof(union e1000_adv_rx_desc); diff --git a/trunk/drivers/net/igbvf/Makefile b/trunk/drivers/net/igbvf/Makefile index 0fa3db3dd8b6..c2f150d8f2d9 100644 --- a/trunk/drivers/net/igbvf/Makefile +++ b/trunk/drivers/net/igbvf/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel(R) 82576 Virtual Function Linux driver -# Copyright(c) 2009 - 2010 Intel Corporation. +# Copyright(c) 2009 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/igbvf/defines.h b/trunk/drivers/net/igbvf/defines.h index 79f2604673fe..88a47537518a 100644 --- a/trunk/drivers/net/igbvf/defines.h +++ b/trunk/drivers/net/igbvf/defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/igbvf/ethtool.c b/trunk/drivers/net/igbvf/ethtool.c index abb3606928fb..33add708bcbe 100644 --- a/trunk/drivers/net/igbvf/ethtool.c +++ b/trunk/drivers/net/igbvf/ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 - 2010 Intel Corporation. + Copyright(c) 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/igbvf/igbvf.h b/trunk/drivers/net/igbvf/igbvf.h index 9d4d63e536d4..debeee2dc717 100644 --- a/trunk/drivers/net/igbvf/igbvf.h +++ b/trunk/drivers/net/igbvf/igbvf.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 - 2010 Intel Corporation. + Copyright(c) 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -126,6 +126,7 @@ struct igbvf_buffer { unsigned int page_offset; }; }; + struct page *page; }; union igbvf_desc { diff --git a/trunk/drivers/net/igbvf/mbx.c b/trunk/drivers/net/igbvf/mbx.c index 3d6f4cc3998a..819a8ec901dc 100644 --- a/trunk/drivers/net/igbvf/mbx.c +++ b/trunk/drivers/net/igbvf/mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 - 2010 Intel Corporation. + Copyright(c) 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/igbvf/mbx.h b/trunk/drivers/net/igbvf/mbx.h index c2883c45d477..4938609dbfb5 100644 --- a/trunk/drivers/net/igbvf/mbx.h +++ b/trunk/drivers/net/igbvf/mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/igbvf/netdev.c b/trunk/drivers/net/igbvf/netdev.c index 8dbde2397c10..28af019c97bb 100644 --- a/trunk/drivers/net/igbvf/netdev.c +++ b/trunk/drivers/net/igbvf/netdev.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 - 2010 Intel Corporation. + Copyright(c) 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -44,13 +44,12 @@ #include "igbvf.h" -#define DRV_VERSION "1.0.8-k0" +#define DRV_VERSION "1.0.0-k0" char igbvf_driver_name[] = "igbvf"; const char igbvf_driver_version[] = DRV_VERSION; static const char igbvf_driver_string[] = "Intel(R) Virtual Function Network Driver"; -static const char igbvf_copyright[] = - "Copyright (c) 2009 - 2010 Intel Corporation."; +static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; static int igbvf_poll(struct napi_struct *napi, int budget); static void igbvf_reset(struct igbvf_adapter *); @@ -430,9 +429,10 @@ int igbvf_setup_tx_resources(struct igbvf_adapter *adapter, int size; size = sizeof(struct igbvf_buffer) * tx_ring->count; - tx_ring->buffer_info = vzalloc(size); + tx_ring->buffer_info = vmalloc(size); if (!tx_ring->buffer_info) goto err; + memset(tx_ring->buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc); @@ -469,9 +469,10 @@ int igbvf_setup_rx_resources(struct igbvf_adapter *adapter, int size, desc_len; size = sizeof(struct igbvf_buffer) * rx_ring->count; - rx_ring->buffer_info = vzalloc(size); + rx_ring->buffer_info = vmalloc(size); if (!rx_ring->buffer_info) goto err; + memset(rx_ring->buffer_info, 0, size); desc_len = sizeof(union e1000_adv_rx_desc); @@ -1850,6 +1851,8 @@ static void igbvf_watchdog_task(struct work_struct *work) if (link) { if (!netif_carrier_ok(netdev)) { + bool txb2b = 1; + mac->ops.get_link_up_info(&adapter->hw, &adapter->link_speed, &adapter->link_duplex); @@ -1859,9 +1862,11 @@ static void igbvf_watchdog_task(struct work_struct *work) adapter->tx_timeout_factor = 1; switch (adapter->link_speed) { case SPEED_10: + txb2b = 0; adapter->tx_timeout_factor = 16; break; case SPEED_100: + txb2b = 0; /* maybe add some timeout factor ? */ break; } diff --git a/trunk/drivers/net/igbvf/regs.h b/trunk/drivers/net/igbvf/regs.h index 77e18d3d6b15..b9e24ed70d0a 100644 --- a/trunk/drivers/net/igbvf/regs.h +++ b/trunk/drivers/net/igbvf/regs.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 - 2010 Intel Corporation. + Copyright(c) 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/igbvf/vf.c b/trunk/drivers/net/igbvf/vf.c index 0cc13c6ed418..a9a61efa964c 100644 --- a/trunk/drivers/net/igbvf/vf.c +++ b/trunk/drivers/net/igbvf/vf.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 - 2010 Intel Corporation. + Copyright(c) 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/igbvf/vf.h b/trunk/drivers/net/igbvf/vf.h index c36ea21f17fa..1e8ce3741a67 100644 --- a/trunk/drivers/net/igbvf/vf.h +++ b/trunk/drivers/net/igbvf/vf.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel(R) 82576 Virtual Function Linux driver - Copyright(c) 2009 - 2010 Intel Corporation. + Copyright(c) 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ipg.c b/trunk/drivers/net/ipg.c index aa93655c3aa7..dc0198092343 100644 --- a/trunk/drivers/net/ipg.c +++ b/trunk/drivers/net/ipg.c @@ -88,14 +88,16 @@ static const char *ipg_brand_name[] = { "IC PLUS IP1000 1000/100/10 based NIC", "Sundance Technology ST2021 based NIC", "Tamarack Microelectronics TC9020/9021 based NIC", + "Tamarack Microelectronics TC9020/9021 based NIC", "D-Link NIC IP1000A" }; static DEFINE_PCI_DEVICE_TABLE(ipg_pci_tbl) = { { PCI_VDEVICE(SUNDANCE, 0x1023), 0 }, { PCI_VDEVICE(SUNDANCE, 0x2021), 1 }, - { PCI_VDEVICE(DLINK, 0x9021), 2 }, - { PCI_VDEVICE(DLINK, 0x4020), 3 }, + { PCI_VDEVICE(SUNDANCE, 0x1021), 2 }, + { PCI_VDEVICE(DLINK, 0x9021), 3 }, + { PCI_VDEVICE(DLINK, 0x4020), 4 }, { 0, } }; diff --git a/trunk/drivers/net/iseries_veth.c b/trunk/drivers/net/iseries_veth.c index 38e15be6d513..8df645e78f2e 100644 --- a/trunk/drivers/net/iseries_veth.c +++ b/trunk/drivers/net/iseries_veth.c @@ -1605,7 +1605,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id) } veth_dev[i] = dev; - port = netdev_priv(dev); + port = (struct veth_port*)netdev_priv(dev); /* Start the state machine on each connection on this vlan. If we're * the first dev to do so this will commence link negotiation */ diff --git a/trunk/drivers/net/ixgb/ixgb_main.c b/trunk/drivers/net/ixgb/ixgb_main.c index 211a1694667e..caa8192fff2a 100644 --- a/trunk/drivers/net/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ixgb/ixgb_main.c @@ -669,12 +669,13 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter) int size; size = sizeof(struct ixgb_buffer) * txdr->count; - txdr->buffer_info = vzalloc(size); + txdr->buffer_info = vmalloc(size); if (!txdr->buffer_info) { netif_err(adapter, probe, adapter->netdev, "Unable to allocate transmit descriptor ring memory\n"); return -ENOMEM; } + memset(txdr->buffer_info, 0, size); /* round up to nearest 4K */ @@ -758,12 +759,13 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter) int size; size = sizeof(struct ixgb_buffer) * rxdr->count; - rxdr->buffer_info = vzalloc(size); + rxdr->buffer_info = vmalloc(size); if (!rxdr->buffer_info) { netif_err(adapter, probe, adapter->netdev, "Unable to allocate receive descriptor ring\n"); return -ENOMEM; } + memset(rxdr->buffer_info, 0, size); /* Round up to nearest 4K */ diff --git a/trunk/drivers/net/ixgbe/Makefile b/trunk/drivers/net/ixgbe/Makefile index 7d7387fbdecd..8f81efb49169 100644 --- a/trunk/drivers/net/ixgbe/Makefile +++ b/trunk/drivers/net/ixgbe/Makefile @@ -34,7 +34,7 @@ obj-$(CONFIG_IXGBE) += ixgbe.o ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \ ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ - ixgbe_mbx.o ixgbe_x540.o + ixgbe_mbx.o ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ ixgbe_dcb_82599.o ixgbe_dcb_nl.o diff --git a/trunk/drivers/net/ixgbe/ixgbe.h b/trunk/drivers/net/ixgbe/ixgbe.h index 3ae30b8cb7d6..ed8703cfffb7 100644 --- a/trunk/drivers/net/ixgbe/ixgbe.h +++ b/trunk/drivers/net/ixgbe/ixgbe.h @@ -61,8 +61,10 @@ #define IXGBE_MIN_RXD 64 /* flow control */ +#define IXGBE_DEFAULT_FCRTL 0x10000 #define IXGBE_MIN_FCRTL 0x40 #define IXGBE_MAX_FCRTL 0x7FF80 +#define IXGBE_DEFAULT_FCRTH 0x20000 #define IXGBE_MIN_FCRTH 0x600 #define IXGBE_MAX_FCRTH 0x7FFF0 #define IXGBE_DEFAULT_FCPAUSE 0xFFFF @@ -128,9 +130,7 @@ struct ixgbe_tx_buffer { unsigned long time_stamp; u16 length; u16 next_to_watch; - unsigned int bytecount; - u16 gso_segs; - u8 mapped_as_page; + u16 mapped_as_page; }; struct ixgbe_rx_buffer { @@ -146,56 +146,12 @@ struct ixgbe_queue_stats { u64 bytes; }; -struct ixgbe_tx_queue_stats { - u64 restart_queue; - u64 tx_busy; - u64 completed; - u64 tx_done_old; -}; - -struct ixgbe_rx_queue_stats { - u64 rsc_count; - u64 rsc_flush; - u64 non_eop_descs; - u64 alloc_rx_page_failed; - u64 alloc_rx_buff_failed; -}; - -enum ixbge_ring_state_t { - __IXGBE_TX_FDIR_INIT_DONE, - __IXGBE_TX_DETECT_HANG, - __IXGBE_HANG_CHECK_ARMED, - __IXGBE_RX_PS_ENABLED, - __IXGBE_RX_RSC_ENABLED, -}; - -#define ring_is_ps_enabled(ring) \ - test_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) -#define set_ring_ps_enabled(ring) \ - set_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) -#define clear_ring_ps_enabled(ring) \ - clear_bit(__IXGBE_RX_PS_ENABLED, &(ring)->state) -#define check_for_tx_hang(ring) \ - test_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) -#define set_check_for_tx_hang(ring) \ - set_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) -#define clear_check_for_tx_hang(ring) \ - clear_bit(__IXGBE_TX_DETECT_HANG, &(ring)->state) -#define ring_is_rsc_enabled(ring) \ - test_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) -#define set_ring_rsc_enabled(ring) \ - set_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) -#define clear_ring_rsc_enabled(ring) \ - clear_bit(__IXGBE_RX_RSC_ENABLED, &(ring)->state) struct ixgbe_ring { void *desc; /* descriptor ring memory */ - struct device *dev; /* device for DMA mapping */ - struct net_device *netdev; /* netdev ring belongs to */ union { struct ixgbe_tx_buffer *tx_buffer_info; struct ixgbe_rx_buffer *rx_buffer_info; }; - unsigned long state; u8 atr_sample_rate; u8 atr_count; u16 count; /* amount of descriptors */ @@ -204,30 +160,38 @@ struct ixgbe_ring { u16 next_to_clean; u8 queue_index; /* needed for multiqueue queue management */ - u8 reg_idx; /* holds the special value that gets - * the hardware register offset - * associated with this ring, which is - * different for DCB and RSS modes - */ - - u16 work_limit; /* max work per interrupt */ - u8 __iomem *tail; +#define IXGBE_RING_RX_PS_ENABLED (u8)(1) + u8 flags; /* per ring feature flags */ + u16 head; + u16 tail; unsigned int total_bytes; unsigned int total_packets; +#ifdef CONFIG_IXGBE_DCA + /* cpu for tx queue */ + int cpu; +#endif + + u16 work_limit; /* max work per interrupt */ + u16 reg_idx; /* holds the special value that gets + * the hardware register offset + * associated with this ring, which is + * different for DCB and RSS modes + */ + struct ixgbe_queue_stats stats; struct u64_stats_sync syncp; - union { - struct ixgbe_tx_queue_stats tx_stats; - struct ixgbe_rx_queue_stats rx_stats; - }; int numa_node; + unsigned long reinit_state; + u64 rsc_count; /* stat for coalesced packets */ + u64 rsc_flush; /* stats for flushed packets */ + u32 restart_queue; /* track tx queue restarts */ + u32 non_eop_descs; /* track hardware descriptor chaining */ + unsigned int size; /* length in bytes */ dma_addr_t dma; /* phys. address of descriptor ring */ - struct rcu_head rcu; - struct ixgbe_q_vector *q_vector; /* back-pointer to host q_vector */ } ____cacheline_internodealigned_in_smp; enum ixgbe_ring_f_enum { @@ -273,9 +237,6 @@ struct ixgbe_q_vector { unsigned int v_idx; /* index of q_vector within array, also used for * finding the bit in EICR and friends that * represents the vector for this ring */ -#ifdef CONFIG_IXGBE_DCA - int cpu; /* CPU for DCA */ -#endif struct napi_struct napi; DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */ DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */ @@ -285,7 +246,6 @@ struct ixgbe_q_vector { u8 rx_itr; u32 eitr; cpumask_var_t affinity_mask; - char name[IFNAMSIZ + 9]; }; /* Helper macros to switch between ints/sec and what the register uses. @@ -334,6 +294,7 @@ struct ixgbe_adapter { u16 bd_number; struct work_struct reset_task; struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; + char name[MAX_MSIX_COUNT][IFNAMSIZ + 9]; struct ixgbe_dcb_config dcb_cfg; struct ixgbe_dcb_config temp_dcb_cfg; u8 dcb_set_bitmap; @@ -456,7 +417,6 @@ struct ixgbe_adapter { int node; struct work_struct check_overtemp_task; u32 interrupt_event; - char lsc_int_name[IFNAMSIZ + 9]; /* SR-IOV */ DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); @@ -468,25 +428,17 @@ enum ixbge_state_t { __IXGBE_TESTING, __IXGBE_RESETTING, __IXGBE_DOWN, + __IXGBE_FDIR_INIT_DONE, __IXGBE_SFP_MODULE_NOT_FOUND }; -struct ixgbe_rsc_cb { - dma_addr_t dma; - u16 skb_cnt; - bool delay_unmap; -}; -#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) - enum ixgbe_boards { board_82598, board_82599, - board_X540, }; extern struct ixgbe_info ixgbe_82598_info; extern struct ixgbe_info ixgbe_82599_info; -extern struct ixgbe_info ixgbe_X540_info; #ifdef CONFIG_IXGBE_DCB extern const struct dcbnl_rtnl_ops dcbnl_ops; extern int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg, @@ -502,24 +454,26 @@ extern void ixgbe_down(struct ixgbe_adapter *adapter); extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter); extern void ixgbe_reset(struct ixgbe_adapter *adapter); extern void ixgbe_set_ethtool_ops(struct net_device *netdev); -extern int ixgbe_setup_rx_resources(struct ixgbe_ring *); -extern int ixgbe_setup_tx_resources(struct ixgbe_ring *); -extern void ixgbe_free_rx_resources(struct ixgbe_ring *); -extern void ixgbe_free_tx_resources(struct ixgbe_ring *); +extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, + struct net_device *, struct ixgbe_adapter *, struct ixgbe_ring *); -extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *, +extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *, struct ixgbe_tx_buffer *); -extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16); +extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + int cleaned_count); extern void ixgbe_write_eitr(struct ixgbe_q_vector *); extern int ethtool_ioctl(struct ifreq *ifr); -extern u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 index); extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); @@ -544,10 +498,6 @@ extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte); extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type); -extern void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring); -extern void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring); extern void ixgbe_set_rx_mode(struct net_device *netdev); #ifdef IXGBE_FCOE extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter); diff --git a/trunk/drivers/net/ixgbe/ixgbe_82598.c b/trunk/drivers/net/ixgbe/ixgbe_82598.c index d0f1d9d2c416..9c02d6014cc4 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_82598.c +++ b/trunk/drivers/net/ixgbe/ixgbe_82598.c @@ -38,6 +38,9 @@ #define IXGBE_82598_MC_TBL_SIZE 128 #define IXGBE_82598_VFT_TBL_SIZE 128 +static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg); static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, @@ -153,7 +156,7 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { mac->ops.setup_link = &ixgbe_setup_copper_link_82598; mac->ops.get_link_capabilities = - &ixgbe_get_copper_link_capabilities_generic; + &ixgbe_get_copper_link_capabilities_82598; } switch (hw->phy.type) { @@ -270,6 +273,37 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, return status; } +/** + * ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: boolean auto-negotiation value + * + * Determines the link capabilities by reading the AUTOC register. + **/ +static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + s32 status = IXGBE_ERR_LINK_SETUP; + u16 speed_ability; + + *speed = 0; + *autoneg = true; + + status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, + &speed_ability); + + if (status == 0) { + if (speed_ability & MDIO_SPEED_10G) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (speed_ability & MDIO_PMA_SPEED_1000) + *speed |= IXGBE_LINK_SPEED_1GB_FULL; + } + + return status; +} + /** * ixgbe_get_media_type_82598 - Determines media type * @hw: pointer to hardware structure @@ -323,7 +357,6 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) u32 fctrl_reg; u32 rmcs_reg; u32 reg; - u32 rx_pba_size; u32 link_speed = 0; bool link_up; @@ -426,18 +459,16 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) /* Set up and enable Rx high/low water mark thresholds, enable XON. */ if (hw->fc.current_mode & ixgbe_fc_tx_pause) { - rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); - rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; - - reg = (rx_pba_size - hw->fc.low_water) << 6; - if (hw->fc.send_xon) - reg |= IXGBE_FCRTL_XONE; - IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg); - - reg = (rx_pba_size - hw->fc.high_water) << 10; - reg |= IXGBE_FCRTH_FCEN; + if (hw->fc.send_xon) { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), + (hw->fc.low_water | IXGBE_FCRTL_XONE)); + } else { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), + hw->fc.low_water); + } - IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), + (hw->fc.high_water | IXGBE_FCRTH_FCEN)); } /* Configure pause time (2 TCs per register) */ @@ -1191,7 +1222,6 @@ static struct ixgbe_mac_operations mac_ops_82598 = { static struct ixgbe_eeprom_operations eeprom_ops_82598 = { .init_params = &ixgbe_init_eeprom_params_generic, .read = &ixgbe_read_eerd_generic, - .calc_checksum = &ixgbe_calc_eeprom_checksum_generic, .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, .update_checksum = &ixgbe_update_eeprom_checksum_generic, }; diff --git a/trunk/drivers/net/ixgbe/ixgbe_82599.c b/trunk/drivers/net/ixgbe/ixgbe_82599.c index e34643eef162..0bd8fbb5bfd0 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_82599.c +++ b/trunk/drivers/net/ixgbe/ixgbe_82599.c @@ -56,6 +56,9 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); +static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg); static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, @@ -171,7 +174,7 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { mac->ops.setup_link = &ixgbe_setup_copper_link_82599; mac->ops.get_link_capabilities = - &ixgbe_get_copper_link_capabilities_generic; + &ixgbe_get_copper_link_capabilities_82599; } /* Set necessary function pointers based on phy type */ @@ -181,10 +184,6 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) phy->ops.get_firmware_version = &ixgbe_get_phy_firmware_version_tnx; break; - case ixgbe_phy_aq: - phy->ops.get_firmware_version = - &ixgbe_get_phy_firmware_version_generic; - break; default: break; } @@ -290,6 +289,37 @@ static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, return status; } +/** + * ixgbe_get_copper_link_capabilities_82599 - Determines link capabilities + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @autoneg: boolean auto-negotiation value + * + * Determines the link capabilities by reading the AUTOC register. + **/ +static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) +{ + s32 status = IXGBE_ERR_LINK_SETUP; + u16 speed_ability; + + *speed = 0; + *autoneg = true; + + status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, + &speed_ability); + + if (status == 0) { + if (speed_ability & MDIO_SPEED_10G) + *speed |= IXGBE_LINK_SPEED_10GB_FULL; + if (speed_ability & MDIO_PMA_SPEED_1000) + *speed |= IXGBE_LINK_SPEED_1GB_FULL; + } + + return status; +} + /** * ixgbe_get_media_type_82599 - Get media type * @hw: pointer to hardware structure @@ -302,8 +332,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) /* Detect if there is a copper PHY attached. */ if (hw->phy.type == ixgbe_phy_cu_unknown || - hw->phy.type == ixgbe_phy_tn || - hw->phy.type == ixgbe_phy_aq) { + hw->phy.type == ixgbe_phy_tn) { media_type = ixgbe_media_type_copper; goto out; } @@ -1895,7 +1924,6 @@ static u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) hw->phy.ops.identify(hw); if (hw->phy.type == ixgbe_phy_tn || - hw->phy.type == ixgbe_phy_aq || hw->phy.type == ixgbe_phy_cu_unknown) { hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, &ext_ability); @@ -2097,6 +2125,51 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) return status; } +/** + * ixgbe_get_wwn_prefix_82599 - Get alternative WWNN/WWPN prefix from + * the EEPROM + * @hw: pointer to hardware structure + * @wwnn_prefix: the alternative WWNN prefix + * @wwpn_prefix: the alternative WWPN prefix + * + * This function will read the EEPROM from the alternative SAN MAC address + * block to check the support for the alternative WWNN/WWPN prefix support. + **/ +static s32 ixgbe_get_wwn_prefix_82599(struct ixgbe_hw *hw, u16 *wwnn_prefix, + u16 *wwpn_prefix) +{ + u16 offset, caps; + u16 alt_san_mac_blk_offset; + + /* clear output first */ + *wwnn_prefix = 0xFFFF; + *wwpn_prefix = 0xFFFF; + + /* check if alternative SAN MAC is supported */ + hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, + &alt_san_mac_blk_offset); + + if ((alt_san_mac_blk_offset == 0) || + (alt_san_mac_blk_offset == 0xFFFF)) + goto wwn_prefix_out; + + /* check capability in alternative san mac address block */ + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; + hw->eeprom.ops.read(hw, offset, &caps); + if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) + goto wwn_prefix_out; + + /* get the corresponding prefix for WWNN/WWPN */ + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; + hw->eeprom.ops.read(hw, offset, wwnn_prefix); + + offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; + hw->eeprom.ops.read(hw, offset, wwpn_prefix); + +wwn_prefix_out: + return 0; +} + static struct ixgbe_mac_operations mac_ops_82599 = { .init_hw = &ixgbe_init_hw_generic, .reset_hw = &ixgbe_reset_hw_82599, @@ -2108,7 +2181,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .get_mac_addr = &ixgbe_get_mac_addr_generic, .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic, .get_device_caps = &ixgbe_get_device_caps_82599, - .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic, + .get_wwn_prefix = &ixgbe_get_wwn_prefix_82599, .stop_adapter = &ixgbe_stop_adapter_generic, .get_bus_info = &ixgbe_get_bus_info_generic, .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie, @@ -2141,7 +2214,6 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = { .init_params = &ixgbe_init_eeprom_params_generic, .read = &ixgbe_read_eerd_generic, .write = &ixgbe_write_eeprom_generic, - .calc_checksum = &ixgbe_calc_eeprom_checksum_generic, .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, .update_checksum = &ixgbe_update_eeprom_checksum_generic, }; @@ -2168,5 +2240,5 @@ struct ixgbe_info ixgbe_82599_info = { .mac_ops = &mac_ops_82599, .eeprom_ops = &eeprom_ops_82599, .phy_ops = &phy_ops_82599, - .mbx_ops = &mbx_ops_generic, + .mbx_ops = &mbx_ops_82599, }; diff --git a/trunk/drivers/net/ixgbe/ixgbe_common.c b/trunk/drivers/net/ixgbe/ixgbe_common.c index 56052570cac5..e3eca1316389 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_common.c +++ b/trunk/drivers/net/ixgbe/ixgbe_common.c @@ -45,12 +45,14 @@ static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); static void ixgbe_release_eeprom(struct ixgbe_hw *hw); +static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw); static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index); static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); +static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); /** * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx @@ -636,7 +638,7 @@ s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) * Polls the status bit (bit 1) of the EERD or EEWR to determine when the * read or write is done respectively. **/ -s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) +static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) { u32 i; u32 reg; @@ -1007,7 +1009,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw) * ixgbe_calc_eeprom_checksum - Calculates and returns the checksum * @hw: pointer to hardware structure **/ -u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw) +static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw) { u16 i; u16 j; @@ -1070,7 +1072,7 @@ s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, status = hw->eeprom.ops.read(hw, 0, &checksum); if (status == 0) { - checksum = hw->eeprom.ops.calc_checksum(hw); + checksum = ixgbe_calc_eeprom_checksum(hw); hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); @@ -1108,7 +1110,7 @@ s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) status = hw->eeprom.ops.read(hw, 0, &checksum); if (status == 0) { - checksum = hw->eeprom.ops.calc_checksum(hw); + checksum = ixgbe_calc_eeprom_checksum(hw); status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, checksum); } else { @@ -1593,7 +1595,6 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) u32 mflcn_reg, fccfg_reg; u32 reg; u32 rx_pba_size; - u32 fcrtl, fcrth; #ifdef CONFIG_DCB if (hw->fc.requested_mode == ixgbe_fc_pfc) @@ -1670,20 +1671,40 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num) IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); - rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); - rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; + reg = IXGBE_READ_REG(hw, IXGBE_MTQC); + /* Thresholds are different for link flow control when in DCB mode */ + if (reg & IXGBE_MTQC_RT_ENA) { + rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num)); - fcrth = (rx_pba_size - hw->fc.high_water) << 10; - fcrtl = (rx_pba_size - hw->fc.low_water) << 10; + /* Always disable XON for LFC when in DCB mode */ + reg = (rx_pba_size >> 5) & 0xFFE0; + IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg); - if (hw->fc.current_mode & ixgbe_fc_tx_pause) { - fcrth |= IXGBE_FCRTH_FCEN; - if (hw->fc.send_xon) - fcrtl |= IXGBE_FCRTL_XONE; - } + reg = (rx_pba_size >> 2) & 0xFFE0; + if (hw->fc.current_mode & ixgbe_fc_tx_pause) + reg |= IXGBE_FCRTH_FCEN; + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), reg); + } else { + /* + * Set up and enable Rx high/low water mark thresholds, + * enable XON. + */ + if (hw->fc.current_mode & ixgbe_fc_tx_pause) { + if (hw->fc.send_xon) { + IXGBE_WRITE_REG(hw, + IXGBE_FCRTL_82599(packetbuf_num), + (hw->fc.low_water | + IXGBE_FCRTL_XONE)); + } else { + IXGBE_WRITE_REG(hw, + IXGBE_FCRTL_82599(packetbuf_num), + hw->fc.low_water); + } - IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), fcrth); - IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), fcrtl); + IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), + (hw->fc.high_water | IXGBE_FCRTH_FCEN)); + } + } /* Configure pause time (2 TCs per register) */ reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2)); @@ -2684,48 +2705,3 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, return 0; } - -/** - * ixgbe_get_wwn_prefix_generic Get alternative WWNN/WWPN prefix from - * the EEPROM - * @hw: pointer to hardware structure - * @wwnn_prefix: the alternative WWNN prefix - * @wwpn_prefix: the alternative WWPN prefix - * - * This function will read the EEPROM from the alternative SAN MAC address - * block to check the support for the alternative WWNN/WWPN prefix support. - **/ -s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, - u16 *wwpn_prefix) -{ - u16 offset, caps; - u16 alt_san_mac_blk_offset; - - /* clear output first */ - *wwnn_prefix = 0xFFFF; - *wwpn_prefix = 0xFFFF; - - /* check if alternative SAN MAC is supported */ - hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, - &alt_san_mac_blk_offset); - - if ((alt_san_mac_blk_offset == 0) || - (alt_san_mac_blk_offset == 0xFFFF)) - goto wwn_prefix_out; - - /* check capability in alternative san mac address block */ - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; - hw->eeprom.ops.read(hw, offset, &caps); - if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) - goto wwn_prefix_out; - - /* get the corresponding prefix for WWNN/WWPN */ - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; - hw->eeprom.ops.read(hw, offset, wwnn_prefix); - - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; - hw->eeprom.ops.read(hw, offset, wwpn_prefix); - -wwn_prefix_out: - return 0; -} diff --git a/trunk/drivers/net/ixgbe/ixgbe_common.h b/trunk/drivers/net/ixgbe/ixgbe_common.h index 341ca514a281..424c223437dc 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_common.h +++ b/trunk/drivers/net/ixgbe/ixgbe_common.h @@ -49,11 +49,9 @@ s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data); s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); -u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw); s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, u16 *checksum_val); s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); -s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); @@ -83,8 +81,7 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw); s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete); -s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, - u16 *wwpn_prefix); + s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index); s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index); diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb.c b/trunk/drivers/net/ixgbe/ixgbe_dcb.c index d16c260c1f50..0d44c6470ca3 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb.c +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb.c @@ -42,8 +42,7 @@ * It should be called only after the rules are checked by * ixgbe_dcb_check_config(). */ -s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config, +s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, int max_frame, u8 direction) { struct tc_bw_alloc *p; @@ -125,8 +124,7 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw, * credit may not be enough to send out a TSO * packet in descriptor plane arbitration. */ - if ((hw->mac.type == ixgbe_mac_82598EB) && - credit_max && + if (credit_max && (credit_max < MINIMUM_CREDIT_FOR_TSO)) credit_max = MINIMUM_CREDIT_FOR_TSO; @@ -152,17 +150,10 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { s32 ret = 0; - switch (hw->mac.type) { - case ixgbe_mac_82598EB: + if (hw->mac.type == ixgbe_mac_82598EB) ret = ixgbe_dcb_hw_config_82598(hw, dcb_config); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + else if (hw->mac.type == ixgbe_mac_82599EB) ret = ixgbe_dcb_hw_config_82599(hw, dcb_config); - break; - default: - break; - } return ret; } diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb.h b/trunk/drivers/net/ixgbe/ixgbe_dcb.h index 1cfe38ee1644..0208a87b129e 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb.h +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb.h @@ -150,8 +150,7 @@ struct ixgbe_dcb_config { /* DCB driver APIs */ /* DCB credits calculation */ -s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *, - struct ixgbe_dcb_config *, int, u8); +s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, int, u8); /* DCB hw initialization */ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb_82598.c b/trunk/drivers/net/ixgbe/ixgbe_dcb_82598.c index 9a5e89c12e05..50288bcadc59 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -256,17 +256,21 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, * for each traffic class. */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); - rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; - reg = (rx_pba_size - hw->fc.low_water) << 10; + if (dcb_config->rx_pba_cfg == pba_equal) { + rx_pba_size = IXGBE_RXPBSIZE_64KB; + } else { + rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB + : IXGBE_RXPBSIZE_48KB; + } + reg = ((rx_pba_size >> 5) & 0xFFF0); if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) reg |= IXGBE_FCRTL_XONE; IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg); - reg = (rx_pba_size - hw->fc.high_water) << 10; + reg = ((rx_pba_size >> 2) & 0xFFF0); if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) reg |= IXGBE_FCRTH_FCEN; diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c b/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c index 374e1f74d0f5..05f224715073 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -251,17 +251,19 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, /* Configure PFC Tx thresholds per TC */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { - rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); - rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; - - reg = (rx_pba_size - hw->fc.low_water) << 10; + if (dcb_config->rx_pba_cfg == pba_equal) + rx_pba_size = IXGBE_RXPBSIZE_64KB; + else + rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB + : IXGBE_RXPBSIZE_48KB; + reg = ((rx_pba_size >> 5) & 0xFFE0); if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) reg |= IXGBE_FCRTL_XONE; IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg); - reg = (rx_pba_size - hw->fc.high_water) << 10; + reg = ((rx_pba_size >> 2) & 0xFFE0); if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full || dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) reg |= IXGBE_FCRTH_FCEN; diff --git a/trunk/drivers/net/ixgbe/ixgbe_dcb_nl.c b/trunk/drivers/net/ixgbe/ixgbe_dcb_nl.c index bf566e8a455e..b53b465e24af 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/trunk/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -130,21 +130,15 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) netdev->netdev_ops->ndo_stop(netdev); ixgbe_clear_interrupt_scheme(adapter); - adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { adapter->last_lfc_mode = adapter->hw.fc.current_mode; adapter->hw.fc.requested_mode = ixgbe_fc_none; - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + } + adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - break; - default: - break; } - adapter->flags |= IXGBE_FLAG_DCB_ENABLED; ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) @@ -161,14 +155,8 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) adapter->dcb_cfg.pfc_mode_enable = false; adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags |= IXGBE_FLAG_RSS_ENABLED; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (adapter->hw.mac.type == ixgbe_mac_82599EB) adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; - break; - default: - break; - } ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) @@ -190,14 +178,9 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, for (i = 0; i < netdev->addr_len; i++) perm_addr[i] = adapter->hw.mac.perm_addr[i]; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { for (j = 0; j < netdev->addr_len; j++, i++) perm_addr[i] = adapter->hw.mac.san_addr[j]; - break; - default: - break; } } @@ -383,29 +366,15 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } if (adapter->dcb_cfg.pfc_mode_enable) { - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - if (adapter->hw.fc.current_mode != ixgbe_fc_pfc) - adapter->last_lfc_mode = - adapter->hw.fc.current_mode; - break; - default: - break; - } + if ((adapter->hw.mac.type != ixgbe_mac_82598EB) && + (adapter->hw.fc.current_mode != ixgbe_fc_pfc)) + adapter->last_lfc_mode = adapter->hw.fc.current_mode; adapter->hw.fc.requested_mode = ixgbe_fc_pfc; } else { - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - adapter->hw.fc.requested_mode = ixgbe_fc_none; - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (adapter->hw.mac.type != ixgbe_mac_82598EB) adapter->hw.fc.requested_mode = adapter->last_lfc_mode; - break; - default: - break; - } + else + adapter->hw.fc.requested_mode = ixgbe_fc_none; } if (adapter->dcb_set_bitmap & BIT_RESETLINK) { diff --git a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c index f9b58394fbb6..3dc731c22ff2 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c @@ -185,16 +185,6 @@ static int ixgbe_get_settings(struct net_device *netdev, ADVERTISED_FIBRE); ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; - } else if ((hw->device_id == IXGBE_DEV_ID_82599_COMBO_BACKPLANE) || - (hw->device_id == IXGBE_DEV_ID_82599_KX4_MEZZ)) { - ecmd->supported |= (SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_FIBRE); - ecmd->advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | - ADVERTISED_FIBRE); - ecmd->port = PORT_FIBRE; } else { ecmd->supported |= (SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE); @@ -214,7 +204,6 @@ static int ixgbe_get_settings(struct net_device *netdev, /* Get PHY type */ switch (adapter->hw.phy.type) { case ixgbe_phy_tn: - case ixgbe_phy_aq: case ixgbe_phy_cu_unknown: /* Copper 10G-BASET */ ecmd->port = PORT_TP; @@ -343,6 +332,13 @@ static void ixgbe_get_pauseparam(struct net_device *netdev, else pause->autoneg = 1; +#ifdef CONFIG_DCB + if (hw->fc.current_mode == ixgbe_fc_pfc) { + pause->rx_pause = 0; + pause->tx_pause = 0; + } + +#endif if (hw->fc.current_mode == ixgbe_fc_rx_pause) { pause->rx_pause = 1; } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) { @@ -350,11 +346,6 @@ static void ixgbe_get_pauseparam(struct net_device *netdev, } else if (hw->fc.current_mode == ixgbe_fc_full) { pause->rx_pause = 1; pause->tx_pause = 1; -#ifdef CONFIG_DCB - } else if (hw->fc.current_mode == ixgbe_fc_pfc) { - pause->rx_pause = 0; - pause->tx_pause = 0; -#endif } } @@ -372,6 +363,7 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, return -EINVAL; #endif + fc = hw->fc; if (pause->autoneg != AUTONEG_ENABLE) @@ -420,6 +412,11 @@ static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) else adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED; + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); + return 0; } @@ -431,21 +428,16 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev) static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - u32 feature_list; - feature_list = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - feature_list |= NETIF_F_SCTP_CSUM; - break; - default: - break; + if (data) { + netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + netdev->features |= NETIF_F_SCTP_CSUM; + } else { + netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + netdev->features &= ~NETIF_F_SCTP_CSUM; } - if (data) - netdev->features |= feature_list; - else - netdev->features &= ~feature_list; return 0; } @@ -538,20 +530,10 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[32] = IXGBE_READ_REG(hw, IXGBE_FCTTV(1)); regs_buff[33] = IXGBE_READ_REG(hw, IXGBE_FCTTV(2)); regs_buff[34] = IXGBE_READ_REG(hw, IXGBE_FCTTV(3)); - for (i = 0; i < 8; i++) { - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL(i)); - regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH(i)); - break; - case ixgbe_mac_82599EB: - regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL_82599(i)); - regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH_82599(i)); - break; - default: - break; - } - } + for (i = 0; i < 8; i++) + regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL(i)); + for (i = 0; i < 8; i++) + regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH(i)); regs_buff[51] = IXGBE_READ_REG(hw, IXGBE_FCRTV); regs_buff[52] = IXGBE_READ_REG(hw, IXGBE_TFCS); @@ -633,7 +615,6 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM); regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0)); - /* DCB */ regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS); regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS); regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS); @@ -924,11 +905,13 @@ static int ixgbe_set_ringparam(struct net_device *netdev, memcpy(&temp_tx_ring[i], adapter->tx_ring[i], sizeof(struct ixgbe_ring)); temp_tx_ring[i].count = new_tx_count; - err = ixgbe_setup_tx_resources(&temp_tx_ring[i]); + err = ixgbe_setup_tx_resources(adapter, + &temp_tx_ring[i]); if (err) { while (i) { i--; - ixgbe_free_tx_resources(&temp_tx_ring[i]); + ixgbe_free_tx_resources(adapter, + &temp_tx_ring[i]); } goto clear_reset; } @@ -947,11 +930,13 @@ static int ixgbe_set_ringparam(struct net_device *netdev, memcpy(&temp_rx_ring[i], adapter->rx_ring[i], sizeof(struct ixgbe_ring)); temp_rx_ring[i].count = new_rx_count; - err = ixgbe_setup_rx_resources(&temp_rx_ring[i]); + err = ixgbe_setup_rx_resources(adapter, + &temp_rx_ring[i]); if (err) { while (i) { i--; - ixgbe_free_rx_resources(&temp_rx_ring[i]); + ixgbe_free_rx_resources(adapter, + &temp_rx_ring[i]); } goto err_setup; } @@ -966,7 +951,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev, /* tx */ if (new_tx_count != adapter->tx_ring_count) { for (i = 0; i < adapter->num_tx_queues; i++) { - ixgbe_free_tx_resources(adapter->tx_ring[i]); + ixgbe_free_tx_resources(adapter, + adapter->tx_ring[i]); memcpy(adapter->tx_ring[i], &temp_tx_ring[i], sizeof(struct ixgbe_ring)); } @@ -976,7 +962,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev, /* rx */ if (new_rx_count != adapter->rx_ring_count) { for (i = 0; i < adapter->num_rx_queues; i++) { - ixgbe_free_rx_resources(adapter->rx_ring[i]); + ixgbe_free_rx_resources(adapter, + adapter->rx_ring[i]); memcpy(adapter->rx_ring[i], &temp_rx_ring[i], sizeof(struct ixgbe_ring)); } @@ -1250,20 +1237,12 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) u32 value, before, after; u32 i, toggle; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - toggle = 0x7FFFF3FF; - test = reg_test_82598; - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { toggle = 0x7FFFF30F; test = reg_test_82599; - break; - default: - *data = 1; - return 1; - break; + } else { + toggle = 0x7FFFF3FF; + test = reg_test_82598; } /* @@ -1481,21 +1460,16 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) reg_ctl &= ~IXGBE_TXDCTL_ENABLE; IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl); - switch (hw->mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (hw->mac.type == ixgbe_mac_82599EB) { reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); reg_ctl &= ~IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl); - break; - default: - break; } ixgbe_reset(adapter); - ixgbe_free_tx_resources(&adapter->test_tx_ring); - ixgbe_free_rx_resources(&adapter->test_rx_ring); + ixgbe_free_tx_resources(adapter, &adapter->test_tx_ring); + ixgbe_free_rx_resources(adapter, &adapter->test_rx_ring); } static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) @@ -1509,24 +1483,17 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) /* Setup Tx descriptor ring and Tx buffers */ tx_ring->count = IXGBE_DEFAULT_TXD; tx_ring->queue_index = 0; - tx_ring->dev = &adapter->pdev->dev; - tx_ring->netdev = adapter->netdev; tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx; tx_ring->numa_node = adapter->node; - err = ixgbe_setup_tx_resources(tx_ring); + err = ixgbe_setup_tx_resources(adapter, tx_ring); if (err) return 1; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); reg_data |= IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); - break; - default: - break; } ixgbe_configure_tx_ring(adapter, tx_ring); @@ -1534,13 +1501,11 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) /* Setup Rx Descriptor ring and Rx buffers */ rx_ring->count = IXGBE_DEFAULT_RXD; rx_ring->queue_index = 0; - rx_ring->dev = &adapter->pdev->dev; - rx_ring->netdev = adapter->netdev; rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx; rx_ring->rx_buf_len = IXGBE_RXBUFFER_2048; rx_ring->numa_node = adapter->node; - err = ixgbe_setup_rx_resources(rx_ring); + err = ixgbe_setup_rx_resources(adapter, rx_ring); if (err) { ret_val = 4; goto err_nomem; @@ -1639,7 +1604,8 @@ static int ixgbe_check_lbtest_frame(struct sk_buff *skb, return 13; } -static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, +static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, struct ixgbe_ring *tx_ring, unsigned int size) { @@ -1661,7 +1627,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc]; /* unmap Rx buffer, will be remapped by alloc_rx_buffers */ - dma_unmap_single(rx_ring->dev, + dma_unmap_single(&adapter->pdev->dev, rx_buffer_info->dma, bufsz, DMA_FROM_DEVICE); @@ -1673,7 +1639,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, /* unmap buffer on Tx side */ tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc]; - ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); + ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); /* increment Rx/Tx next to clean counters */ rx_ntc++; @@ -1689,7 +1655,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring, } /* re-map buffers to ring, store next to clean values */ - ixgbe_alloc_rx_buffers(rx_ring, count); + ixgbe_alloc_rx_buffers(adapter, rx_ring, count); rx_ring->next_to_clean = rx_ntc; tx_ring->next_to_clean = tx_ntc; @@ -1733,6 +1699,7 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) for (i = 0; i < 64; i++) { skb_get(skb); tx_ret_val = ixgbe_xmit_frame_ring(skb, + adapter->netdev, adapter, tx_ring); if (tx_ret_val == NETDEV_TX_OK) @@ -1747,7 +1714,8 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) /* allow 200 milliseconds for packets to go from Tx to Rx */ msleep(200); - good_cnt = ixgbe_clean_test_rings(rx_ring, tx_ring, size); + good_cnt = ixgbe_clean_test_rings(adapter, rx_ring, + tx_ring, size); if (good_cnt != 64) { ret_val = 13; break; @@ -1880,13 +1848,6 @@ static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, int retval = 1; switch(hw->device_id) { - case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: - /* All except this subdevice support WOL */ - if (hw->subsystem_device_id == - IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) { - wol->supported = 0; - break; - } case IXGBE_DEV_ID_82599_KX4: retval = 0; break; @@ -2024,41 +1985,6 @@ static int ixgbe_get_coalesce(struct net_device *netdev, return 0; } -/* - * this function must be called before setting the new value of - * rx_itr_setting - */ -static bool ixgbe_update_rsc(struct ixgbe_adapter *adapter, - struct ethtool_coalesce *ec) -{ - struct net_device *netdev = adapter->netdev; - - if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) - return false; - - /* if interrupt rate is too high then disable RSC */ - if (ec->rx_coalesce_usecs != 1 && - ec->rx_coalesce_usecs <= 1000000/IXGBE_MAX_RSC_INT_RATE) { - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { - e_info(probe, "rx-usecs set too low, " - "disabling RSC\n"); - adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; - return true; - } - } else { - /* check the feature flag value and enable RSC if necessary */ - if ((netdev->features & NETIF_F_LRO) && - !(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) { - e_info(probe, "rx-usecs set to %d, " - "re-enabling RSC\n", - ec->rx_coalesce_usecs); - adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; - return true; - } - } - return false; -} - static int ixgbe_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec) { @@ -2076,14 +2002,17 @@ static int ixgbe_set_coalesce(struct net_device *netdev, adapter->tx_ring[0]->work_limit = ec->tx_max_coalesced_frames_irq; if (ec->rx_coalesce_usecs > 1) { + u32 max_int; + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + max_int = IXGBE_MAX_RSC_INT_RATE; + else + max_int = IXGBE_MAX_INT_RATE; + /* check the limits */ - if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) || + if ((1000000/ec->rx_coalesce_usecs > max_int) || (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE)) return -EINVAL; - /* check the old value and enable RSC if necessary */ - need_reset = ixgbe_update_rsc(adapter, ec); - /* store the value in ints/second */ adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs; @@ -2092,21 +2021,32 @@ static int ixgbe_set_coalesce(struct net_device *netdev, /* clear the lower bit as its used for dynamic state */ adapter->rx_itr_setting &= ~1; } else if (ec->rx_coalesce_usecs == 1) { - /* check the old value and enable RSC if necessary */ - need_reset = ixgbe_update_rsc(adapter, ec); - /* 1 means dynamic mode */ adapter->rx_eitr_param = 20000; adapter->rx_itr_setting = 1; } else { - /* check the old value and enable RSC if necessary */ - need_reset = ixgbe_update_rsc(adapter, ec); /* * any other value means disable eitr, which is best * served by setting the interrupt rate very high */ adapter->rx_eitr_param = IXGBE_MAX_INT_RATE; adapter->rx_itr_setting = 0; + + /* + * if hardware RSC is enabled, disable it when + * setting low latency mode, to avoid errata, assuming + * that when the user set low latency mode they want + * it at the cost of anything else + */ + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; + if (netdev->features & NETIF_F_LRO) { + netdev->features &= ~NETIF_F_LRO; + e_info(probe, "rx-usecs set to 0, " + "disabling RSC\n"); + } + need_reset = true; + } } if (ec->tx_coalesce_usecs > 1) { @@ -2193,39 +2133,28 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) return rc; /* if state changes we need to update adapter->flags and reset */ - if ((adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) && - (!!(data & ETH_FLAG_LRO) != - !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { - if ((data & ETH_FLAG_LRO) && - (!adapter->rx_itr_setting || - (adapter->rx_itr_setting > IXGBE_MAX_RSC_INT_RATE))) { - e_info(probe, "rx-usecs set too low, " - "not enabling RSC.\n"); - } else { + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) { + /* + * cast both to bool and verify if they are set the same + * but only enable RSC if itr is non-zero, as + * itr=0 and RSC are mutually exclusive + */ + if (((!!(data & ETH_FLAG_LRO)) != + (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) && + adapter->rx_itr_setting) { adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: need_reset = true; break; - case ixgbe_mac_X540: { - int i; - for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = - adapter->rx_ring[i]; - if (adapter->flags2 & - IXGBE_FLAG2_RSC_ENABLED) { - ixgbe_configure_rscctl(adapter, - ring); - } else { - ixgbe_clear_rscctl(adapter, - ring); - } - } - } - break; default: break; } + } else if (!adapter->rx_itr_setting) { + netdev->features &= ~NETIF_F_LRO; + if (data & ETH_FLAG_LRO) + e_info(probe, "rx-usecs set to 0, " + "LRO/RSC cannot be enabled.\n"); } } diff --git a/trunk/drivers/net/ixgbe/ixgbe_fcoe.c b/trunk/drivers/net/ixgbe/ixgbe_fcoe.c index 6342d4859790..05efa6a8ce8e 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/trunk/drivers/net/ixgbe/ixgbe_fcoe.c @@ -68,7 +68,7 @@ static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc) static inline void ixgbe_fcoe_clear_ddp(struct ixgbe_fcoe_ddp *ddp) { ddp->len = 0; - ddp->err = 1; + ddp->err = 0; ddp->udl = NULL; ddp->udp = 0UL; ddp->sgl = NULL; @@ -92,7 +92,6 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) struct ixgbe_fcoe *fcoe; struct ixgbe_adapter *adapter; struct ixgbe_fcoe_ddp *ddp; - u32 fcbuff; if (!netdev) goto out_ddp_put; @@ -116,14 +115,7 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid) IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCBUFF, 0); IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW, (xid | IXGBE_FCDMARW_WE)); - - /* guaranteed to be invalidated after 100us */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW, - (xid | IXGBE_FCDMARW_RE)); - fcbuff = IXGBE_READ_REG(&adapter->hw, IXGBE_FCBUFF); spin_unlock_bh(&fcoe->lock); - if (fcbuff & IXGBE_FCBUFF_VALID) - udelay(100); } if (ddp->sgl) pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc, @@ -176,11 +168,6 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, return 0; } - /* no DDP if we are already down or resetting */ - if (test_bit(__IXGBE_DOWN, &adapter->state) || - test_bit(__IXGBE_RESETTING, &adapter->state)) - return 0; - fcoe = &adapter->fcoe; if (!fcoe->pool) { e_warn(drv, "xid=0x%x no ddp pool for fcoe\n", xid); diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 494cb57b700d..2bd3eb4ee5a1 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -52,14 +52,13 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = "Intel(R) 10 Gigabit PCI Express Network Driver"; -#define DRV_VERSION "3.0.12-k2" +#define DRV_VERSION "2.0.84-k2" const char ixgbe_driver_version[] = DRV_VERSION; static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; static const struct ixgbe_info *ixgbe_info_tbl[] = { [board_82598] = &ixgbe_82598_info, [board_82599] = &ixgbe_82599_info, - [board_X540] = &ixgbe_X540_info, }; /* ixgbe_pci_tbl - PCI Device ID Table @@ -113,8 +112,6 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = { board_82599 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE), board_82599 }, - {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T), - board_82599 }, /* required last entry */ {0, } @@ -563,7 +560,6 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar); break; case ixgbe_mac_82599EB: - case ixgbe_mac_X540: if (direction == -1) { /* other causes */ msix_vector |= IXGBE_IVAR_ALLOC_VAL; @@ -593,34 +589,29 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, { u32 mask; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { mask = (IXGBE_EIMS_RTX_QUEUE & qmask); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + } else { mask = (qmask & 0xFFFFFFFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask); mask = (qmask >> 32); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask); - break; - default: - break; } } -void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, - struct ixgbe_tx_buffer *tx_buffer_info) +void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, + struct ixgbe_tx_buffer + *tx_buffer_info) { if (tx_buffer_info->dma) { if (tx_buffer_info->mapped_as_page) - dma_unmap_page(tx_ring->dev, + dma_unmap_page(&adapter->pdev->dev, tx_buffer_info->dma, tx_buffer_info->length, DMA_TO_DEVICE); else - dma_unmap_single(tx_ring->dev, + dma_unmap_single(&adapter->pdev->dev, tx_buffer_info->dma, tx_buffer_info->length, DMA_TO_DEVICE); @@ -635,166 +626,92 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring, } /** - * ixgbe_dcb_txq_to_tc - convert a reg index to a traffic class - * @adapter: driver private struct - * @index: reg idx of queue to query (0-127) + * ixgbe_tx_xon_state - check the tx ring xon state + * @adapter: the ixgbe adapter + * @tx_ring: the corresponding tx_ring * - * Helper function to determine the traffic index for a paticular - * register index. + * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the + * corresponding TC of this tx_ring when checking TFCS. * - * Returns : a tc index for use in range 0-7, or 0-3 + * Returns : true if in xon state (currently not paused) */ -u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx) +static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) { - int tc = -1; - int dcb_i = adapter->ring_feature[RING_F_DCB].indices; - - /* if DCB is not enabled the queues have no TC */ - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - return tc; - - /* check valid range */ - if (reg_idx >= adapter->hw.mac.max_tx_queues) - return tc; + u32 txoff = IXGBE_TFCS_TXOFF; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - tc = reg_idx >> 2; - break; - default: - if (dcb_i != 4 && dcb_i != 8) - break; - - /* if VMDq is enabled the lowest order bits determine TC */ - if (adapter->flags & (IXGBE_FLAG_SRIOV_ENABLED | - IXGBE_FLAG_VMDQ_ENABLED)) { - tc = reg_idx & (dcb_i - 1); - break; - } - - /* - * Convert the reg_idx into the correct TC. This bitmask - * targets the last full 32 ring traffic class and assigns - * it a value of 1. From there the rest of the rings are - * based on shifting the mask further up to include the - * reg_idx / 16 and then reg_idx / 8. It assumes dcB_i - * will only ever be 8 or 4 and that reg_idx will never - * be greater then 128. The code without the power of 2 - * optimizations would be: - * (((reg_idx % 32) + 32) * dcb_i) >> (9 - reg_idx / 32) - */ - tc = ((reg_idx & 0X1F) + 0x20) * dcb_i; - tc >>= 9 - (reg_idx >> 5); - } - - return tc; -} - -static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_hw_stats *hwstats = &adapter->stats; - u32 data = 0; - u32 xoff[8] = {0}; - int i; +#ifdef CONFIG_IXGBE_DCB + if (adapter->dcb_cfg.pfc_mode_enable) { + int tc; + int reg_idx = tx_ring->reg_idx; + int dcb_i = adapter->ring_feature[RING_F_DCB].indices; - if ((hw->fc.current_mode == ixgbe_fc_full) || - (hw->fc.current_mode == ixgbe_fc_rx_pause)) { - switch (hw->mac.type) { + switch (adapter->hw.mac.type) { case ixgbe_mac_82598EB: - data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + tc = reg_idx >> 2; + txoff = IXGBE_TFCS_TXOFF0; break; - default: - data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); - } - hwstats->lxoffrxc += data; - - /* refill credits (no tx hang) if we received xoff */ - if (!data) - return; - - for (i = 0; i < adapter->num_tx_queues; i++) - clear_bit(__IXGBE_HANG_CHECK_ARMED, - &adapter->tx_ring[i]->state); - return; - } else if (!(adapter->dcb_cfg.pfc_mode_enable)) - return; - - /* update stats for each tc, only valid with PFC enabled */ - for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) { - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - xoff[i] = IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); + case ixgbe_mac_82599EB: + tc = 0; + txoff = IXGBE_TFCS_TXOFF; + if (dcb_i == 8) { + /* TC0, TC1 */ + tc = reg_idx >> 5; + if (tc == 2) /* TC2, TC3 */ + tc += (reg_idx - 64) >> 4; + else if (tc == 3) /* TC4, TC5, TC6, TC7 */ + tc += 1 + ((reg_idx - 96) >> 3); + } else if (dcb_i == 4) { + /* TC0, TC1 */ + tc = reg_idx >> 6; + if (tc == 1) { + tc += (reg_idx - 64) >> 5; + if (tc == 2) /* TC2, TC3 */ + tc += (reg_idx - 96) >> 4; + } + } break; default: - xoff[i] = IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + tc = 0; } - hwstats->pxoffrxc[i] += xoff[i]; + txoff <<= tc; } - - /* disarm tx queues that have received xoff frames */ - for (i = 0; i < adapter->num_tx_queues; i++) { - struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; - u32 tc = ixgbe_dcb_txq_to_tc(adapter, tx_ring->reg_idx); - - if (xoff[tc]) - clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state); - } -} - -static u64 ixgbe_get_tx_completed(struct ixgbe_ring *ring) -{ - return ring->tx_stats.completed; +#endif + return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff; } -static u64 ixgbe_get_tx_pending(struct ixgbe_ring *ring) +static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring, + unsigned int eop) { - struct ixgbe_adapter *adapter = netdev_priv(ring->netdev); struct ixgbe_hw *hw = &adapter->hw; - u32 head = IXGBE_READ_REG(hw, IXGBE_TDH(ring->reg_idx)); - u32 tail = IXGBE_READ_REG(hw, IXGBE_TDT(ring->reg_idx)); - - if (head != tail) - return (head < tail) ? - tail - head : (tail + ring->count - head); - - return 0; -} - -static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring) -{ - u32 tx_done = ixgbe_get_tx_completed(tx_ring); - u32 tx_done_old = tx_ring->tx_stats.tx_done_old; - u32 tx_pending = ixgbe_get_tx_pending(tx_ring); - bool ret = false; - - clear_check_for_tx_hang(tx_ring); - - /* - * Check for a hung queue, but be thorough. This verifies - * that a transmit has been completed since the previous - * check AND there is at least one packet pending. The - * ARMED bit is set to indicate a potential hang. The - * bit is cleared if a pause frame is received to remove - * false hang detection due to PFC or 802.3x frames. By - * requiring this to fail twice we avoid races with - * pfc clearing the ARMED bit and conditions where we - * run the check_tx_hang logic with a transmit completion - * pending but without time to complete it yet. - */ - if ((tx_done_old == tx_done) && tx_pending) { - /* make sure it is true for two checks in a row */ - ret = test_and_set_bit(__IXGBE_HANG_CHECK_ARMED, - &tx_ring->state); - } else { - /* update completed stats and continue */ - tx_ring->tx_stats.tx_done_old = tx_done; - /* reset the countdown */ - clear_bit(__IXGBE_HANG_CHECK_ARMED, &tx_ring->state); + /* Detect a transmit hang in hardware, this serializes the + * check with the clearing of time_stamp and movement of eop */ + adapter->detect_tx_hung = false; + if (tx_ring->tx_buffer_info[eop].time_stamp && + time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) && + ixgbe_tx_xon_state(adapter, tx_ring)) { + /* detected Tx unit hang */ + union ixgbe_adv_tx_desc *tx_desc; + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); + e_err(drv, "Detected Tx Unit Hang\n" + " Tx Queue <%d>\n" + " TDH, TDT <%x>, <%x>\n" + " next_to_use <%x>\n" + " next_to_clean <%x>\n" + "tx_buffer_info[next_to_clean]\n" + " time_stamp <%lx>\n" + " jiffies <%lx>\n", + tx_ring->queue_index, + IXGBE_READ_REG(hw, tx_ring->head), + IXGBE_READ_REG(hw, tx_ring->tail), + tx_ring->next_to_use, eop, + tx_ring->tx_buffer_info[eop].time_stamp, jiffies); + return true; } - return ret; + return false; } #define IXGBE_MAX_TXD_PWR 14 @@ -817,10 +734,11 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *tx_ring) { struct ixgbe_adapter *adapter = q_vector->adapter; + struct net_device *netdev = adapter->netdev; union ixgbe_adv_tx_desc *tx_desc, *eop_desc; struct ixgbe_tx_buffer *tx_buffer_info; + unsigned int i, eop, count = 0; unsigned int total_bytes = 0, total_packets = 0; - u16 i, eop, count = 0; i = tx_ring->next_to_clean; eop = tx_ring->tx_buffer_info[i].next_to_watch; @@ -831,182 +749,147 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, bool cleaned = false; rmb(); /* read buffer_info after eop_desc */ for ( ; !cleaned; count++) { + struct sk_buff *skb; tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_buffer_info = &tx_ring->tx_buffer_info[i]; - - tx_desc->wb.status = 0; cleaned = (i == eop); + skb = tx_buffer_info->skb; - i++; - if (i == tx_ring->count) - i = 0; + if (cleaned && skb) { + unsigned int segs, bytecount; + unsigned int hlen = skb_headlen(skb); - if (cleaned && tx_buffer_info->skb) { - total_bytes += tx_buffer_info->bytecount; - total_packets += tx_buffer_info->gso_segs; + /* gso_segs is currently only valid for tcp */ + segs = skb_shinfo(skb)->gso_segs ?: 1; +#ifdef IXGBE_FCOE + /* adjust for FCoE Sequence Offload */ + if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) + && (skb->protocol == htons(ETH_P_FCOE)) && + skb_is_gso(skb)) { + hlen = skb_transport_offset(skb) + + sizeof(struct fc_frame_header) + + sizeof(struct fcoe_crc_eof); + segs = DIV_ROUND_UP(skb->len - hlen, + skb_shinfo(skb)->gso_size); + } +#endif /* IXGBE_FCOE */ + /* multiply data chunks by size of headers */ + bytecount = ((segs - 1) * hlen) + skb->len; + total_packets += segs; + total_bytes += bytecount; } - ixgbe_unmap_and_free_tx_resource(tx_ring, + ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); + + tx_desc->wb.status = 0; + + i++; + if (i == tx_ring->count) + i = 0; } - tx_ring->tx_stats.completed++; eop = tx_ring->tx_buffer_info[i].next_to_watch; eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); } tx_ring->next_to_clean = i; - tx_ring->total_bytes += total_bytes; - tx_ring->total_packets += total_packets; - u64_stats_update_begin(&tx_ring->syncp); - tx_ring->stats.packets += total_packets; - tx_ring->stats.bytes += total_bytes; - u64_stats_update_end(&tx_ring->syncp); - - if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) { - /* schedule immediate reset if we believe we hung */ - struct ixgbe_hw *hw = &adapter->hw; - tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); - e_err(drv, "Detected Tx Unit Hang\n" - " Tx Queue <%d>\n" - " TDH, TDT <%x>, <%x>\n" - " next_to_use <%x>\n" - " next_to_clean <%x>\n" - "tx_buffer_info[next_to_clean]\n" - " time_stamp <%lx>\n" - " jiffies <%lx>\n", - tx_ring->queue_index, - IXGBE_READ_REG(hw, IXGBE_TDH(tx_ring->reg_idx)), - IXGBE_READ_REG(hw, IXGBE_TDT(tx_ring->reg_idx)), - tx_ring->next_to_use, eop, - tx_ring->tx_buffer_info[eop].time_stamp, jiffies); - - netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); - - e_info(probe, - "tx hang %d detected on queue %d, resetting adapter\n", - adapter->tx_timeout_count + 1, tx_ring->queue_index); - - /* schedule immediate reset if we believe we hung */ - ixgbe_tx_timeout(adapter->netdev); - - /* the adapter is about to reset, no point in enabling stuff */ - return true; - } #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) - if (unlikely(count && netif_carrier_ok(tx_ring->netdev) && + if (unlikely(count && netif_carrier_ok(netdev) && (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) { /* Make sure that anybody stopping the queue after this * sees the new next_to_clean. */ smp_mb(); - if (__netif_subqueue_stopped(tx_ring->netdev, tx_ring->queue_index) && + if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) && !test_bit(__IXGBE_DOWN, &adapter->state)) { - netif_wake_subqueue(tx_ring->netdev, tx_ring->queue_index); - ++tx_ring->tx_stats.restart_queue; + netif_wake_subqueue(netdev, tx_ring->queue_index); + ++tx_ring->restart_queue; } } + if (adapter->detect_tx_hung) { + if (ixgbe_check_tx_hang(adapter, tx_ring, i)) { + /* schedule immediate reset if we believe we hung */ + e_info(probe, "tx hang %d detected, resetting " + "adapter\n", adapter->tx_timeout_count + 1); + ixgbe_tx_timeout(adapter->netdev); + } + } + + /* re-arm the interrupt */ + if (count >= tx_ring->work_limit) + ixgbe_irq_rearm_queues(adapter, ((u64)1 << q_vector->v_idx)); + + tx_ring->total_bytes += total_bytes; + tx_ring->total_packets += total_packets; + u64_stats_update_begin(&tx_ring->syncp); + tx_ring->stats.packets += total_packets; + tx_ring->stats.bytes += total_bytes; + u64_stats_update_end(&tx_ring->syncp); return count < tx_ring->work_limit; } #ifdef CONFIG_IXGBE_DCA static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring, - int cpu) + struct ixgbe_ring *rx_ring) { - struct ixgbe_hw *hw = &adapter->hw; u32 rxctrl; - u8 reg_idx = rx_ring->reg_idx; - - rxctrl = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(reg_idx)); - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK; - rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599; - rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); - break; - default: - break; + int cpu = get_cpu(); + int q = rx_ring->reg_idx; + + if (rx_ring->cpu != cpu) { + rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q)); + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK; + rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); + } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599; + rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << + IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); + } + rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; + rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; + rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN); + rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl); + rx_ring->cpu = cpu; } - rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; - rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; - rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN); - rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | - IXGBE_DCA_RXCTRL_DESC_HSRO_EN); - IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl); + put_cpu(); } static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - int cpu) + struct ixgbe_ring *tx_ring) { - struct ixgbe_hw *hw = &adapter->hw; u32 txctrl; - u8 reg_idx = tx_ring->reg_idx; - - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(reg_idx)); - txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK; - txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); - txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; - txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(reg_idx), txctrl); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx)); - txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599; - txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); - txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; - txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx), txctrl); - break; - default: - break; - } -} - -static void ixgbe_update_dca(struct ixgbe_q_vector *q_vector) -{ - struct ixgbe_adapter *adapter = q_vector->adapter; int cpu = get_cpu(); - long r_idx; - int i; - - if (q_vector->cpu == cpu) - goto out_no_update; - - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - for (i = 0; i < q_vector->txr_count; i++) { - ixgbe_update_tx_dca(adapter, adapter->tx_ring[r_idx], cpu); - r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); - } + int q = tx_ring->reg_idx; + struct ixgbe_hw *hw = &adapter->hw; - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { - ixgbe_update_rx_dca(adapter, adapter->rx_ring[r_idx], cpu); - r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + if (tx_ring->cpu != cpu) { + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(q)); + txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK; + txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu); + txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(q), txctrl); + } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q)); + txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599; + txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << + IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); + txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl); + } + tx_ring->cpu = cpu; } - - q_vector->cpu = cpu; -out_no_update: put_cpu(); } static void ixgbe_setup_dca(struct ixgbe_adapter *adapter) { - int num_q_vectors; int i; if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED)) @@ -1015,25 +898,22 @@ static void ixgbe_setup_dca(struct ixgbe_adapter *adapter) /* always use CB2 mode, difference is masked in the CB driver */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2); - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) - num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; - else - num_q_vectors = 1; - - for (i = 0; i < num_q_vectors; i++) { - adapter->q_vector[i]->cpu = -1; - ixgbe_update_dca(adapter->q_vector[i]); + for (i = 0; i < adapter->num_tx_queues; i++) { + adapter->tx_ring[i]->cpu = -1; + ixgbe_update_tx_dca(adapter, adapter->tx_ring[i]); + } + for (i = 0; i < adapter->num_rx_queues; i++) { + adapter->rx_ring[i]->cpu = -1; + ixgbe_update_rx_dca(adapter, adapter->rx_ring[i]); } } static int __ixgbe_notify_dca(struct device *dev, void *data) { - struct ixgbe_adapter *adapter = dev_get_drvdata(dev); + struct net_device *netdev = dev_get_drvdata(dev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); unsigned long event = *(unsigned long *)data; - if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED)) - return 0; - switch (event) { case DCA_PROVIDER_ADD: /* if we're already enabled, don't do it again */ @@ -1132,7 +1012,8 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, skb->ip_summed = CHECKSUM_UNNECESSARY; } -static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) +static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, + struct ixgbe_ring *rx_ring, u32 val) { /* * Force memory writes to complete before letting h/w @@ -1141,81 +1022,72 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val) * such as IA-64). */ wmb(); - writel(val, rx_ring->tail); + IXGBE_WRITE_REG(hw, IXGBE_RDT(rx_ring->reg_idx), val); } /** * ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split - * @rx_ring: ring to place buffers on - * @cleaned_count: number of buffers to replace + * @adapter: address of board private structure **/ -void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) +void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + int cleaned_count) { + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; - struct sk_buff *skb; - u16 i = rx_ring->next_to_use; + unsigned int i; + unsigned int bufsz = rx_ring->rx_buf_len; - /* do nothing if no valid netdev defined */ - if (!rx_ring->netdev) - return; + i = rx_ring->next_to_use; + bi = &rx_ring->rx_buffer_info[i]; while (cleaned_count--) { rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); - bi = &rx_ring->rx_buffer_info[i]; - skb = bi->skb; - if (!skb) { - skb = netdev_alloc_skb_ip_align(rx_ring->netdev, - rx_ring->rx_buf_len); + if (!bi->page_dma && + (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) { + if (!bi->page) { + bi->page = netdev_alloc_page(netdev); + if (!bi->page) { + adapter->alloc_rx_page_failed++; + goto no_buffers; + } + bi->page_offset = 0; + } else { + /* use a half page if we're re-using */ + bi->page_offset ^= (PAGE_SIZE / 2); + } + + bi->page_dma = dma_map_page(&pdev->dev, bi->page, + bi->page_offset, + (PAGE_SIZE / 2), + DMA_FROM_DEVICE); + } + + if (!bi->skb) { + struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, + bufsz); + bi->skb = skb; + if (!skb) { - rx_ring->rx_stats.alloc_rx_buff_failed++; + adapter->alloc_rx_buff_failed++; goto no_buffers; } /* initialize queue mapping */ skb_record_rx_queue(skb, rx_ring->queue_index); - bi->skb = skb; } if (!bi->dma) { - bi->dma = dma_map_single(rx_ring->dev, - skb->data, + bi->dma = dma_map_single(&pdev->dev, + bi->skb->data, rx_ring->rx_buf_len, DMA_FROM_DEVICE); - if (dma_mapping_error(rx_ring->dev, bi->dma)) { - rx_ring->rx_stats.alloc_rx_buff_failed++; - bi->dma = 0; - goto no_buffers; - } } - - if (ring_is_ps_enabled(rx_ring)) { - if (!bi->page) { - bi->page = netdev_alloc_page(rx_ring->netdev); - if (!bi->page) { - rx_ring->rx_stats.alloc_rx_page_failed++; - goto no_buffers; - } - } - - if (!bi->page_dma) { - /* use a half page if we're re-using */ - bi->page_offset ^= PAGE_SIZE / 2; - bi->page_dma = dma_map_page(rx_ring->dev, - bi->page, - bi->page_offset, - PAGE_SIZE / 2, - DMA_FROM_DEVICE); - if (dma_mapping_error(rx_ring->dev, - bi->page_dma)) { - rx_ring->rx_stats.alloc_rx_page_failed++; - bi->page_dma = 0; - goto no_buffers; - } - } - - /* Refresh the desc even if buffer_addrs didn't change - * because each write-back erases this info. */ + /* Refresh the desc even if buffer_addrs didn't change because + * each write-back erases this info. */ + if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma); rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); } else { @@ -1226,48 +1098,56 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count) i++; if (i == rx_ring->count) i = 0; + bi = &rx_ring->rx_buffer_info[i]; } no_buffers: if (rx_ring->next_to_use != i) { rx_ring->next_to_use = i; - ixgbe_release_rx_desc(rx_ring, i); + if (i-- == 0) + i = (rx_ring->count - 1); + + ixgbe_release_rx_desc(&adapter->hw, rx_ring, i); } } -static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc) +static inline u16 ixgbe_get_hdr_info(union ixgbe_adv_rx_desc *rx_desc) { - /* HW will not DMA in data larger than the given buffer, even if it - * parses the (NFS, of course) header to be larger. In that case, it - * fills the header buffer and spills the rest into the page. - */ - u16 hdr_info = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.hdr_info); - u16 hlen = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> - IXGBE_RXDADV_HDRBUFLEN_SHIFT; - if (hlen > IXGBE_RX_HDR_SIZE) - hlen = IXGBE_RX_HDR_SIZE; - return hlen; + return rx_desc->wb.lower.lo_dword.hs_rss.hdr_info; +} + +static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc) +{ + return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; +} + +static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc) +{ + return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) & + IXGBE_RXDADV_RSCCNT_MASK) >> + IXGBE_RXDADV_RSCCNT_SHIFT; } /** * ixgbe_transform_rsc_queue - change rsc queue into a full packet * @skb: pointer to the last skb in the rsc queue + * @count: pointer to number of packets coalesced in this context * * This function changes a queue full of hw rsc buffers into a completed * packet. It uses the ->prev pointers to find the first packet and then * turns it into the frag list owner. **/ -static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb) +static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb, + u64 *count) { unsigned int frag_list_size = 0; - unsigned int skb_cnt = 1; while (skb->prev) { struct sk_buff *prev = skb->prev; frag_list_size += skb->len; skb->prev = NULL; skb = prev; - skb_cnt++; + *count += 1; } skb_shinfo(skb)->frag_list = skb->next; @@ -1275,59 +1155,68 @@ static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb) skb->len += frag_list_size; skb->data_len += frag_list_size; skb->truesize += frag_list_size; - IXGBE_RSC_CB(skb)->skb_cnt = skb_cnt; - return skb; } -static inline bool ixgbe_get_rsc_state(union ixgbe_adv_rx_desc *rx_desc) -{ - return !!(le32_to_cpu(rx_desc->wb.lower.lo_dword.data) & - IXGBE_RXDADV_RSCCNT_MASK); -} +struct ixgbe_rsc_cb { + dma_addr_t dma; + bool delay_unmap; +}; + +#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) -static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, +static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *rx_ring, int *work_done, int work_to_do) { struct ixgbe_adapter *adapter = q_vector->adapter; + struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc, *next_rxd; struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; struct sk_buff *skb; + unsigned int i, rsc_count = 0; + u32 len, staterr; + u16 hdr_info; + bool cleaned = false; + int cleaned_count = 0; unsigned int total_rx_bytes = 0, total_rx_packets = 0; - const int current_node = numa_node_id(); #ifdef IXGBE_FCOE int ddp_bytes = 0; #endif /* IXGBE_FCOE */ - u32 staterr; - u16 i; - u16 cleaned_count = 0; - bool pkt_is_rsc = false; i = rx_ring->next_to_clean; rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); staterr = le32_to_cpu(rx_desc->wb.upper.status_error); + rx_buffer_info = &rx_ring->rx_buffer_info[i]; while (staterr & IXGBE_RXD_STAT_DD) { u32 upper_len = 0; + if (*work_done >= work_to_do) + break; + (*work_done)++; rmb(); /* read descriptor and rx_buffer_info after status DD */ + if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { + hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc)); + len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> + IXGBE_RXDADV_HDRBUFLEN_SHIFT; + upper_len = le16_to_cpu(rx_desc->wb.upper.length); + if ((len > IXGBE_RX_HDR_SIZE) || + (upper_len && !(hdr_info & IXGBE_RXDADV_SPH))) + len = IXGBE_RX_HDR_SIZE; + } else { + len = le16_to_cpu(rx_desc->wb.upper.length); + } - rx_buffer_info = &rx_ring->rx_buffer_info[i]; - + cleaned = true; skb = rx_buffer_info->skb; - rx_buffer_info->skb = NULL; prefetch(skb->data); + rx_buffer_info->skb = NULL; - if (ring_is_rsc_enabled(rx_ring)) - pkt_is_rsc = ixgbe_get_rsc_state(rx_desc); - - /* if this is a skb from previous receive DMA will be 0 */ if (rx_buffer_info->dma) { - u16 hlen; - if (pkt_is_rsc && - !(staterr & IXGBE_RXD_STAT_EOP) && - !skb->prev) { + if ((adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && + (!(staterr & IXGBE_RXD_STAT_EOP)) && + (!(skb->prev))) { /* * When HWRSC is enabled, delay unmapping * of the first packet. It carries the @@ -1338,42 +1227,29 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, IXGBE_RSC_CB(skb)->delay_unmap = true; IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma; } else { - dma_unmap_single(rx_ring->dev, + dma_unmap_single(&pdev->dev, rx_buffer_info->dma, rx_ring->rx_buf_len, DMA_FROM_DEVICE); } rx_buffer_info->dma = 0; - - if (ring_is_ps_enabled(rx_ring)) { - hlen = ixgbe_get_hlen(rx_desc); - upper_len = le16_to_cpu(rx_desc->wb.upper.length); - } else { - hlen = le16_to_cpu(rx_desc->wb.upper.length); - } - - skb_put(skb, hlen); - } else { - /* assume packet split since header is unmapped */ - upper_len = le16_to_cpu(rx_desc->wb.upper.length); + skb_put(skb, len); } if (upper_len) { - dma_unmap_page(rx_ring->dev, - rx_buffer_info->page_dma, - PAGE_SIZE / 2, - DMA_FROM_DEVICE); + dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma, + PAGE_SIZE / 2, DMA_FROM_DEVICE); rx_buffer_info->page_dma = 0; skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, rx_buffer_info->page, rx_buffer_info->page_offset, upper_len); - if ((page_count(rx_buffer_info->page) == 1) && - (page_to_nid(rx_buffer_info->page) == current_node)) - get_page(rx_buffer_info->page); - else + if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) || + (page_count(rx_buffer_info->page) != 1)) rx_buffer_info->page = NULL; + else + get_page(rx_buffer_info->page); skb->len += upper_len; skb->data_len += upper_len; @@ -1388,7 +1264,10 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (pkt_is_rsc) { + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) + rsc_count = ixgbe_get_rsc_count(rx_desc); + + if (rsc_count) { u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >> IXGBE_RXDADV_NEXTP_SHIFT; next_buffer = &rx_ring->rx_buffer_info[nextp]; @@ -1396,8 +1275,32 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, next_buffer = &rx_ring->rx_buffer_info[i]; } - if (!(staterr & IXGBE_RXD_STAT_EOP)) { - if (ring_is_ps_enabled(rx_ring)) { + if (staterr & IXGBE_RXD_STAT_EOP) { + if (skb->prev) + skb = ixgbe_transform_rsc_queue(skb, + &(rx_ring->rsc_count)); + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { + if (IXGBE_RSC_CB(skb)->delay_unmap) { + dma_unmap_single(&pdev->dev, + IXGBE_RSC_CB(skb)->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); + IXGBE_RSC_CB(skb)->dma = 0; + IXGBE_RSC_CB(skb)->delay_unmap = false; + } + if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) + rx_ring->rsc_count += + skb_shinfo(skb)->nr_frags; + else + rx_ring->rsc_count++; + rx_ring->rsc_flush++; + } + u64_stats_update_begin(&rx_ring->syncp); + rx_ring->stats.packets++; + rx_ring->stats.bytes += skb->len; + u64_stats_update_end(&rx_ring->syncp); + } else { + if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { rx_buffer_info->skb = next_buffer->skb; rx_buffer_info->dma = next_buffer->dma; next_buffer->skb = skb; @@ -1406,45 +1309,12 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, skb->next = next_buffer->skb; skb->next->prev = skb; } - rx_ring->rx_stats.non_eop_descs++; + rx_ring->non_eop_descs++; goto next_desc; } - if (skb->prev) { - skb = ixgbe_transform_rsc_queue(skb); - /* if we got here without RSC the packet is invalid */ - if (!pkt_is_rsc) { - __pskb_trim(skb, 0); - rx_buffer_info->skb = skb; - goto next_desc; - } - } - - if (ring_is_rsc_enabled(rx_ring)) { - if (IXGBE_RSC_CB(skb)->delay_unmap) { - dma_unmap_single(rx_ring->dev, - IXGBE_RSC_CB(skb)->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); - IXGBE_RSC_CB(skb)->dma = 0; - IXGBE_RSC_CB(skb)->delay_unmap = false; - } - } - if (pkt_is_rsc) { - if (ring_is_ps_enabled(rx_ring)) - rx_ring->rx_stats.rsc_count += - skb_shinfo(skb)->nr_frags; - else - rx_ring->rx_stats.rsc_count += - IXGBE_RSC_CB(skb)->skb_cnt; - rx_ring->rx_stats.rsc_flush++; - } - - /* ERR_MASK will only have valid bits if EOP set */ if (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) { - /* trim packet back to size 0 and recycle it */ - __pskb_trim(skb, 0); - rx_buffer_info->skb = skb; + dev_kfree_skb_irq(skb); goto next_desc; } @@ -1454,7 +1324,7 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, total_rx_bytes += skb->len; total_rx_packets++; - skb->protocol = eth_type_trans(skb, rx_ring->netdev); + skb->protocol = eth_type_trans(skb, adapter->netdev); #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { @@ -1468,18 +1338,16 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, next_desc: rx_desc->wb.upper.status_error = 0; - (*work_done)++; - if (*work_done >= work_to_do) - break; - /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) { - ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); + ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); cleaned_count = 0; } /* use prefetched values */ rx_desc = next_rxd; + rx_buffer_info = &rx_ring->rx_buffer_info[i]; + staterr = le32_to_cpu(rx_desc->wb.upper.status_error); } @@ -1487,14 +1355,14 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, cleaned_count = IXGBE_DESC_UNUSED(rx_ring); if (cleaned_count) - ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); + ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); #ifdef IXGBE_FCOE /* include DDPed FCoE data */ if (ddp_bytes > 0) { unsigned int mss; - mss = rx_ring->netdev->mtu - sizeof(struct fcoe_hdr) - + mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) - sizeof(struct fc_frame_header) - sizeof(struct fcoe_crc_eof); if (mss > 512) @@ -1506,10 +1374,8 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, rx_ring->total_packets += total_rx_packets; rx_ring->total_bytes += total_rx_bytes; - u64_stats_update_begin(&rx_ring->syncp); - rx_ring->stats.packets += total_rx_packets; - rx_ring->stats.bytes += total_rx_bytes; - u64_stats_update_end(&rx_ring->syncp); + + return cleaned; } static int ixgbe_clean_rxonly(struct napi_struct *, int); @@ -1523,7 +1389,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *, int); static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) { struct ixgbe_q_vector *q_vector; - int i, q_vectors, v_idx, r_idx; + int i, j, q_vectors, v_idx, r_idx; u32 mask; q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; @@ -1539,8 +1405,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { - u8 reg_idx = adapter->rx_ring[r_idx]->reg_idx; - ixgbe_set_ivar(adapter, 0, reg_idx, v_idx); + j = adapter->rx_ring[r_idx]->reg_idx; + ixgbe_set_ivar(adapter, 0, j, v_idx); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, r_idx + 1); @@ -1549,8 +1415,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { - u8 reg_idx = adapter->tx_ring[r_idx]->reg_idx; - ixgbe_set_ivar(adapter, 1, reg_idx, v_idx); + j = adapter->tx_ring[r_idx]->reg_idx; + ixgbe_set_ivar(adapter, 1, j, v_idx); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, r_idx + 1); @@ -1581,19 +1447,11 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) } } - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: + if (adapter->hw.mac.type == ixgbe_mac_82598EB) ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + else if (adapter->hw.mac.type == ixgbe_mac_82599EB) ixgbe_set_ivar(adapter, -1, 1, v_idx); - break; - - default: - break; - } IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950); /* set up to autoclear timer, and the vectors */ @@ -1689,15 +1547,12 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) int v_idx = q_vector->v_idx; u32 itr_reg = EITR_INTS_PER_SEC_TO_REG(q_vector->eitr); - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { /* must write high and low 16 bits to reset counter */ itr_reg |= (itr_reg << 16); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { /* - * 82599 and X540 can support a value of zero, so allow it for + * 82599 can support a value of zero, so allow it for * max interrupt rate, but there is an errata where it can * not be zero with RSC */ @@ -1710,9 +1565,6 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) * immediate assertion of the interrupt */ itr_reg |= IXGBE_EITR_CNT_WDIS; - break; - default: - break; } IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg); } @@ -1720,13 +1572,14 @@ void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector) static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) { struct ixgbe_adapter *adapter = q_vector->adapter; - int i, r_idx; u32 new_itr; u8 current_itr, ret_itr; + int i, r_idx; + struct ixgbe_ring *rx_ring, *tx_ring; r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { - struct ixgbe_ring *tx_ring = adapter->tx_ring[r_idx]; + tx_ring = adapter->tx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, q_vector->tx_itr, tx_ring->total_packets, @@ -1741,7 +1594,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { - struct ixgbe_ring *rx_ring = adapter->rx_ring[r_idx]; + rx_ring = adapter->rx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, q_vector->rx_itr, rx_ring->total_packets, @@ -1772,7 +1625,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) if (new_itr != q_vector->eitr) { /* do an exponential smoothing */ - new_itr = ((q_vector->eitr * 9) + new_itr)/10; + new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); /* save the algorithm value here, not the smoothed one */ q_vector->eitr = new_itr; @@ -1840,18 +1693,17 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr) { struct ixgbe_hw *hw = &adapter->hw; - if (eicr & IXGBE_EICR_GPI_SDP2) { - /* Clear the interrupt */ - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - schedule_work(&adapter->sfp_config_module_task); - } - if (eicr & IXGBE_EICR_GPI_SDP1) { /* Clear the interrupt */ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1); - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - schedule_work(&adapter->multispeed_fiber_task); + schedule_work(&adapter->multispeed_fiber_task); + } else if (eicr & IXGBE_EICR_GPI_SDP2) { + /* Clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2); + schedule_work(&adapter->sfp_config_module_task); + } else { + /* Interrupt isn't for us... */ + return; } } @@ -1891,9 +1743,16 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) if (eicr & IXGBE_EICR_MAILBOX) ixgbe_msg_task(adapter); - switch (hw->mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (hw->mac.type == ixgbe_mac_82598EB) + ixgbe_check_fan_failure(adapter, eicr); + + if (hw->mac.type == ixgbe_mac_82599EB) { + ixgbe_check_sfp_event(adapter, eicr); + adapter->interrupt_event = eicr; + if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) + schedule_work(&adapter->check_overtemp_task); + /* Handle Flow Director Full threshold interrupt */ if (eicr & IXGBE_EICR_FLOW_DIR) { int i; @@ -1903,24 +1762,12 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) for (i = 0; i < adapter->num_tx_queues; i++) { struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; - if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE, - &tx_ring->state)) + if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE, + &tx_ring->reinit_state)) schedule_work(&adapter->fdir_reinit_task); } } - ixgbe_check_sfp_event(adapter, eicr); - if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && - ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { - adapter->interrupt_event = eicr; - schedule_work(&adapter->check_overtemp_task); - } - break; - default: - break; } - - ixgbe_check_fan_failure(adapter, eicr); - if (!test_bit(__IXGBE_DOWN, &adapter->state)) IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); @@ -1931,24 +1778,15 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, u64 qmask) { u32 mask; - struct ixgbe_hw *hw = &adapter->hw; - switch (hw->mac.type) { - case ixgbe_mac_82598EB: + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { mask = (IXGBE_EIMS_RTX_QUEUE & qmask); - IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); + } else { mask = (qmask & 0xFFFFFFFF); - if (mask) - IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask); mask = (qmask >> 32); - if (mask) - IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask); - break; - default: - break; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask); } /* skip the flush */ } @@ -1957,24 +1795,15 @@ static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter, u64 qmask) { u32 mask; - struct ixgbe_hw *hw = &adapter->hw; - switch (hw->mac.type) { - case ixgbe_mac_82598EB: + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { mask = (IXGBE_EIMS_RTX_QUEUE & qmask); - IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, mask); + } else { mask = (qmask & 0xFFFFFFFF); - if (mask) - IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), mask); mask = (qmask >> 32); - if (mask) - IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask); - break; - default: - break; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), mask); } /* skip the flush */ } @@ -2017,13 +1846,8 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) int r_idx; int i; -#ifdef CONFIG_IXGBE_DCA - if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_dca(q_vector); -#endif - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - for (i = 0; i < q_vector->rxr_count; i++) { + for (i = 0; i < q_vector->rxr_count; i++) { rx_ring = adapter->rx_ring[r_idx]; rx_ring->total_bytes = 0; rx_ring->total_packets = 0; @@ -2034,6 +1858,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) if (!q_vector->rxr_count) return IRQ_HANDLED; + /* disable interrupts on this vector only */ /* EIAM disabled interrupts (on this vector) for us */ napi_schedule(&q_vector->napi); @@ -2092,14 +1917,13 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) int work_done = 0; long r_idx; + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + rx_ring = adapter->rx_ring[r_idx]; #ifdef CONFIG_IXGBE_DCA if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_dca(q_vector); + ixgbe_update_rx_dca(adapter, rx_ring); #endif - r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); - rx_ring = adapter->rx_ring[r_idx]; - ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget); /* If all Rx work done, exit the polling mode */ @@ -2133,14 +1957,13 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) long r_idx; bool tx_clean_complete = true; -#ifdef CONFIG_IXGBE_DCA - if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_dca(q_vector); -#endif - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { ring = adapter->tx_ring[r_idx]; +#ifdef CONFIG_IXGBE_DCA + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + ixgbe_update_tx_dca(adapter, ring); +#endif tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, r_idx + 1); @@ -2153,6 +1976,10 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { ring = adapter->rx_ring[r_idx]; +#ifdef CONFIG_IXGBE_DCA + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + ixgbe_update_rx_dca(adapter, ring); +#endif ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, r_idx + 1); @@ -2191,14 +2018,13 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) int work_done = 0; long r_idx; + r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); + tx_ring = adapter->tx_ring[r_idx]; #ifdef CONFIG_IXGBE_DCA if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_dca(q_vector); + ixgbe_update_tx_dca(adapter, tx_ring); #endif - r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); - tx_ring = adapter->tx_ring[r_idx]; - if (!ixgbe_clean_tx_irq(q_vector, tx_ring)) work_done = budget; @@ -2219,27 +2045,24 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, int r_idx) { struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; - struct ixgbe_ring *rx_ring = a->rx_ring[r_idx]; set_bit(r_idx, q_vector->rxr_idx); q_vector->rxr_count++; - rx_ring->q_vector = q_vector; } static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, int t_idx) { struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; - struct ixgbe_ring *tx_ring = a->tx_ring[t_idx]; set_bit(t_idx, q_vector->txr_idx); q_vector->txr_count++; - tx_ring->q_vector = q_vector; } /** * ixgbe_map_rings_to_vectors - Maps descriptor rings to vectors * @adapter: board private structure to initialize + * @vectors: allotted vector count for descriptor rings * * This function maps descriptor rings to the queue-specific vectors * we were allotted through the MSI-X enabling code. Ideally, we'd have @@ -2247,9 +2070,9 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, * group the rings as "efficiently" as possible. You would add new * mapping configurations in here. **/ -static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter) +static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter, + int vectors) { - int q_vectors; int v_start = 0; int rxr_idx = 0, txr_idx = 0; int rxr_remaining = adapter->num_rx_queues; @@ -2262,13 +2085,11 @@ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter) if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) goto out; - q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; - /* * The ideal configuration... * We have enough vectors to map one per queue. */ - if (q_vectors == adapter->num_rx_queues + adapter->num_tx_queues) { + if (vectors == adapter->num_rx_queues + adapter->num_tx_queues) { for (; rxr_idx < rxr_remaining; v_start++, rxr_idx++) map_vector_to_rxq(adapter, v_start, rxr_idx); @@ -2284,20 +2105,23 @@ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter) * multiple queues per vector. */ /* Re-adjusting *qpv takes care of the remainder. */ - for (i = v_start; i < q_vectors; i++) { - rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - i); + for (i = v_start; i < vectors; i++) { + rqpv = DIV_ROUND_UP(rxr_remaining, vectors - i); for (j = 0; j < rqpv; j++) { map_vector_to_rxq(adapter, i, rxr_idx); rxr_idx++; rxr_remaining--; } - tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - i); + } + for (i = v_start; i < vectors; i++) { + tqpv = DIV_ROUND_UP(txr_remaining, vectors - i); for (j = 0; j < tqpv; j++) { map_vector_to_txq(adapter, i, txr_idx); txr_idx++; txr_remaining--; } } + out: return err; } @@ -2319,36 +2143,30 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) /* Decrement for Other and TCP Timer vectors */ q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; - err = ixgbe_map_rings_to_vectors(adapter); + /* Map the Tx/Rx rings to the vectors we were allotted. */ + err = ixgbe_map_rings_to_vectors(adapter, q_vectors); if (err) - return err; + goto out; -#define SET_HANDLER(_v) (((_v)->rxr_count && (_v)->txr_count) \ - ? &ixgbe_msix_clean_many : \ - (_v)->rxr_count ? &ixgbe_msix_clean_rx : \ - (_v)->txr_count ? &ixgbe_msix_clean_tx : \ - NULL) +#define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \ + (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ + &ixgbe_msix_clean_many) for (vector = 0; vector < q_vectors; vector++) { - struct ixgbe_q_vector *q_vector = adapter->q_vector[vector]; - handler = SET_HANDLER(q_vector); + handler = SET_HANDLER(adapter->q_vector[vector]); if (handler == &ixgbe_msix_clean_rx) { - sprintf(q_vector->name, "%s-%s-%d", + sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "rx", ri++); } else if (handler == &ixgbe_msix_clean_tx) { - sprintf(q_vector->name, "%s-%s-%d", + sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "tx", ti++); - } else if (handler == &ixgbe_msix_clean_many) { - sprintf(q_vector->name, "%s-%s-%d", - netdev->name, "TxRx", ri++); - ti++; - } else { - /* skip this unused q_vector */ - continue; - } + } else + sprintf(adapter->name[vector], "%s-%s-%d", + netdev->name, "TxRx", vector); + err = request_irq(adapter->msix_entries[vector].vector, - handler, 0, q_vector->name, - q_vector); + handler, 0, adapter->name[vector], + adapter->q_vector[vector]); if (err) { e_err(probe, "request_irq failed for MSIX interrupt " "Error: %d\n", err); @@ -2356,9 +2174,9 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) } } - sprintf(adapter->lsc_int_name, "%s:lsc", netdev->name); + sprintf(adapter->name[vector], "%s:lsc", netdev->name); err = request_irq(adapter->msix_entries[vector].vector, - ixgbe_msix_lsc, 0, adapter->lsc_int_name, netdev); + ixgbe_msix_lsc, 0, adapter->name[vector], netdev); if (err) { e_err(probe, "request_irq for msix_lsc failed: %d\n", err); goto free_queue_irqs; @@ -2374,16 +2192,17 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) pci_disable_msix(adapter->pdev); kfree(adapter->msix_entries); adapter->msix_entries = NULL; +out: return err; } static void ixgbe_set_itr(struct ixgbe_adapter *adapter) { struct ixgbe_q_vector *q_vector = adapter->q_vector[0]; + u8 current_itr; + u32 new_itr = q_vector->eitr; struct ixgbe_ring *rx_ring = adapter->rx_ring[0]; struct ixgbe_ring *tx_ring = adapter->tx_ring[0]; - u32 new_itr = q_vector->eitr; - u8 current_itr; q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr, q_vector->tx_itr, @@ -2413,9 +2232,9 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) if (new_itr != q_vector->eitr) { /* do an exponential smoothing */ - new_itr = ((q_vector->eitr * 9) + new_itr)/10; + new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100); - /* save the algorithm value here */ + /* save the algorithm value here, not the smoothed one */ q_vector->eitr = new_itr; ixgbe_write_eitr(q_vector); @@ -2436,17 +2255,12 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, mask |= IXGBE_EIMS_GPI_SDP0; if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) mask |= IXGBE_EIMS_GPI_SDP1; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { mask |= IXGBE_EIMS_ECC; mask |= IXGBE_EIMS_GPI_SDP1; mask |= IXGBE_EIMS_GPI_SDP2; if (adapter->num_vfs) mask |= IXGBE_EIMS_MAILBOX; - break; - default: - break; } if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) @@ -2502,21 +2316,13 @@ static irqreturn_t ixgbe_intr(int irq, void *data) if (eicr & IXGBE_EICR_LSC) ixgbe_check_lsc(adapter); - switch (hw->mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (hw->mac.type == ixgbe_mac_82599EB) ixgbe_check_sfp_event(adapter, eicr); - if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && - ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) { - adapter->interrupt_event = eicr; - schedule_work(&adapter->check_overtemp_task); - } - break; - default: - break; - } ixgbe_check_fan_failure(adapter, eicr); + if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) && + ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) + schedule_work(&adapter->check_overtemp_task); if (napi_schedule_prep(&(q_vector->napi))) { adapter->tx_ring[0]->total_packets = 0; @@ -2609,20 +2415,14 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) **/ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) { - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + } else { IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); if (adapter->num_vfs > 32) IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITRSEL, 0); - break; - default: - break; } IXGBE_WRITE_FLUSH(&adapter->hw); if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { @@ -2668,7 +2468,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, u64 tdba = ring->dma; int wait_loop = 10; u32 txdctl; - u8 reg_idx = ring->reg_idx; + u16 reg_idx = ring->reg_idx; /* disable queue to avoid issues while updating state */ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); @@ -2683,7 +2483,8 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, ring->count * sizeof(union ixgbe_adv_tx_desc)); IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0); IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0); - ring->tail = hw->hw_addr + IXGBE_TDT(reg_idx); + ring->head = IXGBE_TDH(reg_idx); + ring->tail = IXGBE_TDT(reg_idx); /* configure fetching thresholds */ if (adapter->rx_itr_setting == 0) { @@ -2699,16 +2500,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, } /* reinitialize flowdirector state */ - if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && - adapter->atr_sample_rate) { - ring->atr_sample_rate = adapter->atr_sample_rate; - ring->atr_count = 0; - set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state); - } else { - ring->atr_sample_rate = 0; - } - - clear_bit(__IXGBE_HANG_CHECK_ARMED, &ring->state); + set_bit(__IXGBE_FDIR_INIT_DONE, &ring->reinit_state); /* enable queue */ txdctl |= IXGBE_TXDCTL_ENABLE; @@ -2799,22 +2591,16 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring) { u32 srrctl; - u8 reg_idx = rx_ring->reg_idx; + int index; + struct ixgbe_ring_feature *feature = adapter->ring_feature; - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: { - struct ixgbe_ring_feature *feature = adapter->ring_feature; - const int mask = feature[RING_F_RSS].mask; - reg_idx = reg_idx & mask; - } - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - default: - break; + index = rx_ring->reg_idx; + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + unsigned long mask; + mask = (unsigned long) feature[RING_F_RSS].mask; + index = index & mask; } - - srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(reg_idx)); + srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(index)); srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; @@ -2824,7 +2610,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & IXGBE_SRRCTL_BSIZEHDR_MASK; - if (ring_is_ps_enabled(rx_ring)) { + if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { #if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; #else @@ -2837,7 +2623,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; } - IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(reg_idx), srrctl); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl); } static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) @@ -2906,37 +2692,20 @@ static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } -/** - * ixgbe_clear_rscctl - disable RSC for the indicated ring - * @adapter: address of board private structure - * @ring: structure containing ring specific data - **/ -void ixgbe_clear_rscctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *ring) -{ - struct ixgbe_hw *hw = &adapter->hw; - u32 rscctrl; - u8 reg_idx = ring->reg_idx; - - rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); - rscctrl &= ~IXGBE_RSCCTL_RSCEN; - IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); -} - /** * ixgbe_configure_rscctl - enable RSC for the indicated ring * @adapter: address of board private structure * @index: index of ring to set **/ -void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, +static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; u32 rscctrl; int rx_buf_len; - u8 reg_idx = ring->reg_idx; + u16 reg_idx = ring->reg_idx; - if (!ring_is_rsc_enabled(ring)) + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) return; rx_buf_len = ring->rx_buf_len; @@ -2947,7 +2716,7 @@ void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, * total size of max desc * buf_len is not greater * than 65535 */ - if (ring_is_ps_enabled(ring)) { + if (ring->flags & IXGBE_RING_RX_PS_ENABLED) { #if (MAX_SKB_FRAGS > 16) rscctrl |= IXGBE_RSCCTL_MAXDESC_16; #elif (MAX_SKB_FRAGS > 8) @@ -3000,9 +2769,9 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, struct ixgbe_ring *ring) { struct ixgbe_hw *hw = &adapter->hw; + int reg_idx = ring->reg_idx; int wait_loop = IXGBE_MAX_RX_DESC_POLL; u32 rxdctl; - u8 reg_idx = ring->reg_idx; /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */ if (hw->mac.type == ixgbe_mac_82598EB && @@ -3026,7 +2795,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, struct ixgbe_hw *hw = &adapter->hw; u64 rdba = ring->dma; u32 rxdctl; - u8 reg_idx = ring->reg_idx; + u16 reg_idx = ring->reg_idx; /* disable queue to avoid issues while updating state */ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); @@ -3040,7 +2809,8 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, ring->count * sizeof(union ixgbe_adv_rx_desc)); IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0); IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0); - ring->tail = hw->hw_addr + IXGBE_RDT(reg_idx); + ring->head = IXGBE_RDH(reg_idx); + ring->tail = IXGBE_RDT(reg_idx); ixgbe_configure_srrctl(adapter, ring); ixgbe_configure_rscctl(adapter, ring); @@ -3062,7 +2832,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); ixgbe_rx_desc_queue_enable(adapter, ring); - ixgbe_alloc_rx_buffers(ring, IXGBE_DESC_UNUSED(ring)); + ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring)); } static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) @@ -3185,32 +2955,24 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) rx_ring->rx_buf_len = rx_buf_len; if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) - set_ring_ps_enabled(rx_ring); - else - clear_ring_ps_enabled(rx_ring); - - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) - set_ring_rsc_enabled(rx_ring); + rx_ring->flags |= IXGBE_RING_RX_PS_ENABLED; else - clear_ring_rsc_enabled(rx_ring); + rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; #ifdef IXGBE_FCOE if (netdev->features & NETIF_F_FCOE_MTU) { struct ixgbe_ring_feature *f; f = &adapter->ring_feature[RING_F_FCOE]; if ((i >= f->mask) && (i < f->mask + f->indices)) { - clear_ring_ps_enabled(rx_ring); + rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE) rx_ring->rx_buf_len = IXGBE_FCOE_JUMBO_FRAME_SIZE; - } else if (!ring_is_rsc_enabled(rx_ring) && - !ring_is_ps_enabled(rx_ring)) { - rx_ring->rx_buf_len = - IXGBE_FCOE_JUMBO_FRAME_SIZE; } } #endif /* IXGBE_FCOE */ } + } static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) @@ -3233,7 +2995,6 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) rdrxctl |= IXGBE_RDRXCTL_MVMEN; break; case ixgbe_mac_82599EB: - case ixgbe_mac_X540: /* Disable RSC for ACK packets */ IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); @@ -3361,7 +3122,6 @@ static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: - case ixgbe_mac_X540: for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i]->reg_idx; vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -3391,7 +3151,6 @@ static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: - case ixgbe_mac_X540: for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i]->reg_idx; vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -3589,6 +3348,8 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; + u32 txdctl; + int i, j; if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) { if (hw->mac.type == ixgbe_mac_82598EB) @@ -3604,18 +3365,25 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); #endif - ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, + ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, DCB_TX_CONFIG); - ixgbe_dcb_calculate_tc_credits(hw, &adapter->dcb_cfg, max_frame, + ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, max_frame, DCB_RX_CONFIG); + /* reconfigure the hardware */ + ixgbe_dcb_hw_config(&adapter->hw, &adapter->dcb_cfg); + + for (i = 0; i < adapter->num_tx_queues; i++) { + j = adapter->tx_ring[i]->reg_idx; + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); + /* PThresh workaround for Tx hang with DFP enabled. */ + txdctl |= 32; + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); + } /* Enable VLAN tag insert/strip */ adapter->netdev->features |= NETIF_F_HW_VLAN_RX; hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); - - /* reconfigure the hardware */ - ixgbe_dcb_hw_config(hw, &adapter->dcb_cfg); } #endif @@ -3747,9 +3515,8 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter) case ixgbe_mac_82598EB: IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: default: + case ixgbe_mac_82599EB: IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(0), 0xFFFFFFFF); IXGBE_WRITE_REG(hw, IXGBE_EIAM_EX(1), 0xFFFFFFFF); break; @@ -3794,20 +3561,12 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) ixgbe_configure_msi_and_legacy(adapter); /* enable the optics */ - if (hw->phy.multispeed_fiber && hw->mac.ops.enable_tx_laser) + if (hw->phy.multispeed_fiber) hw->mac.ops.enable_tx_laser(hw); clear_bit(__IXGBE_DOWN, &adapter->state); ixgbe_napi_enable_all(adapter); - if (ixgbe_is_sfp(hw)) { - ixgbe_sfp_link_config(adapter); - } else { - err = ixgbe_non_sfp_link_config(hw); - if (err) - e_err(probe, "link_config FAILED %d\n", err); - } - /* clear any pending interrupts, may auto mask */ IXGBE_READ_REG(hw, IXGBE_EICR); ixgbe_irq_enable(adapter, true, true); @@ -3830,8 +3589,26 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) * If we're not hot-pluggable SFP+, we just need to configure link * and bring it up. */ - if (hw->phy.type == ixgbe_phy_unknown) - schedule_work(&adapter->sfp_config_module_task); + if (hw->phy.type == ixgbe_phy_unknown) { + err = hw->phy.ops.identify(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + /* + * Take the device down and schedule the sfp tasklet + * which will unregister_netdev and log it. + */ + ixgbe_down(adapter); + schedule_work(&adapter->sfp_config_module_task); + return err; + } + } + + if (ixgbe_is_sfp(hw)) { + ixgbe_sfp_link_config(adapter); + } else { + err = ixgbe_non_sfp_link_config(hw); + if (err) + e_err(probe, "link_config FAILED %d\n", err); + } /* enable transmits */ netif_tx_start_all_queues(adapter->netdev); @@ -3909,13 +3686,15 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) /** * ixgbe_clean_rx_ring - Free Rx Buffers per Queue + * @adapter: board private structure * @rx_ring: ring to free buffers from **/ -static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) +static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring) { - struct device *dev = rx_ring->dev; + struct pci_dev *pdev = adapter->pdev; unsigned long size; - u16 i; + unsigned int i; /* ring already cleared, nothing to do */ if (!rx_ring->rx_buffer_info) @@ -3927,7 +3706,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) rx_buffer_info = &rx_ring->rx_buffer_info[i]; if (rx_buffer_info->dma) { - dma_unmap_single(rx_ring->dev, rx_buffer_info->dma, + dma_unmap_single(&pdev->dev, rx_buffer_info->dma, rx_ring->rx_buf_len, DMA_FROM_DEVICE); rx_buffer_info->dma = 0; @@ -3938,7 +3717,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) do { struct sk_buff *this = skb; if (IXGBE_RSC_CB(this)->delay_unmap) { - dma_unmap_single(dev, + dma_unmap_single(&pdev->dev, IXGBE_RSC_CB(this)->dma, rx_ring->rx_buf_len, DMA_FROM_DEVICE); @@ -3952,7 +3731,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) if (!rx_buffer_info->page) continue; if (rx_buffer_info->page_dma) { - dma_unmap_page(dev, rx_buffer_info->page_dma, + dma_unmap_page(&pdev->dev, rx_buffer_info->page_dma, PAGE_SIZE / 2, DMA_FROM_DEVICE); rx_buffer_info->page_dma = 0; } @@ -3969,17 +3748,24 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring) rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; + + if (rx_ring->head) + writel(0, adapter->hw.hw_addr + rx_ring->head); + if (rx_ring->tail) + writel(0, adapter->hw.hw_addr + rx_ring->tail); } /** * ixgbe_clean_tx_ring - Free Tx Buffers + * @adapter: board private structure * @tx_ring: ring to be cleaned **/ -static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring) +static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) { struct ixgbe_tx_buffer *tx_buffer_info; unsigned long size; - u16 i; + unsigned int i; /* ring already cleared, nothing to do */ if (!tx_ring->tx_buffer_info) @@ -3988,7 +3774,7 @@ static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring) /* Free all the Tx ring sk_buffs */ for (i = 0; i < tx_ring->count; i++) { tx_buffer_info = &tx_ring->tx_buffer_info[i]; - ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); + ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); } size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count; @@ -3999,6 +3785,11 @@ static void ixgbe_clean_tx_ring(struct ixgbe_ring *tx_ring) tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; + + if (tx_ring->head) + writel(0, adapter->hw.hw_addr + tx_ring->head); + if (tx_ring->tail) + writel(0, adapter->hw.hw_addr + tx_ring->tail); } /** @@ -4010,7 +3801,7 @@ static void ixgbe_clean_all_rx_rings(struct ixgbe_adapter *adapter) int i; for (i = 0; i < adapter->num_rx_queues; i++) - ixgbe_clean_rx_ring(adapter->rx_ring[i]); + ixgbe_clean_rx_ring(adapter, adapter->rx_ring[i]); } /** @@ -4022,7 +3813,7 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter) int i; for (i = 0; i < adapter->num_tx_queues; i++) - ixgbe_clean_tx_ring(adapter->tx_ring[i]); + ixgbe_clean_tx_ring(adapter, adapter->tx_ring[i]); } void ixgbe_down(struct ixgbe_adapter *adapter) @@ -4031,7 +3822,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; u32 rxctrl; u32 txdctl; - int i; + int i, j; int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; /* signal that we are down to the interrupt handler */ @@ -4089,25 +3880,19 @@ void ixgbe_down(struct ixgbe_adapter *adapter) /* disable transmits in the hardware now that interrupts are off */ for (i = 0; i < adapter->num_tx_queues; i++) { - u8 reg_idx = adapter->tx_ring[i]->reg_idx; - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), + j = adapter->tx_ring[i]->reg_idx; + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), (txdctl & ~IXGBE_TXDCTL_ENABLE)); } /* Disable the Tx DMA engine on 82599 */ - switch (hw->mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (hw->mac.type == ixgbe_mac_82599EB) IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & ~IXGBE_DMATXCTL_TE)); - break; - default: - break; - } /* power down the optics */ - if (hw->phy.multispeed_fiber && hw->mac.ops.disable_tx_laser) + if (hw->phy.multispeed_fiber) hw->mac.ops.disable_tx_laser(hw); /* clear n-tuple filters that are cached */ @@ -4139,8 +3924,10 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) int tx_clean_complete, work_done = 0; #ifdef CONFIG_IXGBE_DCA - if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) - ixgbe_update_dca(q_vector); + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { + ixgbe_update_tx_dca(adapter, adapter->tx_ring[0]); + ixgbe_update_rx_dca(adapter, adapter->rx_ring[0]); + } #endif tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring[0]); @@ -4168,8 +3955,6 @@ static void ixgbe_tx_timeout(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - adapter->tx_timeout_count++; - /* Do the reset outside of interrupt context */ schedule_work(&adapter->reset_task); } @@ -4184,6 +3969,8 @@ static void ixgbe_reset_task(struct work_struct *work) test_bit(__IXGBE_RESETTING, &adapter->state)) return; + adapter->tx_timeout_count++; + ixgbe_dump(adapter); netdev_err(adapter->netdev, "Reset adapter\n"); ixgbe_reinit_locked(adapter); @@ -4433,16 +4220,19 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter) { int i; + bool ret = false; - if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) - return false; - - for (i = 0; i < adapter->num_rx_queues; i++) - adapter->rx_ring[i]->reg_idx = i; - for (i = 0; i < adapter->num_tx_queues; i++) - adapter->tx_ring[i]->reg_idx = i; + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i]->reg_idx = i; + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i]->reg_idx = i; + ret = true; + } else { + ret = false; + } - return true; + return ret; } #ifdef CONFIG_IXGBE_DCB @@ -4459,67 +4249,71 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) bool ret = false; int dcb_i = adapter->ring_feature[RING_F_DCB].indices; - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - return false; - - /* the number of queues is assumed to be symmetric */ - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - for (i = 0; i < dcb_i; i++) { - adapter->rx_ring[i]->reg_idx = i << 3; - adapter->tx_ring[i]->reg_idx = i << 2; - } - ret = true; - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - if (dcb_i == 8) { - /* - * Tx TC0 starts at: descriptor queue 0 - * Tx TC1 starts at: descriptor queue 32 - * Tx TC2 starts at: descriptor queue 64 - * Tx TC3 starts at: descriptor queue 80 - * Tx TC4 starts at: descriptor queue 96 - * Tx TC5 starts at: descriptor queue 104 - * Tx TC6 starts at: descriptor queue 112 - * Tx TC7 starts at: descriptor queue 120 - * - * Rx TC0-TC7 are offset by 16 queues each - */ - for (i = 0; i < 3; i++) { - adapter->tx_ring[i]->reg_idx = i << 5; - adapter->rx_ring[i]->reg_idx = i << 4; - } - for ( ; i < 5; i++) { - adapter->tx_ring[i]->reg_idx = ((i + 2) << 4); - adapter->rx_ring[i]->reg_idx = i << 4; - } - for ( ; i < dcb_i; i++) { - adapter->tx_ring[i]->reg_idx = ((i + 8) << 3); - adapter->rx_ring[i]->reg_idx = i << 4; + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + /* the number of queues is assumed to be symmetric */ + for (i = 0; i < dcb_i; i++) { + adapter->rx_ring[i]->reg_idx = i << 3; + adapter->tx_ring[i]->reg_idx = i << 2; } ret = true; - } else if (dcb_i == 4) { - /* - * Tx TC0 starts at: descriptor queue 0 - * Tx TC1 starts at: descriptor queue 64 - * Tx TC2 starts at: descriptor queue 96 - * Tx TC3 starts at: descriptor queue 112 - * - * Rx TC0-TC3 are offset by 32 queues each - */ - adapter->tx_ring[0]->reg_idx = 0; - adapter->tx_ring[1]->reg_idx = 64; - adapter->tx_ring[2]->reg_idx = 96; - adapter->tx_ring[3]->reg_idx = 112; - for (i = 0 ; i < dcb_i; i++) - adapter->rx_ring[i]->reg_idx = i << 5; - ret = true; + } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + if (dcb_i == 8) { + /* + * Tx TC0 starts at: descriptor queue 0 + * Tx TC1 starts at: descriptor queue 32 + * Tx TC2 starts at: descriptor queue 64 + * Tx TC3 starts at: descriptor queue 80 + * Tx TC4 starts at: descriptor queue 96 + * Tx TC5 starts at: descriptor queue 104 + * Tx TC6 starts at: descriptor queue 112 + * Tx TC7 starts at: descriptor queue 120 + * + * Rx TC0-TC7 are offset by 16 queues each + */ + for (i = 0; i < 3; i++) { + adapter->tx_ring[i]->reg_idx = i << 5; + adapter->rx_ring[i]->reg_idx = i << 4; + } + for ( ; i < 5; i++) { + adapter->tx_ring[i]->reg_idx = + ((i + 2) << 4); + adapter->rx_ring[i]->reg_idx = i << 4; + } + for ( ; i < dcb_i; i++) { + adapter->tx_ring[i]->reg_idx = + ((i + 8) << 3); + adapter->rx_ring[i]->reg_idx = i << 4; + } + + ret = true; + } else if (dcb_i == 4) { + /* + * Tx TC0 starts at: descriptor queue 0 + * Tx TC1 starts at: descriptor queue 64 + * Tx TC2 starts at: descriptor queue 96 + * Tx TC3 starts at: descriptor queue 112 + * + * Rx TC0-TC3 are offset by 32 queues each + */ + adapter->tx_ring[0]->reg_idx = 0; + adapter->tx_ring[1]->reg_idx = 64; + adapter->tx_ring[2]->reg_idx = 96; + adapter->tx_ring[3]->reg_idx = 112; + for (i = 0 ; i < dcb_i; i++) + adapter->rx_ring[i]->reg_idx = i << 5; + + ret = true; + } else { + ret = false; + } + } else { + ret = false; } - break; - default: - break; + } else { + ret = false; } + return ret; } #endif @@ -4559,55 +4353,55 @@ static inline bool ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) */ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) { + int i, fcoe_rx_i = 0, fcoe_tx_i = 0; + bool ret = false; struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE]; - int i; - u8 fcoe_rx_i = 0, fcoe_tx_i = 0; - - if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) - return false; + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { #ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - struct ixgbe_fcoe *fcoe = &adapter->fcoe; + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + struct ixgbe_fcoe *fcoe = &adapter->fcoe; - ixgbe_cache_ring_dcb(adapter); - /* find out queues in TC for FCoE */ - fcoe_rx_i = adapter->rx_ring[fcoe->tc]->reg_idx + 1; - fcoe_tx_i = adapter->tx_ring[fcoe->tc]->reg_idx + 1; - /* - * In 82599, the number of Tx queues for each traffic - * class for both 8-TC and 4-TC modes are: - * TCs : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7 - * 8 TCs: 32 32 16 16 8 8 8 8 - * 4 TCs: 64 64 32 32 - * We have max 8 queues for FCoE, where 8 the is - * FCoE redirection table size. If TC for FCoE is - * less than or equal to TC3, we have enough queues - * to add max of 8 queues for FCoE, so we start FCoE - * Tx queue from the next one, i.e., reg_idx + 1. - * If TC for FCoE is above TC3, implying 8 TC mode, - * and we need 8 for FCoE, we have to take all queues - * in that traffic class for FCoE. - */ - if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3)) - fcoe_tx_i--; - } + ixgbe_cache_ring_dcb(adapter); + /* find out queues in TC for FCoE */ + fcoe_rx_i = adapter->rx_ring[fcoe->tc]->reg_idx + 1; + fcoe_tx_i = adapter->tx_ring[fcoe->tc]->reg_idx + 1; + /* + * In 82599, the number of Tx queues for each traffic + * class for both 8-TC and 4-TC modes are: + * TCs : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7 + * 8 TCs: 32 32 16 16 8 8 8 8 + * 4 TCs: 64 64 32 32 + * We have max 8 queues for FCoE, where 8 the is + * FCoE redirection table size. If TC for FCoE is + * less than or equal to TC3, we have enough queues + * to add max of 8 queues for FCoE, so we start FCoE + * tx descriptor from the next one, i.e., reg_idx + 1. + * If TC for FCoE is above TC3, implying 8 TC mode, + * and we need 8 for FCoE, we have to take all queues + * in that traffic class for FCoE. + */ + if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3)) + fcoe_tx_i--; + } #endif /* CONFIG_IXGBE_DCB */ - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { - if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || - (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) - ixgbe_cache_ring_fdir(adapter); - else - ixgbe_cache_ring_rss(adapter); + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || + (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + ixgbe_cache_ring_fdir(adapter); + else + ixgbe_cache_ring_rss(adapter); - fcoe_rx_i = f->mask; - fcoe_tx_i = f->mask; - } - for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) { - adapter->rx_ring[f->mask + i]->reg_idx = fcoe_rx_i; - adapter->tx_ring[f->mask + i]->reg_idx = fcoe_tx_i; + fcoe_rx_i = f->mask; + fcoe_tx_i = f->mask; + } + for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) { + adapter->rx_ring[f->mask + i]->reg_idx = fcoe_rx_i; + adapter->tx_ring[f->mask + i]->reg_idx = fcoe_tx_i; + } + ret = true; } - return true; + return ret; } #endif /* IXGBE_FCOE */ @@ -4676,55 +4470,65 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) **/ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) { - int rx = 0, tx = 0, nid = adapter->node; - - if (nid < 0 || !node_online(nid)) - nid = first_online_node; - - for (; tx < adapter->num_tx_queues; tx++) { - struct ixgbe_ring *ring; + int i; + int orig_node = adapter->node; - ring = kzalloc_node(sizeof(*ring), GFP_KERNEL, nid); + for (i = 0; i < adapter->num_tx_queues; i++) { + struct ixgbe_ring *ring = adapter->tx_ring[i]; + if (orig_node == -1) { + int cur_node = next_online_node(adapter->node); + if (cur_node == MAX_NUMNODES) + cur_node = first_online_node; + adapter->node = cur_node; + } + ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL, + adapter->node); if (!ring) - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); if (!ring) - goto err_allocation; + goto err_tx_ring_allocation; ring->count = adapter->tx_ring_count; - ring->queue_index = tx; - ring->numa_node = nid; - ring->dev = &adapter->pdev->dev; - ring->netdev = adapter->netdev; + ring->queue_index = i; + ring->numa_node = adapter->node; - adapter->tx_ring[tx] = ring; + adapter->tx_ring[i] = ring; } - for (; rx < adapter->num_rx_queues; rx++) { - struct ixgbe_ring *ring; + /* Restore the adapter's original node */ + adapter->node = orig_node; - ring = kzalloc_node(sizeof(*ring), GFP_KERNEL, nid); + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + if (orig_node == -1) { + int cur_node = next_online_node(adapter->node); + if (cur_node == MAX_NUMNODES) + cur_node = first_online_node; + adapter->node = cur_node; + } + ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL, + adapter->node); if (!ring) - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); if (!ring) - goto err_allocation; + goto err_rx_ring_allocation; ring->count = adapter->rx_ring_count; - ring->queue_index = rx; - ring->numa_node = nid; - ring->dev = &adapter->pdev->dev; - ring->netdev = adapter->netdev; + ring->queue_index = i; + ring->numa_node = adapter->node; - adapter->rx_ring[rx] = ring; + adapter->rx_ring[i] = ring; } + /* Restore the adapter's original node */ + adapter->node = orig_node; + ixgbe_cache_ring_register(adapter); return 0; -err_allocation: - while (tx) - kfree(adapter->tx_ring[--tx]); - - while (rx) - kfree(adapter->rx_ring[--rx]); +err_rx_ring_allocation: + for (i = 0; i < adapter->num_tx_queues; i++) + kfree(adapter->tx_ring[i]); +err_tx_ring_allocation: return -ENOMEM; } @@ -4946,11 +4750,6 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter) return err; } -static void ring_free_rcu(struct rcu_head *head) -{ - kfree(container_of(head, struct ixgbe_ring, rcu)); -} - /** * ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings * @adapter: board private structure to clear interrupt scheme on @@ -4967,12 +4766,7 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) adapter->tx_ring[i] = NULL; } for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = adapter->rx_ring[i]; - - /* ixgbe_get_stats64() might access this ring, we must wait - * a grace period before freeing it. - */ - call_rcu(&ring->rcu, ring_free_rcu); + kfree(adapter->rx_ring[i]); adapter->rx_ring[i] = NULL; } @@ -5049,7 +4843,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) int j; struct tc_configuration *tc; #endif - int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; /* PCI config space info */ @@ -5064,14 +4857,11 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->ring_feature[RING_F_RSS].indices = rss; adapter->flags |= IXGBE_FLAG_RSS_ENABLED; adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES; - switch (hw->mac.type) { - case ixgbe_mac_82598EB: + if (hw->mac.type == ixgbe_mac_82598EB) { if (hw->device_id == IXGBE_DEV_ID_82598AT) adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE; adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598; - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + } else if (hw->mac.type == ixgbe_mac_82599EB) { adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; @@ -5100,9 +4890,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->fcoe.up = IXGBE_FCOE_DEFTC; #endif #endif /* IXGBE_FCOE */ - break; - default: - break; } #ifdef CONFIG_IXGBE_DCB @@ -5132,8 +4919,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) #ifdef CONFIG_DCB adapter->last_lfc_mode = hw->fc.current_mode; #endif - hw->fc.high_water = FC_HIGH_WATER(max_frame); - hw->fc.low_water = FC_LOW_WATER(max_frame); + hw->fc.high_water = IXGBE_DEFAULT_FCRTH; + hw->fc.low_water = IXGBE_DEFAULT_FCRTL; hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE; hw->fc.send_xon = true; hw->fc.disable_fc_autoneg = false; @@ -5171,27 +4958,30 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) /** * ixgbe_setup_tx_resources - allocate Tx resources (Descriptors) + * @adapter: board private structure * @tx_ring: tx descriptor ring (for a specific queue) to setup * * Return 0 on success, negative on failure **/ -int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring) +int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) { - struct device *dev = tx_ring->dev; + struct pci_dev *pdev = adapter->pdev; int size; size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count; - tx_ring->tx_buffer_info = vzalloc_node(size, tx_ring->numa_node); + tx_ring->tx_buffer_info = vmalloc_node(size, tx_ring->numa_node); if (!tx_ring->tx_buffer_info) - tx_ring->tx_buffer_info = vzalloc(size); + tx_ring->tx_buffer_info = vmalloc(size); if (!tx_ring->tx_buffer_info) goto err; + memset(tx_ring->tx_buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc); tx_ring->size = ALIGN(tx_ring->size, 4096); - tx_ring->desc = dma_alloc_coherent(dev, tx_ring->size, + tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, &tx_ring->dma, GFP_KERNEL); if (!tx_ring->desc) goto err; @@ -5204,7 +4994,7 @@ int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring) err: vfree(tx_ring->tx_buffer_info); tx_ring->tx_buffer_info = NULL; - dev_err(dev, "Unable to allocate memory for the Tx descriptor ring\n"); + e_err(probe, "Unable to allocate memory for the Tx descriptor ring\n"); return -ENOMEM; } @@ -5223,7 +5013,7 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) int i, err = 0; for (i = 0; i < adapter->num_tx_queues; i++) { - err = ixgbe_setup_tx_resources(adapter->tx_ring[i]); + err = ixgbe_setup_tx_resources(adapter, adapter->tx_ring[i]); if (!err) continue; e_err(probe, "Allocation for Tx Queue %u failed\n", i); @@ -5235,40 +5025,48 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) /** * ixgbe_setup_rx_resources - allocate Rx resources (Descriptors) + * @adapter: board private structure * @rx_ring: rx descriptor ring (for a specific queue) to setup * * Returns 0 on success, negative on failure **/ -int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring) +int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring) { - struct device *dev = rx_ring->dev; + struct pci_dev *pdev = adapter->pdev; int size; size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count; - rx_ring->rx_buffer_info = vzalloc_node(size, rx_ring->numa_node); + rx_ring->rx_buffer_info = vmalloc_node(size, adapter->node); if (!rx_ring->rx_buffer_info) - rx_ring->rx_buffer_info = vzalloc(size); - if (!rx_ring->rx_buffer_info) - goto err; + rx_ring->rx_buffer_info = vmalloc(size); + if (!rx_ring->rx_buffer_info) { + e_err(probe, "vmalloc allocation failed for the Rx " + "descriptor ring\n"); + goto alloc_failed; + } + memset(rx_ring->rx_buffer_info, 0, size); /* Round up to nearest 4K */ rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); rx_ring->size = ALIGN(rx_ring->size, 4096); - rx_ring->desc = dma_alloc_coherent(dev, rx_ring->size, + rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); - if (!rx_ring->desc) - goto err; + if (!rx_ring->desc) { + e_err(probe, "Memory allocation failed for the Rx " + "descriptor ring\n"); + vfree(rx_ring->rx_buffer_info); + goto alloc_failed; + } rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; return 0; -err: - vfree(rx_ring->rx_buffer_info); - rx_ring->rx_buffer_info = NULL; - dev_err(dev, "Unable to allocate memory for the Rx descriptor ring\n"); + +alloc_failed: return -ENOMEM; } @@ -5282,12 +5080,13 @@ int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring) * * Return 0 on success, negative on failure **/ + static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) { int i, err = 0; for (i = 0; i < adapter->num_rx_queues; i++) { - err = ixgbe_setup_rx_resources(adapter->rx_ring[i]); + err = ixgbe_setup_rx_resources(adapter, adapter->rx_ring[i]); if (!err) continue; e_err(probe, "Allocation for Rx Queue %u failed\n", i); @@ -5299,23 +5098,23 @@ static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) /** * ixgbe_free_tx_resources - Free Tx Resources per Queue + * @adapter: board private structure * @tx_ring: Tx descriptor ring for a specific queue * * Free all transmit software resources **/ -void ixgbe_free_tx_resources(struct ixgbe_ring *tx_ring) +void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) { - ixgbe_clean_tx_ring(tx_ring); + struct pci_dev *pdev = adapter->pdev; + + ixgbe_clean_tx_ring(adapter, tx_ring); vfree(tx_ring->tx_buffer_info); tx_ring->tx_buffer_info = NULL; - /* if not set, then don't free */ - if (!tx_ring->desc) - return; - - dma_free_coherent(tx_ring->dev, tx_ring->size, - tx_ring->desc, tx_ring->dma); + dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc, + tx_ring->dma); tx_ring->desc = NULL; } @@ -5332,28 +5131,28 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter) for (i = 0; i < adapter->num_tx_queues; i++) if (adapter->tx_ring[i]->desc) - ixgbe_free_tx_resources(adapter->tx_ring[i]); + ixgbe_free_tx_resources(adapter, adapter->tx_ring[i]); } /** * ixgbe_free_rx_resources - Free Rx Resources + * @adapter: board private structure * @rx_ring: ring to clean the resources from * * Free all receive software resources **/ -void ixgbe_free_rx_resources(struct ixgbe_ring *rx_ring) +void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring) { - ixgbe_clean_rx_ring(rx_ring); + struct pci_dev *pdev = adapter->pdev; + + ixgbe_clean_rx_ring(adapter, rx_ring); vfree(rx_ring->rx_buffer_info); rx_ring->rx_buffer_info = NULL; - /* if not set, then don't free */ - if (!rx_ring->desc) - return; - - dma_free_coherent(rx_ring->dev, rx_ring->size, - rx_ring->desc, rx_ring->dma); + dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, + rx_ring->dma); rx_ring->desc = NULL; } @@ -5370,7 +5169,7 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter) for (i = 0; i < adapter->num_rx_queues; i++) if (adapter->rx_ring[i]->desc) - ixgbe_free_rx_resources(adapter->rx_ring[i]); + ixgbe_free_rx_resources(adapter, adapter->rx_ring[i]); } /** @@ -5383,7 +5182,6 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter) static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_hw *hw = &adapter->hw; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* MTU < 68 is an error and causes problems on some kernels */ @@ -5394,9 +5192,6 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) /* must set new MTU before calling down or up */ netdev->mtu = new_mtu; - hw->fc.high_water = FC_HIGH_WATER(max_frame); - hw->fc.low_water = FC_LOW_WATER(max_frame); - if (netif_running(netdev)) ixgbe_reinit_locked(adapter); @@ -5492,8 +5287,8 @@ static int ixgbe_close(struct net_device *netdev) #ifdef CONFIG_PM static int ixgbe_resume(struct pci_dev *pdev) { - struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); u32 err; pci_set_power_state(pdev, PCI_D0); @@ -5524,7 +5319,7 @@ static int ixgbe_resume(struct pci_dev *pdev) IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); if (netif_running(netdev)) { - err = ixgbe_open(netdev); + err = ixgbe_open(adapter->netdev); if (err) return err; } @@ -5537,8 +5332,8 @@ static int ixgbe_resume(struct pci_dev *pdev) static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) { - struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; u32 ctrl, fctrl; u32 wufc = adapter->wol; @@ -5555,8 +5350,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) ixgbe_free_all_rx_resources(adapter); } - ixgbe_clear_interrupt_scheme(adapter); - #ifdef CONFIG_PM retval = pci_save_state(pdev); if (retval) @@ -5583,20 +5376,15 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0); } - switch (hw->mac.type) { - case ixgbe_mac_82598EB: + if (wufc && hw->mac.type == ixgbe_mac_82599EB) + pci_wake_from_d3(pdev, true); + else pci_wake_from_d3(pdev, false); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - pci_wake_from_d3(pdev, !!wufc); - break; - default: - break; - } *enable_wake = !!wufc; + ixgbe_clear_interrupt_scheme(adapter); + ixgbe_release_hw_control(adapter); pci_disable_device(pdev); @@ -5645,12 +5433,10 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_hw_stats *hwstats = &adapter->stats; u64 total_mpc = 0; u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot; - u64 non_eop_descs = 0, restart_queue = 0, tx_busy = 0; - u64 alloc_rx_page_failed = 0, alloc_rx_buff_failed = 0; - u64 bytes = 0, packets = 0; + u64 non_eop_descs = 0, restart_queue = 0; + struct ixgbe_hw_stats *hwstats = &adapter->stats; if (test_bit(__IXGBE_DOWN, &adapter->state) || test_bit(__IXGBE_RESETTING, &adapter->state)) @@ -5663,41 +5449,21 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) adapter->hw_rx_no_dma_resources += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); for (i = 0; i < adapter->num_rx_queues; i++) { - rsc_count += adapter->rx_ring[i]->rx_stats.rsc_count; - rsc_flush += adapter->rx_ring[i]->rx_stats.rsc_flush; + rsc_count += adapter->rx_ring[i]->rsc_count; + rsc_flush += adapter->rx_ring[i]->rsc_flush; } adapter->rsc_total_count = rsc_count; adapter->rsc_total_flush = rsc_flush; } - for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *rx_ring = adapter->rx_ring[i]; - non_eop_descs += rx_ring->rx_stats.non_eop_descs; - alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed; - alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed; - bytes += rx_ring->stats.bytes; - packets += rx_ring->stats.packets; - } - adapter->non_eop_descs = non_eop_descs; - adapter->alloc_rx_page_failed = alloc_rx_page_failed; - adapter->alloc_rx_buff_failed = alloc_rx_buff_failed; - netdev->stats.rx_bytes = bytes; - netdev->stats.rx_packets = packets; - - bytes = 0; - packets = 0; /* gather some stats to the adapter struct that are per queue */ - for (i = 0; i < adapter->num_tx_queues; i++) { - struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; - restart_queue += tx_ring->tx_stats.restart_queue; - tx_busy += tx_ring->tx_stats.tx_busy; - bytes += tx_ring->stats.bytes; - packets += tx_ring->stats.packets; - } + for (i = 0; i < adapter->num_tx_queues; i++) + restart_queue += adapter->tx_ring[i]->restart_queue; adapter->restart_queue = restart_queue; - adapter->tx_busy = tx_busy; - netdev->stats.tx_bytes = bytes; - netdev->stats.tx_packets = packets; + + for (i = 0; i < adapter->num_rx_queues; i++) + non_eop_descs += adapter->rx_ring[i]->non_eop_descs; + adapter->non_eop_descs = non_eop_descs; hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); for (i = 0; i < 8; i++) { @@ -5712,18 +5478,17 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i)); hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - hwstats->pxonrxc[i] += - IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (hw->mac.type == ixgbe_mac_82599EB) { hwstats->pxonrxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); - break; - default: - break; + hwstats->pxoffrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + hwstats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + } else { + hwstats->pxonrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); + hwstats->pxoffrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); } hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); @@ -5732,25 +5497,21 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) /* work around hardware counting issue */ hwstats->gprc -= missed_rx; - ixgbe_update_xoff_received(adapter); - /* 82598 hardware only has a 32 bit counter in the high register */ - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); - hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); - hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); - hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (hw->mac.type == ixgbe_mac_82599EB) { + u64 tmp; hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); - IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */ + tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; + /* 4 high bits of GORC */ + hwstats->gorc += (tmp << 32); hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); - IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */ + tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; + /* 4 high bits of GOTC */ + hwstats->gotc += (tmp << 32); hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL); - IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ + IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); #ifdef IXGBE_FCOE @@ -5761,9 +5522,12 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); #endif /* IXGBE_FCOE */ - break; - default: - break; + } else { + hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); + hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); + hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); + hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); } bprc = IXGBE_READ_REG(hw, IXGBE_BPRC); hwstats->bprc += bprc; @@ -5936,8 +5700,8 @@ static void ixgbe_fdir_reinit_task(struct work_struct *work) if (ixgbe_reinit_fdir_tables_82599(hw) == 0) { for (i = 0; i < adapter->num_tx_queues; i++) - set_bit(__IXGBE_TX_FDIR_INIT_DONE, - &(adapter->tx_ring[i]->state)); + set_bit(__IXGBE_FDIR_INIT_DONE, + &(adapter->tx_ring[i]->reinit_state)); } else { e_err(probe, "failed to finish FDIR re-initialization, " "ignored adding FDIR ATR filters\n"); @@ -5999,26 +5763,16 @@ static void ixgbe_watchdog_task(struct work_struct *work) if (!netif_carrier_ok(netdev)) { bool flow_rx, flow_tx; - switch (hw->mac.type) { - case ixgbe_mac_82598EB: { - u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL); - u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS); - flow_rx = !!(frctl & IXGBE_FCTRL_RFCE); - flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X); - } - break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: { + if (hw->mac.type == ixgbe_mac_82599EB) { u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN); u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG); flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE); flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X); - } - break; - default: - flow_tx = false; - flow_rx = false; - break; + } else { + u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS); + flow_rx = !!(frctl & IXGBE_FCTRL_RFCE); + flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X); } e_info(drv, "NIC Link is Up %s, Flow Control: %s\n", @@ -6033,10 +5787,7 @@ static void ixgbe_watchdog_task(struct work_struct *work) netif_carrier_on(netdev); } else { /* Force detection of hung controller */ - for (i = 0; i < adapter->num_tx_queues; i++) { - tx_ring = adapter->tx_ring[i]; - set_check_for_tx_hang(tx_ring); - } + adapter->detect_tx_hung = true; } } else { adapter->link_up = false; @@ -6072,7 +5823,7 @@ static void ixgbe_watchdog_task(struct work_struct *work) static int ixgbe_tso(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring, struct sk_buff *skb, - u32 tx_flags, u8 *hdr_len, __be16 protocol) + u32 tx_flags, u8 *hdr_len) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -6090,7 +5841,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, l4len = tcp_hdrlen(skb); *hdr_len += l4len; - if (protocol == htons(ETH_P_IP)) { + if (skb->protocol == htons(ETH_P_IP)) { struct iphdr *iph = ip_hdr(skb); iph->tot_len = 0; iph->check = 0; @@ -6129,7 +5880,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT); - if (protocol == htons(ETH_P_IP)) + if (skb->protocol == htons(ETH_P_IP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); @@ -6155,10 +5906,16 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, return false; } -static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb, - __be16 protocol) +static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb) { u32 rtn = 0; + __be16 protocol; + + if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) + protocol = ((const struct vlan_ethhdr *)skb->data)-> + h_vlan_encapsulated_proto; + else + protocol = skb->protocol; switch (protocol) { case cpu_to_be16(ETH_P_IP): @@ -6186,7 +5943,7 @@ static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb, default: if (unlikely(net_ratelimit())) e_warn(probe, "partial checksum but proto=%x!\n", - protocol); + skb->protocol); break; } @@ -6195,8 +5952,7 @@ static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb, static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags, - __be16 protocol) + struct sk_buff *skb, u32 tx_flags) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -6225,7 +5981,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, IXGBE_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) - type_tucmd_mlhl |= ixgbe_psum(adapter, skb, protocol); + type_tucmd_mlhl |= ixgbe_psum(adapter, skb); context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); /* use index zero for tx checksum offload */ @@ -6248,17 +6004,15 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, static int ixgbe_tx_map(struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring, struct sk_buff *skb, u32 tx_flags, - unsigned int first, const u8 hdr_len) + unsigned int first) { - struct device *dev = tx_ring->dev; + struct pci_dev *pdev = adapter->pdev; struct ixgbe_tx_buffer *tx_buffer_info; unsigned int len; unsigned int total = skb->len; unsigned int offset = 0, size, count = 0, i; unsigned int nr_frags = skb_shinfo(skb)->nr_frags; unsigned int f; - unsigned int bytecount = skb->len; - u16 gso_segs = 1; i = tx_ring->next_to_use; @@ -6273,10 +6027,10 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, tx_buffer_info->length = size; tx_buffer_info->mapped_as_page = false; - tx_buffer_info->dma = dma_map_single(dev, + tx_buffer_info->dma = dma_map_single(&pdev->dev, skb->data + offset, size, DMA_TO_DEVICE); - if (dma_mapping_error(dev, tx_buffer_info->dma)) + if (dma_mapping_error(&pdev->dev, tx_buffer_info->dma)) goto dma_error; tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -6309,12 +6063,12 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD); tx_buffer_info->length = size; - tx_buffer_info->dma = dma_map_page(dev, + tx_buffer_info->dma = dma_map_page(&adapter->pdev->dev, frag->page, offset, size, DMA_TO_DEVICE); tx_buffer_info->mapped_as_page = true; - if (dma_mapping_error(dev, tx_buffer_info->dma)) + if (dma_mapping_error(&pdev->dev, tx_buffer_info->dma)) goto dma_error; tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -6328,19 +6082,6 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, break; } - if (tx_flags & IXGBE_TX_FLAGS_TSO) - gso_segs = skb_shinfo(skb)->gso_segs; -#ifdef IXGBE_FCOE - /* adjust for FCoE Sequence Offload */ - else if (tx_flags & IXGBE_TX_FLAGS_FSO) - gso_segs = DIV_ROUND_UP(skb->len - hdr_len, - skb_shinfo(skb)->gso_size); -#endif /* IXGBE_FCOE */ - bytecount += (gso_segs - 1) * hdr_len; - - /* multiply data chunks by size of headers */ - tx_ring->tx_buffer_info[i].bytecount = bytecount; - tx_ring->tx_buffer_info[i].gso_segs = gso_segs; tx_ring->tx_buffer_info[i].skb = skb; tx_ring->tx_buffer_info[first].next_to_watch = i; @@ -6362,13 +6103,14 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, i += tx_ring->count; i--; tx_buffer_info = &tx_ring->tx_buffer_info[i]; - ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info); + ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); } return 0; } -static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring, +static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring, int tx_flags, int count, u32 paylen, u8 hdr_len) { union ixgbe_adv_tx_desc *tx_desc = NULL; @@ -6433,46 +6175,60 @@ static void ixgbe_tx_queue(struct ixgbe_ring *tx_ring, wmb(); tx_ring->next_to_use = i; - writel(i, tx_ring->tail); + writel(i, adapter->hw.hw_addr + tx_ring->tail); } static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, - u8 queue, u32 tx_flags, __be16 protocol) + int queue, u32 tx_flags) { struct ixgbe_atr_input atr_input; + struct tcphdr *th; struct iphdr *iph = ip_hdr(skb); struct ethhdr *eth = (struct ethhdr *)skb->data; - struct tcphdr *th; - u16 vlan_id; + u16 vlan_id, src_port, dst_port, flex_bytes; + u32 src_ipv4_addr, dst_ipv4_addr; + u8 l4type = 0; - /* Right now, we support IPv4 w/ TCP only */ - if (protocol != htons(ETH_P_IP) || - iph->protocol != IPPROTO_TCP) + /* Right now, we support IPv4 only */ + if (skb->protocol != htons(ETH_P_IP)) + return; + /* check if we're UDP or TCP */ + if (iph->protocol == IPPROTO_TCP) { + th = tcp_hdr(skb); + src_port = th->source; + dst_port = th->dest; + l4type |= IXGBE_ATR_L4TYPE_TCP; + /* l4type IPv4 type is 0, no need to assign */ + } else { + /* Unsupported L4 header, just bail here */ return; + } memset(&atr_input, 0, sizeof(struct ixgbe_atr_input)); vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >> IXGBE_TX_FLAGS_VLAN_SHIFT; - - th = tcp_hdr(skb); + src_ipv4_addr = iph->saddr; + dst_ipv4_addr = iph->daddr; + flex_bytes = eth->h_proto; ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id); - ixgbe_atr_set_src_port_82599(&atr_input, th->dest); - ixgbe_atr_set_dst_port_82599(&atr_input, th->source); - ixgbe_atr_set_flex_byte_82599(&atr_input, eth->h_proto); - ixgbe_atr_set_l4type_82599(&atr_input, IXGBE_ATR_L4TYPE_TCP); + ixgbe_atr_set_src_port_82599(&atr_input, dst_port); + ixgbe_atr_set_dst_port_82599(&atr_input, src_port); + ixgbe_atr_set_flex_byte_82599(&atr_input, flex_bytes); + ixgbe_atr_set_l4type_82599(&atr_input, l4type); /* src and dst are inverted, think how the receiver sees them */ - ixgbe_atr_set_src_ipv4_82599(&atr_input, iph->daddr); - ixgbe_atr_set_dst_ipv4_82599(&atr_input, iph->saddr); + ixgbe_atr_set_src_ipv4_82599(&atr_input, dst_ipv4_addr); + ixgbe_atr_set_dst_ipv4_82599(&atr_input, src_ipv4_addr); /* This assumes the Rx queue and Tx queue are bound to the same CPU */ ixgbe_fdir_add_signature_filter_82599(&adapter->hw, &atr_input, queue); } -static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) +static int __ixgbe_maybe_stop_tx(struct net_device *netdev, + struct ixgbe_ring *tx_ring, int size) { - netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); + netif_stop_subqueue(netdev, tx_ring->queue_index); /* Herbert's original patch had: * smp_mb__after_netif_stop_queue(); * but since that doesn't exist yet, just open code it. */ @@ -6484,29 +6240,27 @@ static int __ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) return -EBUSY; /* A reprieve! - use start_queue because it doesn't call schedule */ - netif_start_subqueue(tx_ring->netdev, tx_ring->queue_index); - ++tx_ring->tx_stats.restart_queue; + netif_start_subqueue(netdev, tx_ring->queue_index); + ++tx_ring->restart_queue; return 0; } -static int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, int size) +static int ixgbe_maybe_stop_tx(struct net_device *netdev, + struct ixgbe_ring *tx_ring, int size) { if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size)) return 0; - return __ixgbe_maybe_stop_tx(tx_ring, size); + return __ixgbe_maybe_stop_tx(netdev, tx_ring, size); } static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) { struct ixgbe_adapter *adapter = netdev_priv(dev); int txq = smp_processor_id(); -#ifdef IXGBE_FCOE - __be16 protocol; - - protocol = vlan_get_protocol(skb); - if ((protocol == htons(ETH_P_FCOE)) || - (protocol == htons(ETH_P_FIP))) { +#ifdef IXGBE_FCOE + if ((skb->protocol == htons(ETH_P_FCOE)) || + (skb->protocol == htons(ETH_P_FIP))) { if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); txq += adapter->ring_feature[RING_F_FCOE].mask; @@ -6538,11 +6292,10 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) return skb_tx_hash(dev, skb); } -netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, +netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev, struct ixgbe_adapter *adapter, struct ixgbe_ring *tx_ring) { - struct net_device *netdev = tx_ring->netdev; struct netdev_queue *txq; unsigned int first; unsigned int tx_flags = 0; @@ -6550,9 +6303,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, int tso; int count = 0; unsigned int f; - __be16 protocol; - - protocol = vlan_get_protocol(skb); if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); @@ -6573,8 +6323,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, /* for FCoE with DCB, we force the priority to what * was specified by the switch */ if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED && - (protocol == htons(ETH_P_FCOE) || - protocol == htons(ETH_P_FIP))) { + (skb->protocol == htons(ETH_P_FCOE) || + skb->protocol == htons(ETH_P_FIP))) { #ifdef CONFIG_IXGBE_DCB if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK @@ -6584,7 +6334,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, } #endif /* flag for FCoE offloads */ - if (protocol == htons(ETH_P_FCOE)) + if (skb->protocol == htons(ETH_P_FCOE)) tx_flags |= IXGBE_TX_FLAGS_FCOE; } #endif @@ -6600,8 +6350,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); - if (ixgbe_maybe_stop_tx(tx_ring, count)) { - tx_ring->tx_stats.tx_busy++; + if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) { + adapter->tx_busy++; return NETDEV_TX_BUSY; } @@ -6618,10 +6368,9 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, tx_flags |= IXGBE_TX_FLAGS_FSO; #endif /* IXGBE_FCOE */ } else { - if (protocol == htons(ETH_P_IP)) + if (skb->protocol == htons(ETH_P_IP)) tx_flags |= IXGBE_TX_FLAGS_IPV4; - tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len, - protocol); + tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len); if (tso < 0) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; @@ -6629,30 +6378,30 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, if (tso) tx_flags |= IXGBE_TX_FLAGS_TSO; - else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags, - protocol) && + else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) && (skb->ip_summed == CHECKSUM_PARTIAL)) tx_flags |= IXGBE_TX_FLAGS_CSUM; } - count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first, hdr_len); + count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first); if (count) { /* add the ATR filter if ATR is on */ if (tx_ring->atr_sample_rate) { ++tx_ring->atr_count; if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) && - test_bit(__IXGBE_TX_FDIR_INIT_DONE, - &tx_ring->state)) { + test_bit(__IXGBE_FDIR_INIT_DONE, + &tx_ring->reinit_state)) { ixgbe_atr(adapter, skb, tx_ring->queue_index, - tx_flags, protocol); + tx_flags); tx_ring->atr_count = 0; } } txq = netdev_get_tx_queue(netdev, tx_ring->queue_index); txq->tx_bytes += skb->len; txq->tx_packets++; - ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len); - ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED); + ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len, + hdr_len); + ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED); } else { dev_kfree_skb_any(skb); @@ -6669,7 +6418,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netd struct ixgbe_ring *tx_ring; tx_ring = adapter->tx_ring[skb->queue_mapping]; - return ixgbe_xmit_frame_ring(skb, adapter, tx_ring); + return ixgbe_xmit_frame_ring(skb, netdev, adapter, tx_ring); } /** @@ -6810,23 +6559,20 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, /* accurate rx/tx bytes/packets stats */ dev_txq_stats_fold(netdev, stats); - rcu_read_lock(); for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = ACCESS_ONCE(adapter->rx_ring[i]); + struct ixgbe_ring *ring = adapter->rx_ring[i]; u64 bytes, packets; unsigned int start; - if (ring) { - do { - start = u64_stats_fetch_begin_bh(&ring->syncp); - packets = ring->stats.packets; - bytes = ring->stats.bytes; - } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); - stats->rx_packets += packets; - stats->rx_bytes += bytes; - } + do { + start = u64_stats_fetch_begin_bh(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; + } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; } - rcu_read_unlock(); + /* following stats updated by ixgbe_watchdog_task() */ stats->multicast = netdev->stats.multicast; stats->rx_errors = netdev->stats.rx_errors; @@ -7008,8 +6754,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, SET_NETDEV_DEV(netdev, &pdev->dev); + pci_set_drvdata(pdev, netdev); adapter = netdev_priv(netdev); - pci_set_drvdata(pdev, adapter); adapter->netdev = netdev; adapter->pdev = pdev; @@ -7082,14 +6828,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_sw_init; /* Make it possible the adapter to be woken up via WOL */ - switch (adapter->hw.mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (adapter->hw.mac.type == ixgbe_mac_82599EB) IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); - break; - default: - break; - } /* * If there is a fan on this device and it has failed log the @@ -7198,7 +6938,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } /* power down the optics */ - if (hw->phy.multispeed_fiber && hw->mac.ops.disable_tx_laser) + if (hw->phy.multispeed_fiber) hw->mac.ops.disable_tx_laser(hw); init_timer(&adapter->watchdog_timer); @@ -7213,13 +6953,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, goto err_sw_init; switch (pdev->device) { - case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: - /* All except this subdevice support WOL */ - if (pdev->subsystem_device == - IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) { - adapter->wol = 0; - break; - } case IXGBE_DEV_ID_82599_KX4: adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | IXGBE_WUFC_MC | IXGBE_WUFC_BC); @@ -7345,8 +7078,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, **/ static void __devexit ixgbe_remove(struct pci_dev *pdev) { - struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); set_bit(__IXGBE_DOWN, &adapter->state); /* clear the module not found bit to make sure the worker won't @@ -7416,8 +7149,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); netif_device_detach(netdev); @@ -7440,7 +7173,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, */ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) { - struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); pci_ers_result_t result; int err; @@ -7478,8 +7212,8 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) */ static void ixgbe_io_resume(struct pci_dev *pdev) { - struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); if (netif_running(netdev)) { if (ixgbe_up(adapter)) { @@ -7544,7 +7278,6 @@ static void __exit ixgbe_exit_module(void) dca_unregister_notify(&dca_notifier); #endif pci_unregister_driver(&ixgbe_driver); - rcu_barrier(); /* Wait for completion of call_rcu()'s */ } #ifdef CONFIG_IXGBE_DCA diff --git a/trunk/drivers/net/ixgbe/ixgbe_mbx.c b/trunk/drivers/net/ixgbe/ixgbe_mbx.c index 027c628c3aae..471f0f2cdb98 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_mbx.c +++ b/trunk/drivers/net/ixgbe/ixgbe_mbx.c @@ -319,14 +319,8 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) u32 vflre = 0; s32 ret_val = IXGBE_ERR_MBX; - switch (hw->mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: + if (hw->mac.type == ixgbe_mac_82599EB) vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); - break; - default: - break; - } if (vflre & (1 << vf_shift)) { ret_val = 0; @@ -445,26 +439,22 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) { struct ixgbe_mbx_info *mbx = &hw->mbx; - switch (hw->mac.type) { - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: - mbx->timeout = 0; - mbx->usec_delay = 0; - - mbx->size = IXGBE_VFMAILBOX_SIZE; - - mbx->stats.msgs_tx = 0; - mbx->stats.msgs_rx = 0; - mbx->stats.reqs = 0; - mbx->stats.acks = 0; - mbx->stats.rsts = 0; - break; - default: - break; - } + if (hw->mac.type != ixgbe_mac_82599EB) + return; + + mbx->timeout = 0; + mbx->usec_delay = 0; + + mbx->size = IXGBE_VFMAILBOX_SIZE; + + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; } -struct ixgbe_mbx_operations mbx_ops_generic = { +struct ixgbe_mbx_operations mbx_ops_82599 = { .read = ixgbe_read_mbx_pf, .write = ixgbe_write_mbx_pf, .read_posted = ixgbe_read_posted_mbx, diff --git a/trunk/drivers/net/ixgbe/ixgbe_mbx.h b/trunk/drivers/net/ixgbe/ixgbe_mbx.h index 3df9b1590218..7e0d08ff5b53 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_mbx.h +++ b/trunk/drivers/net/ixgbe/ixgbe_mbx.h @@ -88,6 +88,6 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16); s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16); void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); -extern struct ixgbe_mbx_operations mbx_ops_generic; +extern struct ixgbe_mbx_operations mbx_ops_82599; #endif /* _IXGBE_MBX_H_ */ diff --git a/trunk/drivers/net/ixgbe/ixgbe_phy.c b/trunk/drivers/net/ixgbe/ixgbe_phy.c index c445fbce56ee..6c0d42e33f21 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_phy.c +++ b/trunk/drivers/net/ixgbe/ixgbe_phy.c @@ -115,9 +115,6 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) case TN1010_PHY_ID: phy_type = ixgbe_phy_tn; break; - case AQ1202_PHY_ID: - phy_type = ixgbe_phy_aq; - break; case QT2022_PHY_ID: phy_type = ixgbe_phy_qt; break; @@ -427,39 +424,6 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, return 0; } -/** - * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities - * @hw: pointer to hardware structure - * @speed: pointer to link speed - * @autoneg: boolean auto-negotiation value - * - * Determines the link capabilities by reading the AUTOC register. - */ -s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg) -{ - s32 status = IXGBE_ERR_LINK_SETUP; - u16 speed_ability; - - *speed = 0; - *autoneg = true; - - status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, - &speed_ability); - - if (status == 0) { - if (speed_ability & MDIO_SPEED_10G) - *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (speed_ability & MDIO_PMA_SPEED_1000) - *speed |= IXGBE_LINK_SPEED_1GB_FULL; - if (speed_ability & MDIO_PMA_SPEED_100) - *speed |= IXGBE_LINK_SPEED_100_FULL; - } - - return status; -} - /** * ixgbe_reset_phy_nl - Performs a PHY reset * @hw: pointer to hardware structure @@ -1413,22 +1377,6 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, return status; } -/** - * ixgbe_get_phy_firmware_version_generic - Gets the PHY Firmware Version - * @hw: pointer to hardware structure - * @firmware_version: pointer to the PHY Firmware Version -**/ -s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, - u16 *firmware_version) -{ - s32 status = 0; - - status = hw->phy.ops.read_reg(hw, AQ_FW_REV, MDIO_MMD_VEND1, - firmware_version); - - return status; -} - /** * ixgbe_tn_check_overtemp - Checks if an overtemp occured. * @hw: pointer to hardware structure diff --git a/trunk/drivers/net/ixgbe/ixgbe_phy.h b/trunk/drivers/net/ixgbe/ixgbe_phy.h index e2c6b7eac641..fb3898f12fc5 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_phy.h +++ b/trunk/drivers/net/ixgbe/ixgbe_phy.h @@ -96,9 +96,6 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, - ixgbe_link_speed *speed, - bool *autoneg); /* PHY specific */ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, @@ -106,8 +103,6 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, bool *link_up); s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, u16 *firmware_version); -s32 ixgbe_get_phy_firmware_version_generic(struct ixgbe_hw *hw, - u16 *firmware_version); s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw); s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw); diff --git a/trunk/drivers/net/ixgbe/ixgbe_sriov.c b/trunk/drivers/net/ixgbe/ixgbe_sriov.c index 6e3e94b5a5f6..5428153af8f3 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_sriov.c +++ b/trunk/drivers/net/ixgbe/ixgbe_sriov.c @@ -68,7 +68,7 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, * addresses */ for (i = 0; i < entries; i++) { - vfinfo->vf_mc_hashes[i] = hash_list[i]; + vfinfo->vf_mc_hashes[i] = hash_list[i];; } for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) { @@ -178,7 +178,8 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) { unsigned char vf_mac_addr[6]; - struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); unsigned int vfn = (event_mask & 0x3f); bool enable = ((event_mask & 0x10000000U) != 0); diff --git a/trunk/drivers/net/ixgbe/ixgbe_type.h b/trunk/drivers/net/ixgbe/ixgbe_type.h index 42c607339a62..d3cc6ce7c973 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_type.h +++ b/trunk/drivers/net/ixgbe/ixgbe_type.h @@ -57,8 +57,6 @@ #define IXGBE_DEV_ID_82599_SFP_EM 0x1507 #define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8 -#define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ 0x000C -#define IXGBE_DEV_ID_X540T 0x1528 /* General Registers */ #define IXGBE_CTRL 0x00000 @@ -996,10 +994,8 @@ /* PHY IDs*/ #define TN1010_PHY_ID 0x00A19410 #define TNX_FW_REV 0xB -#define AQ1202_PHY_ID 0x03A1B440 #define QT2022_PHY_ID 0x0043A400 #define ATH_PHY_ID 0x03429050 -#define AQ_FW_REV 0x20 /* PHY Types */ #define IXGBE_M88E1145_E_PHY_ID 0x01410CD0 @@ -1495,7 +1491,6 @@ #define IXGBE_EEC_PRES 0x00000100 /* EEPROM Present */ #define IXGBE_EEC_ARD 0x00000200 /* EEPROM Auto Read Done */ #define IXGBE_EEC_FLUP 0x00800000 /* Flash update command */ -#define IXGBE_EEC_SEC1VAL 0x02000000 /* Sector 1 Valid */ #define IXGBE_EEC_FLUDONE 0x04000000 /* Flash update done */ /* EEPROM Addressing bits based on type (0-small, 1-large) */ #define IXGBE_EEC_ADDR_SIZE 0x00000400 @@ -1510,9 +1505,7 @@ #define IXGBE_EEPROM_SUM 0xBABA #define IXGBE_PCIE_ANALOG_PTR 0x03 #define IXGBE_ATLAS0_CONFIG_PTR 0x04 -#define IXGBE_PHY_PTR 0x04 #define IXGBE_ATLAS1_CONFIG_PTR 0x05 -#define IXGBE_OPTION_ROM_PTR 0x05 #define IXGBE_PCIE_GENERAL_PTR 0x06 #define IXGBE_PCIE_CONFIG0_PTR 0x07 #define IXGBE_PCIE_CONFIG1_PTR 0x08 @@ -2120,14 +2113,6 @@ typedef u32 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000 #define IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA 0x2000 -/* Flow Control Macros */ -#define PAUSE_RTT 8 -#define PAUSE_MTU(MTU) ((MTU + 1024 - 1) / 1024) - -#define FC_HIGH_WATER(MTU) ((((PAUSE_RTT + PAUSE_MTU(MTU)) * 144) + 99) / 100 +\ - PAUSE_MTU(MTU)) -#define FC_LOW_WATER(MTU) (2 * (2 * PAUSE_MTU(MTU) + PAUSE_RTT)) - /* Software ATR hash keys */ #define IXGBE_ATR_BUCKET_HASH_KEY 0xE214AD3D #define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17 @@ -2179,7 +2164,6 @@ struct ixgbe_atr_input_masks { enum ixgbe_eeprom_type { ixgbe_eeprom_uninitialized = 0, ixgbe_eeprom_spi, - ixgbe_flash, ixgbe_eeprom_none /* No NVM support */ }; @@ -2187,14 +2171,12 @@ enum ixgbe_mac_type { ixgbe_mac_unknown = 0, ixgbe_mac_82598EB, ixgbe_mac_82599EB, - ixgbe_mac_X540, ixgbe_num_macs }; enum ixgbe_phy_type { ixgbe_phy_unknown = 0, ixgbe_phy_tn, - ixgbe_phy_aq, ixgbe_phy_cu_unknown, ixgbe_phy_qt, ixgbe_phy_xaui, @@ -2423,7 +2405,6 @@ struct ixgbe_eeprom_operations { s32 (*write)(struct ixgbe_hw *, u16, u16); s32 (*validate_checksum)(struct ixgbe_hw *, u16 *); s32 (*update_checksum)(struct ixgbe_hw *); - u16 (*calc_checksum)(struct ixgbe_hw *); }; struct ixgbe_mac_operations { @@ -2593,7 +2574,6 @@ struct ixgbe_hw { u16 subsystem_vendor_id; u8 revision_id; bool adapter_stopped; - bool force_full_reset; }; struct ixgbe_info { diff --git a/trunk/drivers/net/ixgbe/ixgbe_x540.c b/trunk/drivers/net/ixgbe/ixgbe_x540.c deleted file mode 100644 index 9649fa727e31..000000000000 --- a/trunk/drivers/net/ixgbe/ixgbe_x540.c +++ /dev/null @@ -1,722 +0,0 @@ -/******************************************************************************* - - Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2010 Intel Corporation. - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information: - e1000-devel Mailing List - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -#include -#include -#include - -#include "ixgbe.h" -#include "ixgbe_phy.h" -//#include "ixgbe_mbx.h" - -#define IXGBE_X540_MAX_TX_QUEUES 128 -#define IXGBE_X540_MAX_RX_QUEUES 128 -#define IXGBE_X540_RAR_ENTRIES 128 -#define IXGBE_X540_MC_TBL_SIZE 128 -#define IXGBE_X540_VFT_TBL_SIZE 128 - -static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); -static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw); -static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); -static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); -static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw); -static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw); - -static enum ixgbe_media_type ixgbe_get_media_type_X540(struct ixgbe_hw *hw) -{ - return ixgbe_media_type_copper; -} - -static s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw) -{ - struct ixgbe_mac_info *mac = &hw->mac; - - /* Call PHY identify routine to get the phy type */ - ixgbe_identify_phy_generic(hw); - - mac->mcft_size = IXGBE_X540_MC_TBL_SIZE; - mac->vft_size = IXGBE_X540_VFT_TBL_SIZE; - mac->num_rar_entries = IXGBE_X540_RAR_ENTRIES; - mac->max_rx_queues = IXGBE_X540_MAX_RX_QUEUES; - mac->max_tx_queues = IXGBE_X540_MAX_TX_QUEUES; - mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw); - - return 0; -} - -/** - * ixgbe_setup_mac_link_X540 - Set the auto advertised capabilitires - * @hw: pointer to hardware structure - * @speed: new link speed - * @autoneg: true if autonegotiation enabled - * @autoneg_wait_to_complete: true when waiting for completion is needed - **/ -static s32 ixgbe_setup_mac_link_X540(struct ixgbe_hw *hw, - ixgbe_link_speed speed, bool autoneg, - bool autoneg_wait_to_complete) -{ - return hw->phy.ops.setup_link_speed(hw, speed, autoneg, - autoneg_wait_to_complete); -} - -/** - * ixgbe_reset_hw_X540 - Perform hardware reset - * @hw: pointer to hardware structure - * - * Resets the hardware by resetting the transmit and receive units, masks - * and clears all interrupts, perform a PHY reset, and perform a link (MAC) - * reset. - **/ -static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) -{ - ixgbe_link_speed link_speed; - s32 status = 0; - u32 ctrl; - u32 ctrl_ext; - u32 reset_bit; - u32 i; - u32 autoc; - u32 autoc2; - bool link_up = false; - - /* Call adapter stop to disable tx/rx and clear interrupts */ - hw->mac.ops.stop_adapter(hw); - - /* - * Prevent the PCI-E bus from from hanging by disabling PCI-E master - * access and verify no pending requests before reset - */ - status = ixgbe_disable_pcie_master(hw); - if (status != 0) { - status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); - } - - /* - * Issue global reset to the MAC. Needs to be SW reset if link is up. - * If link reset is used when link is up, it might reset the PHY when - * mng is using it. If link is down or the flag to force full link - * reset is set, then perform link reset. - */ - if (hw->force_full_reset) { - reset_bit = IXGBE_CTRL_LNK_RST; - } else { - hw->mac.ops.check_link(hw, &link_speed, &link_up, false); - if (!link_up) - reset_bit = IXGBE_CTRL_LNK_RST; - else - reset_bit = IXGBE_CTRL_RST; - } - - ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); - IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST)); - IXGBE_WRITE_FLUSH(hw); - - /* Poll for reset bit to self-clear indicating reset is complete */ - for (i = 0; i < 10; i++) { - udelay(1); - ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); - if (!(ctrl & IXGBE_CTRL_RST)) - break; - } - if (ctrl & IXGBE_CTRL_RST) { - status = IXGBE_ERR_RESET_FAILED; - hw_dbg(hw, "Reset polling failed to complete.\n"); - } - - /* Clear PF Reset Done bit so PF/VF Mail Ops can work */ - ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); - ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; - IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); - - msleep(50); - - /* Set the Rx packet buffer size. */ - IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); - - /* Store the permanent mac address */ - hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); - - /* - * Store the original AUTOC/AUTOC2 values if they have not been - * stored off yet. Otherwise restore the stored original - * values since the reset operation sets back to defaults. - */ - autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); - autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); - if (hw->mac.orig_link_settings_stored == false) { - hw->mac.orig_autoc = autoc; - hw->mac.orig_autoc2 = autoc2; - hw->mac.orig_link_settings_stored = true; - } else { - if (autoc != hw->mac.orig_autoc) - IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc | - IXGBE_AUTOC_AN_RESTART)); - - if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) != - (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) { - autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK; - autoc2 |= (hw->mac.orig_autoc2 & - IXGBE_AUTOC2_UPPER_MASK); - IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2); - } - } - - /* - * Store MAC address from RAR0, clear receive address registers, and - * clear the multicast table. Also reset num_rar_entries to 128, - * since we modify this value when programming the SAN MAC address. - */ - hw->mac.num_rar_entries = 128; - hw->mac.ops.init_rx_addrs(hw); - - /* Store the permanent mac address */ - hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); - - /* Store the permanent SAN mac address */ - hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); - - /* Add the SAN MAC address to the RAR only if it's a valid address */ - if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { - hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1, - hw->mac.san_addr, 0, IXGBE_RAH_AV); - - /* Reserve the last RAR for the SAN MAC address */ - hw->mac.num_rar_entries--; - } - - /* Store the alternative WWNN/WWPN prefix */ - hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, - &hw->mac.wwpn_prefix); - - return status; -} - -/** - * ixgbe_get_supported_physical_layer_X540 - Returns physical layer type - * @hw: pointer to hardware structure - * - * Determines physical layer capabilities of the current configuration. - **/ -static u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw) -{ - u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; - u16 ext_ability = 0; - - hw->phy.ops.identify(hw); - - hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, - &ext_ability); - if (ext_ability & MDIO_PMA_EXTABLE_10GBT) - physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; - if (ext_ability & MDIO_PMA_EXTABLE_1000BT) - physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; - if (ext_ability & MDIO_PMA_EXTABLE_100BTX) - physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; - - return physical_layer; -} - -/** - * ixgbe_init_eeprom_params_X540 - Initialize EEPROM params - * @hw: pointer to hardware structure - **/ -static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw) -{ - struct ixgbe_eeprom_info *eeprom = &hw->eeprom; - u32 eec; - u16 eeprom_size; - - if (eeprom->type == ixgbe_eeprom_uninitialized) { - eeprom->semaphore_delay = 10; - eeprom->type = ixgbe_flash; - - eec = IXGBE_READ_REG(hw, IXGBE_EEC); - eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >> - IXGBE_EEC_SIZE_SHIFT); - eeprom->word_size = 1 << (eeprom_size + - IXGBE_EEPROM_WORD_SIZE_SHIFT); - - hw_dbg(hw, "Eeprom params: type = %d, size = %d\n", - eeprom->type, eeprom->word_size); - } - - return 0; -} - -/** - * ixgbe_read_eerd_X540 - Read EEPROM word using EERD - * @hw: pointer to hardware structure - * @offset: offset of word in the EEPROM to read - * @data: word read from the EERPOM - **/ -static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data) -{ - s32 status; - - if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM)) - status = ixgbe_read_eerd_generic(hw, offset, data); - else - status = IXGBE_ERR_SWFW_SYNC; - - ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM); - return status; -} - -/** - * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR - * @hw: pointer to hardware structure - * @offset: offset of word in the EEPROM to write - * @data: word write to the EEPROM - * - * Write a 16 bit word to the EEPROM using the EEWR register. - **/ -static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data) -{ - u32 eewr; - s32 status; - - hw->eeprom.ops.init_params(hw); - - if (offset >= hw->eeprom.word_size) { - status = IXGBE_ERR_EEPROM; - goto out; - } - - eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) | - (data << IXGBE_EEPROM_RW_REG_DATA) | - IXGBE_EEPROM_RW_REG_START; - - if (ixgbe_acquire_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM)) { - status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); - if (status != 0) { - hw_dbg(hw, "Eeprom write EEWR timed out\n"); - goto out; - } - - IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr); - - status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE); - if (status != 0) { - hw_dbg(hw, "Eeprom write EEWR timed out\n"); - goto out; - } - } else { - status = IXGBE_ERR_SWFW_SYNC; - } - -out: - ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM); - return status; -} - -/** - * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum - * @hw: pointer to hardware structure - **/ -static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw) -{ - u16 i; - u16 j; - u16 checksum = 0; - u16 length = 0; - u16 pointer = 0; - u16 word = 0; - - /* Include 0x0-0x3F in the checksum */ - for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { - if (hw->eeprom.ops.read(hw, i, &word) != 0) { - hw_dbg(hw, "EEPROM read failed\n"); - break; - } - checksum += word; - } - - /* - * Include all data from pointers 0x3, 0x6-0xE. This excludes the - * FW, PHY module, and PCIe Expansion/Option ROM pointers. - */ - for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { - if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR) - continue; - - if (hw->eeprom.ops.read(hw, i, &pointer) != 0) { - hw_dbg(hw, "EEPROM read failed\n"); - break; - } - - /* Skip pointer section if the pointer is invalid. */ - if (pointer == 0xFFFF || pointer == 0 || - pointer >= hw->eeprom.word_size) - continue; - - if (hw->eeprom.ops.read(hw, pointer, &length) != 0) { - hw_dbg(hw, "EEPROM read failed\n"); - break; - } - - /* Skip pointer section if length is invalid. */ - if (length == 0xFFFF || length == 0 || - (pointer + length) >= hw->eeprom.word_size) - continue; - - for (j = pointer+1; j <= pointer+length; j++) { - if (hw->eeprom.ops.read(hw, j, &word) != 0) { - hw_dbg(hw, "EEPROM read failed\n"); - break; - } - checksum += word; - } - } - - checksum = (u16)IXGBE_EEPROM_SUM - checksum; - - return checksum; -} - -/** - * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash - * @hw: pointer to hardware structure - * - * After writing EEPROM to shadow RAM using EEWR register, software calculates - * checksum and updates the EEPROM and instructs the hardware to update - * the flash. - **/ -static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw) -{ - s32 status; - - status = ixgbe_update_eeprom_checksum_generic(hw); - - if (status) - status = ixgbe_update_flash_X540(hw); - - return status; -} - -/** - * ixgbe_update_flash_X540 - Instruct HW to copy EEPROM to Flash device - * @hw: pointer to hardware structure - * - * Set FLUP (bit 23) of the EEC register to instruct Hardware to copy - * EEPROM from shadow RAM to the flash device. - **/ -static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw) -{ - u32 flup; - s32 status = IXGBE_ERR_EEPROM; - - status = ixgbe_poll_flash_update_done_X540(hw); - if (status == IXGBE_ERR_EEPROM) { - hw_dbg(hw, "Flash update time out\n"); - goto out; - } - - flup = IXGBE_READ_REG(hw, IXGBE_EEC) | IXGBE_EEC_FLUP; - IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); - - status = ixgbe_poll_flash_update_done_X540(hw); - if (status) - hw_dbg(hw, "Flash update complete\n"); - else - hw_dbg(hw, "Flash update time out\n"); - - if (hw->revision_id == 0) { - flup = IXGBE_READ_REG(hw, IXGBE_EEC); - - if (flup & IXGBE_EEC_SEC1VAL) { - flup |= IXGBE_EEC_FLUP; - IXGBE_WRITE_REG(hw, IXGBE_EEC, flup); - } - - status = ixgbe_poll_flash_update_done_X540(hw); - if (status) - hw_dbg(hw, "Flash update complete\n"); - else - hw_dbg(hw, "Flash update time out\n"); - - } -out: - return status; -} - -/** - * ixgbe_poll_flash_update_done_X540 - Poll flash update status - * @hw: pointer to hardware structure - * - * Polls the FLUDONE (bit 26) of the EEC Register to determine when the - * flash update is done. - **/ -static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) -{ - u32 i; - u32 reg; - s32 status = IXGBE_ERR_EEPROM; - - for (i = 0; i < IXGBE_FLUDONE_ATTEMPTS; i++) { - reg = IXGBE_READ_REG(hw, IXGBE_EEC); - if (reg & IXGBE_EEC_FLUDONE) { - status = 0; - break; - } - udelay(5); - } - return status; -} - -/** - * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore - * @hw: pointer to hardware structure - * @mask: Mask to specify which semaphore to acquire - * - * Acquires the SWFW semaphore thought the SW_FW_SYNC register for - * the specified function (CSR, PHY0, PHY1, NVM, Flash) - **/ -static s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) -{ - u32 swfw_sync; - u32 swmask = mask; - u32 fwmask = mask << 5; - u32 hwmask = 0; - u32 timeout = 200; - u32 i; - - if (swmask == IXGBE_GSSR_EEP_SM) - hwmask = IXGBE_GSSR_FLASH_SM; - - for (i = 0; i < timeout; i++) { - /* - * SW NVM semaphore bit is used for access to all - * SW_FW_SYNC bits (not just NVM) - */ - if (ixgbe_get_swfw_sync_semaphore(hw)) - return IXGBE_ERR_SWFW_SYNC; - - swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); - if (!(swfw_sync & (fwmask | swmask | hwmask))) { - swfw_sync |= swmask; - IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); - ixgbe_release_swfw_sync_semaphore(hw); - break; - } else { - /* - * Firmware currently using resource (fwmask), - * hardware currently using resource (hwmask), - * or other software thread currently using - * resource (swmask) - */ - ixgbe_release_swfw_sync_semaphore(hw); - msleep(5); - } - } - - /* - * If the resource is not released by the FW/HW the SW can assume that - * the FW/HW malfunctions. In that case the SW should sets the - * SW bit(s) of the requested resource(s) while ignoring the - * corresponding FW/HW bits in the SW_FW_SYNC register. - */ - if (i >= timeout) { - swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); - if (swfw_sync & (fwmask | hwmask)) { - if (ixgbe_get_swfw_sync_semaphore(hw)) - return IXGBE_ERR_SWFW_SYNC; - - swfw_sync |= swmask; - IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); - ixgbe_release_swfw_sync_semaphore(hw); - } - } - - msleep(5); - return 0; -} - -/** - * ixgbe_release_swfw_sync_X540 - Release SWFW semaphore - * @hw: pointer to hardware structure - * @mask: Mask to specify which semaphore to release - * - * Releases the SWFW semaphore throught the SW_FW_SYNC register - * for the specified function (CSR, PHY0, PHY1, EVM, Flash) - **/ -static void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) -{ - u32 swfw_sync; - u32 swmask = mask; - - ixgbe_get_swfw_sync_semaphore(hw); - - swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); - swfw_sync &= ~swmask; - IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); - - ixgbe_release_swfw_sync_semaphore(hw); - msleep(5); -} - -/** - * ixgbe_get_nvm_semaphore - Get hardware semaphore - * @hw: pointer to hardware structure - * - * Sets the hardware semaphores so SW/FW can gain control of shared resources - **/ -static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw) -{ - s32 status = IXGBE_ERR_EEPROM; - u32 timeout = 2000; - u32 i; - u32 swsm; - - /* Get SMBI software semaphore between device drivers first */ - for (i = 0; i < timeout; i++) { - /* - * If the SMBI bit is 0 when we read it, then the bit will be - * set and we have the semaphore - */ - swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); - if (!(swsm & IXGBE_SWSM_SMBI)) { - status = 0; - break; - } - udelay(50); - } - - /* Now get the semaphore between SW/FW through the REGSMP bit */ - if (status) { - for (i = 0; i < timeout; i++) { - swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); - if (!(swsm & IXGBE_SWFW_REGSMP)) - break; - - udelay(50); - } - } else { - hw_dbg(hw, "Software semaphore SMBI between device drivers " - "not granted.\n"); - } - - return status; -} - -/** - * ixgbe_release_nvm_semaphore - Release hardware semaphore - * @hw: pointer to hardware structure - * - * This function clears hardware semaphore bits. - **/ -static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) -{ - u32 swsm; - - /* Release both semaphores by writing 0 to the bits REGSMP and SMBI */ - - swsm = IXGBE_READ_REG(hw, IXGBE_SWSM); - swsm &= ~IXGBE_SWSM_SMBI; - IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); - - swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); - swsm &= ~IXGBE_SWFW_REGSMP; - IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm); - - IXGBE_WRITE_FLUSH(hw); -} - -static struct ixgbe_mac_operations mac_ops_X540 = { - .init_hw = &ixgbe_init_hw_generic, - .reset_hw = &ixgbe_reset_hw_X540, - .start_hw = &ixgbe_start_hw_generic, - .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic, - .get_media_type = &ixgbe_get_media_type_X540, - .get_supported_physical_layer = - &ixgbe_get_supported_physical_layer_X540, - .enable_rx_dma = &ixgbe_enable_rx_dma_generic, - .get_mac_addr = &ixgbe_get_mac_addr_generic, - .get_san_mac_addr = &ixgbe_get_san_mac_addr_generic, - .get_device_caps = NULL, - .get_wwn_prefix = &ixgbe_get_wwn_prefix_generic, - .stop_adapter = &ixgbe_stop_adapter_generic, - .get_bus_info = &ixgbe_get_bus_info_generic, - .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie, - .read_analog_reg8 = NULL, - .write_analog_reg8 = NULL, - .setup_link = &ixgbe_setup_mac_link_X540, - .check_link = &ixgbe_check_mac_link_generic, - .get_link_capabilities = &ixgbe_get_copper_link_capabilities_generic, - .led_on = &ixgbe_led_on_generic, - .led_off = &ixgbe_led_off_generic, - .blink_led_start = &ixgbe_blink_led_start_generic, - .blink_led_stop = &ixgbe_blink_led_stop_generic, - .set_rar = &ixgbe_set_rar_generic, - .clear_rar = &ixgbe_clear_rar_generic, - .set_vmdq = &ixgbe_set_vmdq_generic, - .clear_vmdq = &ixgbe_clear_vmdq_generic, - .init_rx_addrs = &ixgbe_init_rx_addrs_generic, - .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic, - .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, - .enable_mc = &ixgbe_enable_mc_generic, - .disable_mc = &ixgbe_disable_mc_generic, - .clear_vfta = &ixgbe_clear_vfta_generic, - .set_vfta = &ixgbe_set_vfta_generic, - .fc_enable = &ixgbe_fc_enable_generic, - .init_uta_tables = &ixgbe_init_uta_tables_generic, - .setup_sfp = NULL, -}; - -static struct ixgbe_eeprom_operations eeprom_ops_X540 = { - .init_params = &ixgbe_init_eeprom_params_X540, - .read = &ixgbe_read_eerd_X540, - .write = &ixgbe_write_eewr_X540, - .calc_checksum = &ixgbe_calc_eeprom_checksum_X540, - .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, - .update_checksum = &ixgbe_update_eeprom_checksum_X540, -}; - -static struct ixgbe_phy_operations phy_ops_X540 = { - .identify = &ixgbe_identify_phy_generic, - .identify_sfp = &ixgbe_identify_sfp_module_generic, - .init = NULL, - .reset = &ixgbe_reset_phy_generic, - .read_reg = &ixgbe_read_phy_reg_generic, - .write_reg = &ixgbe_write_phy_reg_generic, - .setup_link = &ixgbe_setup_phy_link_generic, - .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, - .read_i2c_byte = &ixgbe_read_i2c_byte_generic, - .write_i2c_byte = &ixgbe_write_i2c_byte_generic, - .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic, - .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, - .check_overtemp = &ixgbe_tn_check_overtemp, -}; - -struct ixgbe_info ixgbe_X540_info = { - .mac = ixgbe_mac_X540, - .get_invariants = &ixgbe_get_invariants_X540, - .mac_ops = &mac_ops_X540, - .eeprom_ops = &eeprom_ops_X540, - .phy_ops = &phy_ops_X540, - .mbx_ops = &mbx_ops_generic, -}; diff --git a/trunk/drivers/net/ixgbevf/Makefile b/trunk/drivers/net/ixgbevf/Makefile index 1f35d229e71a..dd4e0d27e8cc 100644 --- a/trunk/drivers/net/ixgbevf/Makefile +++ b/trunk/drivers/net/ixgbevf/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel 82599 Virtual Function driver -# Copyright(c) 1999 - 2010 Intel Corporation. +# Copyright(c) 1999 - 2009 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ixgbevf/defines.h b/trunk/drivers/net/ixgbevf/defines.h index f8a807d606c7..ca2c81f49a05 100644 --- a/trunk/drivers/net/ixgbevf/defines.h +++ b/trunk/drivers/net/ixgbevf/defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ixgbevf/ixgbevf.h b/trunk/drivers/net/ixgbevf/ixgbevf.h index 0cd6abcf9306..da4033c6efa2 100644 --- a/trunk/drivers/net/ixgbevf/ixgbevf.h +++ b/trunk/drivers/net/ixgbevf/ixgbevf.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ixgbevf/ixgbevf_main.c index 2216a3c8b12b..dc03c9652389 100644 --- a/trunk/drivers/net/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ixgbevf/ixgbevf_main.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -51,10 +51,9 @@ char ixgbevf_driver_name[] = "ixgbevf"; static const char ixgbevf_driver_string[] = "Intel(R) 82599 Virtual Function"; -#define DRV_VERSION "1.0.12-k0" +#define DRV_VERSION "1.0.0-k0" const char ixgbevf_driver_version[] = DRV_VERSION; -static char ixgbevf_copyright[] = - "Copyright (c) 2009 - 2010 Intel Corporation."; +static char ixgbevf_copyright[] = "Copyright (c) 2009 Intel Corporation."; static const struct ixgbevf_info *ixgbevf_info_tbl[] = { [board_82599_vf] = &ixgbevf_vf_info, @@ -2489,9 +2488,10 @@ int ixgbevf_setup_tx_resources(struct ixgbevf_adapter *adapter, int size; size = sizeof(struct ixgbevf_tx_buffer) * tx_ring->count; - tx_ring->tx_buffer_info = vzalloc(size); + tx_ring->tx_buffer_info = vmalloc(size); if (!tx_ring->tx_buffer_info) goto err; + memset(tx_ring->tx_buffer_info, 0, size); /* round up to nearest 4K */ tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc); @@ -2555,13 +2555,14 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter, int size; size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count; - rx_ring->rx_buffer_info = vzalloc(size); + rx_ring->rx_buffer_info = vmalloc(size); if (!rx_ring->rx_buffer_info) { hw_dbg(&adapter->hw, "Unable to vmalloc buffer memory for " "the receive descriptor ring\n"); goto alloc_failed; } + memset(rx_ring->rx_buffer_info, 0, size); /* Round up to nearest 4K */ rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); @@ -3423,6 +3424,10 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, if (hw->mac.ops.get_bus_info) hw->mac.ops.get_bus_info(hw); + + netif_carrier_off(netdev); + netif_tx_stop_all_queues(netdev); + strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); @@ -3431,8 +3436,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, adapter->netdev_registered = true; - netif_carrier_off(netdev); - ixgbevf_init_last_counter_stats(adapter); /* print the MAC address */ diff --git a/trunk/drivers/net/ixgbevf/mbx.c b/trunk/drivers/net/ixgbevf/mbx.c index 7a8833125770..84ac486f4a65 100644 --- a/trunk/drivers/net/ixgbevf/mbx.c +++ b/trunk/drivers/net/ixgbevf/mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ixgbevf/mbx.h b/trunk/drivers/net/ixgbevf/mbx.h index b2b5bf5daa3d..8c063bebee7f 100644 --- a/trunk/drivers/net/ixgbevf/mbx.h +++ b/trunk/drivers/net/ixgbevf/mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ixgbevf/regs.h b/trunk/drivers/net/ixgbevf/regs.h index fb80ca1bcc93..12f75960aec1 100644 --- a/trunk/drivers/net/ixgbevf/regs.h +++ b/trunk/drivers/net/ixgbevf/regs.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ixgbevf/vf.c b/trunk/drivers/net/ixgbevf/vf.c index 971019d819b4..bfe42c1fcfaf 100644 --- a/trunk/drivers/net/ixgbevf/vf.c +++ b/trunk/drivers/net/ixgbevf/vf.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/ixgbevf/vf.h b/trunk/drivers/net/ixgbevf/vf.h index 144c99d5363a..61f9dc831424 100644 --- a/trunk/drivers/net/ixgbevf/vf.h +++ b/trunk/drivers/net/ixgbevf/vf.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 82599 Virtual Function driver - Copyright(c) 1999 - 2010 Intel Corporation. + Copyright(c) 1999 - 2009 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/trunk/drivers/net/jme.c b/trunk/drivers/net/jme.c index c57d9a43ceca..d85edf3119c2 100644 --- a/trunk/drivers/net/jme.c +++ b/trunk/drivers/net/jme.c @@ -2955,7 +2955,11 @@ jme_init_one(struct pci_dev *pdev, * Tell stack that we are not ready to work until open() */ netif_carrier_off(netdev); + netif_stop_queue(netdev); + /* + * Register netdev + */ rc = register_netdev(netdev); if (rc) { pr_err("Cannot register net device\n"); diff --git a/trunk/drivers/net/ks8851.c b/trunk/drivers/net/ks8851.c index 0fa4a9887ba2..51919fcd50c2 100644 --- a/trunk/drivers/net/ks8851.c +++ b/trunk/drivers/net/ks8851.c @@ -1545,37 +1545,6 @@ static int ks8851_read_selftest(struct ks8851_net *ks) /* driver bus management functions */ -#ifdef CONFIG_PM -static int ks8851_suspend(struct spi_device *spi, pm_message_t state) -{ - struct ks8851_net *ks = dev_get_drvdata(&spi->dev); - struct net_device *dev = ks->netdev; - - if (netif_running(dev)) { - netif_device_detach(dev); - ks8851_net_stop(dev); - } - - return 0; -} - -static int ks8851_resume(struct spi_device *spi) -{ - struct ks8851_net *ks = dev_get_drvdata(&spi->dev); - struct net_device *dev = ks->netdev; - - if (netif_running(dev)) { - ks8851_net_open(dev); - netif_device_attach(dev); - } - - return 0; -} -#else -#define ks8851_suspend NULL -#define ks8851_resume NULL -#endif - static int __devinit ks8851_probe(struct spi_device *spi) { struct net_device *ndev; @@ -1710,8 +1679,6 @@ static struct spi_driver ks8851_driver = { }, .probe = ks8851_probe, .remove = __devexit_p(ks8851_remove), - .suspend = ks8851_suspend, - .resume = ks8851_resume, }; static int __init ks8851_init(void) diff --git a/trunk/drivers/net/lance.c b/trunk/drivers/net/lance.c index 02336edce748..f06296bfe293 100644 --- a/trunk/drivers/net/lance.c +++ b/trunk/drivers/net/lance.c @@ -207,7 +207,7 @@ tx_full and tbusy flags. #define LANCE_BUS_IF 0x16 #define LANCE_TOTAL_SIZE 0x18 -#define TX_TIMEOUT (HZ/5) +#define TX_TIMEOUT 20 /* The LANCE Rx and Tx ring descriptors. */ struct lance_rx_head { diff --git a/trunk/drivers/net/lib82596.c b/trunk/drivers/net/lib82596.c index 9e042894479b..c27f4291b350 100644 --- a/trunk/drivers/net/lib82596.c +++ b/trunk/drivers/net/lib82596.c @@ -161,7 +161,7 @@ enum commands { #define RX_SUSPEND 0x0030 #define RX_ABORT 0x0040 -#define TX_TIMEOUT (HZ/20) +#define TX_TIMEOUT 5 struct i596_reg { diff --git a/trunk/drivers/net/lib8390.c b/trunk/drivers/net/lib8390.c index da74db4a03d4..e7030ceb178b 100644 --- a/trunk/drivers/net/lib8390.c +++ b/trunk/drivers/net/lib8390.c @@ -203,7 +203,7 @@ static void __NS8390_init(struct net_device *dev, int startp); static int __ei_open(struct net_device *dev) { unsigned long flags; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); if (dev->watchdog_timeo <= 0) dev->watchdog_timeo = TX_TIMEOUT; @@ -231,7 +231,7 @@ static int __ei_open(struct net_device *dev) */ static int __ei_close(struct net_device *dev) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned long flags; /* @@ -256,7 +256,7 @@ static int __ei_close(struct net_device *dev) static void __ei_tx_timeout(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int txsr, isr, tickssofar = jiffies - dev_trans_start(dev); unsigned long flags; @@ -303,7 +303,7 @@ static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int send_length = skb->len, output_page; unsigned long flags; char buf[ETH_ZLEN]; @@ -592,7 +592,7 @@ static void ei_tx_err(struct net_device *dev) static void ei_tx_intr(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int status = ei_inb(e8390_base + EN0_TSR); ei_outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */ @@ -675,7 +675,7 @@ static void ei_tx_intr(struct net_device *dev) static void ei_receive(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned char rxing_page, this_frame, next_frame; unsigned short current_offset; int rx_pkt_count = 0; @@ -879,7 +879,7 @@ static void ei_rx_overrun(struct net_device *dev) static struct net_device_stats *__ei_get_stats(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned long flags; /* If the card is stopped, just return the present stats. */ @@ -927,7 +927,7 @@ static void do_set_multicast_list(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; int i; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev); if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { @@ -981,7 +981,7 @@ static void do_set_multicast_list(struct net_device *dev) static void __ei_set_multicast_list(struct net_device *dev) { unsigned long flags; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev); spin_lock_irqsave(&ei_local->page_lock, flags); do_set_multicast_list(dev); @@ -998,7 +998,7 @@ static void __ei_set_multicast_list(struct net_device *dev) static void ethdev_setup(struct net_device *dev) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); if (ei_debug > 1) printk(version); @@ -1036,7 +1036,7 @@ static struct net_device *____alloc_ei_netdev(int size) static void __NS8390_init(struct net_device *dev, int startp) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int i; int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0)) @@ -1099,7 +1099,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page) { unsigned long e8390_base = dev->base_addr; - struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); + struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev); ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); diff --git a/trunk/drivers/net/macvlan.c b/trunk/drivers/net/macvlan.c index 6ed577b065df..0fc9dc7f20db 100644 --- a/trunk/drivers/net/macvlan.c +++ b/trunk/drivers/net/macvlan.c @@ -38,7 +38,6 @@ struct macvlan_port { struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; struct list_head vlans; struct rcu_head rcu; - bool passthru; }; #define macvlan_port_get_rcu(dev) \ @@ -170,7 +169,6 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) macvlan_broadcast(skb, port, NULL, MACVLAN_MODE_PRIVATE | MACVLAN_MODE_VEPA | - MACVLAN_MODE_PASSTHRU| MACVLAN_MODE_BRIDGE); else if (src->mode == MACVLAN_MODE_VEPA) /* flood to everyone except source */ @@ -187,10 +185,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) return skb; } - if (port->passthru) - vlan = list_first_entry(&port->vlans, struct macvlan_dev, list); - else - vlan = macvlan_hash_lookup(port, eth->h_dest); + vlan = macvlan_hash_lookup(port, eth->h_dest); if (vlan == NULL) return skb; @@ -248,22 +243,18 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, struct net_device *dev) { + int i = skb_get_queue_mapping(skb); + struct netdev_queue *txq = netdev_get_tx_queue(dev, i); unsigned int len = skb->len; int ret; - const struct macvlan_dev *vlan = netdev_priv(dev); ret = macvlan_queue_xmit(skb, dev); if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { - struct macvlan_pcpu_stats *pcpu_stats; + txq->tx_packets++; + txq->tx_bytes += len; + } else + txq->tx_dropped++; - pcpu_stats = this_cpu_ptr(vlan->pcpu_stats); - u64_stats_update_begin(&pcpu_stats->syncp); - pcpu_stats->tx_packets++; - pcpu_stats->tx_bytes += len; - u64_stats_update_end(&pcpu_stats->syncp); - } else { - this_cpu_inc(vlan->pcpu_stats->tx_dropped); - } return ret; } EXPORT_SYMBOL_GPL(macvlan_start_xmit); @@ -293,11 +284,6 @@ static int macvlan_open(struct net_device *dev) struct net_device *lowerdev = vlan->lowerdev; int err; - if (vlan->port->passthru) { - dev_set_promiscuity(lowerdev, 1); - goto hash_add; - } - err = -EBUSY; if (macvlan_addr_busy(vlan->port, dev->dev_addr)) goto out; @@ -310,8 +296,6 @@ static int macvlan_open(struct net_device *dev) if (err < 0) goto del_unicast; } - -hash_add: macvlan_hash_add(vlan); return 0; @@ -326,18 +310,12 @@ static int macvlan_stop(struct net_device *dev) struct macvlan_dev *vlan = netdev_priv(dev); struct net_device *lowerdev = vlan->lowerdev; - if (vlan->port->passthru) { - dev_set_promiscuity(lowerdev, -1); - goto hash_del; - } - dev_mc_unsync(lowerdev, dev); if (dev->flags & IFF_ALLMULTI) dev_set_allmulti(lowerdev, -1); dev_uc_del(lowerdev, dev->dev_addr); -hash_del: macvlan_hash_del(vlan); return 0; } @@ -436,15 +414,14 @@ static int macvlan_init(struct net_device *dev) dev->state = (dev->state & ~MACVLAN_STATE_MASK) | (lowerdev->state & MACVLAN_STATE_MASK); dev->features = lowerdev->features & MACVLAN_FEATURES; - dev->features |= NETIF_F_LLTX; dev->gso_max_size = lowerdev->gso_max_size; dev->iflink = lowerdev->ifindex; dev->hard_header_len = lowerdev->hard_header_len; macvlan_set_lockdep_class(dev); - vlan->pcpu_stats = alloc_percpu(struct macvlan_pcpu_stats); - if (!vlan->pcpu_stats) + vlan->rx_stats = alloc_percpu(struct macvlan_rx_stats); + if (!vlan->rx_stats) return -ENOMEM; return 0; @@ -454,7 +431,7 @@ static void macvlan_uninit(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); - free_percpu(vlan->pcpu_stats); + free_percpu(vlan->rx_stats); } static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, @@ -462,38 +439,33 @@ static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, { struct macvlan_dev *vlan = netdev_priv(dev); - if (vlan->pcpu_stats) { - struct macvlan_pcpu_stats *p; - u64 rx_packets, rx_bytes, rx_multicast, tx_packets, tx_bytes; - u32 rx_errors = 0, tx_dropped = 0; + dev_txq_stats_fold(dev, stats); + + if (vlan->rx_stats) { + struct macvlan_rx_stats *p, accum = {0}; + u64 rx_packets, rx_bytes, rx_multicast; unsigned int start; int i; for_each_possible_cpu(i) { - p = per_cpu_ptr(vlan->pcpu_stats, i); + p = per_cpu_ptr(vlan->rx_stats, i); do { start = u64_stats_fetch_begin_bh(&p->syncp); rx_packets = p->rx_packets; rx_bytes = p->rx_bytes; rx_multicast = p->rx_multicast; - tx_packets = p->tx_packets; - tx_bytes = p->tx_bytes; } while (u64_stats_fetch_retry_bh(&p->syncp, start)); - - stats->rx_packets += rx_packets; - stats->rx_bytes += rx_bytes; - stats->multicast += rx_multicast; - stats->tx_packets += tx_packets; - stats->tx_bytes += tx_bytes; - /* rx_errors & tx_dropped are u32, updated - * without syncp protection. - */ - rx_errors += p->rx_errors; - tx_dropped += p->tx_dropped; + accum.rx_packets += rx_packets; + accum.rx_bytes += rx_bytes; + accum.rx_multicast += rx_multicast; + /* rx_errors is an ulong, updated without syncp protection */ + accum.rx_errors += p->rx_errors; } - stats->rx_errors = rx_errors; - stats->rx_dropped = rx_errors; - stats->tx_dropped = tx_dropped; + stats->rx_packets = accum.rx_packets; + stats->rx_bytes = accum.rx_bytes; + stats->rx_errors = accum.rx_errors; + stats->rx_dropped = accum.rx_errors; + stats->multicast = accum.rx_multicast; } return stats; } @@ -577,7 +549,6 @@ static int macvlan_port_create(struct net_device *dev) if (port == NULL) return -ENOMEM; - port->passthru = false; port->dev = dev; INIT_LIST_HEAD(&port->vlans); for (i = 0; i < MACVLAN_HASH_SIZE; i++) @@ -622,7 +593,6 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) case MACVLAN_MODE_PRIVATE: case MACVLAN_MODE_VEPA: case MACVLAN_MODE_BRIDGE: - case MACVLAN_MODE_PASSTHRU: break; default: return -EINVAL; @@ -631,6 +601,25 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) return 0; } +static int macvlan_get_tx_queues(struct net *net, + struct nlattr *tb[], + unsigned int *num_tx_queues, + unsigned int *real_num_tx_queues) +{ + struct net_device *real_dev; + + if (!tb[IFLA_LINK]) + return -EINVAL; + + real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); + if (!real_dev) + return -ENODEV; + + *num_tx_queues = real_dev->num_tx_queues; + *real_num_tx_queues = real_dev->real_num_tx_queues; + return 0; +} + int macvlan_common_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], int (*receive)(struct sk_buff *skb), @@ -672,10 +661,6 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, } port = macvlan_port_get(lowerdev); - /* Only 1 macvlan device can be created in passthru mode */ - if (port->passthru) - return -EINVAL; - vlan->lowerdev = lowerdev; vlan->dev = dev; vlan->port = port; @@ -686,13 +671,6 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, if (data && data[IFLA_MACVLAN_MODE]) vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); - if (vlan->mode == MACVLAN_MODE_PASSTHRU) { - if (!list_empty(&port->vlans)) - return -EINVAL; - port->passthru = true; - memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN); - } - err = register_netdevice(dev); if (err < 0) goto destroy_port; @@ -765,6 +743,7 @@ int macvlan_link_register(struct rtnl_link_ops *ops) { /* common fields */ ops->priv_size = sizeof(struct macvlan_dev); + ops->get_tx_queues = macvlan_get_tx_queues; ops->validate = macvlan_validate; ops->maxtype = IFLA_MACVLAN_MAX; ops->policy = macvlan_policy; diff --git a/trunk/drivers/net/ne-h8300.c b/trunk/drivers/net/ne-h8300.c index 30be8c634ebd..e0b0ef11f110 100644 --- a/trunk/drivers/net/ne-h8300.c +++ b/trunk/drivers/net/ne-h8300.c @@ -86,7 +86,7 @@ static u32 reg_offset[16]; static int __init init_reg_offset(struct net_device *dev,unsigned long base_addr) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int i; unsigned char bus_width; @@ -218,7 +218,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) int start_page, stop_page; int reg0, ret; static unsigned version_printed; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned char bus_width; if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) @@ -371,7 +371,7 @@ static int ne_close(struct net_device *dev) static void ne_reset_8390(struct net_device *dev) { unsigned long reset_start_time = jiffies; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); if (ei_debug > 1) printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies); @@ -397,7 +397,7 @@ static void ne_reset_8390(struct net_device *dev) static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); /* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_status.dmaing) @@ -437,7 +437,7 @@ static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, i static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); #ifdef NE_SANITY_CHECK int xfer_count = count; #endif @@ -507,7 +507,7 @@ static void ne_block_input(struct net_device *dev, int count, struct sk_buff *sk static void ne_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page) { - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned long dma_start; #ifdef NE_SANITY_CHECK int retries = 0; diff --git a/trunk/drivers/net/netxen/netxen_nic_init.c b/trunk/drivers/net/netxen/netxen_nic_init.c index 731077d8d962..95fe552aa279 100644 --- a/trunk/drivers/net/netxen/netxen_nic_init.c +++ b/trunk/drivers/net/netxen/netxen_nic_init.c @@ -214,12 +214,13 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) tx_ring->num_desc = adapter->num_txd; tx_ring->txq = netdev_get_tx_queue(netdev, 0); - cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); + cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); if (cmd_buf_arr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n", netdev->name); goto err_out; } + memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); tx_ring->cmd_buf_arr = cmd_buf_arr; recv_ctx = &adapter->recv_ctx; @@ -278,7 +279,8 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) break; } - rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); + rds_ring->rx_buf_arr = (struct netxen_rx_buffer *) + vmalloc(RCV_BUFF_RINGSIZE(rds_ring)); if (rds_ring->rx_buf_arr == NULL) { printk(KERN_ERR "%s: Failed to allocate " "rx buffer ring %d\n", @@ -286,6 +288,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) /* free whatever was already allocated */ goto err_out; } + memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring)); INIT_LIST_HEAD(&rds_ring->free_list); /* * Now go through all of them, set reference handles diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index ceeaac989df2..a75ba9517404 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -41,6 +41,9 @@ MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); +MODULE_FIRMWARE(NX_P2_MN_ROMIMAGE_NAME); +MODULE_FIRMWARE(NX_P3_CT_ROMIMAGE_NAME); +MODULE_FIRMWARE(NX_P3_MN_ROMIMAGE_NAME); MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); char netxen_nic_driver_name[] = "netxen_nic"; @@ -1277,7 +1280,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int i = 0, err; int pci_func_id = PCI_FUNC(pdev->devfn); uint8_t revision_id; - u32 val; if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) { pr_warning("%s: chip revisions between 0x%x-0x%x " @@ -1353,9 +1355,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - if (adapter->portnum == 0) { - val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT); - if (val != 0xffffffff && val != 0) { + if (reset_devices) { + if (adapter->portnum == 0) { NXWR32(adapter, NX_CRB_DEV_REF_COUNT, 0); adapter->need_fw_reset = 1; } diff --git a/trunk/drivers/net/pch_gbe/pch_gbe_main.c b/trunk/drivers/net/pch_gbe/pch_gbe_main.c index afb75066b14d..472056b47440 100644 --- a/trunk/drivers/net/pch_gbe/pch_gbe_main.c +++ b/trunk/drivers/net/pch_gbe/pch_gbe_main.c @@ -1523,11 +1523,12 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, int desNo; size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count; - tx_ring->buffer_info = vzalloc(size); + tx_ring->buffer_info = vmalloc(size); if (!tx_ring->buffer_info) { pr_err("Unable to allocate memory for the buffer infomation\n"); return -ENOMEM; } + memset(tx_ring->buffer_info, 0, size); tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc); @@ -1572,11 +1573,12 @@ int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, int desNo; size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count; - rx_ring->buffer_info = vzalloc(size); + rx_ring->buffer_info = vmalloc(size); if (!rx_ring->buffer_info) { pr_err("Unable to allocate memory for the receive descriptor ring\n"); return -ENOMEM; } + memset(rx_ring->buffer_info, 0, size); rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc); rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index 1a0eb128e607..d2e166e29dda 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -111,14 +111,13 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id); typedef struct axnet_dev_t { struct pcmcia_device *p_dev; - caddr_t base; - struct timer_list watchdog; - int stale, fast_poll; - u_short link_status; - u_char duplex_flag; - int phy_id; - int flags; - int active_low; + caddr_t base; + struct timer_list watchdog; + int stale, fast_poll; + u_short link_status; + u_char duplex_flag; + int phy_id; + int flags; } axnet_dev_t; static inline axnet_dev_t *PRIV(struct net_device *dev) @@ -323,8 +322,6 @@ static int axnet_config(struct pcmcia_device *link) if (info->flags & IS_AX88790) outb(0x10, dev->base_addr + AXNET_GPIO); /* select Internal PHY */ - info->active_low = 0; - for (i = 0; i < 32; i++) { j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2); @@ -332,18 +329,15 @@ static int axnet_config(struct pcmcia_device *link) if ((j != 0) && (j != 0xffff)) break; } + /* Maybe PHY is in power down mode. (PPD_SET = 1) + Bit 2 of CCSR is active low. */ if (i == 32) { - /* Maybe PHY is in power down mode. (PPD_SET = 1) - Bit 2 of CCSR is active low. */ pcmcia_write_config_byte(link, CISREG_CCSR, 0x04); for (i = 0; i < 32; i++) { j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2); if (j == j2) continue; - if ((j != 0) && (j != 0xffff)) { - info->active_low = 1; - break; - } + if ((j != 0) && (j != 0xffff)) break; } } @@ -389,12 +383,8 @@ static int axnet_suspend(struct pcmcia_device *link) static int axnet_resume(struct pcmcia_device *link) { struct net_device *dev = link->priv; - axnet_dev_t *info = PRIV(dev); if (link->open) { - if (info->active_low == 1) - pcmcia_write_config_byte(link, CISREG_CCSR, 0x04); - axnet_reset_8390(dev); AX88190_init(dev, 1); netif_device_attach(dev); @@ -875,7 +865,7 @@ static void do_set_multicast_list(struct net_device *dev); static int ax_open(struct net_device *dev) { unsigned long flags; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); /* * Grab the page lock so we own the register set, then call @@ -926,7 +916,7 @@ static int ax_close(struct net_device *dev) static void axnet_tx_timeout(struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int txsr, isr, tickssofar = jiffies - dev_trans_start(dev); unsigned long flags; @@ -973,7 +963,7 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int length, send_length, output_page; unsigned long flags; u8 packet[ETH_ZLEN]; @@ -1270,7 +1260,7 @@ static void ei_tx_err(struct net_device *dev) static void ei_tx_intr(struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int status = inb(e8390_base + EN0_TSR); /* @@ -1354,7 +1344,7 @@ static void ei_tx_intr(struct net_device *dev) static void ei_receive(struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned char rxing_page, this_frame, next_frame; unsigned short current_offset; int rx_pkt_count = 0; @@ -1539,7 +1529,7 @@ static void ei_rx_overrun(struct net_device *dev) static struct net_device_stats *get_stats(struct net_device *dev) { long ioaddr = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned long flags; /* If the card is stopped, just return the present stats. */ @@ -1588,7 +1578,7 @@ static void do_set_multicast_list(struct net_device *dev) { long e8390_base = dev->base_addr; int i; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev); if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { memset(ei_local->mcfilter, 0, 8); @@ -1646,7 +1636,7 @@ static void AX88190_init(struct net_device *dev, int startp) { axnet_dev_t *info = PRIV(dev); long e8390_base = dev->base_addr; - struct ei_device *ei_local = netdev_priv(dev); + struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int i; int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48; @@ -1712,7 +1702,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, int start_page) { long e8390_base = dev->base_addr; - struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); + struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev); if (inb_p(e8390_base) & E8390_TRANS) { diff --git a/trunk/drivers/net/phy/phy.c b/trunk/drivers/net/phy/phy.c index a8445c72fc13..7670aac0e93f 100644 --- a/trunk/drivers/net/phy/phy.c +++ b/trunk/drivers/net/phy/phy.c @@ -47,11 +47,11 @@ void phy_print_status(struct phy_device *phydev) pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev), phydev->link ? "Up" : "Down"); if (phydev->link) - printk(KERN_CONT " - %d/%s", phydev->speed, + printk(" - %d/%s", phydev->speed, DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); - printk(KERN_CONT "\n"); + printk("\n"); } EXPORT_SYMBOL(phy_print_status); diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index 0c91598ae280..09cf56d0416a 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -1136,7 +1136,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) a four-byte PPP header on each packet */ *skb_push(skb, 2) = 1; if (ppp->pass_filter && - sk_run_filter(skb, ppp->pass_filter) == 0) { + sk_run_filter(skb, ppp->pass_filter, + ppp->pass_len) == 0) { if (ppp->debug & 1) printk(KERN_DEBUG "PPP: outbound frame not passed\n"); kfree_skb(skb); @@ -1144,7 +1145,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) } /* if this packet passes the active filter, record the time */ if (!(ppp->active_filter && - sk_run_filter(skb, ppp->active_filter) == 0)) + sk_run_filter(skb, ppp->active_filter, + ppp->active_len) == 0)) ppp->last_xmit = jiffies; skb_pull(skb, 2); #else @@ -1756,7 +1758,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) *skb_push(skb, 2) = 0; if (ppp->pass_filter && - sk_run_filter(skb, ppp->pass_filter) == 0) { + sk_run_filter(skb, ppp->pass_filter, + ppp->pass_len) == 0) { if (ppp->debug & 1) printk(KERN_DEBUG "PPP: inbound frame " "not passed\n"); @@ -1764,7 +1767,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) return; } if (!(ppp->active_filter && - sk_run_filter(skb, ppp->active_filter) == 0)) + sk_run_filter(skb, ppp->active_filter, + ppp->active_len) == 0)) ppp->last_recv = jiffies; __skb_pull(skb, 2); } else diff --git a/trunk/drivers/net/pptp.c b/trunk/drivers/net/pptp.c index 7556a9224f72..ccbc91326bfa 100644 --- a/trunk/drivers/net/pptp.c +++ b/trunk/drivers/net/pptp.c @@ -673,7 +673,8 @@ static int __init pptp_init_module(void) int err = 0; pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n"); - callid_sock = vzalloc((MAX_CALLID + 1) * sizeof(void *)); + callid_sock = __vmalloc((MAX_CALLID + 1) * sizeof(void *), + GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); if (!callid_sock) { pr_err("PPTP: cann't allocate memory\n"); return -ENOMEM; diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c index 1a3584edd79c..7496ed2c34ab 100644 --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -2467,7 +2467,7 @@ static int ql_send_map(struct ql3_adapter *qdev, static netdev_tx_t ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) { - struct ql3_adapter *qdev = netdev_priv(ndev); + struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; struct ql_tx_buf_cb *tx_cb; @@ -3390,7 +3390,7 @@ static void ql_set_mac_info(struct ql3_adapter *qdev) static void ql_display_dev_info(struct net_device *ndev) { - struct ql3_adapter *qdev = netdev_priv(ndev); + struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); struct pci_dev *pdev = qdev->pdev; netdev_info(ndev, @@ -3573,7 +3573,7 @@ static int ql3xxx_open(struct net_device *ndev) static int ql3xxx_set_mac_address(struct net_device *ndev, void *p) { - struct ql3_adapter *qdev = netdev_priv(ndev); + struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; struct sockaddr *addr = p; @@ -3608,7 +3608,7 @@ static int ql3xxx_set_mac_address(struct net_device *ndev, void *p) static void ql3xxx_tx_timeout(struct net_device *ndev) { - struct ql3_adapter *qdev = netdev_priv(ndev); + struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); netdev_err(ndev, "Resetting...\n"); /* diff --git a/trunk/drivers/net/qlcnic/qlcnic.h b/trunk/drivers/net/qlcnic/qlcnic.h index 9513a83b9537..8ecc170c9b74 100644 --- a/trunk/drivers/net/qlcnic/qlcnic.h +++ b/trunk/drivers/net/qlcnic/qlcnic.h @@ -51,8 +51,8 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 12 -#define QLCNIC_LINUX_VERSIONID "5.0.12" +#define _QLCNIC_LINUX_SUBVERSION 11 +#define QLCNIC_LINUX_VERSIONID "5.0.11" #define QLCNIC_DRV_IDC_VER 0x01 #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) @@ -923,7 +923,6 @@ struct qlcnic_ipaddr { #define QLCNIC_MACSPOOF 0x200 #define QLCNIC_MAC_OVERRIDE_DISABLED 0x400 #define QLCNIC_PROMISC_DISABLED 0x800 -#define QLCNIC_NEED_FLR 0x1000 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) @@ -1127,7 +1126,8 @@ struct qlcnic_eswitch { /* Return codes for Error handling */ #define QL_STATUS_INVALID_PARAM -1 -#define MAX_BW 100 /* % of link speed */ +#define MAX_BW 100 +#define MIN_BW 1 #define MAX_VLAN_ID 4095 #define MIN_VLAN_ID 2 #define MAX_TX_QUEUES 1 @@ -1135,7 +1135,7 @@ struct qlcnic_eswitch { #define DEFAULT_MAC_LEARN 1 #define IS_VALID_VLAN(vlan) (vlan >= MIN_VLAN_ID && vlan < MAX_VLAN_ID) -#define IS_VALID_BW(bw) (bw <= MAX_BW) +#define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW) #define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) #define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) @@ -1377,8 +1377,6 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = { "3200 Series Single Port 10Gb Intelligent Ethernet Adapter"}, {0x1077, 0x8020, 0x103c, 0x3733, "NC523SFP 10Gb 2-port Server Adapter"}, - {0x1077, 0x8020, 0x103c, 0x3346, - "CN1000Q Dual Port Converged Network Adapter"}, {0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"}, }; diff --git a/trunk/drivers/net/qlcnic/qlcnic_ctx.c b/trunk/drivers/net/qlcnic/qlcnic_ctx.c index 29cbc2a6e79f..1cdc05dade6b 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_ctx.c +++ b/trunk/drivers/net/qlcnic/qlcnic_ctx.c @@ -480,11 +480,6 @@ int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter) { int err; - if (adapter->flags & QLCNIC_NEED_FLR) { - pci_reset_function(adapter->pdev); - adapter->flags &= ~QLCNIC_NEED_FLR; - } - err = qlcnic_fw_cmd_create_rx_ctx(adapter); if (err) return err; diff --git a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c index c38929636488..ec21d24015c4 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/trunk/drivers/net/qlcnic/qlcnic_ethtool.c @@ -925,10 +925,9 @@ static int qlcnic_set_rx_csum(struct net_device *dev, u32 data) dev->features &= ~NETIF_F_LRO; qlcnic_send_lro_cleanup(adapter); - dev_info(&adapter->pdev->dev, - "disabling LRO as rx_csum is off\n"); } adapter->rx_csum = !!data; + dev_info(&adapter->pdev->dev, "disabling LRO as rx_csum is off\n"); return 0; } diff --git a/trunk/drivers/net/qlcnic/qlcnic_hdr.h b/trunk/drivers/net/qlcnic/qlcnic_hdr.h index 566e0e8437e4..4290b80cde1a 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_hdr.h +++ b/trunk/drivers/net/qlcnic/qlcnic_hdr.h @@ -722,7 +722,7 @@ enum { #define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */ #define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */ -#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) & (1 << (FN * 4))) +#define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) #define QLC_DEV_CLR_REF_CNT(VAL, FN) ((VAL) &= ~(1 << (FN * 4))) #define QLC_DEV_SET_RST_RDY(VAL, FN) ((VAL) |= (1 << (FN * 4))) diff --git a/trunk/drivers/net/qlcnic/qlcnic_init.c b/trunk/drivers/net/qlcnic/qlcnic_init.c index c5ea2f4eb980..0d180c6e41fe 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_init.c +++ b/trunk/drivers/net/qlcnic/qlcnic_init.c @@ -236,11 +236,12 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) tx_ring->num_desc = adapter->num_txd; tx_ring->txq = netdev_get_tx_queue(netdev, 0); - cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring)); + cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); if (cmd_buf_arr == NULL) { dev_err(&netdev->dev, "failed to allocate cmd buffer ring\n"); goto err_out; } + memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); tx_ring->cmd_buf_arr = cmd_buf_arr; recv_ctx = &adapter->recv_ctx; @@ -274,12 +275,14 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) rds_ring->dma_size + NET_IP_ALIGN; break; } - rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); + rds_ring->rx_buf_arr = (struct qlcnic_rx_buffer *) + vmalloc(RCV_BUFF_RINGSIZE(rds_ring)); if (rds_ring->rx_buf_arr == NULL) { dev_err(&netdev->dev, "Failed to allocate " "rx buffer ring %d\n", ring); goto err_out; } + memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring)); INIT_LIST_HEAD(&rds_ring->free_list); /* * Now go through all of them, set reference handles diff --git a/trunk/drivers/net/qlcnic/qlcnic_main.c b/trunk/drivers/net/qlcnic/qlcnic_main.c index 899df5a81fda..7a298cdf9ab3 100644 --- a/trunk/drivers/net/qlcnic/qlcnic_main.c +++ b/trunk/drivers/net/qlcnic/qlcnic_main.c @@ -1450,6 +1450,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, netdev->irq = adapter->msix_entries[0].vector; netif_carrier_off(netdev); + netif_stop_queue(netdev); err = register_netdev(netdev); if (err) { @@ -1485,7 +1486,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) uint8_t revision_id; uint8_t pci_using_dac; char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; - u32 val; err = pci_enable_device(pdev); if (err) @@ -1547,10 +1547,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_out_iounmap; - val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); - if (QLC_DEV_CHECK_ACTIVE(val, adapter->portnum)) - adapter->flags |= QLCNIC_NEED_FLR; - err = adapter->nic_ops->start_firmware(adapter); if (err) { dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); diff --git a/trunk/drivers/net/qlge/qlge.h b/trunk/drivers/net/qlge/qlge.h index bdb8fe868539..22821398fc63 100644 --- a/trunk/drivers/net/qlge/qlge.h +++ b/trunk/drivers/net/qlge/qlge.h @@ -16,7 +16,7 @@ */ #define DRV_NAME "qlge" #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION "v1.00.00.27.00.00-01" +#define DRV_VERSION "v1.00.00.25.00.00-01" #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ @@ -2221,7 +2221,6 @@ int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data); int ql_unpause_mpi_risc(struct ql_adapter *qdev); int ql_pause_mpi_risc(struct ql_adapter *qdev); int ql_hard_reset_mpi_risc(struct ql_adapter *qdev); -int ql_soft_reset_mpi_risc(struct ql_adapter *qdev); int ql_dump_risc_ram_area(struct ql_adapter *qdev, void *buf, u32 ram_addr, int word_count); int ql_core_dump(struct ql_adapter *qdev, @@ -2237,7 +2236,6 @@ int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control); int ql_mb_get_port_cfg(struct ql_adapter *qdev); int ql_mb_set_port_cfg(struct ql_adapter *qdev); int ql_wait_fifo_empty(struct ql_adapter *qdev); -void ql_get_dump(struct ql_adapter *qdev, void *buff); void ql_gen_reg_dump(struct ql_adapter *qdev, struct ql_reg_dump *mpi_coredump); netdev_tx_t ql_lb_send(struct sk_buff *skb, struct net_device *ndev); diff --git a/trunk/drivers/net/qlge/qlge_dbg.c b/trunk/drivers/net/qlge/qlge_dbg.c index fca804f36d61..4747492935ef 100644 --- a/trunk/drivers/net/qlge/qlge_dbg.c +++ b/trunk/drivers/net/qlge/qlge_dbg.c @@ -1317,28 +1317,9 @@ void ql_gen_reg_dump(struct ql_adapter *qdev, status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]); if (status) return; -} - -void ql_get_dump(struct ql_adapter *qdev, void *buff) -{ - /* - * If the dump has already been taken and is stored - * in our internal buffer and if force dump is set then - * just start the spool to dump it to the log file - * and also, take a snapshot of the general regs to - * to the user's buffer or else take complete dump - * to the user's buffer if force is not set. - */ - if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) { - if (!ql_core_dump(qdev, buff)) - ql_soft_reset_mpi_risc(qdev); - else - netif_err(qdev, drv, qdev->ndev, "coredump failed!\n"); - } else { - ql_gen_reg_dump(qdev, buff); + if (test_bit(QL_FRC_COREDUMP, &qdev->flags)) ql_get_core_dump(qdev); - } } /* Coredump to messages log file using separate worker thread */ diff --git a/trunk/drivers/net/qlge/qlge_ethtool.c b/trunk/drivers/net/qlge/qlge_ethtool.c index 8149cc9de4ca..4892d64f4e05 100644 --- a/trunk/drivers/net/qlge/qlge_ethtool.c +++ b/trunk/drivers/net/qlge/qlge_ethtool.c @@ -375,10 +375,7 @@ static void ql_get_drvinfo(struct net_device *ndev, strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); drvinfo->n_stats = 0; drvinfo->testinfo_len = 0; - if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) - drvinfo->regdump_len = sizeof(struct ql_mpi_coredump); - else - drvinfo->regdump_len = sizeof(struct ql_reg_dump); + drvinfo->regdump_len = 0; drvinfo->eedump_len = 0; } @@ -550,12 +547,7 @@ static void ql_self_test(struct net_device *ndev, static int ql_get_regs_len(struct net_device *ndev) { - struct ql_adapter *qdev = netdev_priv(ndev); - - if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) - return sizeof(struct ql_mpi_coredump); - else - return sizeof(struct ql_reg_dump); + return sizeof(struct ql_reg_dump); } static void ql_get_regs(struct net_device *ndev, @@ -563,12 +555,7 @@ static void ql_get_regs(struct net_device *ndev, { struct ql_adapter *qdev = netdev_priv(ndev); - ql_get_dump(qdev, p); - qdev->core_is_dumped = 0; - if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) - regs->len = sizeof(struct ql_mpi_coredump); - else - regs->len = sizeof(struct ql_reg_dump); + ql_gen_reg_dump(qdev, p); } static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) diff --git a/trunk/drivers/net/qlge/qlge_main.c b/trunk/drivers/net/qlge/qlge_main.c index d9a76260880b..c30e0fe55a31 100644 --- a/trunk/drivers/net/qlge/qlge_main.c +++ b/trunk/drivers/net/qlge/qlge_main.c @@ -3844,7 +3844,7 @@ static int ql_adapter_reset(struct ql_adapter *qdev) static void ql_display_dev_info(struct net_device *ndev) { - struct ql_adapter *qdev = netdev_priv(ndev); + struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); netif_info(qdev, probe, qdev->ndev, "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, " @@ -4264,7 +4264,7 @@ static struct net_device_stats *qlge_get_stats(struct net_device static void qlge_set_multicast_list(struct net_device *ndev) { - struct ql_adapter *qdev = netdev_priv(ndev); + struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); struct netdev_hw_addr *ha; int i, status; @@ -4354,7 +4354,7 @@ static void qlge_set_multicast_list(struct net_device *ndev) static int qlge_set_mac_address(struct net_device *ndev, void *p) { - struct ql_adapter *qdev = netdev_priv(ndev); + struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); struct sockaddr *addr = p; int status; @@ -4377,7 +4377,7 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p) static void qlge_tx_timeout(struct net_device *ndev) { - struct ql_adapter *qdev = netdev_priv(ndev); + struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev); ql_queue_asic_error(qdev); } diff --git a/trunk/drivers/net/qlge/qlge_mpi.c b/trunk/drivers/net/qlge/qlge_mpi.c index 100a462cc916..0e7c7c7ee164 100644 --- a/trunk/drivers/net/qlge/qlge_mpi.c +++ b/trunk/drivers/net/qlge/qlge_mpi.c @@ -87,7 +87,7 @@ int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data) return status; } -int ql_soft_reset_mpi_risc(struct ql_adapter *qdev) +static int ql_soft_reset_mpi_risc(struct ql_adapter *qdev) { int status; status = ql_write_mpi_reg(qdev, 0x00001010, 1); diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 7d33ef4bcb4a..d88ce9fb1cbd 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -846,10 +846,10 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) else tp->features &= ~RTL_FEATURE_WOL; __rtl8169_set_wol(tp, wol->wolopts); - spin_unlock_irq(&tp->lock); - device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); + spin_unlock_irq(&tp->lock); + return 0; } @@ -2931,7 +2931,7 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8168, .region = 2, .align = 8, - .intr_event = SYSErr | LinkChg | RxOverflow | + .intr_event = SYSErr | RxFIFOOver | LinkChg | RxOverflow | TxErr | TxOK | RxOK | RxErr, .napi_event = TxErr | TxOK | RxOK | RxOverflow, .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, @@ -4440,7 +4440,8 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) u32 status = opts1 & RxProtoMask; if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || - ((status == RxProtoUDP) && !(opts1 & UDPFail))) + ((status == RxProtoUDP) && !(opts1 & UDPFail)) || + ((status == RxProtoIP) && !(opts1 & IPFail))) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb_checksum_none_assert(skb); @@ -4587,8 +4588,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) } /* Work around for rx fifo overflow */ - if (unlikely(status & RxFIFOOver) && - (tp->mac_version == RTL_GIGA_MAC_VER_11)) { + if (unlikely(status & RxFIFOOver)) { netif_stop_queue(dev); rtl8169_tx_timeout(dev); break; diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 0f4219cb0be2..ecc25aab896a 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -8321,7 +8321,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) static void __devexit s2io_rem_nic(struct pci_dev *pdev) { - struct net_device *dev = pci_get_drvdata(pdev); + struct net_device *dev = + (struct net_device *)pci_get_drvdata(pdev); struct s2io_nic *sp; if (dev == NULL) { diff --git a/trunk/drivers/net/sfc/filter.c b/trunk/drivers/net/sfc/filter.c index 44500b54fd5f..52cb6082b910 100644 --- a/trunk/drivers/net/sfc/filter.c +++ b/trunk/drivers/net/sfc/filter.c @@ -428,9 +428,10 @@ int efx_probe_filters(struct efx_nic *efx) GFP_KERNEL); if (!table->used_bitmap) goto fail; - table->spec = vzalloc(table->size * sizeof(*table->spec)); + table->spec = vmalloc(table->size * sizeof(*table->spec)); if (!table->spec) goto fail; + memset(table->spec, 0, table->size * sizeof(*table->spec)); } return 0; diff --git a/trunk/drivers/net/sh_eth.c b/trunk/drivers/net/sh_eth.c index b12660d72338..50259dfec583 100644 --- a/trunk/drivers/net/sh_eth.c +++ b/trunk/drivers/net/sh_eth.c @@ -45,9 +45,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -57,10 +57,10 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - writel(readl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR); break; case 100:/* 100BASE */ - writel(readl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR); break; default: break; @@ -96,9 +96,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -108,10 +108,10 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - writel(0, ioaddr + RTRATE); + ctrl_outl(0, ioaddr + RTRATE); break; case 100:/* 100BASE */ - writel(1, ioaddr + RTRATE); + ctrl_outl(1, ioaddr + RTRATE); break; default: break; @@ -143,7 +143,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { static void sh_eth_chip_reset(struct net_device *ndev) { /* reset device */ - writel(ARSTR_ARSTR, ARSTR); + ctrl_outl(ARSTR_ARSTR, ARSTR); mdelay(1); } @@ -152,10 +152,10 @@ static void sh_eth_reset(struct net_device *ndev) u32 ioaddr = ndev->base_addr; int cnt = 100; - writel(EDSR_ENALL, ioaddr + EDSR); - writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); + ctrl_outl(EDSR_ENALL, ioaddr + EDSR); + ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); while (cnt > 0) { - if (!(readl(ioaddr + EDMR) & 0x3)) + if (!(ctrl_inl(ioaddr + EDMR) & 0x3)) break; mdelay(1); cnt--; @@ -164,14 +164,14 @@ static void sh_eth_reset(struct net_device *ndev) printk(KERN_ERR "Device reset fail\n"); /* Table Init */ - writel(0x0, ioaddr + TDLAR); - writel(0x0, ioaddr + TDFAR); - writel(0x0, ioaddr + TDFXR); - writel(0x0, ioaddr + TDFFR); - writel(0x0, ioaddr + RDLAR); - writel(0x0, ioaddr + RDFAR); - writel(0x0, ioaddr + RDFXR); - writel(0x0, ioaddr + RDFFR); + ctrl_outl(0x0, ioaddr + TDLAR); + ctrl_outl(0x0, ioaddr + TDFAR); + ctrl_outl(0x0, ioaddr + TDFXR); + ctrl_outl(0x0, ioaddr + TDFFR); + ctrl_outl(0x0, ioaddr + RDLAR); + ctrl_outl(0x0, ioaddr + RDFAR); + ctrl_outl(0x0, ioaddr + RDFXR); + ctrl_outl(0x0, ioaddr + RDFFR); } static void sh_eth_set_duplex(struct net_device *ndev) @@ -180,9 +180,9 @@ static void sh_eth_set_duplex(struct net_device *ndev) u32 ioaddr = ndev->base_addr; if (mdp->duplex) /* Full */ - writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR); else /* Half */ - writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR); } static void sh_eth_set_rate(struct net_device *ndev) @@ -192,13 +192,13 @@ static void sh_eth_set_rate(struct net_device *ndev) switch (mdp->speed) { case 10: /* 10BASE */ - writel(GECMR_10, ioaddr + GECMR); + ctrl_outl(GECMR_10, ioaddr + GECMR); break; case 100:/* 100BASE */ - writel(GECMR_100, ioaddr + GECMR); + ctrl_outl(GECMR_100, ioaddr + GECMR); break; case 1000: /* 1000BASE */ - writel(GECMR_1000, ioaddr + GECMR); + ctrl_outl(GECMR_1000, ioaddr + GECMR); break; default: break; @@ -283,9 +283,9 @@ static void sh_eth_reset(struct net_device *ndev) { u32 ioaddr = ndev->base_addr; - writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); + ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); mdelay(3); - writel(readl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); + ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); } #endif @@ -336,10 +336,10 @@ static void update_mac_address(struct net_device *ndev) { u32 ioaddr = ndev->base_addr; - writel((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | + ctrl_outl((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), ioaddr + MAHR); - writel((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), + ctrl_outl((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), ioaddr + MALR); } @@ -358,12 +358,12 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac) if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) { memcpy(ndev->dev_addr, mac, 6); } else { - ndev->dev_addr[0] = (readl(ioaddr + MAHR) >> 24); - ndev->dev_addr[1] = (readl(ioaddr + MAHR) >> 16) & 0xFF; - ndev->dev_addr[2] = (readl(ioaddr + MAHR) >> 8) & 0xFF; - ndev->dev_addr[3] = (readl(ioaddr + MAHR) & 0xFF); - ndev->dev_addr[4] = (readl(ioaddr + MALR) >> 8) & 0xFF; - ndev->dev_addr[5] = (readl(ioaddr + MALR) & 0xFF); + ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24); + ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF; + ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF; + ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF); + ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF; + ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF); } } @@ -379,19 +379,19 @@ struct bb_info { /* PHY bit set */ static void bb_set(u32 addr, u32 msk) { - writel(readl(addr) | msk, addr); + ctrl_outl(ctrl_inl(addr) | msk, addr); } /* PHY bit clear */ static void bb_clr(u32 addr, u32 msk) { - writel((readl(addr) & ~msk), addr); + ctrl_outl((ctrl_inl(addr) & ~msk), addr); } /* PHY bit read */ static int bb_read(u32 addr, u32 msk) { - return (readl(addr) & msk) != 0; + return (ctrl_inl(addr) & msk) != 0; } /* Data I/O pin control */ @@ -506,9 +506,9 @@ static void sh_eth_ring_format(struct net_device *ndev) rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); /* Rx descriptor address set */ if (i == 0) { - writel(mdp->rx_desc_dma, ioaddr + RDLAR); + ctrl_outl(mdp->rx_desc_dma, ioaddr + RDLAR); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(mdp->rx_desc_dma, ioaddr + RDFAR); + ctrl_outl(mdp->rx_desc_dma, ioaddr + RDFAR); #endif } } @@ -528,9 +528,9 @@ static void sh_eth_ring_format(struct net_device *ndev) txdesc->buffer_length = 0; if (i == 0) { /* Tx descriptor address set */ - writel(mdp->tx_desc_dma, ioaddr + TDLAR); + ctrl_outl(mdp->tx_desc_dma, ioaddr + TDLAR); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(mdp->tx_desc_dma, ioaddr + TDFAR); + ctrl_outl(mdp->tx_desc_dma, ioaddr + TDFAR); #endif } } @@ -623,71 +623,71 @@ static int sh_eth_dev_init(struct net_device *ndev) /* Descriptor format */ sh_eth_ring_format(ndev); if (mdp->cd->rpadir) - writel(mdp->cd->rpadir_value, ioaddr + RPADIR); + ctrl_outl(mdp->cd->rpadir_value, ioaddr + RPADIR); /* all sh_eth int mask */ - writel(0, ioaddr + EESIPR); + ctrl_outl(0, ioaddr + EESIPR); #if defined(__LITTLE_ENDIAN__) if (mdp->cd->hw_swap) - writel(EDMR_EL, ioaddr + EDMR); + ctrl_outl(EDMR_EL, ioaddr + EDMR); else #endif - writel(0, ioaddr + EDMR); + ctrl_outl(0, ioaddr + EDMR); /* FIFO size set */ - writel(mdp->cd->fdr_value, ioaddr + FDR); - writel(0, ioaddr + TFTR); + ctrl_outl(mdp->cd->fdr_value, ioaddr + FDR); + ctrl_outl(0, ioaddr + TFTR); /* Frame recv control */ - writel(mdp->cd->rmcr_value, ioaddr + RMCR); + ctrl_outl(mdp->cd->rmcr_value, ioaddr + RMCR); rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; tx_int_var = mdp->tx_int_var = DESC_I_TINT2; - writel(rx_int_var | tx_int_var, ioaddr + TRSCER); + ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER); if (mdp->cd->bculr) - writel(0x800, ioaddr + BCULR); /* Burst sycle set */ + ctrl_outl(0x800, ioaddr + BCULR); /* Burst sycle set */ - writel(mdp->cd->fcftr_value, ioaddr + FCFTR); + ctrl_outl(mdp->cd->fcftr_value, ioaddr + FCFTR); if (!mdp->cd->no_trimd) - writel(0, ioaddr + TRIMD); + ctrl_outl(0, ioaddr + TRIMD); /* Recv frame limit set register */ - writel(RFLR_VALUE, ioaddr + RFLR); + ctrl_outl(RFLR_VALUE, ioaddr + RFLR); - writel(readl(ioaddr + EESR), ioaddr + EESR); - writel(mdp->cd->eesipr_value, ioaddr + EESIPR); + ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR); + ctrl_outl(mdp->cd->eesipr_value, ioaddr + EESIPR); /* PAUSE Prohibition */ - val = (readl(ioaddr + ECMR) & ECMR_DM) | + val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) | ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE; - writel(val, ioaddr + ECMR); + ctrl_outl(val, ioaddr + ECMR); if (mdp->cd->set_rate) mdp->cd->set_rate(ndev); /* E-MAC Status Register clear */ - writel(mdp->cd->ecsr_value, ioaddr + ECSR); + ctrl_outl(mdp->cd->ecsr_value, ioaddr + ECSR); /* E-MAC Interrupt Enable register */ - writel(mdp->cd->ecsipr_value, ioaddr + ECSIPR); + ctrl_outl(mdp->cd->ecsipr_value, ioaddr + ECSIPR); /* Set MAC address */ update_mac_address(ndev); /* mask reset */ if (mdp->cd->apr) - writel(APR_AP, ioaddr + APR); + ctrl_outl(APR_AP, ioaddr + APR); if (mdp->cd->mpr) - writel(MPR_MP, ioaddr + MPR); + ctrl_outl(MPR_MP, ioaddr + MPR); if (mdp->cd->tpauser) - writel(TPAUSER_UNLIMITED, ioaddr + TPAUSER); + ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER); /* Setting the Rx mode will start the Rx process. */ - writel(EDRRR_R, ioaddr + EDRRR); + ctrl_outl(EDRRR_R, ioaddr + EDRRR); netif_start_queue(ndev); @@ -811,8 +811,8 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ - if (!(readl(ndev->base_addr + EDRRR) & EDRRR_R)) - writel(EDRRR_R, ndev->base_addr + EDRRR); + if (!(ctrl_inl(ndev->base_addr + EDRRR) & EDRRR_R)) + ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR); return 0; } @@ -827,8 +827,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) u32 mask; if (intr_status & EESR_ECI) { - felic_stat = readl(ioaddr + ECSR); - writel(felic_stat, ioaddr + ECSR); /* clear int */ + felic_stat = ctrl_inl(ioaddr + ECSR); + ctrl_outl(felic_stat, ioaddr + ECSR); /* clear int */ if (felic_stat & ECSR_ICD) mdp->stats.tx_carrier_errors++; if (felic_stat & ECSR_LCHNG) { @@ -839,25 +839,25 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) else link_stat = PHY_ST_LINK; } else { - link_stat = (readl(ioaddr + PSR)); + link_stat = (ctrl_inl(ioaddr + PSR)); if (mdp->ether_link_active_low) link_stat = ~link_stat; } if (!(link_stat & PHY_ST_LINK)) { /* Link Down : disable tx and rx */ - writel(readl(ioaddr + ECMR) & + ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~(ECMR_RE | ECMR_TE), ioaddr + ECMR); } else { /* Link Up */ - writel(readl(ioaddr + EESIPR) & + ctrl_outl(ctrl_inl(ioaddr + EESIPR) & ~DMAC_M_ECI, ioaddr + EESIPR); /*clear int */ - writel(readl(ioaddr + ECSR), + ctrl_outl(ctrl_inl(ioaddr + ECSR), ioaddr + ECSR); - writel(readl(ioaddr + EESIPR) | + ctrl_outl(ctrl_inl(ioaddr + EESIPR) | DMAC_M_ECI, ioaddr + EESIPR); /* enable tx and rx */ - writel(readl(ioaddr + ECMR) | + ctrl_outl(ctrl_inl(ioaddr + ECMR) | (ECMR_RE | ECMR_TE), ioaddr + ECMR); } } @@ -888,8 +888,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* Receive Descriptor Empty int */ mdp->stats.rx_over_errors++; - if (readl(ioaddr + EDRRR) ^ EDRRR_R) - writel(EDRRR_R, ioaddr + EDRRR); + if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R) + ctrl_outl(EDRRR_R, ioaddr + EDRRR); dev_err(&ndev->dev, "Receive Descriptor Empty\n"); } if (intr_status & EESR_RFE) { @@ -903,7 +903,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) mask &= ~EESR_ADE; if (intr_status & mask) { /* Tx error */ - u32 edtrr = readl(ndev->base_addr + EDTRR); + u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR); /* dmesg */ dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ", intr_status, mdp->cur_tx); @@ -915,7 +915,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) /* SH7712 BUG */ if (edtrr ^ EDTRR_TRNS) { /* tx dma start */ - writel(EDTRR_TRNS, ndev->base_addr + EDTRR); + ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); } /* wakeup */ netif_wake_queue(ndev); @@ -934,12 +934,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) spin_lock(&mdp->lock); /* Get interrpt stat */ - intr_status = readl(ioaddr + EESR); + intr_status = ctrl_inl(ioaddr + EESR); /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | cd->tx_check | cd->eesr_err_check)) { - writel(intr_status, ioaddr + EESR); + ctrl_outl(intr_status, ioaddr + EESR); ret = IRQ_HANDLED; } else goto other_irq; @@ -1000,7 +1000,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) mdp->cd->set_rate(ndev); } if (mdp->link == PHY_DOWN) { - writel((readl(ioaddr + ECMR) & ~ECMR_TXF) + ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF) | ECMR_DM, ioaddr + ECMR); new_state = 1; mdp->link = phydev->link; @@ -1125,7 +1125,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev) /* worning message out. */ printk(KERN_WARNING "%s: transmit timed out, status %8.8x," - " resetting...\n", ndev->name, (int)readl(ioaddr + EESR)); + " resetting...\n", ndev->name, (int)ctrl_inl(ioaddr + EESR)); /* tx_errors count up */ mdp->stats.tx_errors++; @@ -1196,8 +1196,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) mdp->cur_tx++; - if (!(readl(ndev->base_addr + EDTRR) & EDTRR_TRNS)) - writel(EDTRR_TRNS, ndev->base_addr + EDTRR); + if (!(ctrl_inl(ndev->base_addr + EDTRR) & EDTRR_TRNS)) + ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); return NETDEV_TX_OK; } @@ -1212,11 +1212,11 @@ static int sh_eth_close(struct net_device *ndev) netif_stop_queue(ndev); /* Disable interrupts by clearing the interrupt mask. */ - writel(0x0000, ioaddr + EESIPR); + ctrl_outl(0x0000, ioaddr + EESIPR); /* Stop the chip's Tx and Rx processes. */ - writel(0, ioaddr + EDTRR); - writel(0, ioaddr + EDRRR); + ctrl_outl(0, ioaddr + EDTRR); + ctrl_outl(0, ioaddr + EDRRR); /* PHY Disconnect */ if (mdp->phydev) { @@ -1251,20 +1251,20 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) pm_runtime_get_sync(&mdp->pdev->dev); - mdp->stats.tx_dropped += readl(ioaddr + TROCR); - writel(0, ioaddr + TROCR); /* (write clear) */ - mdp->stats.collisions += readl(ioaddr + CDCR); - writel(0, ioaddr + CDCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += readl(ioaddr + LCCR); - writel(0, ioaddr + LCCR); /* (write clear) */ + mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR); + ctrl_outl(0, ioaddr + TROCR); /* (write clear) */ + mdp->stats.collisions += ctrl_inl(ioaddr + CDCR); + ctrl_outl(0, ioaddr + CDCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR); + ctrl_outl(0, ioaddr + LCCR); /* (write clear) */ #if defined(CONFIG_CPU_SUBTYPE_SH7763) - mdp->stats.tx_carrier_errors += readl(ioaddr + CERCR);/* CERCR */ - writel(0, ioaddr + CERCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += readl(ioaddr + CEECR);/* CEECR */ - writel(0, ioaddr + CEECR); /* (write clear) */ + mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CERCR);/* CERCR */ + ctrl_outl(0, ioaddr + CERCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CEECR);/* CEECR */ + ctrl_outl(0, ioaddr + CEECR); /* (write clear) */ #else - mdp->stats.tx_carrier_errors += readl(ioaddr + CNDCR); - writel(0, ioaddr + CNDCR); /* (write clear) */ + mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR); + ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */ #endif pm_runtime_put_sync(&mdp->pdev->dev); @@ -1295,11 +1295,11 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) if (ndev->flags & IFF_PROMISC) { /* Set promiscuous. */ - writel((readl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, + ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, ioaddr + ECMR); } else { /* Normal, unicast/broadcast-only mode. */ - writel((readl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, + ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, ioaddr + ECMR); } } @@ -1307,30 +1307,30 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) /* SuperH's TSU register init function */ static void sh_eth_tsu_init(u32 ioaddr) { - writel(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */ - writel(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */ - writel(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */ - writel(0xc, ioaddr + TSU_BSYSL0); - writel(0xc, ioaddr + TSU_BSYSL1); - writel(0, ioaddr + TSU_PRISL0); - writel(0, ioaddr + TSU_PRISL1); - writel(0, ioaddr + TSU_FWSL0); - writel(0, ioaddr + TSU_FWSL1); - writel(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); + ctrl_outl(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */ + ctrl_outl(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */ + ctrl_outl(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */ + ctrl_outl(0xc, ioaddr + TSU_BSYSL0); + ctrl_outl(0xc, ioaddr + TSU_BSYSL1); + ctrl_outl(0, ioaddr + TSU_PRISL0); + ctrl_outl(0, ioaddr + TSU_PRISL1); + ctrl_outl(0, ioaddr + TSU_FWSL0); + ctrl_outl(0, ioaddr + TSU_FWSL1); + ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); #if defined(CONFIG_CPU_SUBTYPE_SH7763) - writel(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */ - writel(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */ + ctrl_outl(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */ + ctrl_outl(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */ #else - writel(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ - writel(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ + ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ + ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ #endif - writel(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ - writel(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ - writel(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ - writel(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */ - writel(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */ - writel(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ - writel(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ + ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ + ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ + ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ + ctrl_outl(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */ + ctrl_outl(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */ + ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ + ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ } #endif /* SH_ETH_HAS_TSU */ diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index 220e0398f1d5..bfec2e0f5275 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -3858,6 +3858,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, /* device is off until link detection */ netif_carrier_off(dev); + netif_stop_queue(dev); return dev; } diff --git a/trunk/drivers/net/smsc911x.h b/trunk/drivers/net/smsc911x.h index 50f712e99e96..52f38e12a879 100644 --- a/trunk/drivers/net/smsc911x.h +++ b/trunk/drivers/net/smsc911x.h @@ -22,7 +22,7 @@ #define __SMSC911X_H__ #define TX_FIFO_LOW_THRESHOLD ((u32)1600) -#define SMSC911X_EEPROM_SIZE ((u32)128) +#define SMSC911X_EEPROM_SIZE ((u32)7) #define USE_DEBUG 0 /* This is the maximum number of packets to be received every diff --git a/trunk/drivers/net/stmmac/stmmac.h b/trunk/drivers/net/stmmac/stmmac.h index 5f06c4706abe..79bdc2e13224 100644 --- a/trunk/drivers/net/stmmac/stmmac.h +++ b/trunk/drivers/net/stmmac/stmmac.h @@ -20,7 +20,7 @@ Author: Giuseppe Cavallaro *******************************************************************************/ -#define DRV_MODULE_VERSION "Nov_2010" +#define DRV_MODULE_VERSION "Apr_2010" #include #include @@ -37,6 +37,7 @@ struct stmmac_priv { unsigned int cur_tx; unsigned int dirty_tx; unsigned int dma_tx_size; + int tx_coe; int tx_coalesce; struct dma_desc *dma_rx ; @@ -47,6 +48,7 @@ struct stmmac_priv { struct sk_buff_head rx_recycle; struct net_device *dev; + int is_gmac; dma_addr_t dma_rx_phy; unsigned int dma_rx_size; unsigned int dma_buf_sz; @@ -58,11 +60,14 @@ struct stmmac_priv { struct napi_struct napi; phy_interface_t phy_interface; + int pbl; + int bus_id; int phy_addr; int phy_mask; int (*phy_reset) (void *priv); - int rx_coe; - int no_csum_insertion; + void (*fix_mac_speed) (void *priv, unsigned int speed); + void (*bus_setup)(void __iomem *ioaddr); + void *bsp_priv; int phy_irq; struct phy_device *phydev; @@ -72,20 +77,47 @@ struct stmmac_priv { unsigned int flow_ctrl; unsigned int pause; struct mii_bus *mii; + int mii_clk_csr; u32 msg_enable; spinlock_t lock; int wolopts; int wolenabled; + int shutdown; #ifdef CONFIG_STMMAC_TIMER struct stmmac_timer *tm; #endif #ifdef STMMAC_VLAN_TAG_USED struct vlan_group *vlgrp; #endif - struct plat_stmmacenet_data *plat; + int enh_desc; + int rx_coe; + int bugged_jumbo; + int no_csum_insertion; }; +#ifdef CONFIG_STM_DRIVERS +#include +static inline int stmmac_claim_resource(struct platform_device *pdev) +{ + int ret = 0; + struct plat_stmmacenet_data *plat_dat = pdev->dev.platform_data; + + /* Pad routing setup */ + if (IS_ERR(devm_stm_pad_claim(&pdev->dev, plat_dat->pad_config, + dev_name(&pdev->dev)))) { + printk(KERN_ERR "%s: Failed to request pads!\n", __func__); + ret = -ENODEV; + } + return ret; +} +#else +static inline int stmmac_claim_resource(struct platform_device *pdev) +{ + return 0; +} +#endif + extern int stmmac_mdio_unregister(struct net_device *ndev); extern int stmmac_mdio_register(struct net_device *ndev); extern void stmmac_set_ethtool_ops(struct net_device *netdev); diff --git a/trunk/drivers/net/stmmac/stmmac_ethtool.c b/trunk/drivers/net/stmmac/stmmac_ethtool.c index f2695fd180ca..6d65482e789a 100644 --- a/trunk/drivers/net/stmmac/stmmac_ethtool.c +++ b/trunk/drivers/net/stmmac/stmmac_ethtool.c @@ -94,7 +94,7 @@ static void stmmac_ethtool_getdrvinfo(struct net_device *dev, { struct stmmac_priv *priv = netdev_priv(dev); - if (!priv->plat->has_gmac) + if (!priv->is_gmac) strcpy(info->driver, MAC100_ETHTOOL_NAME); else strcpy(info->driver, GMAC_ETHTOOL_NAME); @@ -176,7 +176,7 @@ static void stmmac_ethtool_gregs(struct net_device *dev, memset(reg_space, 0x0, REG_SPACE_SIZE); - if (!priv->plat->has_gmac) { + if (!priv->is_gmac) { /* MAC registers */ for (i = 0; i < 12; i++) reg_space[i] = readl(priv->ioaddr + (i * 4)); diff --git a/trunk/drivers/net/stmmac/stmmac_main.c b/trunk/drivers/net/stmmac/stmmac_main.c index 730a6fd79ee0..06bc6034ce81 100644 --- a/trunk/drivers/net/stmmac/stmmac_main.c +++ b/trunk/drivers/net/stmmac/stmmac_main.c @@ -186,18 +186,6 @@ static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; } -/* On some ST platforms, some HW system configuraton registers have to be - * set according to the link speed negotiated. - */ -static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) -{ - struct phy_device *phydev = priv->phydev; - - if (likely(priv->plat->fix_mac_speed)) - priv->plat->fix_mac_speed(priv->plat->bsp_priv, - phydev->speed); -} - /** * stmmac_adjust_link * @dev: net device structure @@ -240,13 +228,15 @@ static void stmmac_adjust_link(struct net_device *dev) new_state = 1; switch (phydev->speed) { case 1000: - if (likely(priv->plat->has_gmac)) + if (likely(priv->is_gmac)) ctrl &= ~priv->hw->link.port; - stmmac_hw_fix_mac_speed(priv); + if (likely(priv->fix_mac_speed)) + priv->fix_mac_speed(priv->bsp_priv, + phydev->speed); break; case 100: case 10: - if (priv->plat->has_gmac) { + if (priv->is_gmac) { ctrl |= priv->hw->link.port; if (phydev->speed == SPEED_100) { ctrl |= priv->hw->link.speed; @@ -256,7 +246,9 @@ static void stmmac_adjust_link(struct net_device *dev) } else { ctrl &= ~priv->hw->link.port; } - stmmac_hw_fix_mac_speed(priv); + if (likely(priv->fix_mac_speed)) + priv->fix_mac_speed(priv->bsp_priv, + phydev->speed); break; default: if (netif_msg_link(priv)) @@ -313,7 +305,7 @@ static int stmmac_init_phy(struct net_device *dev) return 0; } - snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); + snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->bus_id); snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, priv->phy_addr); pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); @@ -560,7 +552,7 @@ static void free_dma_desc_resources(struct stmmac_priv *priv) */ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) { - if (likely((priv->plat->tx_coe) && (!priv->no_csum_insertion))) { + if (likely((priv->tx_coe) && (!priv->no_csum_insertion))) { /* In case of GMAC, SF mode has to be enabled * to perform the TX COE. This depends on: * 1) TX COE if actually supported @@ -822,7 +814,7 @@ static int stmmac_open(struct net_device *dev) init_dma_desc_rings(dev); /* DMA initialization and SW reset */ - if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->plat->pbl, + if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->pbl, priv->dma_tx_phy, priv->dma_rx_phy) < 0)) { @@ -833,17 +825,19 @@ static int stmmac_open(struct net_device *dev) /* Copy the MAC addr into the HW */ priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); /* If required, perform hw setup of the bus. */ - if (priv->plat->bus_setup) - priv->plat->bus_setup(priv->ioaddr); + if (priv->bus_setup) + priv->bus_setup(priv->ioaddr); /* Initialize the MAC Core */ priv->hw->mac->core_init(priv->ioaddr); priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); if (priv->rx_coe) pr_info("stmmac: Rx Checksum Offload Engine supported\n"); - if (priv->plat->tx_coe) + if (priv->tx_coe) pr_info("\tTX Checksum insertion supported\n"); + priv->shutdown = 0; + /* Initialise the MMC (if present) to disable all interrupts. */ writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK); writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK); @@ -1048,8 +1042,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) return stmmac_sw_tso(priv, skb); if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) { - if (unlikely((!priv->plat->tx_coe) || - (priv->no_csum_insertion))) + if (unlikely((!priv->tx_coe) || (priv->no_csum_insertion))) skb_checksum_help(skb); else csum_insertion = 1; @@ -1153,7 +1146,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) DMA_FROM_DEVICE); (p + entry)->des2 = priv->rx_skbuff_dma[entry]; - if (unlikely(priv->plat->has_gmac)) { + if (unlikely(priv->is_gmac)) { if (bfsize >= BUF_SIZE_8KiB) (p + entry)->des3 = (p + entry)->des2 + BUF_SIZE_8KiB; @@ -1363,7 +1356,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) return -EBUSY; } - if (priv->plat->has_gmac) + if (priv->is_gmac) max_mtu = JUMBO_LEN; else max_mtu = ETH_DATA_LEN; @@ -1377,7 +1370,7 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) * needs to have the Tx COE disabled for oversized frames * (due to limited buffer sizes). In this case we disable * the TX csum insertionin the TDES and not use SF. */ - if ((priv->plat->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN)) + if ((priv->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN)) priv->no_csum_insertion = 1; else priv->no_csum_insertion = 0; @@ -1397,7 +1390,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) return IRQ_NONE; } - if (priv->plat->has_gmac) + if (priv->is_gmac) /* To handle GMAC own interrupts */ priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr); @@ -1543,7 +1536,7 @@ static int stmmac_mac_device_setup(struct net_device *dev) struct mac_device_info *device; - if (priv->plat->has_gmac) + if (priv->is_gmac) device = dwmac1000_setup(priv->ioaddr); else device = dwmac100_setup(priv->ioaddr); @@ -1551,7 +1544,7 @@ static int stmmac_mac_device_setup(struct net_device *dev) if (!device) return -ENOMEM; - if (priv->plat->enh_desc) { + if (priv->enh_desc) { device->desc = &enh_desc_ops; pr_info("\tEnhanced descriptor structure\n"); } else @@ -1605,7 +1598,7 @@ static int stmmac_associate_phy(struct device *dev, void *data) plat_dat->bus_id); /* Check that this phy is for the MAC being initialised */ - if (priv->plat->bus_id != plat_dat->bus_id) + if (priv->bus_id != plat_dat->bus_id) return 0; /* OK, this PHY is connected to the MAC. @@ -1641,7 +1634,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) struct resource *res; void __iomem *addr = NULL; struct net_device *ndev = NULL; - struct stmmac_priv *priv = NULL; + struct stmmac_priv *priv; struct plat_stmmacenet_data *plat_dat; pr_info("STMMAC driver:\n\tplatform registration... "); @@ -1690,9 +1683,13 @@ static int stmmac_dvr_probe(struct platform_device *pdev) priv->device = &(pdev->dev); priv->dev = ndev; plat_dat = pdev->dev.platform_data; - - priv->plat = plat_dat; - + priv->bus_id = plat_dat->bus_id; + priv->pbl = plat_dat->pbl; /* TLI */ + priv->mii_clk_csr = plat_dat->clk_csr; + priv->tx_coe = plat_dat->tx_coe; + priv->bugged_jumbo = plat_dat->bugged_jumbo; + priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */ + priv->enh_desc = plat_dat->enh_desc; priv->ioaddr = addr; /* PMT module is not integrated in all the MAC devices. */ @@ -1706,12 +1703,10 @@ static int stmmac_dvr_probe(struct platform_device *pdev) /* Set the I/O base addr */ ndev->base_addr = (unsigned long)addr; - /* Custom initialisation */ - if (priv->plat->init) { - ret = priv->plat->init(pdev); - if (unlikely(ret)) - goto out; - } + /* Verify embedded resource for the platform */ + ret = stmmac_claim_resource(pdev); + if (ret < 0) + goto out; /* MAC HW revice detection */ ret = stmmac_mac_device_setup(ndev); @@ -1732,12 +1727,16 @@ static int stmmac_dvr_probe(struct platform_device *pdev) goto out; } + priv->fix_mac_speed = plat_dat->fix_mac_speed; + priv->bus_setup = plat_dat->bus_setup; + priv->bsp_priv = plat_dat->bsp_priv; + pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, pdev->id, ndev->irq, addr); /* MDIO bus Registration */ - pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id); + pr_debug("\tMDIO bus (id: %d)...", priv->bus_id); ret = stmmac_mdio_register(ndev); if (ret < 0) goto out; @@ -1745,9 +1744,6 @@ static int stmmac_dvr_probe(struct platform_device *pdev) out: if (ret < 0) { - if (priv->plat->exit) - priv->plat->exit(pdev); - platform_set_drvdata(pdev, NULL); release_mem_region(res->start, resource_size(res)); if (addr != NULL) @@ -1781,9 +1777,6 @@ static int stmmac_dvr_remove(struct platform_device *pdev) stmmac_mdio_unregister(ndev); - if (priv->plat->exit) - priv->plat->exit(pdev); - platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); @@ -1797,55 +1790,70 @@ static int stmmac_dvr_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int stmmac_suspend(struct device *dev) +static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) { - struct net_device *ndev = dev_get_drvdata(dev); - struct stmmac_priv *priv = netdev_priv(ndev); + struct net_device *dev = platform_get_drvdata(pdev); + struct stmmac_priv *priv = netdev_priv(dev); int dis_ic = 0; - if (!ndev || !netif_running(ndev)) + if (!dev || !netif_running(dev)) return 0; spin_lock(&priv->lock); - netif_device_detach(ndev); - netif_stop_queue(ndev); - if (priv->phydev) - phy_stop(priv->phydev); + if (state.event == PM_EVENT_SUSPEND) { + netif_device_detach(dev); + netif_stop_queue(dev); + if (priv->phydev) + phy_stop(priv->phydev); #ifdef CONFIG_STMMAC_TIMER - priv->tm->timer_stop(); - if (likely(priv->tm->enable)) - dis_ic = 1; + priv->tm->timer_stop(); + if (likely(priv->tm->enable)) + dis_ic = 1; #endif - napi_disable(&priv->napi); - - /* Stop TX/RX DMA */ - priv->hw->dma->stop_tx(priv->ioaddr); - priv->hw->dma->stop_rx(priv->ioaddr); - /* Clear the Rx/Tx descriptors */ - priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, - dis_ic); - priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); - - /* Enable Power down mode by programming the PMT regs */ - if (device_may_wakeup(priv->device)) - priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); - else - stmmac_disable_mac(priv->ioaddr); + napi_disable(&priv->napi); + + /* Stop TX/RX DMA */ + priv->hw->dma->stop_tx(priv->ioaddr); + priv->hw->dma->stop_rx(priv->ioaddr); + /* Clear the Rx/Tx descriptors */ + priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, + dis_ic); + priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); + + /* Enable Power down mode by programming the PMT regs */ + if (device_can_wakeup(priv->device)) + priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); + else + stmmac_disable_mac(priv->ioaddr); + } else { + priv->shutdown = 1; + /* Although this can appear slightly redundant it actually + * makes fast the standby operation and guarantees the driver + * working if hibernation is on media. */ + stmmac_release(dev); + } spin_unlock(&priv->lock); return 0; } -static int stmmac_resume(struct device *dev) +static int stmmac_resume(struct platform_device *pdev) { - struct net_device *ndev = dev_get_drvdata(dev); - struct stmmac_priv *priv = netdev_priv(ndev); + struct net_device *dev = platform_get_drvdata(pdev); + struct stmmac_priv *priv = netdev_priv(dev); - if (!netif_running(ndev)) + if (!netif_running(dev)) return 0; + if (priv->shutdown) { + /* Re-open the interface and re-init the MAC/DMA + and the rings (i.e. on hibernation stage) */ + stmmac_open(dev); + return 0; + } + spin_lock(&priv->lock); /* Power Down bit, into the PM register, is cleared @@ -1853,10 +1861,10 @@ static int stmmac_resume(struct device *dev) * is received. Anyway, it's better to manually clear * this bit because it can generate problems while resuming * from another devices (e.g. serial console). */ - if (device_may_wakeup(priv->device)) + if (device_can_wakeup(priv->device)) priv->hw->mac->pmt(priv->ioaddr, 0); - netif_device_attach(ndev); + netif_device_attach(dev); /* Enable the MAC and DMA */ stmmac_enable_mac(priv->ioaddr); @@ -1864,59 +1872,31 @@ static int stmmac_resume(struct device *dev) priv->hw->dma->start_rx(priv->ioaddr); #ifdef CONFIG_STMMAC_TIMER - if (likely(priv->tm->enable)) - priv->tm->timer_start(tmrate); + priv->tm->timer_start(tmrate); #endif napi_enable(&priv->napi); if (priv->phydev) phy_start(priv->phydev); - netif_start_queue(ndev); + netif_start_queue(dev); spin_unlock(&priv->lock); return 0; } - -static int stmmac_freeze(struct device *dev) -{ - struct net_device *ndev = dev_get_drvdata(dev); - - if (!ndev || !netif_running(ndev)) - return 0; - - return stmmac_release(ndev); -} - -static int stmmac_restore(struct device *dev) -{ - struct net_device *ndev = dev_get_drvdata(dev); - - if (!ndev || !netif_running(ndev)) - return 0; - - return stmmac_open(ndev); -} - -static const struct dev_pm_ops stmmac_pm_ops = { - .suspend = stmmac_suspend, - .resume = stmmac_resume, - .freeze = stmmac_freeze, - .thaw = stmmac_restore, - .restore = stmmac_restore, -}; -#else -static const struct dev_pm_ops stmmac_pm_ops; -#endif /* CONFIG_PM */ +#endif static struct platform_driver stmmac_driver = { + .driver = { + .name = STMMAC_RESOURCE_NAME, + }, .probe = stmmac_dvr_probe, .remove = stmmac_dvr_remove, - .driver = { - .name = STMMAC_RESOURCE_NAME, - .owner = THIS_MODULE, - .pm = &stmmac_pm_ops, - }, +#ifdef CONFIG_PM + .suspend = stmmac_suspend, + .resume = stmmac_resume, +#endif + }; /** diff --git a/trunk/drivers/net/stmmac/stmmac_mdio.c b/trunk/drivers/net/stmmac/stmmac_mdio.c index 234b4068a1fc..d7441616357d 100644 --- a/trunk/drivers/net/stmmac/stmmac_mdio.c +++ b/trunk/drivers/net/stmmac/stmmac_mdio.c @@ -53,7 +53,7 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) int data; u16 regValue = (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))); - regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2); + regValue |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2); do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); writel(regValue, priv->ioaddr + mii_address); @@ -85,7 +85,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))) | MII_WRITE; - value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2); + value |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2); /* Wait until any existing MII operation is complete */ @@ -114,7 +114,7 @@ static int stmmac_mdio_reset(struct mii_bus *bus) if (priv->phy_reset) { pr_debug("stmmac_mdio_reset: calling phy_reset\n"); - priv->phy_reset(priv->plat->bsp_priv); + priv->phy_reset(priv->bsp_priv); } /* This is a workaround for problems with the STE101P PHY. @@ -157,7 +157,7 @@ int stmmac_mdio_register(struct net_device *ndev) new_bus->read = &stmmac_mdio_read; new_bus->write = &stmmac_mdio_write; new_bus->reset = &stmmac_mdio_reset; - snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); + snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->bus_id); new_bus->priv = ndev; new_bus->irq = irqlist; new_bus->phy_mask = priv->phy_mask; diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index afb79db5327e..30ccbb6d097a 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -2728,10 +2728,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))) mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL; - if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) - mac_mode |= MAC_MODE_APE_TX_EN | - MAC_MODE_APE_RX_EN | - MAC_MODE_TDE_ENABLE; + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { + mac_mode |= tp->mac_mode & + (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN); + if (mac_mode & MAC_MODE_APE_TX_EN) + mac_mode |= MAC_MODE_TDE_ENABLE; + } tw32_f(MAC_MODE, mac_mode); udelay(100); @@ -6337,13 +6339,13 @@ static void tg3_rx_prodring_fini(struct tg3 *tp, kfree(tpr->rx_jmb_buffers); tpr->rx_jmb_buffers = NULL; if (tpr->rx_std) { - dma_free_coherent(&tp->pdev->dev, TG3_RX_STD_RING_BYTES(tp), - tpr->rx_std, tpr->rx_std_mapping); + pci_free_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp), + tpr->rx_std, tpr->rx_std_mapping); tpr->rx_std = NULL; } if (tpr->rx_jmb) { - dma_free_coherent(&tp->pdev->dev, TG3_RX_JMB_RING_BYTES(tp), - tpr->rx_jmb, tpr->rx_jmb_mapping); + pci_free_consistent(tp->pdev, TG3_RX_JMB_RING_BYTES(tp), + tpr->rx_jmb, tpr->rx_jmb_mapping); tpr->rx_jmb = NULL; } } @@ -6356,10 +6358,8 @@ static int tg3_rx_prodring_init(struct tg3 *tp, if (!tpr->rx_std_buffers) return -ENOMEM; - tpr->rx_std = dma_alloc_coherent(&tp->pdev->dev, - TG3_RX_STD_RING_BYTES(tp), - &tpr->rx_std_mapping, - GFP_KERNEL); + tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp), + &tpr->rx_std_mapping); if (!tpr->rx_std) goto err_out; @@ -6370,10 +6370,9 @@ static int tg3_rx_prodring_init(struct tg3 *tp, if (!tpr->rx_jmb_buffers) goto err_out; - tpr->rx_jmb = dma_alloc_coherent(&tp->pdev->dev, - TG3_RX_JMB_RING_BYTES(tp), - &tpr->rx_jmb_mapping, - GFP_KERNEL); + tpr->rx_jmb = pci_alloc_consistent(tp->pdev, + TG3_RX_JMB_RING_BYTES(tp), + &tpr->rx_jmb_mapping); if (!tpr->rx_jmb) goto err_out; } @@ -6492,7 +6491,7 @@ static void tg3_free_consistent(struct tg3 *tp) struct tg3_napi *tnapi = &tp->napi[i]; if (tnapi->tx_ring) { - dma_free_coherent(&tp->pdev->dev, TG3_TX_RING_BYTES, + pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES, tnapi->tx_ring, tnapi->tx_desc_mapping); tnapi->tx_ring = NULL; } @@ -6501,26 +6500,25 @@ static void tg3_free_consistent(struct tg3 *tp) tnapi->tx_buffers = NULL; if (tnapi->rx_rcb) { - dma_free_coherent(&tp->pdev->dev, - TG3_RX_RCB_RING_BYTES(tp), - tnapi->rx_rcb, - tnapi->rx_rcb_mapping); + pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp), + tnapi->rx_rcb, + tnapi->rx_rcb_mapping); tnapi->rx_rcb = NULL; } tg3_rx_prodring_fini(tp, &tnapi->prodring); if (tnapi->hw_status) { - dma_free_coherent(&tp->pdev->dev, TG3_HW_STATUS_SIZE, - tnapi->hw_status, - tnapi->status_mapping); + pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE, + tnapi->hw_status, + tnapi->status_mapping); tnapi->hw_status = NULL; } } if (tp->hw_stats) { - dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats), - tp->hw_stats, tp->stats_mapping); + pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats), + tp->hw_stats, tp->stats_mapping); tp->hw_stats = NULL; } } @@ -6533,10 +6531,9 @@ static int tg3_alloc_consistent(struct tg3 *tp) { int i; - tp->hw_stats = dma_alloc_coherent(&tp->pdev->dev, - sizeof(struct tg3_hw_stats), - &tp->stats_mapping, - GFP_KERNEL); + tp->hw_stats = pci_alloc_consistent(tp->pdev, + sizeof(struct tg3_hw_stats), + &tp->stats_mapping); if (!tp->hw_stats) goto err_out; @@ -6546,10 +6543,9 @@ static int tg3_alloc_consistent(struct tg3 *tp) struct tg3_napi *tnapi = &tp->napi[i]; struct tg3_hw_status *sblk; - tnapi->hw_status = dma_alloc_coherent(&tp->pdev->dev, - TG3_HW_STATUS_SIZE, - &tnapi->status_mapping, - GFP_KERNEL); + tnapi->hw_status = pci_alloc_consistent(tp->pdev, + TG3_HW_STATUS_SIZE, + &tnapi->status_mapping); if (!tnapi->hw_status) goto err_out; @@ -6570,10 +6566,9 @@ static int tg3_alloc_consistent(struct tg3 *tp) if (!tnapi->tx_buffers) goto err_out; - tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev, - TG3_TX_RING_BYTES, - &tnapi->tx_desc_mapping, - GFP_KERNEL); + tnapi->tx_ring = pci_alloc_consistent(tp->pdev, + TG3_TX_RING_BYTES, + &tnapi->tx_desc_mapping); if (!tnapi->tx_ring) goto err_out; } @@ -6606,10 +6601,9 @@ static int tg3_alloc_consistent(struct tg3 *tp) if (!i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) continue; - tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev, - TG3_RX_RCB_RING_BYTES(tp), - &tnapi->rx_rcb_mapping, - GFP_KERNEL); + tnapi->rx_rcb = pci_alloc_consistent(tp->pdev, + TG3_RX_RCB_RING_BYTES(tp), + &tnapi->rx_rcb_mapping); if (!tnapi->rx_rcb) goto err_out; @@ -6993,7 +6987,7 @@ static void tg3_restore_pci_state(struct tg3 *tp) if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) { if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) - pcie_set_readrq(tp->pdev, tp->pcie_readrq); + pcie_set_readrq(tp->pdev, 4096); else { pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, tp->pci_cacheline_sz); @@ -7187,7 +7181,7 @@ static int tg3_chip_reset(struct tg3 *tp) tp->pcie_cap + PCI_EXP_DEVCTL, val16); - pcie_set_readrq(tp->pdev, tp->pcie_readrq); + pcie_set_readrq(tp->pdev, 4096); /* Clear error status */ pci_write_config_word(tp->pdev, @@ -7228,21 +7222,19 @@ static int tg3_chip_reset(struct tg3 *tp) tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); } - if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) - tp->mac_mode = MAC_MODE_APE_TX_EN | - MAC_MODE_APE_RX_EN | - MAC_MODE_TDE_ENABLE; - if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) { - tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; - val = tp->mac_mode; + tp->mac_mode = MAC_MODE_PORT_MODE_TBI; + tw32_f(MAC_MODE, tp->mac_mode); } else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) { - tp->mac_mode |= MAC_MODE_PORT_MODE_GMII; - val = tp->mac_mode; + tp->mac_mode = MAC_MODE_PORT_MODE_GMII; + tw32_f(MAC_MODE, tp->mac_mode); + } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) { + tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN); + if (tp->mac_mode & MAC_MODE_APE_TX_EN) + tp->mac_mode |= MAC_MODE_TDE_ENABLE; + tw32_f(MAC_MODE, tp->mac_mode); } else - val = 0; - - tw32_f(MAC_MODE, val); + tw32_f(MAC_MODE, 0); udelay(40); tg3_ape_unlock(tp, TG3_APE_LOCK_GRC); @@ -7868,21 +7860,18 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(GRC_MODE, grc_mode); } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { - if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) { - u32 grc_mode = tr32(GRC_MODE); + if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) { + u32 grc_mode = tr32(GRC_MODE); - /* Access the lower 1K of PL PCIE block registers. */ - val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK; - tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL); + /* Access the lower 1K of PL PCIE block registers. */ + val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK; + tw32(GRC_MODE, val | GRC_MODE_PCIE_PL_SEL); - val = tr32(TG3_PCIE_TLDLPL_PORT + - TG3_PCIE_PL_LO_PHYCTL5); - tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5, - val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ); + val = tr32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5); + tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_PL_LO_PHYCTL5, + val | TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ); - tw32(GRC_MODE, grc_mode); - } + tw32(GRC_MODE, grc_mode); val = tr32(TG3_CPMU_LSPD_10MB_CLK); val &= ~CPMU_LSPD_10MB_MACCLK_MASK; @@ -8173,7 +8162,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | RDMAC_MODE_LNGREAD_ENAB); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || @@ -8213,10 +8203,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { val = tr32(TG3_RDMA_RSRVCTRL_REG); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { - val &= ~TG3_RDMA_RSRVCTRL_TXMRGN_MASK; - val |= TG3_RDMA_RSRVCTRL_TXMRGN_320B; - } tw32(TG3_RDMA_RSRVCTRL_REG, val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX); } @@ -8294,7 +8280,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) } if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) - tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; + tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; else tp->mac_mode = 0; tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | @@ -9045,14 +9031,8 @@ static bool tg3_enable_msix(struct tg3 *tp) pci_disable_msix(tp->pdev); return false; } - - if (tp->irq_cnt > 1) { + if (tp->irq_cnt > 1) tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { - tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS; - netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1); - } - } return true; } @@ -12431,9 +12411,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if (cfg2 & (1 << 18)) tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS; - if (((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) || - ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && - GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX))) && + if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && + GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX)) && (cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN)) tp->phy_flags |= TG3_PHYFLG_ENABLE_APD; @@ -13380,45 +13359,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS; - tp->pcie_readrq = 4096; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { - u16 word; - - pci_read_config_word(tp->pdev, - tp->pcie_cap + PCI_EXP_LNKSTA, - &word); - switch (word & PCI_EXP_LNKSTA_CLS) { - case PCI_EXP_LNKSTA_CLS_2_5GB: - word &= PCI_EXP_LNKSTA_NLW; - word >>= PCI_EXP_LNKSTA_NLW_SHIFT; - switch (word) { - case 2: - tp->pcie_readrq = 2048; - break; - case 4: - tp->pcie_readrq = 1024; - break; - } - break; - - case PCI_EXP_LNKSTA_CLS_5_0GB: - word &= PCI_EXP_LNKSTA_NLW; - word >>= PCI_EXP_LNKSTA_NLW_SHIFT; - switch (word) { - case 1: - tp->pcie_readrq = 2048; - break; - case 2: - tp->pcie_readrq = 1024; - break; - case 4: - tp->pcie_readrq = 512; - break; - } - } - } - - pcie_set_readrq(tp->pdev, tp->pcie_readrq); + pcie_set_readrq(tp->pdev, 4096); pci_read_config_word(tp->pdev, tp->pcie_cap + PCI_EXP_LNKCTL, @@ -13781,7 +13722,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) /* Preserve the APE MAC_MODE bits */ if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) - tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; + tp->mac_mode = tr32(MAC_MODE) | + MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN; else tp->mac_mode = TG3_DEF_MAC_MODE; @@ -14217,8 +14159,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) u32 *buf, saved_dma_rwctrl; int ret = 0; - buf = dma_alloc_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE, - &buf_dma, GFP_KERNEL); + buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma); if (!buf) { ret = -ENOMEM; goto out_nofree; @@ -14402,7 +14343,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) } out: - dma_free_coherent(&tp->pdev->dev, TEST_BUFFER_SIZE, buf, buf_dma); + pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma); out_nofree: return ret; } diff --git a/trunk/drivers/net/tg3.h b/trunk/drivers/net/tg3.h index 59b0e096149e..4a1974804b9f 100644 --- a/trunk/drivers/net/tg3.h +++ b/trunk/drivers/net/tg3.h @@ -1327,8 +1327,6 @@ #define TG3_RDMA_RSRVCTRL_REG 0x00004900 #define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004 -#define TG3_RDMA_RSRVCTRL_TXMRGN_320B 0x28000000 -#define TG3_RDMA_RSRVCTRL_TXMRGN_MASK 0xffe00000 /* 0x4904 --> 0x4910 unused */ #define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 @@ -2564,6 +2562,10 @@ struct ring_info { DEFINE_DMA_UNMAP_ADDR(mapping); }; +struct tg3_config_info { + u32 flags; +}; + struct tg3_link_config { /* Describes what we're trying to get. */ u32 advertising; @@ -2711,17 +2713,17 @@ struct tg3_napi { u32 last_irq_tag; u32 int_mbox; u32 coal_now; + u32 tx_prod; + u32 tx_cons; + u32 tx_pending; + u32 prodmbox; - u32 consmbox ____cacheline_aligned; + u32 consmbox; u32 rx_rcb_ptr; u16 *rx_rcb_prod_idx; struct tg3_rx_prodring_set prodring; - struct tg3_rx_buffer_desc *rx_rcb; - u32 tx_prod ____cacheline_aligned; - u32 tx_cons; - u32 tx_pending; - u32 prodmbox; + struct tg3_rx_buffer_desc *rx_rcb; struct tg3_tx_buffer_desc *tx_ring; struct ring_info *tx_buffers; @@ -2944,7 +2946,6 @@ struct tg3 { int pcix_cap; int pcie_cap; }; - int pcie_readrq; struct mii_bus *mdio_bus; int mdio_irq[PHY_MAX_ADDR]; diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c index c78a50586c1d..28e1ffb13db9 100644 --- a/trunk/drivers/net/tulip/de2104x.c +++ b/trunk/drivers/net/tulip/de2104x.c @@ -2021,6 +2021,7 @@ static int __devinit de_init_one (struct pci_dev *pdev, de->media_timer.data = (unsigned long) de; netif_carrier_off(dev); + netif_stop_queue(dev); /* wake up device, assign resources */ rc = pci_enable_device(pdev); diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index acbdab3d66ca..a4c3f5708246 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -2050,16 +2050,12 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) ugeth_vdbg("%s: IN", __func__); - /* - * Tell the kernel the link is down. - * Must be done before disabling the controller - * or deadlock may happen. - */ - phy_stop(phydev); - /* Disable the controller */ ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); + /* Tell the kernel the link is down */ + phy_stop(phydev); + /* Mask all interrupts */ out_be32(ugeth->uccf->p_uccm, 0x00000000); @@ -2069,6 +2065,9 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) /* Disable Rx and Tx */ clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); + phy_disconnect(ugeth->phydev); + ugeth->phydev = NULL; + ucc_geth_memclean(ugeth); } @@ -3551,10 +3550,7 @@ static int ucc_geth_close(struct net_device *dev) napi_disable(&ugeth->napi); - cancel_work_sync(&ugeth->timeout_work); ucc_geth_stop(ugeth); - phy_disconnect(ugeth->phydev); - ugeth->phydev = NULL; free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev); @@ -3583,12 +3579,8 @@ static void ucc_geth_timeout_work(struct work_struct *work) * Must reset MAC *and* PHY. This is done by reopening * the device. */ - netif_tx_stop_all_queues(dev); - ucc_geth_stop(ugeth); - ucc_geth_init_mac(ugeth); - /* Must start PHY here */ - phy_start(ugeth->phydev); - netif_tx_start_all_queues(dev); + ucc_geth_close(dev); + ucc_geth_open(dev); } netif_tx_schedule_all(dev); @@ -3602,6 +3594,7 @@ static void ucc_geth_timeout(struct net_device *dev) { struct ucc_geth_private *ugeth = netdev_priv(dev); + netif_carrier_off(dev); schedule_work(&ugeth->timeout_work); } diff --git a/trunk/drivers/net/usb/hso.c b/trunk/drivers/net/usb/hso.c index be8cc2a8e213..b154a94de03e 100644 --- a/trunk/drivers/net/usb/hso.c +++ b/trunk/drivers/net/usb/hso.c @@ -1745,6 +1745,7 @@ static int hso_serial_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct hso_serial *serial = get_serial_by_tty(tty); + void __user *uarg = (void __user *)arg; int ret = 0; D4("IOCTL cmd: %d, arg: %ld", cmd, arg); diff --git a/trunk/drivers/net/usb/ipheth.c b/trunk/drivers/net/usb/ipheth.c index 7d42f9a2c068..b2bcf99e6f08 100644 --- a/trunk/drivers/net/usb/ipheth.c +++ b/trunk/drivers/net/usb/ipheth.c @@ -363,7 +363,7 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net) /* Paranoid */ if (skb->len > IPHETH_BUF_SIZE) { - WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len); + WARN(1, "%s: skb too large: %d bytes", __func__, skb->len); dev->net->stats.tx_dropped++; dev_kfree_skb_irq(skb); return NETDEV_TX_OK; diff --git a/trunk/drivers/net/usb/pegasus.c b/trunk/drivers/net/usb/pegasus.c index ef3667690b12..6710f09346d6 100644 --- a/trunk/drivers/net/usb/pegasus.c +++ b/trunk/drivers/net/usb/pegasus.c @@ -359,7 +359,7 @@ static int read_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd) static int mdio_read(struct net_device *dev, int phy_id, int loc) { - pegasus_t *pegasus = netdev_priv(dev); + pegasus_t *pegasus = (pegasus_t *) netdev_priv(dev); u16 res; read_mii_word(pegasus, phy_id, loc, &res); @@ -397,7 +397,7 @@ static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 regd) static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) { - pegasus_t *pegasus = netdev_priv(dev); + pegasus_t *pegasus = (pegasus_t *) netdev_priv(dev); write_mii_word(pegasus, phy_id, loc, val); } diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index c04d49e31f81..ca7fc9df1ccf 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -45,7 +45,6 @@ #include #include #include -#include #define DRIVER_VERSION "22-Aug-2005" @@ -1274,16 +1273,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) struct usb_device *xdev; int status; const char *name; - struct usb_driver *driver = to_usb_driver(udev->dev.driver); - - /* usbnet already took usb runtime pm, so have to enable the feature - * for usb interface, otherwise usb_autopm_get_interface may return - * failure if USB_SUSPEND(RUNTIME_PM) is enabled. - */ - if (!driver->supports_autosuspend) { - driver->supports_autosuspend = 1; - pm_runtime_enable(&udev->dev); - } name = udev->dev.driver->name; info = (struct driver_info *) prod->driver_info; diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index b6d402806ae6..bb6b67f6b0cc 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -986,15 +986,9 @@ static int virtnet_probe(struct virtio_device *vdev) goto unregister; } - /* Assume link up if device can't report link status, - otherwise get link status from config. */ - if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { - netif_carrier_off(dev); - virtnet_update_status(vi); - } else { - vi->status = VIRTIO_NET_S_LINK_UP; - netif_carrier_on(dev); - } + vi->status = VIRTIO_NET_S_LINK_UP; + virtnet_update_status(vi); + netif_carrier_on(dev); pr_debug("virtnet: registered device %s\n", dev->name); return 0; diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c index 65860a998321..21314e06e6d7 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_drv.c @@ -44,9 +44,6 @@ MODULE_DEVICE_TABLE(pci, vmxnet3_pciid_table); static atomic_t devices_found; -#define VMXNET3_MAX_DEVICES 10 -static int enable_mq = 1; -static int irq_share_mode; /* * Enable/Disable the given intr @@ -102,7 +99,7 @@ vmxnet3_ack_events(struct vmxnet3_adapter *adapter, u32 events) static bool vmxnet3_tq_stopped(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { - return tq->stopped; + return netif_queue_stopped(adapter->netdev); } @@ -110,7 +107,7 @@ static void vmxnet3_tq_start(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { tq->stopped = false; - netif_start_subqueue(adapter->netdev, tq - adapter->tx_queue); + netif_start_queue(adapter->netdev); } @@ -118,7 +115,7 @@ static void vmxnet3_tq_wake(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { tq->stopped = false; - netif_wake_subqueue(adapter->netdev, (tq - adapter->tx_queue)); + netif_wake_queue(adapter->netdev); } @@ -127,7 +124,7 @@ vmxnet3_tq_stop(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { tq->stopped = true; tq->num_stop++; - netif_stop_subqueue(adapter->netdev, (tq - adapter->tx_queue)); + netif_stop_queue(adapter->netdev); } @@ -138,7 +135,6 @@ static void vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue) { u32 ret; - int i; VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK); ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD); @@ -149,28 +145,22 @@ vmxnet3_check_link(struct vmxnet3_adapter *adapter, bool affectTxQueue) if (!netif_carrier_ok(adapter->netdev)) netif_carrier_on(adapter->netdev); - if (affectTxQueue) { - for (i = 0; i < adapter->num_tx_queues; i++) - vmxnet3_tq_start(&adapter->tx_queue[i], - adapter); - } + if (affectTxQueue) + vmxnet3_tq_start(&adapter->tx_queue, adapter); } else { printk(KERN_INFO "%s: NIC Link is Down\n", adapter->netdev->name); if (netif_carrier_ok(adapter->netdev)) netif_carrier_off(adapter->netdev); - if (affectTxQueue) { - for (i = 0; i < adapter->num_tx_queues; i++) - vmxnet3_tq_stop(&adapter->tx_queue[i], adapter); - } + if (affectTxQueue) + vmxnet3_tq_stop(&adapter->tx_queue, adapter); } } static void vmxnet3_process_events(struct vmxnet3_adapter *adapter) { - int i; u32 events = le32_to_cpu(adapter->shared->ecr); if (!events) return; @@ -186,18 +176,16 @@ vmxnet3_process_events(struct vmxnet3_adapter *adapter) VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_QUEUE_STATUS); - for (i = 0; i < adapter->num_tx_queues; i++) - if (adapter->tqd_start[i].status.stopped) - dev_err(&adapter->netdev->dev, - "%s: tq[%d] error 0x%x\n", - adapter->netdev->name, i, le32_to_cpu( - adapter->tqd_start[i].status.error)); - for (i = 0; i < adapter->num_rx_queues; i++) - if (adapter->rqd_start[i].status.stopped) - dev_err(&adapter->netdev->dev, - "%s: rq[%d] error 0x%x\n", - adapter->netdev->name, i, - adapter->rqd_start[i].status.error); + if (adapter->tqd_start->status.stopped) { + printk(KERN_ERR "%s: tq error 0x%x\n", + adapter->netdev->name, + le32_to_cpu(adapter->tqd_start->status.error)); + } + if (adapter->rqd_start->status.stopped) { + printk(KERN_ERR "%s: rq error 0x%x\n", + adapter->netdev->name, + adapter->rqd_start->status.error); + } schedule_work(&adapter->work); } @@ -422,7 +410,7 @@ vmxnet3_tq_cleanup(struct vmxnet3_tx_queue *tq, } -static void +void vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) { @@ -449,17 +437,6 @@ vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq, } -/* Destroy all tx queues */ -void -vmxnet3_tq_destroy_all(struct vmxnet3_adapter *adapter) -{ - int i; - - for (i = 0; i < adapter->num_tx_queues; i++) - vmxnet3_tq_destroy(&adapter->tx_queue[i], adapter); -} - - static void vmxnet3_tq_init(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter) @@ -541,14 +518,6 @@ vmxnet3_tq_create(struct vmxnet3_tx_queue *tq, return -ENOMEM; } -static void -vmxnet3_tq_cleanup_all(struct vmxnet3_adapter *adapter) -{ - int i; - - for (i = 0; i < adapter->num_tx_queues; i++) - vmxnet3_tq_cleanup(&adapter->tx_queue[i], adapter); -} /* * starting from ring->next2fill, allocate rx buffers for the given ring @@ -763,17 +732,6 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx, } -/* Init all tx queues */ -static void -vmxnet3_tq_init_all(struct vmxnet3_adapter *adapter) -{ - int i; - - for (i = 0; i < adapter->num_tx_queues; i++) - vmxnet3_tq_init(&adapter->tx_queue[i], adapter); -} - - /* * parse and copy relevant protocol headers: * For a tso pkt, relevant headers are L2/3/4 including options @@ -945,21 +903,6 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, } } - spin_lock_irqsave(&tq->tx_lock, flags); - - if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) { - tq->stats.tx_ring_full++; - dev_dbg(&adapter->netdev->dev, - "tx queue stopped on %s, next2comp %u" - " next2fill %u\n", adapter->netdev->name, - tq->tx_ring.next2comp, tq->tx_ring.next2fill); - - vmxnet3_tq_stop(tq, adapter); - spin_unlock_irqrestore(&tq->tx_lock, flags); - return NETDEV_TX_BUSY; - } - - ret = vmxnet3_parse_and_copy_hdr(skb, tq, &ctx, adapter); if (ret >= 0) { BUG_ON(ret <= 0 && ctx.copy_size != 0); @@ -983,6 +926,20 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, goto drop_pkt; } + spin_lock_irqsave(&tq->tx_lock, flags); + + if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) { + tq->stats.tx_ring_full++; + dev_dbg(&adapter->netdev->dev, + "tx queue stopped on %s, next2comp %u" + " next2fill %u\n", adapter->netdev->name, + tq->tx_ring.next2comp, tq->tx_ring.next2fill); + + vmxnet3_tq_stop(tq, adapter); + spin_unlock_irqrestore(&tq->tx_lock, flags); + return NETDEV_TX_BUSY; + } + /* fill tx descs related to addr & len */ vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter); @@ -1043,8 +1000,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, if (le32_to_cpu(tq->shared->txNumDeferred) >= le32_to_cpu(tq->shared->txThreshold)) { tq->shared->txNumDeferred = 0; - VMXNET3_WRITE_BAR0_REG(adapter, - VMXNET3_REG_TXPROD + tq->qid * 8, + VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_TXPROD, tq->tx_ring.next2fill); } @@ -1064,10 +1020,7 @@ vmxnet3_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); - BUG_ON(skb->queue_mapping > adapter->num_tx_queues); - return vmxnet3_tq_xmit(skb, - &adapter->tx_queue[skb->queue_mapping], - adapter, netdev); + return vmxnet3_tq_xmit(skb, &adapter->tx_queue, adapter, netdev); } @@ -1153,9 +1106,9 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, break; } num_rxd++; - BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2); + idx = rcd->rxdIdx; - ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1; + ring_idx = rcd->rqID == rq->qid ? 0 : 1; vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd, &rxCmdDesc); rbi = rq->buf_info[ring_idx] + idx; @@ -1307,16 +1260,6 @@ vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq, } -static void -vmxnet3_rq_cleanup_all(struct vmxnet3_adapter *adapter) -{ - int i; - - for (i = 0; i < adapter->num_rx_queues; i++) - vmxnet3_rq_cleanup(&adapter->rx_queue[i], adapter); -} - - void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter) { @@ -1407,25 +1350,6 @@ vmxnet3_rq_init(struct vmxnet3_rx_queue *rq, } -static int -vmxnet3_rq_init_all(struct vmxnet3_adapter *adapter) -{ - int i, err = 0; - - for (i = 0; i < adapter->num_rx_queues; i++) { - err = vmxnet3_rq_init(&adapter->rx_queue[i], adapter); - if (unlikely(err)) { - dev_err(&adapter->netdev->dev, "%s: failed to " - "initialize rx queue%i\n", - adapter->netdev->name, i); - break; - } - } - return err; - -} - - static int vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter) { @@ -1473,178 +1397,34 @@ vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter) } -static int -vmxnet3_rq_create_all(struct vmxnet3_adapter *adapter) -{ - int i, err = 0; - - for (i = 0; i < adapter->num_rx_queues; i++) { - err = vmxnet3_rq_create(&adapter->rx_queue[i], adapter); - if (unlikely(err)) { - dev_err(&adapter->netdev->dev, - "%s: failed to create rx queue%i\n", - adapter->netdev->name, i); - goto err_out; - } - } - return err; -err_out: - vmxnet3_rq_destroy_all(adapter); - return err; - -} - -/* Multiple queue aware polling function for tx and rx */ - static int vmxnet3_do_poll(struct vmxnet3_adapter *adapter, int budget) { - int rcd_done = 0, i; if (unlikely(adapter->shared->ecr)) vmxnet3_process_events(adapter); - for (i = 0; i < adapter->num_tx_queues; i++) - vmxnet3_tq_tx_complete(&adapter->tx_queue[i], adapter); - for (i = 0; i < adapter->num_rx_queues; i++) - rcd_done += vmxnet3_rq_rx_complete(&adapter->rx_queue[i], - adapter, budget); - return rcd_done; + vmxnet3_tq_tx_complete(&adapter->tx_queue, adapter); + return vmxnet3_rq_rx_complete(&adapter->rx_queue, adapter, budget); } static int vmxnet3_poll(struct napi_struct *napi, int budget) { - struct vmxnet3_rx_queue *rx_queue = container_of(napi, - struct vmxnet3_rx_queue, napi); - int rxd_done; - - rxd_done = vmxnet3_do_poll(rx_queue->adapter, budget); - - if (rxd_done < budget) { - napi_complete(napi); - vmxnet3_enable_all_intrs(rx_queue->adapter); - } - return rxd_done; -} - -/* - * NAPI polling function for MSI-X mode with multiple Rx queues - * Returns the # of the NAPI credit consumed (# of rx descriptors processed) - */ - -static int -vmxnet3_poll_rx_only(struct napi_struct *napi, int budget) -{ - struct vmxnet3_rx_queue *rq = container_of(napi, - struct vmxnet3_rx_queue, napi); - struct vmxnet3_adapter *adapter = rq->adapter; + struct vmxnet3_adapter *adapter = container_of(napi, + struct vmxnet3_adapter, napi); int rxd_done; - /* When sharing interrupt with corresponding tx queue, process - * tx completions in that queue as well - */ - if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE) { - struct vmxnet3_tx_queue *tq = - &adapter->tx_queue[rq - adapter->rx_queue]; - vmxnet3_tq_tx_complete(tq, adapter); - } - - rxd_done = vmxnet3_rq_rx_complete(rq, adapter, budget); + rxd_done = vmxnet3_do_poll(adapter, budget); if (rxd_done < budget) { napi_complete(napi); - vmxnet3_enable_intr(adapter, rq->comp_ring.intr_idx); + vmxnet3_enable_intr(adapter, 0); } return rxd_done; } -#ifdef CONFIG_PCI_MSI - -/* - * Handle completion interrupts on tx queues - * Returns whether or not the intr is handled - */ - -static irqreturn_t -vmxnet3_msix_tx(int irq, void *data) -{ - struct vmxnet3_tx_queue *tq = data; - struct vmxnet3_adapter *adapter = tq->adapter; - - if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) - vmxnet3_disable_intr(adapter, tq->comp_ring.intr_idx); - - /* Handle the case where only one irq is allocate for all tx queues */ - if (adapter->share_intr == VMXNET3_INTR_TXSHARE) { - int i; - for (i = 0; i < adapter->num_tx_queues; i++) { - struct vmxnet3_tx_queue *txq = &adapter->tx_queue[i]; - vmxnet3_tq_tx_complete(txq, adapter); - } - } else { - vmxnet3_tq_tx_complete(tq, adapter); - } - vmxnet3_enable_intr(adapter, tq->comp_ring.intr_idx); - - return IRQ_HANDLED; -} - - -/* - * Handle completion interrupts on rx queues. Returns whether or not the - * intr is handled - */ - -static irqreturn_t -vmxnet3_msix_rx(int irq, void *data) -{ - struct vmxnet3_rx_queue *rq = data; - struct vmxnet3_adapter *adapter = rq->adapter; - - /* disable intr if needed */ - if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) - vmxnet3_disable_intr(adapter, rq->comp_ring.intr_idx); - napi_schedule(&rq->napi); - - return IRQ_HANDLED; -} - -/* - *---------------------------------------------------------------------------- - * - * vmxnet3_msix_event -- - * - * vmxnet3 msix event intr handler - * - * Result: - * whether or not the intr is handled - * - *---------------------------------------------------------------------------- - */ - -static irqreturn_t -vmxnet3_msix_event(int irq, void *data) -{ - struct net_device *dev = data; - struct vmxnet3_adapter *adapter = netdev_priv(dev); - - /* disable intr if needed */ - if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) - vmxnet3_disable_intr(adapter, adapter->intr.event_intr_idx); - - if (adapter->shared->ecr) - vmxnet3_process_events(adapter); - - vmxnet3_enable_intr(adapter, adapter->intr.event_intr_idx); - - return IRQ_HANDLED; -} - -#endif /* CONFIG_PCI_MSI */ - - /* Interrupt handler for vmxnet3 */ static irqreturn_t vmxnet3_intr(int irq, void *dev_id) @@ -1652,7 +1432,7 @@ vmxnet3_intr(int irq, void *dev_id) struct net_device *dev = dev_id; struct vmxnet3_adapter *adapter = netdev_priv(dev); - if (adapter->intr.type == VMXNET3_IT_INTX) { + if (unlikely(adapter->intr.type == VMXNET3_IT_INTX)) { u32 icr = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ICR); if (unlikely(icr == 0)) /* not ours */ @@ -1662,144 +1442,77 @@ vmxnet3_intr(int irq, void *dev_id) /* disable intr if needed */ if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) - vmxnet3_disable_all_intrs(adapter); + vmxnet3_disable_intr(adapter, 0); - napi_schedule(&adapter->rx_queue[0].napi); + napi_schedule(&adapter->napi); return IRQ_HANDLED; } #ifdef CONFIG_NET_POLL_CONTROLLER + /* netpoll callback. */ static void vmxnet3_netpoll(struct net_device *netdev) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); + int irq; - if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) - vmxnet3_disable_all_intrs(adapter); - - vmxnet3_do_poll(adapter, adapter->rx_queue[0].rx_ring[0].size); - vmxnet3_enable_all_intrs(adapter); +#ifdef CONFIG_PCI_MSI + if (adapter->intr.type == VMXNET3_IT_MSIX) + irq = adapter->intr.msix_entries[0].vector; + else +#endif + irq = adapter->pdev->irq; + disable_irq(irq); + vmxnet3_intr(irq, netdev); + enable_irq(irq); } -#endif /* CONFIG_NET_POLL_CONTROLLER */ +#endif static int vmxnet3_request_irqs(struct vmxnet3_adapter *adapter) { - struct vmxnet3_intr *intr = &adapter->intr; - int err = 0, i; - int vector = 0; + int err; #ifdef CONFIG_PCI_MSI if (adapter->intr.type == VMXNET3_IT_MSIX) { - for (i = 0; i < adapter->num_tx_queues; i++) { - if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) { - sprintf(adapter->tx_queue[i].name, "%s-tx-%d", - adapter->netdev->name, vector); - err = request_irq( - intr->msix_entries[vector].vector, - vmxnet3_msix_tx, 0, - adapter->tx_queue[i].name, - &adapter->tx_queue[i]); - } else { - sprintf(adapter->tx_queue[i].name, "%s-rxtx-%d", - adapter->netdev->name, vector); - } - if (err) { - dev_err(&adapter->netdev->dev, - "Failed to request irq for MSIX, %s, " - "error %d\n", - adapter->tx_queue[i].name, err); - return err; - } - - /* Handle the case where only 1 MSIx was allocated for - * all tx queues */ - if (adapter->share_intr == VMXNET3_INTR_TXSHARE) { - for (; i < adapter->num_tx_queues; i++) - adapter->tx_queue[i].comp_ring.intr_idx - = vector; - vector++; - break; - } else { - adapter->tx_queue[i].comp_ring.intr_idx - = vector++; - } - } - if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE) - vector = 0; - - for (i = 0; i < adapter->num_rx_queues; i++) { - if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) - sprintf(adapter->rx_queue[i].name, "%s-rx-%d", - adapter->netdev->name, vector); - else - sprintf(adapter->rx_queue[i].name, "%s-rxtx-%d", - adapter->netdev->name, vector); - err = request_irq(intr->msix_entries[vector].vector, - vmxnet3_msix_rx, 0, - adapter->rx_queue[i].name, - &(adapter->rx_queue[i])); - if (err) { - printk(KERN_ERR "Failed to request irq for MSIX" - ", %s, error %d\n", - adapter->rx_queue[i].name, err); - return err; - } - - adapter->rx_queue[i].comp_ring.intr_idx = vector++; - } - - sprintf(intr->event_msi_vector_name, "%s-event-%d", - adapter->netdev->name, vector); - err = request_irq(intr->msix_entries[vector].vector, - vmxnet3_msix_event, 0, - intr->event_msi_vector_name, adapter->netdev); - intr->event_intr_idx = vector; - - } else if (intr->type == VMXNET3_IT_MSI) { - adapter->num_rx_queues = 1; + /* we only use 1 MSI-X vector */ + err = request_irq(adapter->intr.msix_entries[0].vector, + vmxnet3_intr, 0, adapter->netdev->name, + adapter->netdev); + } else if (adapter->intr.type == VMXNET3_IT_MSI) { err = request_irq(adapter->pdev->irq, vmxnet3_intr, 0, adapter->netdev->name, adapter->netdev); - } else { + } else #endif - adapter->num_rx_queues = 1; + { err = request_irq(adapter->pdev->irq, vmxnet3_intr, IRQF_SHARED, adapter->netdev->name, adapter->netdev); -#ifdef CONFIG_PCI_MSI } -#endif - intr->num_intrs = vector + 1; - if (err) { - printk(KERN_ERR "Failed to request irq %s (intr type:%d), error" - ":%d\n", adapter->netdev->name, intr->type, err); - } else { - /* Number of rx queues will not change after this */ - for (i = 0; i < adapter->num_rx_queues; i++) { - struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i]; - rq->qid = i; - rq->qid2 = i + adapter->num_rx_queues; - } + if (err) + printk(KERN_ERR "Failed to request irq %s (intr type:%d), error" + ":%d\n", adapter->netdev->name, adapter->intr.type, err); + if (!err) { + int i; /* init our intr settings */ - for (i = 0; i < intr->num_intrs; i++) - intr->mod_levels[i] = UPT1_IML_ADAPTIVE; - if (adapter->intr.type != VMXNET3_IT_MSIX) { - adapter->intr.event_intr_idx = 0; - for (i = 0; i < adapter->num_tx_queues; i++) - adapter->tx_queue[i].comp_ring.intr_idx = 0; - adapter->rx_queue[0].comp_ring.intr_idx = 0; - } + for (i = 0; i < adapter->intr.num_intrs; i++) + adapter->intr.mod_levels[i] = UPT1_IML_ADAPTIVE; + + /* next setup intr index for all intr sources */ + adapter->tx_queue.comp_ring.intr_idx = 0; + adapter->rx_queue.comp_ring.intr_idx = 0; + adapter->intr.event_intr_idx = 0; printk(KERN_INFO "%s: intr type %u, mode %u, %u vectors " - "allocated\n", adapter->netdev->name, intr->type, - intr->mask_mode, intr->num_intrs); + "allocated\n", adapter->netdev->name, adapter->intr.type, + adapter->intr.mask_mode, adapter->intr.num_intrs); } return err; @@ -1809,32 +1522,18 @@ vmxnet3_request_irqs(struct vmxnet3_adapter *adapter) static void vmxnet3_free_irqs(struct vmxnet3_adapter *adapter) { - struct vmxnet3_intr *intr = &adapter->intr; - BUG_ON(intr->type == VMXNET3_IT_AUTO || intr->num_intrs <= 0); + BUG_ON(adapter->intr.type == VMXNET3_IT_AUTO || + adapter->intr.num_intrs <= 0); - switch (intr->type) { + switch (adapter->intr.type) { #ifdef CONFIG_PCI_MSI case VMXNET3_IT_MSIX: { - int i, vector = 0; - - if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE) { - for (i = 0; i < adapter->num_tx_queues; i++) { - free_irq(intr->msix_entries[vector++].vector, - &(adapter->tx_queue[i])); - if (adapter->share_intr == VMXNET3_INTR_TXSHARE) - break; - } - } - - for (i = 0; i < adapter->num_rx_queues; i++) { - free_irq(intr->msix_entries[vector++].vector, - &(adapter->rx_queue[i])); - } + int i; - free_irq(intr->msix_entries[vector].vector, - adapter->netdev); - BUG_ON(vector >= intr->num_intrs); + for (i = 0; i < adapter->intr.num_intrs; i++) + free_irq(adapter->intr.msix_entries[i].vector, + adapter->netdev); break; } #endif @@ -2028,15 +1727,6 @@ vmxnet3_set_mc(struct net_device *netdev) kfree(new_table); } -void -vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter) -{ - int i; - - for (i = 0; i < adapter->num_rx_queues; i++) - vmxnet3_rq_destroy(&adapter->rx_queue[i], adapter); -} - /* * Set up driver_shared based on settings in adapter. @@ -2084,72 +1774,40 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter) devRead->misc.mtu = cpu_to_le32(adapter->netdev->mtu); devRead->misc.queueDescPA = cpu_to_le64(adapter->queue_desc_pa); devRead->misc.queueDescLen = cpu_to_le32( - adapter->num_tx_queues * sizeof(struct Vmxnet3_TxQueueDesc) + - adapter->num_rx_queues * sizeof(struct Vmxnet3_RxQueueDesc)); + sizeof(struct Vmxnet3_TxQueueDesc) + + sizeof(struct Vmxnet3_RxQueueDesc)); /* tx queue settings */ - devRead->misc.numTxQueues = adapter->num_tx_queues; - for (i = 0; i < adapter->num_tx_queues; i++) { - struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i]; - BUG_ON(adapter->tx_queue[i].tx_ring.base == NULL); - tqc = &adapter->tqd_start[i].conf; - tqc->txRingBasePA = cpu_to_le64(tq->tx_ring.basePA); - tqc->dataRingBasePA = cpu_to_le64(tq->data_ring.basePA); - tqc->compRingBasePA = cpu_to_le64(tq->comp_ring.basePA); - tqc->ddPA = cpu_to_le64(virt_to_phys(tq->buf_info)); - tqc->txRingSize = cpu_to_le32(tq->tx_ring.size); - tqc->dataRingSize = cpu_to_le32(tq->data_ring.size); - tqc->compRingSize = cpu_to_le32(tq->comp_ring.size); - tqc->ddLen = cpu_to_le32( - sizeof(struct vmxnet3_tx_buf_info) * - tqc->txRingSize); - tqc->intrIdx = tq->comp_ring.intr_idx; - } + BUG_ON(adapter->tx_queue.tx_ring.base == NULL); + + devRead->misc.numTxQueues = 1; + tqc = &adapter->tqd_start->conf; + tqc->txRingBasePA = cpu_to_le64(adapter->tx_queue.tx_ring.basePA); + tqc->dataRingBasePA = cpu_to_le64(adapter->tx_queue.data_ring.basePA); + tqc->compRingBasePA = cpu_to_le64(adapter->tx_queue.comp_ring.basePA); + tqc->ddPA = cpu_to_le64(virt_to_phys( + adapter->tx_queue.buf_info)); + tqc->txRingSize = cpu_to_le32(adapter->tx_queue.tx_ring.size); + tqc->dataRingSize = cpu_to_le32(adapter->tx_queue.data_ring.size); + tqc->compRingSize = cpu_to_le32(adapter->tx_queue.comp_ring.size); + tqc->ddLen = cpu_to_le32(sizeof(struct vmxnet3_tx_buf_info) * + tqc->txRingSize); + tqc->intrIdx = adapter->tx_queue.comp_ring.intr_idx; /* rx queue settings */ - devRead->misc.numRxQueues = adapter->num_rx_queues; - for (i = 0; i < adapter->num_rx_queues; i++) { - struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i]; - rqc = &adapter->rqd_start[i].conf; - rqc->rxRingBasePA[0] = cpu_to_le64(rq->rx_ring[0].basePA); - rqc->rxRingBasePA[1] = cpu_to_le64(rq->rx_ring[1].basePA); - rqc->compRingBasePA = cpu_to_le64(rq->comp_ring.basePA); - rqc->ddPA = cpu_to_le64(virt_to_phys( - rq->buf_info)); - rqc->rxRingSize[0] = cpu_to_le32(rq->rx_ring[0].size); - rqc->rxRingSize[1] = cpu_to_le32(rq->rx_ring[1].size); - rqc->compRingSize = cpu_to_le32(rq->comp_ring.size); - rqc->ddLen = cpu_to_le32( - sizeof(struct vmxnet3_rx_buf_info) * - (rqc->rxRingSize[0] + - rqc->rxRingSize[1])); - rqc->intrIdx = rq->comp_ring.intr_idx; - } - -#ifdef VMXNET3_RSS - memset(adapter->rss_conf, 0, sizeof(*adapter->rss_conf)); - - if (adapter->rss) { - struct UPT1_RSSConf *rssConf = adapter->rss_conf; - devRead->misc.uptFeatures |= UPT1_F_RSS; - devRead->misc.numRxQueues = adapter->num_rx_queues; - rssConf->hashType = UPT1_RSS_HASH_TYPE_TCP_IPV4 | - UPT1_RSS_HASH_TYPE_IPV4 | - UPT1_RSS_HASH_TYPE_TCP_IPV6 | - UPT1_RSS_HASH_TYPE_IPV6; - rssConf->hashFunc = UPT1_RSS_HASH_FUNC_TOEPLITZ; - rssConf->hashKeySize = UPT1_RSS_MAX_KEY_SIZE; - rssConf->indTableSize = VMXNET3_RSS_IND_TABLE_SIZE; - get_random_bytes(&rssConf->hashKey[0], rssConf->hashKeySize); - for (i = 0; i < rssConf->indTableSize; i++) - rssConf->indTable[i] = i % adapter->num_rx_queues; - - devRead->rssConfDesc.confVer = 1; - devRead->rssConfDesc.confLen = sizeof(*rssConf); - devRead->rssConfDesc.confPA = virt_to_phys(rssConf); - } - -#endif /* VMXNET3_RSS */ + devRead->misc.numRxQueues = 1; + rqc = &adapter->rqd_start->conf; + rqc->rxRingBasePA[0] = cpu_to_le64(adapter->rx_queue.rx_ring[0].basePA); + rqc->rxRingBasePA[1] = cpu_to_le64(adapter->rx_queue.rx_ring[1].basePA); + rqc->compRingBasePA = cpu_to_le64(adapter->rx_queue.comp_ring.basePA); + rqc->ddPA = cpu_to_le64(virt_to_phys( + adapter->rx_queue.buf_info)); + rqc->rxRingSize[0] = cpu_to_le32(adapter->rx_queue.rx_ring[0].size); + rqc->rxRingSize[1] = cpu_to_le32(adapter->rx_queue.rx_ring[1].size); + rqc->compRingSize = cpu_to_le32(adapter->rx_queue.comp_ring.size); + rqc->ddLen = cpu_to_le32(sizeof(struct vmxnet3_rx_buf_info) * + (rqc->rxRingSize[0] + rqc->rxRingSize[1])); + rqc->intrIdx = adapter->rx_queue.comp_ring.intr_idx; /* intr settings */ devRead->intrConf.autoMask = adapter->intr.mask_mode == @@ -2171,18 +1829,18 @@ vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter) int vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) { - int err, i; + int err; u32 ret; - dev_dbg(&adapter->netdev->dev, "%s: skb_buf_size %d, rx_buf_per_pkt %d," - " ring sizes %u %u %u\n", adapter->netdev->name, - adapter->skb_buf_size, adapter->rx_buf_per_pkt, - adapter->tx_queue[0].tx_ring.size, - adapter->rx_queue[0].rx_ring[0].size, - adapter->rx_queue[0].rx_ring[1].size); - - vmxnet3_tq_init_all(adapter); - err = vmxnet3_rq_init_all(adapter); + dev_dbg(&adapter->netdev->dev, + "%s: skb_buf_size %d, rx_buf_per_pkt %d, ring sizes" + " %u %u %u\n", adapter->netdev->name, adapter->skb_buf_size, + adapter->rx_buf_per_pkt, adapter->tx_queue.tx_ring.size, + adapter->rx_queue.rx_ring[0].size, + adapter->rx_queue.rx_ring[1].size); + + vmxnet3_tq_init(&adapter->tx_queue, adapter); + err = vmxnet3_rq_init(&adapter->rx_queue, adapter); if (err) { printk(KERN_ERR "Failed to init rx queue for %s: error %d\n", adapter->netdev->name, err); @@ -2212,15 +1870,10 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) err = -EINVAL; goto activate_err; } - - for (i = 0; i < adapter->num_rx_queues; i++) { - VMXNET3_WRITE_BAR0_REG(adapter, - VMXNET3_REG_RXPROD + i * VMXNET3_REG_ALIGN, - adapter->rx_queue[i].rx_ring[0].next2fill); - VMXNET3_WRITE_BAR0_REG(adapter, (VMXNET3_REG_RXPROD2 + - (i * VMXNET3_REG_ALIGN)), - adapter->rx_queue[i].rx_ring[1].next2fill); - } + VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD, + adapter->rx_queue.rx_ring[0].next2fill); + VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD2, + adapter->rx_queue.rx_ring[1].next2fill); /* Apply the rx filter settins last. */ vmxnet3_set_mc(adapter->netdev); @@ -2230,8 +1883,8 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) * tx queue if the link is up. */ vmxnet3_check_link(adapter, true); - for (i = 0; i < adapter->num_rx_queues; i++) - napi_enable(&adapter->rx_queue[i].napi); + + napi_enable(&adapter->napi); vmxnet3_enable_all_intrs(adapter); clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state); return 0; @@ -2243,7 +1896,7 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) irq_err: rq_err: /* free up buffers we allocated */ - vmxnet3_rq_cleanup_all(adapter); + vmxnet3_rq_cleanup(&adapter->rx_queue, adapter); return err; } @@ -2258,7 +1911,6 @@ vmxnet3_reset_dev(struct vmxnet3_adapter *adapter) int vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter) { - int i; if (test_and_set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state)) return 0; @@ -2267,14 +1919,13 @@ vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter) VMXNET3_CMD_QUIESCE_DEV); vmxnet3_disable_all_intrs(adapter); - for (i = 0; i < adapter->num_rx_queues; i++) - napi_disable(&adapter->rx_queue[i].napi); + napi_disable(&adapter->napi); netif_tx_disable(adapter->netdev); adapter->link_speed = 0; netif_carrier_off(adapter->netdev); - vmxnet3_tq_cleanup_all(adapter); - vmxnet3_rq_cleanup_all(adapter); + vmxnet3_tq_cleanup(&adapter->tx_queue, adapter); + vmxnet3_rq_cleanup(&adapter->rx_queue, adapter); vmxnet3_free_irqs(adapter); return 0; } @@ -2396,9 +2047,7 @@ vmxnet3_free_pci_resources(struct vmxnet3_adapter *adapter) static void vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter) { - size_t sz, i, ring0_size, ring1_size, comp_size; - struct vmxnet3_rx_queue *rq = &adapter->rx_queue[0]; - + size_t sz; if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE - VMXNET3_MAX_ETH_HDR_SIZE) { @@ -2420,19 +2069,11 @@ vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter) * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN */ sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN; - ring0_size = adapter->rx_queue[0].rx_ring[0].size; - ring0_size = (ring0_size + sz - 1) / sz * sz; - ring0_size = min_t(u32, rq->rx_ring[0].size, VMXNET3_RX_RING_MAX_SIZE / - sz * sz); - ring1_size = adapter->rx_queue[0].rx_ring[1].size; - comp_size = ring0_size + ring1_size; - - for (i = 0; i < adapter->num_rx_queues; i++) { - rq = &adapter->rx_queue[i]; - rq->rx_ring[0].size = ring0_size; - rq->rx_ring[1].size = ring1_size; - rq->comp_ring.size = comp_size; - } + adapter->rx_queue.rx_ring[0].size = (adapter->rx_queue.rx_ring[0].size + + sz - 1) / sz * sz; + adapter->rx_queue.rx_ring[0].size = min_t(u32, + adapter->rx_queue.rx_ring[0].size, + VMXNET3_RX_RING_MAX_SIZE / sz * sz); } @@ -2440,53 +2081,29 @@ int vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size) { - int err = 0, i; - - for (i = 0; i < adapter->num_tx_queues; i++) { - struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i]; - tq->tx_ring.size = tx_ring_size; - tq->data_ring.size = tx_ring_size; - tq->comp_ring.size = tx_ring_size; - tq->shared = &adapter->tqd_start[i].ctrl; - tq->stopped = true; - tq->adapter = adapter; - tq->qid = i; - err = vmxnet3_tq_create(tq, adapter); - /* - * Too late to change num_tx_queues. We cannot do away with - * lesser number of queues than what we asked for - */ - if (err) - goto queue_err; - } + int err; - adapter->rx_queue[0].rx_ring[0].size = rx_ring_size; - adapter->rx_queue[0].rx_ring[1].size = rx_ring2_size; + adapter->tx_queue.tx_ring.size = tx_ring_size; + adapter->tx_queue.data_ring.size = tx_ring_size; + adapter->tx_queue.comp_ring.size = tx_ring_size; + adapter->tx_queue.shared = &adapter->tqd_start->ctrl; + adapter->tx_queue.stopped = true; + err = vmxnet3_tq_create(&adapter->tx_queue, adapter); + if (err) + return err; + + adapter->rx_queue.rx_ring[0].size = rx_ring_size; + adapter->rx_queue.rx_ring[1].size = rx_ring2_size; vmxnet3_adjust_rx_ring_size(adapter); - for (i = 0; i < adapter->num_rx_queues; i++) { - struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i]; - /* qid and qid2 for rx queues will be assigned later when num - * of rx queues is finalized after allocating intrs */ - rq->shared = &adapter->rqd_start[i].ctrl; - rq->adapter = adapter; - err = vmxnet3_rq_create(rq, adapter); - if (err) { - if (i == 0) { - printk(KERN_ERR "Could not allocate any rx" - "queues. Aborting.\n"); - goto queue_err; - } else { - printk(KERN_INFO "Number of rx queues changed " - "to : %d.\n", i); - adapter->num_rx_queues = i; - err = 0; - break; - } - } - } - return err; -queue_err: - vmxnet3_tq_destroy_all(adapter); + adapter->rx_queue.comp_ring.size = adapter->rx_queue.rx_ring[0].size + + adapter->rx_queue.rx_ring[1].size; + adapter->rx_queue.qid = 0; + adapter->rx_queue.qid2 = 1; + adapter->rx_queue.shared = &adapter->rqd_start->ctrl; + err = vmxnet3_rq_create(&adapter->rx_queue, adapter); + if (err) + vmxnet3_tq_destroy(&adapter->tx_queue, adapter); + return err; } @@ -2494,12 +2111,11 @@ static int vmxnet3_open(struct net_device *netdev) { struct vmxnet3_adapter *adapter; - int err, i; + int err; adapter = netdev_priv(netdev); - for (i = 0; i < adapter->num_tx_queues; i++) - spin_lock_init(&adapter->tx_queue[i].tx_lock); + spin_lock_init(&adapter->tx_queue.tx_lock); err = vmxnet3_create_queues(adapter, VMXNET3_DEF_TX_RING_SIZE, VMXNET3_DEF_RX_RING_SIZE, @@ -2514,8 +2130,8 @@ vmxnet3_open(struct net_device *netdev) return 0; activate_err: - vmxnet3_rq_destroy_all(adapter); - vmxnet3_tq_destroy_all(adapter); + vmxnet3_rq_destroy(&adapter->rx_queue, adapter); + vmxnet3_tq_destroy(&adapter->tx_queue, adapter); queue_err: return err; } @@ -2535,8 +2151,8 @@ vmxnet3_close(struct net_device *netdev) vmxnet3_quiesce_dev(adapter); - vmxnet3_rq_destroy_all(adapter); - vmxnet3_tq_destroy_all(adapter); + vmxnet3_rq_destroy(&adapter->rx_queue, adapter); + vmxnet3_tq_destroy(&adapter->tx_queue, adapter); clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state); @@ -2548,8 +2164,6 @@ vmxnet3_close(struct net_device *netdev) void vmxnet3_force_close(struct vmxnet3_adapter *adapter) { - int i; - /* * we must clear VMXNET3_STATE_BIT_RESETTING, otherwise * vmxnet3_close() will deadlock. @@ -2557,8 +2171,7 @@ vmxnet3_force_close(struct vmxnet3_adapter *adapter) BUG_ON(test_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state)); /* we need to enable NAPI, otherwise dev_close will deadlock */ - for (i = 0; i < adapter->num_rx_queues; i++) - napi_enable(&adapter->rx_queue[i].napi); + napi_enable(&adapter->napi); dev_close(adapter->netdev); } @@ -2589,11 +2202,14 @@ vmxnet3_change_mtu(struct net_device *netdev, int new_mtu) vmxnet3_reset_dev(adapter); /* we need to re-create the rx queue based on the new mtu */ - vmxnet3_rq_destroy_all(adapter); + vmxnet3_rq_destroy(&adapter->rx_queue, adapter); vmxnet3_adjust_rx_ring_size(adapter); - err = vmxnet3_rq_create_all(adapter); + adapter->rx_queue.comp_ring.size = + adapter->rx_queue.rx_ring[0].size + + adapter->rx_queue.rx_ring[1].size; + err = vmxnet3_rq_create(&adapter->rx_queue, adapter); if (err) { - printk(KERN_ERR "%s: failed to re-create rx queues," + printk(KERN_ERR "%s: failed to re-create rx queue," " error %d. Closing it.\n", netdev->name, err); goto out; } @@ -2658,55 +2274,6 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac) mac[5] = (tmp >> 8) & 0xff; } -#ifdef CONFIG_PCI_MSI - -/* - * Enable MSIx vectors. - * Returns : - * 0 on successful enabling of required vectors, - * VMXNET3_LINUX_MIN_MSIX_VECT when only minumum number of vectors required - * could be enabled. - * number of vectors which can be enabled otherwise (this number is smaller - * than VMXNET3_LINUX_MIN_MSIX_VECT) - */ - -static int -vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, - int vectors) -{ - int err = 0, vector_threshold; - vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT; - - while (vectors >= vector_threshold) { - err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries, - vectors); - if (!err) { - adapter->intr.num_intrs = vectors; - return 0; - } else if (err < 0) { - printk(KERN_ERR "Failed to enable MSI-X for %s, error" - " %d\n", adapter->netdev->name, err); - vectors = 0; - } else if (err < vector_threshold) { - break; - } else { - /* If fails to enable required number of MSI-x vectors - * try enabling 3 of them. One each for rx, tx and event - */ - vectors = vector_threshold; - printk(KERN_ERR "Failed to enable %d MSI-X for %s, try" - " %d instead\n", vectors, adapter->netdev->name, - vector_threshold); - } - } - - printk(KERN_INFO "Number of MSI-X interrupts which can be allocatedi" - " are lower than min threshold required.\n"); - return err; -} - - -#endif /* CONFIG_PCI_MSI */ static void vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) @@ -2726,47 +2293,16 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) #ifdef CONFIG_PCI_MSI if (adapter->intr.type == VMXNET3_IT_MSIX) { - int vector, err = 0; - - adapter->intr.num_intrs = (adapter->share_intr == - VMXNET3_INTR_TXSHARE) ? 1 : - adapter->num_tx_queues; - adapter->intr.num_intrs += (adapter->share_intr == - VMXNET3_INTR_BUDDYSHARE) ? 0 : - adapter->num_rx_queues; - adapter->intr.num_intrs += 1; /* for link event */ - - adapter->intr.num_intrs = (adapter->intr.num_intrs > - VMXNET3_LINUX_MIN_MSIX_VECT - ? adapter->intr.num_intrs : - VMXNET3_LINUX_MIN_MSIX_VECT); - - for (vector = 0; vector < adapter->intr.num_intrs; vector++) - adapter->intr.msix_entries[vector].entry = vector; - - err = vmxnet3_acquire_msix_vectors(adapter, - adapter->intr.num_intrs); - /* If we cannot allocate one MSIx vector per queue - * then limit the number of rx queues to 1 - */ - if (err == VMXNET3_LINUX_MIN_MSIX_VECT) { - if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE - || adapter->num_rx_queues != 2) { - adapter->share_intr = VMXNET3_INTR_TXSHARE; - printk(KERN_ERR "Number of rx queues : 1\n"); - adapter->num_rx_queues = 1; - adapter->intr.num_intrs = - VMXNET3_LINUX_MIN_MSIX_VECT; - } + int err; + + adapter->intr.msix_entries[0].entry = 0; + err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries, + VMXNET3_LINUX_MAX_MSIX_VECT); + if (!err) { + adapter->intr.num_intrs = 1; + adapter->intr.type = VMXNET3_IT_MSIX; return; } - if (!err) - return; - - /* If we cannot allocate MSIx vectors use only one rx queue */ - printk(KERN_INFO "Failed to enable MSI-X for %s, error %d." - "#rx queues : 1, try MSI\n", adapter->netdev->name, err); - adapter->intr.type = VMXNET3_IT_MSI; } @@ -2774,15 +2310,12 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) int err; err = pci_enable_msi(adapter->pdev); if (!err) { - adapter->num_rx_queues = 1; adapter->intr.num_intrs = 1; return; } } #endif /* CONFIG_PCI_MSI */ - adapter->num_rx_queues = 1; - printk(KERN_INFO "Using INTx interrupt, #Rx queues: 1.\n"); adapter->intr.type = VMXNET3_IT_INTX; /* INT-X related setting */ @@ -2810,7 +2343,6 @@ vmxnet3_tx_timeout(struct net_device *netdev) printk(KERN_ERR "%s: tx hang\n", adapter->netdev->name); schedule_work(&adapter->work); - netif_wake_queue(adapter->netdev); } @@ -2867,29 +2399,8 @@ vmxnet3_probe_device(struct pci_dev *pdev, struct net_device *netdev; struct vmxnet3_adapter *adapter; u8 mac[ETH_ALEN]; - int size; - int num_tx_queues; - int num_rx_queues; - -#ifdef VMXNET3_RSS - if (enable_mq) - num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES, - (int)num_online_cpus()); - else -#endif - num_rx_queues = 1; - - if (enable_mq) - num_tx_queues = min(VMXNET3_DEVICE_MAX_TX_QUEUES, - (int)num_online_cpus()); - else - num_tx_queues = 1; - - netdev = alloc_etherdev_mq(sizeof(struct vmxnet3_adapter), - max(num_tx_queues, num_rx_queues)); - printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n", - num_tx_queues, num_rx_queues); + netdev = alloc_etherdev(sizeof(struct vmxnet3_adapter)); if (!netdev) { printk(KERN_ERR "Failed to alloc ethernet device for adapter " "%s\n", pci_name(pdev)); @@ -2911,12 +2422,9 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_alloc_shared; } - adapter->num_rx_queues = num_rx_queues; - adapter->num_tx_queues = num_tx_queues; - - size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues; - size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues; - adapter->tqd_start = pci_alloc_consistent(adapter->pdev, size, + adapter->tqd_start = pci_alloc_consistent(adapter->pdev, + sizeof(struct Vmxnet3_TxQueueDesc) + + sizeof(struct Vmxnet3_RxQueueDesc), &adapter->queue_desc_pa); if (!adapter->tqd_start) { @@ -2925,8 +2433,8 @@ vmxnet3_probe_device(struct pci_dev *pdev, err = -ENOMEM; goto err_alloc_queue_desc; } - adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start + - adapter->num_tx_queues); + adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start + + 1); adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL); if (adapter->pm_conf == NULL) { @@ -2936,17 +2444,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, goto err_alloc_pm; } -#ifdef VMXNET3_RSS - - adapter->rss_conf = kmalloc(sizeof(struct UPT1_RSSConf), GFP_KERNEL); - if (adapter->rss_conf == NULL) { - printk(KERN_ERR "Failed to allocate memory for %s\n", - pci_name(pdev)); - err = -ENOMEM; - goto err_alloc_rss; - } -#endif /* VMXNET3_RSS */ - err = vmxnet3_alloc_pci_resources(adapter, &dma64); if (err < 0) goto err_alloc_pci; @@ -2974,48 +2471,18 @@ vmxnet3_probe_device(struct pci_dev *pdev, vmxnet3_declare_features(adapter, dma64); adapter->dev_number = atomic_read(&devices_found); - - adapter->share_intr = irq_share_mode; - if (adapter->share_intr == VMXNET3_INTR_BUDDYSHARE && - adapter->num_tx_queues != adapter->num_rx_queues) - adapter->share_intr = VMXNET3_INTR_DONTSHARE; - vmxnet3_alloc_intr_resources(adapter); -#ifdef VMXNET3_RSS - if (adapter->num_rx_queues > 1 && - adapter->intr.type == VMXNET3_IT_MSIX) { - adapter->rss = true; - printk(KERN_INFO "RSS is enabled.\n"); - } else { - adapter->rss = false; - } -#endif - vmxnet3_read_mac_addr(adapter, mac); memcpy(netdev->dev_addr, mac, netdev->addr_len); netdev->netdev_ops = &vmxnet3_netdev_ops; - vmxnet3_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; + vmxnet3_set_ethtool_ops(netdev); INIT_WORK(&adapter->work, vmxnet3_reset_work); - if (adapter->intr.type == VMXNET3_IT_MSIX) { - int i; - for (i = 0; i < adapter->num_rx_queues; i++) { - netif_napi_add(adapter->netdev, - &adapter->rx_queue[i].napi, - vmxnet3_poll_rx_only, 64); - } - } else { - netif_napi_add(adapter->netdev, &adapter->rx_queue[0].napi, - vmxnet3_poll, 64); - } - - netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); - netif_set_real_num_rx_queues(adapter->netdev, adapter->num_rx_queues); - + netif_napi_add(netdev, &adapter->napi, vmxnet3_poll, 64); SET_NETDEV_DEV(netdev, &pdev->dev); err = register_netdev(netdev); @@ -3035,14 +2502,11 @@ vmxnet3_probe_device(struct pci_dev *pdev, err_ver: vmxnet3_free_pci_resources(adapter); err_alloc_pci: -#ifdef VMXNET3_RSS - kfree(adapter->rss_conf); -err_alloc_rss: -#endif kfree(adapter->pm_conf); err_alloc_pm: - pci_free_consistent(adapter->pdev, size, adapter->tqd_start, - adapter->queue_desc_pa); + pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) + + sizeof(struct Vmxnet3_RxQueueDesc), + adapter->tqd_start, adapter->queue_desc_pa); err_alloc_queue_desc: pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared), adapter->shared, adapter->shared_pa); @@ -3058,16 +2522,6 @@ vmxnet3_remove_device(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct vmxnet3_adapter *adapter = netdev_priv(netdev); - int size = 0; - int num_rx_queues; - -#ifdef VMXNET3_RSS - if (enable_mq) - num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES, - (int)num_online_cpus()); - else -#endif - num_rx_queues = 1; flush_scheduled_work(); @@ -3075,15 +2529,10 @@ vmxnet3_remove_device(struct pci_dev *pdev) vmxnet3_free_intr_resources(adapter); vmxnet3_free_pci_resources(adapter); -#ifdef VMXNET3_RSS - kfree(adapter->rss_conf); -#endif kfree(adapter->pm_conf); - - size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues; - size += sizeof(struct Vmxnet3_RxQueueDesc) * num_rx_queues; - pci_free_consistent(adapter->pdev, size, adapter->tqd_start, - adapter->queue_desc_pa); + pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) + + sizeof(struct Vmxnet3_RxQueueDesc), + adapter->tqd_start, adapter->queue_desc_pa); pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared), adapter->shared, adapter->shared_pa); free_netdev(netdev); @@ -3114,7 +2563,7 @@ vmxnet3_suspend(struct device *device) vmxnet3_free_intr_resources(adapter); netif_device_detach(netdev); - netif_tx_stop_all_queues(netdev); + netif_stop_queue(netdev); /* Create wake-up filters. */ pmConf = adapter->pm_conf; diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c index 8e17fc8a7fe7..b79070bcc92e 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -151,42 +151,44 @@ vmxnet3_get_stats(struct net_device *netdev) struct UPT1_TxStats *devTxStats; struct UPT1_RxStats *devRxStats; struct net_device_stats *net_stats = &netdev->stats; - int i; adapter = netdev_priv(netdev); /* Collect the dev stats into the shared area */ VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS); + /* Assuming that we have a single queue device */ + devTxStats = &adapter->tqd_start->stats; + devRxStats = &adapter->rqd_start->stats; + + /* Get access to the driver stats per queue */ + drvTxStats = &adapter->tx_queue.stats; + drvRxStats = &adapter->rx_queue.stats; + memset(net_stats, 0, sizeof(*net_stats)); - for (i = 0; i < adapter->num_tx_queues; i++) { - devTxStats = &adapter->tqd_start[i].stats; - drvTxStats = &adapter->tx_queue[i].stats; - net_stats->tx_packets += devTxStats->ucastPktsTxOK + - devTxStats->mcastPktsTxOK + - devTxStats->bcastPktsTxOK; - net_stats->tx_bytes += devTxStats->ucastBytesTxOK + - devTxStats->mcastBytesTxOK + - devTxStats->bcastBytesTxOK; - net_stats->tx_errors += devTxStats->pktsTxError; - net_stats->tx_dropped += drvTxStats->drop_total; - } - for (i = 0; i < adapter->num_rx_queues; i++) { - devRxStats = &adapter->rqd_start[i].stats; - drvRxStats = &adapter->rx_queue[i].stats; - net_stats->rx_packets += devRxStats->ucastPktsRxOK + - devRxStats->mcastPktsRxOK + - devRxStats->bcastPktsRxOK; + net_stats->rx_packets = devRxStats->ucastPktsRxOK + + devRxStats->mcastPktsRxOK + + devRxStats->bcastPktsRxOK; - net_stats->rx_bytes += devRxStats->ucastBytesRxOK + - devRxStats->mcastBytesRxOK + - devRxStats->bcastBytesRxOK; + net_stats->tx_packets = devTxStats->ucastPktsTxOK + + devTxStats->mcastPktsTxOK + + devTxStats->bcastPktsTxOK; + + net_stats->rx_bytes = devRxStats->ucastBytesRxOK + + devRxStats->mcastBytesRxOK + + devRxStats->bcastBytesRxOK; + + net_stats->tx_bytes = devTxStats->ucastBytesTxOK + + devTxStats->mcastBytesTxOK + + devTxStats->bcastBytesTxOK; + + net_stats->rx_errors = devRxStats->pktsRxError; + net_stats->tx_errors = devTxStats->pktsTxError; + net_stats->rx_dropped = drvRxStats->drop_total; + net_stats->tx_dropped = drvTxStats->drop_total; + net_stats->multicast = devRxStats->mcastPktsRxOK; - net_stats->rx_errors += devRxStats->pktsRxError; - net_stats->rx_dropped += drvRxStats->drop_total; - net_stats->multicast += devRxStats->mcastPktsRxOK; - } return net_stats; } @@ -305,26 +307,24 @@ vmxnet3_get_ethtool_stats(struct net_device *netdev, struct vmxnet3_adapter *adapter = netdev_priv(netdev); u8 *base; int i; - int j = 0; VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS); /* this does assume each counter is 64-bit wide */ -/* TODO change this for multiple queues */ - base = (u8 *)&adapter->tqd_start[j].stats; + base = (u8 *)&adapter->tqd_start->stats; for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++) *buf++ = *(u64 *)(base + vmxnet3_tq_dev_stats[i].offset); - base = (u8 *)&adapter->tx_queue[j].stats; + base = (u8 *)&adapter->tx_queue.stats; for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++) *buf++ = *(u64 *)(base + vmxnet3_tq_driver_stats[i].offset); - base = (u8 *)&adapter->rqd_start[j].stats; + base = (u8 *)&adapter->rqd_start->stats; for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++) *buf++ = *(u64 *)(base + vmxnet3_rq_dev_stats[i].offset); - base = (u8 *)&adapter->rx_queue[j].stats; + base = (u8 *)&adapter->rx_queue.stats; for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++) *buf++ = *(u64 *)(base + vmxnet3_rq_driver_stats[i].offset); @@ -339,7 +339,6 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); u32 *buf = p; - int i = 0; memset(p, 0, vmxnet3_get_regs_len(netdev)); @@ -348,29 +347,28 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) /* Update vmxnet3_get_regs_len if we want to dump more registers */ /* make each ring use multiple of 16 bytes */ -/* TODO change this for multiple queues */ - buf[0] = adapter->tx_queue[i].tx_ring.next2fill; - buf[1] = adapter->tx_queue[i].tx_ring.next2comp; - buf[2] = adapter->tx_queue[i].tx_ring.gen; + buf[0] = adapter->tx_queue.tx_ring.next2fill; + buf[1] = adapter->tx_queue.tx_ring.next2comp; + buf[2] = adapter->tx_queue.tx_ring.gen; buf[3] = 0; - buf[4] = adapter->tx_queue[i].comp_ring.next2proc; - buf[5] = adapter->tx_queue[i].comp_ring.gen; - buf[6] = adapter->tx_queue[i].stopped; + buf[4] = adapter->tx_queue.comp_ring.next2proc; + buf[5] = adapter->tx_queue.comp_ring.gen; + buf[6] = adapter->tx_queue.stopped; buf[7] = 0; - buf[8] = adapter->rx_queue[i].rx_ring[0].next2fill; - buf[9] = adapter->rx_queue[i].rx_ring[0].next2comp; - buf[10] = adapter->rx_queue[i].rx_ring[0].gen; + buf[8] = adapter->rx_queue.rx_ring[0].next2fill; + buf[9] = adapter->rx_queue.rx_ring[0].next2comp; + buf[10] = adapter->rx_queue.rx_ring[0].gen; buf[11] = 0; - buf[12] = adapter->rx_queue[i].rx_ring[1].next2fill; - buf[13] = adapter->rx_queue[i].rx_ring[1].next2comp; - buf[14] = adapter->rx_queue[i].rx_ring[1].gen; + buf[12] = adapter->rx_queue.rx_ring[1].next2fill; + buf[13] = adapter->rx_queue.rx_ring[1].next2comp; + buf[14] = adapter->rx_queue.rx_ring[1].gen; buf[15] = 0; - buf[16] = adapter->rx_queue[i].comp_ring.next2proc; - buf[17] = adapter->rx_queue[i].comp_ring.gen; + buf[16] = adapter->rx_queue.comp_ring.next2proc; + buf[17] = adapter->rx_queue.comp_ring.gen; buf[18] = 0; buf[19] = 0; } @@ -437,10 +435,8 @@ vmxnet3_get_ringparam(struct net_device *netdev, param->rx_mini_max_pending = 0; param->rx_jumbo_max_pending = 0; - param->rx_pending = adapter->rx_queue[0].rx_ring[0].size * - adapter->num_rx_queues; - param->tx_pending = adapter->tx_queue[0].tx_ring.size * - adapter->num_tx_queues; + param->rx_pending = adapter->rx_queue.rx_ring[0].size; + param->tx_pending = adapter->tx_queue.tx_ring.size; param->rx_mini_pending = 0; param->rx_jumbo_pending = 0; } @@ -484,8 +480,8 @@ vmxnet3_set_ringparam(struct net_device *netdev, sz) != 0) return -EINVAL; - if (new_tx_ring_size == adapter->tx_queue[0].tx_ring.size && - new_rx_ring_size == adapter->rx_queue[0].rx_ring[0].size) { + if (new_tx_ring_size == adapter->tx_queue.tx_ring.size && + new_rx_ring_size == adapter->rx_queue.rx_ring[0].size) { return 0; } @@ -502,12 +498,11 @@ vmxnet3_set_ringparam(struct net_device *netdev, /* recreate the rx queue and the tx queue based on the * new sizes */ - vmxnet3_tq_destroy_all(adapter); - vmxnet3_rq_destroy_all(adapter); + vmxnet3_tq_destroy(&adapter->tx_queue, adapter); + vmxnet3_rq_destroy(&adapter->rx_queue, adapter); err = vmxnet3_create_queues(adapter, new_tx_ring_size, new_rx_ring_size, VMXNET3_DEF_RX_RING_SIZE); - if (err) { /* failed, most likely because of OOM, try default * size */ @@ -540,66 +535,6 @@ vmxnet3_set_ringparam(struct net_device *netdev, } -static int -vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info, - void *rules) -{ - struct vmxnet3_adapter *adapter = netdev_priv(netdev); - switch (info->cmd) { - case ETHTOOL_GRXRINGS: - info->data = adapter->num_rx_queues; - return 0; - } - return -EOPNOTSUPP; -} - -#ifdef VMXNET3_RSS -static int -vmxnet3_get_rss_indir(struct net_device *netdev, - struct ethtool_rxfh_indir *p) -{ - struct vmxnet3_adapter *adapter = netdev_priv(netdev); - struct UPT1_RSSConf *rssConf = adapter->rss_conf; - unsigned int n = min_t(unsigned int, p->size, rssConf->indTableSize); - - p->size = rssConf->indTableSize; - while (n--) - p->ring_index[n] = rssConf->indTable[n]; - return 0; - -} - -static int -vmxnet3_set_rss_indir(struct net_device *netdev, - const struct ethtool_rxfh_indir *p) -{ - unsigned int i; - struct vmxnet3_adapter *adapter = netdev_priv(netdev); - struct UPT1_RSSConf *rssConf = adapter->rss_conf; - - if (p->size != rssConf->indTableSize) - return -EINVAL; - for (i = 0; i < rssConf->indTableSize; i++) { - /* - * Return with error code if any of the queue indices - * is out of range - */ - if (p->ring_index[i] < 0 || - p->ring_index[i] >= adapter->num_rx_queues) - return -EINVAL; - } - - for (i = 0; i < rssConf->indTableSize; i++) - rssConf->indTable[i] = p->ring_index[i]; - - VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, - VMXNET3_CMD_UPDATE_RSSIDT); - - return 0; - -} -#endif - static struct ethtool_ops vmxnet3_ethtool_ops = { .get_settings = vmxnet3_get_settings, .get_drvinfo = vmxnet3_get_drvinfo, @@ -623,11 +558,6 @@ static struct ethtool_ops vmxnet3_ethtool_ops = { .get_ethtool_stats = vmxnet3_get_ethtool_stats, .get_ringparam = vmxnet3_get_ringparam, .set_ringparam = vmxnet3_set_ringparam, - .get_rxnfc = vmxnet3_get_rxnfc, -#ifdef VMXNET3_RSS - .get_rxfh_indir = vmxnet3_get_rss_indir, - .set_rxfh_indir = vmxnet3_set_rss_indir, -#endif }; void vmxnet3_set_ethtool_ops(struct net_device *netdev) diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_int.h b/trunk/drivers/net/vmxnet3/vmxnet3_int.h index 7fadeed37f03..edf228843afc 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_int.h +++ b/trunk/drivers/net/vmxnet3/vmxnet3_int.h @@ -68,15 +68,11 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.0.16.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.0.14.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01001000 +#define VMXNET3_DRIVER_VERSION_NUM 0x01000E00 -#if defined(CONFIG_PCI_MSI) - /* RSS only makes sense if MSI-X is supported. */ - #define VMXNET3_RSS -#endif /* * Capabilities @@ -222,19 +218,16 @@ struct vmxnet3_tx_ctx { }; struct vmxnet3_tx_queue { - char name[IFNAMSIZ+8]; /* To identify interrupt */ - struct vmxnet3_adapter *adapter; spinlock_t tx_lock; struct vmxnet3_cmd_ring tx_ring; - struct vmxnet3_tx_buf_info *buf_info; + struct vmxnet3_tx_buf_info *buf_info; struct vmxnet3_tx_data_ring data_ring; struct vmxnet3_comp_ring comp_ring; - struct Vmxnet3_TxQueueCtrl *shared; + struct Vmxnet3_TxQueueCtrl *shared; struct vmxnet3_tq_driver_stats stats; bool stopped; int num_stop; /* # of times the queue is * stopped */ - int qid; } __attribute__((__aligned__(SMP_CACHE_BYTES))); enum vmxnet3_rx_buf_type { @@ -266,9 +259,6 @@ struct vmxnet3_rq_driver_stats { }; struct vmxnet3_rx_queue { - char name[IFNAMSIZ + 8]; /* To identify interrupt */ - struct vmxnet3_adapter *adapter; - struct napi_struct napi; struct vmxnet3_cmd_ring rx_ring[2]; struct vmxnet3_comp_ring comp_ring; struct vmxnet3_rx_ctx rx_ctx; @@ -281,16 +271,7 @@ struct vmxnet3_rx_queue { struct vmxnet3_rq_driver_stats stats; } __attribute__((__aligned__(SMP_CACHE_BYTES))); -#define VMXNET3_DEVICE_MAX_TX_QUEUES 8 -#define VMXNET3_DEVICE_MAX_RX_QUEUES 8 /* Keep this value as a power of 2 */ - -/* Should be less than UPT1_RSS_MAX_IND_TABLE_SIZE */ -#define VMXNET3_RSS_IND_TABLE_SIZE (VMXNET3_DEVICE_MAX_RX_QUEUES * 4) - -#define VMXNET3_LINUX_MAX_MSIX_VECT (VMXNET3_DEVICE_MAX_TX_QUEUES + \ - VMXNET3_DEVICE_MAX_RX_QUEUES + 1) -#define VMXNET3_LINUX_MIN_MSIX_VECT 3 /* 1 for each : tx, rx and event */ - +#define VMXNET3_LINUX_MAX_MSIX_VECT 1 struct vmxnet3_intr { enum vmxnet3_intr_mask_mode mask_mode; @@ -298,32 +279,27 @@ struct vmxnet3_intr { u8 num_intrs; /* # of intr vectors */ u8 event_intr_idx; /* idx of the intr vector for event */ u8 mod_levels[VMXNET3_LINUX_MAX_MSIX_VECT]; /* moderation level */ - char event_msi_vector_name[IFNAMSIZ+11]; #ifdef CONFIG_PCI_MSI struct msix_entry msix_entries[VMXNET3_LINUX_MAX_MSIX_VECT]; #endif }; -/* Interrupt sharing schemes, share_intr */ -#define VMXNET3_INTR_BUDDYSHARE 0 /* Corresponding tx,rx queues share irq */ -#define VMXNET3_INTR_TXSHARE 1 /* All tx queues share one irq */ -#define VMXNET3_INTR_DONTSHARE 2 /* each queue has its own irq */ - - #define VMXNET3_STATE_BIT_RESETTING 0 #define VMXNET3_STATE_BIT_QUIESCED 1 struct vmxnet3_adapter { - struct vmxnet3_tx_queue tx_queue[VMXNET3_DEVICE_MAX_TX_QUEUES]; - struct vmxnet3_rx_queue rx_queue[VMXNET3_DEVICE_MAX_RX_QUEUES]; - struct vlan_group *vlan_grp; - struct vmxnet3_intr intr; - struct Vmxnet3_DriverShared *shared; - struct Vmxnet3_PMConf *pm_conf; - struct Vmxnet3_TxQueueDesc *tqd_start; /* all tx queue desc */ - struct Vmxnet3_RxQueueDesc *rqd_start; /* all rx queue desc */ - struct net_device *netdev; - struct net_device_stats net_stats; - struct pci_dev *pdev; + struct vmxnet3_tx_queue tx_queue; + struct vmxnet3_rx_queue rx_queue; + struct napi_struct napi; + struct vlan_group *vlan_grp; + + struct vmxnet3_intr intr; + + struct Vmxnet3_DriverShared *shared; + struct Vmxnet3_PMConf *pm_conf; + struct Vmxnet3_TxQueueDesc *tqd_start; /* first tx queue desc */ + struct Vmxnet3_RxQueueDesc *rqd_start; /* first rx queue desc */ + struct net_device *netdev; + struct pci_dev *pdev; u8 __iomem *hw_addr0; /* for BAR 0 */ u8 __iomem *hw_addr1; /* for BAR 1 */ @@ -332,12 +308,6 @@ struct vmxnet3_adapter { bool rxcsum; bool lro; bool jumbo_frame; -#ifdef VMXNET3_RSS - struct UPT1_RSSConf *rss_conf; - bool rss; -#endif - u32 num_rx_queues; - u32 num_tx_queues; /* rx buffer related */ unsigned skb_buf_size; @@ -357,7 +327,6 @@ struct vmxnet3_adapter { unsigned long state; /* VMXNET3_STATE_BIT_xxx */ int dev_number; - int share_intr; }; #define VMXNET3_WRITE_BAR0_REG(adapter, reg, val) \ @@ -397,10 +366,12 @@ void vmxnet3_reset_dev(struct vmxnet3_adapter *adapter); void -vmxnet3_tq_destroy_all(struct vmxnet3_adapter *adapter); +vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq, + struct vmxnet3_adapter *adapter); void -vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter); +vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq, + struct vmxnet3_adapter *adapter); int vmxnet3_create_queues(struct vmxnet3_adapter *adapter, diff --git a/trunk/drivers/net/vxge/vxge-config.c b/trunk/drivers/net/vxge/vxge-config.c index a0241fe72d8b..906a3ca3676b 100644 --- a/trunk/drivers/net/vxge/vxge-config.c +++ b/trunk/drivers/net/vxge/vxge-config.c @@ -19,7 +19,19 @@ #include "vxge-traffic.h" #include "vxge-config.h" -#include "vxge-main.h" + +static enum vxge_hw_status +__vxge_hw_fifo_create( + struct __vxge_hw_vpath_handle *vpath_handle, + struct vxge_hw_fifo_attr *attr); + +static enum vxge_hw_status +__vxge_hw_fifo_abort( + struct __vxge_hw_fifo *fifoh); + +static enum vxge_hw_status +__vxge_hw_fifo_reset( + struct __vxge_hw_fifo *ringh); static enum vxge_hw_status __vxge_hw_fifo_delete( @@ -59,15 +71,53 @@ __vxge_hw_blockpool_free(struct __vxge_hw_device *hldev, u32 size, struct vxge_hw_mempool_dma *dma_object); + +static struct __vxge_hw_channel* +__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, + enum __vxge_hw_channel_type type, u32 length, + u32 per_dtr_space, void *userdata); + static void __vxge_hw_channel_free( struct __vxge_hw_channel *channel); +static enum vxge_hw_status +__vxge_hw_channel_initialize( + struct __vxge_hw_channel *channel); + +static enum vxge_hw_status +__vxge_hw_channel_reset( + struct __vxge_hw_channel *channel); + static enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp); +static enum vxge_hw_status +__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config); + static enum vxge_hw_status __vxge_hw_device_config_check(struct vxge_hw_device_config *new_config); +static void +__vxge_hw_device_id_get(struct __vxge_hw_device *hldev); + +static void +__vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev); + +static enum vxge_hw_status +__vxge_hw_vpath_card_info_get( + u32 vp_id, + struct vxge_hw_vpath_reg __iomem *vpath_reg, + struct vxge_hw_device_hw_info *hw_info); + +static enum vxge_hw_status +__vxge_hw_device_initialize(struct __vxge_hw_device *hldev); + +static void +__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev); + +static enum vxge_hw_status +__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev); + static enum vxge_hw_status __vxge_hw_device_register_poll( void __iomem *reg, @@ -88,10 +138,9 @@ __vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr, static struct vxge_hw_mempool* __vxge_hw_mempool_create(struct __vxge_hw_device *devh, u32 memblock_size, - u32 item_size, u32 private_size, u32 items_initial, - u32 items_max, struct vxge_hw_mempool_cbs *mp_callback, - void *userdata); - + u32 item_size, u32 private_size, u32 items_initial, + u32 items_max, struct vxge_hw_mempool_cbs *mp_callback, + void *userdata); static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool); static enum vxge_hw_status @@ -104,353 +153,52 @@ vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vpath_handle); static enum vxge_hw_status __vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg); -static void -__vxge_hw_vp_terminate(struct __vxge_hw_device *devh, u32 vp_id); +static u64 +__vxge_hw_vpath_pci_func_mode_get(u32 vp_id, + struct vxge_hw_vpath_reg __iomem *vpath_reg); -static enum vxge_hw_status -__vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats); +static u32 +__vxge_hw_vpath_func_id_get(u32 vp_id, struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg); static enum vxge_hw_status -__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats); - -static void -vxge_hw_vpath_set_zero_rx_frm_len(struct vxge_hw_vpath_reg __iomem *vp_reg) -{ - u64 val64; - - val64 = readq(&vp_reg->rxmac_vcfg0); - val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff); - writeq(val64, &vp_reg->rxmac_vcfg0); - val64 = readq(&vp_reg->rxmac_vcfg0); - - return; -} - -/* - * vxge_hw_vpath_wait_receive_idle - Wait for Rx to become idle - */ -int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id) -{ - struct vxge_hw_vpath_reg __iomem *vp_reg; - struct __vxge_hw_virtualpath *vpath; - u64 val64, rxd_count, rxd_spat; - int count = 0, total_count = 0; - - vpath = &hldev->virtual_paths[vp_id]; - vp_reg = vpath->vp_reg; - - vxge_hw_vpath_set_zero_rx_frm_len(vp_reg); - - /* Check that the ring controller for this vpath has enough free RxDs - * to send frames to the host. This is done by reading the - * PRC_RXD_DOORBELL_VPn register and comparing the read value to the - * RXD_SPAT value for the vpath. - */ - val64 = readq(&vp_reg->prc_cfg6); - rxd_spat = VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val64) + 1; - /* Use a factor of 2 when comparing rxd_count against rxd_spat for some - * leg room. - */ - rxd_spat *= 2; - - do { - mdelay(1); - - rxd_count = readq(&vp_reg->prc_rxd_doorbell); - - /* Check that the ring controller for this vpath does - * not have any frame in its pipeline. - */ - val64 = readq(&vp_reg->frm_in_progress_cnt); - if ((rxd_count <= rxd_spat) || (val64 > 0)) - count = 0; - else - count++; - total_count++; - } while ((count < VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT) && - (total_count < VXGE_HW_MAX_POLLING_COUNT)); - - if (total_count >= VXGE_HW_MAX_POLLING_COUNT) - printk(KERN_ALERT "%s: Still Receiving traffic. Abort wait\n", - __func__); - - return total_count; -} - -/* vxge_hw_device_wait_receive_idle - This function waits until all frames - * stored in the frame buffer for each vpath assigned to the given - * function (hldev) have been sent to the host. - */ -void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev) -{ - int i, total_count = 0; - - for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { - if (!(hldev->vpaths_deployed & vxge_mBIT(i))) - continue; - - total_count += vxge_hw_vpath_wait_receive_idle(hldev, i); - if (total_count >= VXGE_HW_MAX_POLLING_COUNT) - break; - } -} +__vxge_hw_vpath_addr_get(u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg, + u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN]); static enum vxge_hw_status -vxge_hw_vpath_fw_api(struct __vxge_hw_virtualpath *vpath, u32 action, - u32 fw_memo, u32 offset, u64 *data0, u64 *data1, - u64 *steer_ctrl) -{ - struct vxge_hw_vpath_reg __iomem *vp_reg; - enum vxge_hw_status status; - u64 val64; - u32 retry = 0, max_retry = 100; - - vp_reg = vpath->vp_reg; - - if (vpath->vp_open) { - max_retry = 3; - spin_lock(&vpath->lock); - } - - writeq(*data0, &vp_reg->rts_access_steer_data0); - writeq(*data1, &vp_reg->rts_access_steer_data1); - wmb(); - - val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(fw_memo) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset) | - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | - *steer_ctrl; - - status = __vxge_hw_pio_mem_write64(val64, - &vp_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); - - /* The __vxge_hw_device_register_poll can udelay for a significant - * amount of time, blocking other proccess from the CPU. If it delays - * for ~5secs, a NMI error can occur. A way around this is to give up - * the processor via msleep, but this is not allowed is under lock. - * So, only allow it to sleep for ~4secs if open. Otherwise, delay for - * 1sec and sleep for 10ms until the firmware operation has completed - * or timed-out. - */ - while ((status != VXGE_HW_OK) && retry++ < max_retry) { - if (!vpath->vp_open) - msleep(20); - status = __vxge_hw_device_register_poll( - &vp_reg->rts_access_steer_ctrl, - VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, - VXGE_HW_DEF_DEVICE_POLL_MILLIS); - } - - if (status != VXGE_HW_OK) - goto out; - - val64 = readq(&vp_reg->rts_access_steer_ctrl); - if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - *data0 = readq(&vp_reg->rts_access_steer_data0); - *data1 = readq(&vp_reg->rts_access_steer_data1); - *steer_ctrl = val64; - } else - status = VXGE_HW_FAIL; - -out: - if (vpath->vp_open) - spin_unlock(&vpath->lock); - return status; -} - -enum vxge_hw_status -vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major, - u32 *minor, u32 *build) -{ - u64 data0 = 0, data1 = 0, steer_ctrl = 0; - struct __vxge_hw_virtualpath *vpath; - enum vxge_hw_status status; - - vpath = &hldev->virtual_paths[hldev->first_vp_id]; - - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_FW_UPGRADE_ACTION, - VXGE_HW_FW_UPGRADE_MEMO, - VXGE_HW_FW_UPGRADE_OFFSET_READ, - &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) - return status; - - *major = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0); - *minor = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0); - *build = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0); +__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath); - return status; -} - -enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev) -{ - u64 data0 = 0, data1 = 0, steer_ctrl = 0; - struct __vxge_hw_virtualpath *vpath; - enum vxge_hw_status status; - u32 ret; - - vpath = &hldev->virtual_paths[hldev->first_vp_id]; - - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_FW_UPGRADE_ACTION, - VXGE_HW_FW_UPGRADE_MEMO, - VXGE_HW_FW_UPGRADE_OFFSET_COMMIT, - &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, "%s: FW upgrade failed", __func__); - goto exit; - } - - ret = VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(steer_ctrl) & 0x7F; - if (ret != 1) { - vxge_debug_init(VXGE_ERR, "%s: FW commit failed with error %d", - __func__, ret); - status = VXGE_HW_FAIL; - } - -exit: - return status; -} -enum vxge_hw_status -vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *fwdata, int size) -{ - u64 data0 = 0, data1 = 0, steer_ctrl = 0; - struct __vxge_hw_virtualpath *vpath; - enum vxge_hw_status status; - int ret_code, sec_code; - - vpath = &hldev->virtual_paths[hldev->first_vp_id]; - - /* send upgrade start command */ - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_FW_UPGRADE_ACTION, - VXGE_HW_FW_UPGRADE_MEMO, - VXGE_HW_FW_UPGRADE_OFFSET_START, - &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, " %s: Upgrade start cmd failed", - __func__); - return status; - } - - /* Transfer fw image to adapter 16 bytes at a time */ - for (; size > 0; size -= VXGE_HW_FW_UPGRADE_BLK_SIZE) { - steer_ctrl = 0; - - /* The next 128bits of fwdata to be loaded onto the adapter */ - data0 = *((u64 *)fwdata); - data1 = *((u64 *)fwdata + 1); - - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_FW_UPGRADE_ACTION, - VXGE_HW_FW_UPGRADE_MEMO, - VXGE_HW_FW_UPGRADE_OFFSET_SEND, - &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, "%s: Upgrade send failed", - __func__); - goto out; - } - - ret_code = VXGE_HW_UPGRADE_GET_RET_ERR_CODE(data0); - switch (ret_code) { - case VXGE_HW_FW_UPGRADE_OK: - /* All OK, send next 16 bytes. */ - break; - case VXGE_FW_UPGRADE_BYTES2SKIP: - /* skip bytes in the stream */ - fwdata += (data0 >> 8) & 0xFFFFFFFF; - break; - case VXGE_HW_FW_UPGRADE_DONE: - goto out; - case VXGE_HW_FW_UPGRADE_ERR: - sec_code = VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(data0); - switch (sec_code) { - case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1: - case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7: - printk(KERN_ERR - "corrupted data from .ncf file\n"); - break; - case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3: - case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4: - case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5: - case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6: - case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8: - printk(KERN_ERR "invalid .ncf file\n"); - break; - case VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW: - printk(KERN_ERR "buffer overflow\n"); - break; - case VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH: - printk(KERN_ERR "failed to flash the image\n"); - break; - case VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN: - printk(KERN_ERR - "generic error. Unknown error type\n"); - break; - default: - printk(KERN_ERR "Unknown error of type %d\n", - sec_code); - break; - } - status = VXGE_HW_FAIL; - goto out; - default: - printk(KERN_ERR "Unknown FW error: %d\n", ret_code); - status = VXGE_HW_FAIL; - goto out; - } - /* point to next 16 bytes */ - fwdata += VXGE_HW_FW_UPGRADE_BLK_SIZE; - } -out: - return status; -} +static enum vxge_hw_status +__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *devh, u32 vp_id); -enum vxge_hw_status -vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev, - struct eprom_image *img) -{ - u64 data0 = 0, data1 = 0, steer_ctrl = 0; - struct __vxge_hw_virtualpath *vpath; - enum vxge_hw_status status; - int i; +static enum vxge_hw_status +__vxge_hw_vpath_fw_ver_get(u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg, + struct vxge_hw_device_hw_info *hw_info); - vpath = &hldev->virtual_paths[hldev->first_vp_id]; +static enum vxge_hw_status +__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *devh, u32 vp_id); - for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) { - data0 = VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(i); - data1 = steer_ctrl = 0; +static void +__vxge_hw_vp_terminate(struct __vxge_hw_device *devh, u32 vp_id); - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, - VXGE_HW_FW_API_GET_EPROM_REV, - 0, &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) - break; +static enum vxge_hw_status +__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath, + u32 operation, u32 offset, u64 *stat); - img[i].is_valid = VXGE_HW_GET_EPROM_IMAGE_VALID(data0); - img[i].index = VXGE_HW_GET_EPROM_IMAGE_INDEX(data0); - img[i].type = VXGE_HW_GET_EPROM_IMAGE_TYPE(data0); - img[i].version = VXGE_HW_GET_EPROM_IMAGE_REV(data0); - } +static enum vxge_hw_status +__vxge_hw_vpath_xmac_tx_stats_get(struct __vxge_hw_virtualpath *vpath, + struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats); - return status; -} +static enum vxge_hw_status +__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath, + struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats); /* * __vxge_hw_channel_allocate - Allocate memory for channel * This function allocates required memory for the channel and various arrays * in the channel */ -static struct __vxge_hw_channel * +struct __vxge_hw_channel* __vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, enum __vxge_hw_channel_type type, u32 length, u32 per_dtr_space, void *userdata) @@ -521,7 +269,7 @@ __vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph, * This function deallocates memory from the channel and various arrays * in the channel */ -static void __vxge_hw_channel_free(struct __vxge_hw_channel *channel) +void __vxge_hw_channel_free(struct __vxge_hw_channel *channel) { kfree(channel->work_arr); kfree(channel->free_arr); @@ -535,7 +283,7 @@ static void __vxge_hw_channel_free(struct __vxge_hw_channel *channel) * This function initializes a channel by properly setting the * various references */ -static enum vxge_hw_status +enum vxge_hw_status __vxge_hw_channel_initialize(struct __vxge_hw_channel *channel) { u32 i; @@ -570,7 +318,7 @@ __vxge_hw_channel_initialize(struct __vxge_hw_channel *channel) * __vxge_hw_channel_reset - Resets a channel * This function resets a channel by properly setting the various references */ -static enum vxge_hw_status +enum vxge_hw_status __vxge_hw_channel_reset(struct __vxge_hw_channel *channel) { u32 i; @@ -597,7 +345,8 @@ __vxge_hw_channel_reset(struct __vxge_hw_channel *channel) * Initialize certain PCI/PCI-X configuration registers * with recommended values. Save config space for future hw resets. */ -static void __vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev) +void +__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev) { u16 cmd = 0; @@ -641,7 +390,7 @@ __vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis) return ret; } -/* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset + /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset * in progress * This routine checks the vpath reset in progress register is turned zero */ @@ -686,7 +435,7 @@ __vxge_hw_device_toc_get(void __iomem *bar0) * register location pointers in the device object. It waits until the ric is * completed initializing registers. */ -static enum vxge_hw_status +enum vxge_hw_status __vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev) { u64 val64; @@ -746,6 +495,26 @@ __vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev) return status; } +/* + * __vxge_hw_device_id_get + * This routine returns sets the device id and revision numbers into the device + * structure + */ +void __vxge_hw_device_id_get(struct __vxge_hw_device *hldev) +{ + u64 val64; + + val64 = readq(&hldev->common_reg->titan_asic_id); + hldev->device_id = + (u16)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_DEVICE_ID(val64); + + hldev->major_revision = + (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MAJOR_REVISION(val64); + + hldev->minor_revision = + (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MINOR_REVISION(val64); +} + /* * __vxge_hw_device_access_rights_get: Get Access Rights of the driver * This routine returns the Access Rights of the driver @@ -798,26 +567,11 @@ __vxge_hw_device_is_privilaged(u32 host_type, u32 func_id) return VXGE_HW_ERR_PRIVILAGED_OPEARATION; } -/* - * __vxge_hw_vpath_func_id_get - Get the function id of the vpath. - * Returns the function number of the vpath. - */ -static u32 -__vxge_hw_vpath_func_id_get(struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg) -{ - u64 val64; - - val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1); - - return - (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64); -} - /* * __vxge_hw_device_host_info_get * This routine returns the host type assignments */ -static void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev) +void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev) { u64 val64; u32 i; @@ -830,18 +584,16 @@ static void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev) hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments); for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { + if (!(hldev->vpath_assignments & vxge_mBIT(i))) continue; hldev->func_id = - __vxge_hw_vpath_func_id_get(hldev->vpmgmt_reg[i]); + __vxge_hw_vpath_func_id_get(i, hldev->vpmgmt_reg[i]); hldev->access_rights = __vxge_hw_device_access_rights_get( hldev->host_type, hldev->func_id); - hldev->virtual_paths[i].vp_open = VXGE_HW_VP_NOT_OPEN; - hldev->virtual_paths[i].vp_reg = hldev->vpath_reg[i]; - hldev->first_vp_id = i; break; } @@ -868,223 +620,32 @@ __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev) case PCIE_LNK_WIDTH_RESRV: case PCIE_LNK_X1: case PCIE_LNK_X2: - case PCIE_LNK_X4: - case PCIE_LNK_X8: - break; - default: - return VXGE_HW_ERR_INVALID_PCI_INFO; - } - - return VXGE_HW_OK; -} - -/* - * __vxge_hw_device_initialize - * Initialize Titan-V hardware. - */ -static enum vxge_hw_status -__vxge_hw_device_initialize(struct __vxge_hw_device *hldev) -{ - enum vxge_hw_status status = VXGE_HW_OK; - - if (VXGE_HW_OK == __vxge_hw_device_is_privilaged(hldev->host_type, - hldev->func_id)) { - /* Validate the pci-e link width and speed */ - status = __vxge_hw_verify_pci_e_info(hldev); - if (status != VXGE_HW_OK) - goto exit; - } - -exit: - return status; -} - -/* - * __vxge_hw_vpath_fw_ver_get - Get the fw version - * Returns FW Version - */ -static enum vxge_hw_status -__vxge_hw_vpath_fw_ver_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_device_hw_info *hw_info) -{ - struct vxge_hw_device_version *fw_version = &hw_info->fw_version; - struct vxge_hw_device_date *fw_date = &hw_info->fw_date; - struct vxge_hw_device_version *flash_version = &hw_info->flash_version; - struct vxge_hw_device_date *flash_date = &hw_info->flash_date; - u64 data0, data1 = 0, steer_ctrl = 0; - enum vxge_hw_status status; - - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, - 0, &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) - goto exit; - - fw_date->day = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(data0); - fw_date->month = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(data0); - fw_date->year = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(data0); - - snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d", - fw_date->month, fw_date->day, fw_date->year); - - fw_version->major = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0); - fw_version->minor = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0); - fw_version->build = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0); - - snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", - fw_version->major, fw_version->minor, fw_version->build); - - flash_date->day = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data1); - flash_date->month = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data1); - flash_date->year = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data1); - - snprintf(flash_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d", - flash_date->month, flash_date->day, flash_date->year); - - flash_version->major = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data1); - flash_version->minor = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data1); - flash_version->build = - (u32) VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data1); - - snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", - flash_version->major, flash_version->minor, - flash_version->build); - -exit: - return status; -} - -/* - * __vxge_hw_vpath_card_info_get - Get the serial numbers, - * part number and product description. - */ -static enum vxge_hw_status -__vxge_hw_vpath_card_info_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_device_hw_info *hw_info) -{ - enum vxge_hw_status status; - u64 data0, data1 = 0, steer_ctrl = 0; - u8 *serial_number = hw_info->serial_number; - u8 *part_number = hw_info->part_number; - u8 *product_desc = hw_info->product_desc; - u32 i, j = 0; - - data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER; - - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, - 0, &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) - return status; - - ((u64 *)serial_number)[0] = be64_to_cpu(data0); - ((u64 *)serial_number)[1] = be64_to_cpu(data1); - - data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER; - data1 = steer_ctrl = 0; - - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, - 0, &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) - return status; - - ((u64 *)part_number)[0] = be64_to_cpu(data0); - ((u64 *)part_number)[1] = be64_to_cpu(data1); - - for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0; - i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) { - data0 = i; - data1 = steer_ctrl = 0; - - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, - 0, &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) - return status; - - ((u64 *)product_desc)[j++] = be64_to_cpu(data0); - ((u64 *)product_desc)[j++] = be64_to_cpu(data1); - } - - return status; -} - -/* - * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode - * Returns pci function mode - */ -static enum vxge_hw_status -__vxge_hw_vpath_pci_func_mode_get(struct __vxge_hw_virtualpath *vpath, - struct vxge_hw_device_hw_info *hw_info) -{ - u64 data0, data1 = 0, steer_ctrl = 0; - enum vxge_hw_status status; - - data0 = 0; - - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_FW_API_GET_FUNC_MODE, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, - 0, &data0, &data1, &steer_ctrl); - if (status != VXGE_HW_OK) - return status; + case PCIE_LNK_X4: + case PCIE_LNK_X8: + break; + default: + return VXGE_HW_ERR_INVALID_PCI_INFO; + } - hw_info->function_mode = VXGE_HW_GET_FUNC_MODE_VAL(data0); - return status; + return VXGE_HW_OK; } /* - * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath - * from MAC address table. + * __vxge_hw_device_initialize + * Initialize Titan-V hardware. */ -static enum vxge_hw_status -__vxge_hw_vpath_addr_get(struct __vxge_hw_virtualpath *vpath, - u8 *macaddr, u8 *macaddr_mask) +enum vxge_hw_status __vxge_hw_device_initialize(struct __vxge_hw_device *hldev) { - u64 action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY, - data0 = 0, data1 = 0, steer_ctrl = 0; - enum vxge_hw_status status; - int i; + enum vxge_hw_status status = VXGE_HW_OK; - do { - status = vxge_hw_vpath_fw_api(vpath, action, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA, - 0, &data0, &data1, &steer_ctrl); + if (VXGE_HW_OK == __vxge_hw_device_is_privilaged(hldev->host_type, + hldev->func_id)) { + /* Validate the pci-e link width and speed */ + status = __vxge_hw_verify_pci_e_info(hldev); if (status != VXGE_HW_OK) goto exit; + } - data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data0); - data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK( - data1); - - for (i = ETH_ALEN; i > 0; i--) { - macaddr[i - 1] = (u8) (data0 & 0xFF); - data0 >>= 8; - - macaddr_mask[i - 1] = (u8) (data1 & 0xFF); - data1 >>= 8; - } - - action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY; - data0 = 0, data1 = 0, steer_ctrl = 0; - - } while (!is_valid_ether_addr(macaddr)); exit: return status; } @@ -1104,9 +665,9 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, struct vxge_hw_toc_reg __iomem *toc; struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg; struct vxge_hw_common_reg __iomem *common_reg; + struct vxge_hw_vpath_reg __iomem *vpath_reg; struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg; enum vxge_hw_status status; - struct __vxge_hw_virtualpath vpath; memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info)); @@ -1141,7 +702,7 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, vpmgmt_reg = (struct vxge_hw_vpmgmt_reg __iomem *) (bar0 + val64); - hw_info->func_id = __vxge_hw_vpath_func_id_get(vpmgmt_reg); + hw_info->func_id = __vxge_hw_vpath_func_id_get(i, vpmgmt_reg); if (__vxge_hw_device_access_rights_get(hw_info->host_type, hw_info->func_id) & VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) { @@ -1157,19 +718,16 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, val64 = readq(&toc->toc_vpath_pointer[i]); - vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *) - (bar0 + val64); - vpath.vp_open = 0; + vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64); - status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info); - if (status != VXGE_HW_OK) - goto exit; + hw_info->function_mode = + __vxge_hw_vpath_pci_func_mode_get(i, vpath_reg); - status = __vxge_hw_vpath_fw_ver_get(&vpath, hw_info); + status = __vxge_hw_vpath_fw_ver_get(i, vpath_reg, hw_info); if (status != VXGE_HW_OK) goto exit; - status = __vxge_hw_vpath_card_info_get(&vpath, hw_info); + status = __vxge_hw_vpath_card_info_get(i, vpath_reg, hw_info); if (status != VXGE_HW_OK) goto exit; @@ -1177,15 +735,14 @@ vxge_hw_device_hw_info_get(void __iomem *bar0, } for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { + if (!((hw_info->vpath_mask) & vxge_mBIT(i))) continue; val64 = readq(&toc->toc_vpath_pointer[i]); - vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *) - (bar0 + val64); - vpath.vp_open = 0; + vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64); - status = __vxge_hw_vpath_addr_get(&vpath, + status = __vxge_hw_vpath_addr_get(i, vpath_reg, hw_info->mac_addrs[i], hw_info->mac_addr_masks[i]); if (status != VXGE_HW_OK) @@ -1219,12 +776,14 @@ vxge_hw_device_initialize( if (status != VXGE_HW_OK) goto exit; - hldev = vzalloc(sizeof(struct __vxge_hw_device)); + hldev = (struct __vxge_hw_device *) + vmalloc(sizeof(struct __vxge_hw_device)); if (hldev == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; } + memset(hldev, 0, sizeof(struct __vxge_hw_device)); hldev->magic = VXGE_HW_DEVICE_MAGIC; vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_ALL); @@ -1247,6 +806,7 @@ vxge_hw_device_initialize( vfree(hldev); goto exit; } + __vxge_hw_device_id_get(hldev); __vxge_hw_device_host_info_get(hldev); @@ -1254,6 +814,7 @@ vxge_hw_device_initialize( nblocks++; for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { + if (!(hldev->vpath_assignments & vxge_mBIT(i))) continue; @@ -1278,6 +839,7 @@ vxge_hw_device_initialize( } status = __vxge_hw_device_initialize(hldev); + if (status != VXGE_HW_OK) { vxge_hw_device_terminate(hldev); goto exit; @@ -1314,6 +876,7 @@ vxge_hw_device_stats_get(struct __vxge_hw_device *hldev, enum vxge_hw_status status = VXGE_HW_OK; for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) { + if (!(hldev->vpaths_deployed & vxge_mBIT(i)) || (hldev->virtual_paths[i].vp_open == VXGE_HW_VP_NOT_OPEN)) @@ -1602,6 +1165,7 @@ enum vxge_hw_status vxge_hw_device_getpause_data(struct __vxge_hw_device *hldev, * It can be used to set or reset Pause frame generation or reception * support of the NIC. */ + enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev, u32 port, u32 tx, u32 rx) { @@ -1845,6 +1409,7 @@ vxge_hw_ring_replenish(struct __vxge_hw_ring *ring) /* * __vxge_hw_ring_create - Create a Ring * This function creates Ring and initializes it. + * */ static enum vxge_hw_status __vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp, @@ -2062,12 +1627,15 @@ __vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate, * allocate new memblock and its private part at once. * This helps to minimize memory usage a lot. */ mempool->memblocks_priv_arr[i] = - vzalloc(mempool->items_priv_size * n_items); + vmalloc(mempool->items_priv_size * n_items); if (mempool->memblocks_priv_arr[i] == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; } + memset(mempool->memblocks_priv_arr[i], 0, + mempool->items_priv_size * n_items); + /* allocate DMA-capable memblock */ mempool->memblocks_arr[i] = __vxge_hw_blockpool_malloc(mempool->devh, @@ -2139,11 +1707,13 @@ __vxge_hw_mempool_create( goto exit; } - mempool = vzalloc(sizeof(struct vxge_hw_mempool)); + mempool = (struct vxge_hw_mempool *) + vmalloc(sizeof(struct vxge_hw_mempool)); if (mempool == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto exit; } + memset(mempool, 0, sizeof(struct vxge_hw_mempool)); mempool->devh = devh; mempool->memblock_size = memblock_size; @@ -2163,27 +1733,31 @@ __vxge_hw_mempool_create( /* allocate array of memblocks */ mempool->memblocks_arr = - vzalloc(sizeof(void *) * mempool->memblocks_max); + (void **) vmalloc(sizeof(void *) * mempool->memblocks_max); if (mempool->memblocks_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; mempool = NULL; goto exit; } + memset(mempool->memblocks_arr, 0, + sizeof(void *) * mempool->memblocks_max); /* allocate array of private parts of items per memblocks */ mempool->memblocks_priv_arr = - vzalloc(sizeof(void *) * mempool->memblocks_max); + (void **) vmalloc(sizeof(void *) * mempool->memblocks_max); if (mempool->memblocks_priv_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; mempool = NULL; goto exit; } + memset(mempool->memblocks_priv_arr, 0, + sizeof(void *) * mempool->memblocks_max); /* allocate array of memblocks DMA objects */ - mempool->memblocks_dma_arr = - vzalloc(sizeof(struct vxge_hw_mempool_dma) * + mempool->memblocks_dma_arr = (struct vxge_hw_mempool_dma *) + vmalloc(sizeof(struct vxge_hw_mempool_dma) * mempool->memblocks_max); if (mempool->memblocks_dma_arr == NULL) { @@ -2192,15 +1766,20 @@ __vxge_hw_mempool_create( mempool = NULL; goto exit; } + memset(mempool->memblocks_dma_arr, 0, + sizeof(struct vxge_hw_mempool_dma) * + mempool->memblocks_max); /* allocate hash array of items */ - mempool->items_arr = vzalloc(sizeof(void *) * mempool->items_max); + mempool->items_arr = + (void **) vmalloc(sizeof(void *) * mempool->items_max); if (mempool->items_arr == NULL) { __vxge_hw_mempool_destroy(mempool); status = VXGE_HW_ERR_OUT_OF_MEMORY; mempool = NULL; goto exit; } + memset(mempool->items_arr, 0, sizeof(void *) * mempool->items_max); /* calculate initial number of memblocks */ memblocks_to_allocate = (mempool->items_initial + @@ -2266,7 +1845,7 @@ static void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool) * __vxge_hw_device_fifo_config_check - Check fifo configuration. * Check the fifo configuration */ -static enum vxge_hw_status +enum vxge_hw_status __vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config) { if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) || @@ -2314,7 +1893,7 @@ __vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config) * __vxge_hw_device_config_check - Check device configuration. * Check the device configuration */ -static enum vxge_hw_status +enum vxge_hw_status __vxge_hw_device_config_check(struct vxge_hw_device_config *new_config) { u32 i; @@ -2874,7 +2453,7 @@ __vxge_hw_fifo_mempool_item_alloc( * __vxge_hw_fifo_create - Create a FIFO * This function creates FIFO and initializes it. */ -static enum vxge_hw_status +enum vxge_hw_status __vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp, struct vxge_hw_fifo_attr *attr) { @@ -2942,159 +2521,449 @@ __vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp, * routine which will essentially stop the channel and free resources. */ - /* TxDL common private size == TxDL private + driver private */ - fifo->priv_size = - sizeof(struct __vxge_hw_fifo_txdl_priv) + attr->per_txdl_space; - fifo->priv_size = ((fifo->priv_size + VXGE_CACHE_LINE_SIZE - 1) / - VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE; + /* TxDL common private size == TxDL private + driver private */ + fifo->priv_size = + sizeof(struct __vxge_hw_fifo_txdl_priv) + attr->per_txdl_space; + fifo->priv_size = ((fifo->priv_size + VXGE_CACHE_LINE_SIZE - 1) / + VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE; + + fifo->per_txdl_space = attr->per_txdl_space; + + /* recompute txdl size to be cacheline aligned */ + fifo->txdl_size = txdl_size; + fifo->txdl_per_memblock = txdl_per_memblock; + + fifo->txdl_term = attr->txdl_term; + fifo->callback = attr->callback; + + if (fifo->txdl_per_memblock == 0) { + __vxge_hw_fifo_delete(vp); + status = VXGE_HW_ERR_INVALID_BLOCK_SIZE; + goto exit; + } + + fifo_mp_callback.item_func_alloc = __vxge_hw_fifo_mempool_item_alloc; + + fifo->mempool = + __vxge_hw_mempool_create(vpath->hldev, + fifo->config->memblock_size, + fifo->txdl_size, + fifo->priv_size, + (fifo->config->fifo_blocks * fifo->txdl_per_memblock), + (fifo->config->fifo_blocks * fifo->txdl_per_memblock), + &fifo_mp_callback, + fifo); + + if (fifo->mempool == NULL) { + __vxge_hw_fifo_delete(vp); + status = VXGE_HW_ERR_OUT_OF_MEMORY; + goto exit; + } + + status = __vxge_hw_channel_initialize(&fifo->channel); + if (status != VXGE_HW_OK) { + __vxge_hw_fifo_delete(vp); + goto exit; + } + + vxge_assert(fifo->channel.reserve_ptr); +exit: + return status; +} + +/* + * __vxge_hw_fifo_abort - Returns the TxD + * This function terminates the TxDs of fifo + */ +static enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo) +{ + void *txdlh; + + for (;;) { + vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh); + + if (txdlh == NULL) + break; + + vxge_hw_channel_dtr_complete(&fifo->channel); + + if (fifo->txdl_term) { + fifo->txdl_term(txdlh, + VXGE_HW_TXDL_STATE_POSTED, + fifo->channel.userdata); + } + + vxge_hw_channel_dtr_free(&fifo->channel, txdlh); + } + + return VXGE_HW_OK; +} + +/* + * __vxge_hw_fifo_reset - Resets the fifo + * This function resets the fifo during vpath reset operation + */ +static enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo) +{ + enum vxge_hw_status status = VXGE_HW_OK; + + __vxge_hw_fifo_abort(fifo); + status = __vxge_hw_channel_reset(&fifo->channel); + + return status; +} + +/* + * __vxge_hw_fifo_delete - Removes the FIFO + * This function freeup the memory pool and removes the FIFO + */ +enum vxge_hw_status __vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp) +{ + struct __vxge_hw_fifo *fifo = vp->vpath->fifoh; + + __vxge_hw_fifo_abort(fifo); + + if (fifo->mempool) + __vxge_hw_mempool_destroy(fifo->mempool); + + vp->vpath->fifoh = NULL; + + __vxge_hw_channel_free(&fifo->channel); + + return VXGE_HW_OK; +} + +/* + * __vxge_hw_vpath_pci_read - Read the content of given address + * in pci config space. + * Read from the vpath pci config space. + */ +static enum vxge_hw_status +__vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath, + u32 phy_func_0, u32 offset, u32 *val) +{ + u64 val64; + enum vxge_hw_status status = VXGE_HW_OK; + struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg; + + val64 = VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(offset); + + if (phy_func_0) + val64 |= VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0; + + writeq(val64, &vp_reg->pci_config_access_cfg1); + wmb(); + writeq(VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ, + &vp_reg->pci_config_access_cfg2); + wmb(); + + status = __vxge_hw_device_register_poll( + &vp_reg->pci_config_access_cfg2, + VXGE_HW_INTR_MASK_ALL, VXGE_HW_DEF_DEVICE_POLL_MILLIS); + + if (status != VXGE_HW_OK) + goto exit; + + val64 = readq(&vp_reg->pci_config_access_status); + + if (val64 & VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR) { + status = VXGE_HW_FAIL; + *val = 0; + } else + *val = (u32)vxge_bVALn(val64, 32, 32); +exit: + return status; +} + +/* + * __vxge_hw_vpath_func_id_get - Get the function id of the vpath. + * Returns the function number of the vpath. + */ +static u32 +__vxge_hw_vpath_func_id_get(u32 vp_id, + struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg) +{ + u64 val64; + + val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1); + + return + (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64); +} + +/* + * __vxge_hw_read_rts_ds - Program RTS steering critieria + */ +static inline void +__vxge_hw_read_rts_ds(struct vxge_hw_vpath_reg __iomem *vpath_reg, + u64 dta_struct_sel) +{ + writeq(0, &vpath_reg->rts_access_steer_ctrl); + wmb(); + writeq(dta_struct_sel, &vpath_reg->rts_access_steer_data0); + writeq(0, &vpath_reg->rts_access_steer_data1); + wmb(); +} + + +/* + * __vxge_hw_vpath_card_info_get - Get the serial numbers, + * part number and product description. + */ +static enum vxge_hw_status +__vxge_hw_vpath_card_info_get( + u32 vp_id, + struct vxge_hw_vpath_reg __iomem *vpath_reg, + struct vxge_hw_device_hw_info *hw_info) +{ + u32 i, j; + u64 val64; + u64 data1 = 0ULL; + u64 data2 = 0ULL; + enum vxge_hw_status status = VXGE_HW_OK; + u8 *serial_number = hw_info->serial_number; + u8 *part_number = hw_info->part_number; + u8 *product_desc = hw_info->product_desc; + + __vxge_hw_read_rts_ds(vpath_reg, + VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER); + + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); + + status = __vxge_hw_pio_mem_write64(val64, + &vpath_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); + + if (status != VXGE_HW_OK) + return status; + + val64 = readq(&vpath_reg->rts_access_steer_ctrl); + + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { + data1 = readq(&vpath_reg->rts_access_steer_data0); + ((u64 *)serial_number)[0] = be64_to_cpu(data1); + + data2 = readq(&vpath_reg->rts_access_steer_data1); + ((u64 *)serial_number)[1] = be64_to_cpu(data2); + status = VXGE_HW_OK; + } else + *serial_number = 0; + + __vxge_hw_read_rts_ds(vpath_reg, + VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER); + + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); + + status = __vxge_hw_pio_mem_write64(val64, + &vpath_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); + + if (status != VXGE_HW_OK) + return status; + + val64 = readq(&vpath_reg->rts_access_steer_ctrl); - fifo->per_txdl_space = attr->per_txdl_space; + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - /* recompute txdl size to be cacheline aligned */ - fifo->txdl_size = txdl_size; - fifo->txdl_per_memblock = txdl_per_memblock; + data1 = readq(&vpath_reg->rts_access_steer_data0); + ((u64 *)part_number)[0] = be64_to_cpu(data1); - fifo->txdl_term = attr->txdl_term; - fifo->callback = attr->callback; + data2 = readq(&vpath_reg->rts_access_steer_data1); + ((u64 *)part_number)[1] = be64_to_cpu(data2); - if (fifo->txdl_per_memblock == 0) { - __vxge_hw_fifo_delete(vp); - status = VXGE_HW_ERR_INVALID_BLOCK_SIZE; - goto exit; - } + status = VXGE_HW_OK; - fifo_mp_callback.item_func_alloc = __vxge_hw_fifo_mempool_item_alloc; + } else + *part_number = 0; - fifo->mempool = - __vxge_hw_mempool_create(vpath->hldev, - fifo->config->memblock_size, - fifo->txdl_size, - fifo->priv_size, - (fifo->config->fifo_blocks * fifo->txdl_per_memblock), - (fifo->config->fifo_blocks * fifo->txdl_per_memblock), - &fifo_mp_callback, - fifo); + j = 0; - if (fifo->mempool == NULL) { - __vxge_hw_fifo_delete(vp); - status = VXGE_HW_ERR_OUT_OF_MEMORY; - goto exit; - } + for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0; + i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) { - status = __vxge_hw_channel_initialize(&fifo->channel); - if (status != VXGE_HW_OK) { - __vxge_hw_fifo_delete(vp); - goto exit; - } + __vxge_hw_read_rts_ds(vpath_reg, i); - vxge_assert(fifo->channel.reserve_ptr); -exit: - return status; -} + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); -/* - * __vxge_hw_fifo_abort - Returns the TxD - * This function terminates the TxDs of fifo - */ -static enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo) -{ - void *txdlh; + status = __vxge_hw_pio_mem_write64(val64, + &vpath_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); - for (;;) { - vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh); + if (status != VXGE_HW_OK) + return status; - if (txdlh == NULL) - break; + val64 = readq(&vpath_reg->rts_access_steer_ctrl); - vxge_hw_channel_dtr_complete(&fifo->channel); + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - if (fifo->txdl_term) { - fifo->txdl_term(txdlh, - VXGE_HW_TXDL_STATE_POSTED, - fifo->channel.userdata); - } + data1 = readq(&vpath_reg->rts_access_steer_data0); + ((u64 *)product_desc)[j++] = be64_to_cpu(data1); - vxge_hw_channel_dtr_free(&fifo->channel, txdlh); + data2 = readq(&vpath_reg->rts_access_steer_data1); + ((u64 *)product_desc)[j++] = be64_to_cpu(data2); + + status = VXGE_HW_OK; + } else + *product_desc = 0; } - return VXGE_HW_OK; + return status; } /* - * __vxge_hw_fifo_reset - Resets the fifo - * This function resets the fifo during vpath reset operation + * __vxge_hw_vpath_fw_ver_get - Get the fw version + * Returns FW Version */ -static enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo) +static enum vxge_hw_status +__vxge_hw_vpath_fw_ver_get( + u32 vp_id, + struct vxge_hw_vpath_reg __iomem *vpath_reg, + struct vxge_hw_device_hw_info *hw_info) { + u64 val64; + u64 data1 = 0ULL; + u64 data2 = 0ULL; + struct vxge_hw_device_version *fw_version = &hw_info->fw_version; + struct vxge_hw_device_date *fw_date = &hw_info->fw_date; + struct vxge_hw_device_version *flash_version = &hw_info->flash_version; + struct vxge_hw_device_date *flash_date = &hw_info->flash_date; enum vxge_hw_status status = VXGE_HW_OK; - __vxge_hw_fifo_abort(fifo); - status = __vxge_hw_channel_reset(&fifo->channel); + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - return status; -} + status = __vxge_hw_pio_mem_write64(val64, + &vpath_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); -/* - * __vxge_hw_fifo_delete - Removes the FIFO - * This function freeup the memory pool and removes the FIFO - */ -static enum vxge_hw_status -__vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp) -{ - struct __vxge_hw_fifo *fifo = vp->vpath->fifoh; + if (status != VXGE_HW_OK) + goto exit; - __vxge_hw_fifo_abort(fifo); + val64 = readq(&vpath_reg->rts_access_steer_ctrl); - if (fifo->mempool) - __vxge_hw_mempool_destroy(fifo->mempool); + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { - vp->vpath->fifoh = NULL; + data1 = readq(&vpath_reg->rts_access_steer_data0); + data2 = readq(&vpath_reg->rts_access_steer_data1); + + fw_date->day = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY( + data1); + fw_date->month = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH( + data1); + fw_date->year = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR( + data1); + + snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d", + fw_date->month, fw_date->day, fw_date->year); + + fw_version->major = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data1); + fw_version->minor = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data1); + fw_version->build = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data1); + + snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", + fw_version->major, fw_version->minor, fw_version->build); + + flash_date->day = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data2); + flash_date->month = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data2); + flash_date->year = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data2); + + snprintf(flash_date->date, VXGE_HW_FW_STRLEN, + "%2.2d/%2.2d/%4.4d", + flash_date->month, flash_date->day, flash_date->year); + + flash_version->major = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data2); + flash_version->minor = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data2); + flash_version->build = + (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data2); + + snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d", + flash_version->major, flash_version->minor, + flash_version->build); - __vxge_hw_channel_free(&fifo->channel); + status = VXGE_HW_OK; - return VXGE_HW_OK; + } else + status = VXGE_HW_FAIL; +exit: + return status; } /* - * __vxge_hw_vpath_pci_read - Read the content of given address - * in pci config space. - * Read from the vpath pci config space. + * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode + * Returns pci function mode */ -static enum vxge_hw_status -__vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath, - u32 phy_func_0, u32 offset, u32 *val) +static u64 +__vxge_hw_vpath_pci_func_mode_get( + u32 vp_id, + struct vxge_hw_vpath_reg __iomem *vpath_reg) { u64 val64; + u64 data1 = 0ULL; enum vxge_hw_status status = VXGE_HW_OK; - struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg; - - val64 = VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(offset); - if (phy_func_0) - val64 |= VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0; + __vxge_hw_read_rts_ds(vpath_reg, + VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE); - writeq(val64, &vp_reg->pci_config_access_cfg1); - wmb(); - writeq(VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ, - &vp_reg->pci_config_access_cfg2); - wmb(); + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - status = __vxge_hw_device_register_poll( - &vp_reg->pci_config_access_cfg2, - VXGE_HW_INTR_MASK_ALL, VXGE_HW_DEF_DEVICE_POLL_MILLIS); + status = __vxge_hw_pio_mem_write64(val64, + &vpath_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); if (status != VXGE_HW_OK) goto exit; - val64 = readq(&vp_reg->pci_config_access_status); + val64 = readq(&vpath_reg->rts_access_steer_ctrl); - if (val64 & VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR) { + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { + data1 = readq(&vpath_reg->rts_access_steer_data0); + status = VXGE_HW_OK; + } else { + data1 = 0; status = VXGE_HW_FAIL; - *val = 0; - } else - *val = (u32)vxge_bVALn(val64, 32, 32); + } exit: - return status; + return data1; } /** @@ -3105,24 +2974,37 @@ __vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath, * Flicker the link LED. */ enum vxge_hw_status -vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev, u64 on_off) +vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev, + u64 on_off) { - struct __vxge_hw_virtualpath *vpath; - u64 data0, data1 = 0, steer_ctrl = 0; - enum vxge_hw_status status; + u64 val64; + enum vxge_hw_status status = VXGE_HW_OK; + struct vxge_hw_vpath_reg __iomem *vp_reg; if (hldev == NULL) { status = VXGE_HW_ERR_INVALID_DEVICE; goto exit; } - vpath = &hldev->virtual_paths[hldev->first_vp_id]; + vp_reg = hldev->vpath_reg[hldev->first_vp_id]; + + writeq(0, &vp_reg->rts_access_steer_ctrl); + wmb(); + writeq(on_off, &vp_reg->rts_access_steer_data0); + writeq(0, &vp_reg->rts_access_steer_data1); + wmb(); + + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); - data0 = on_off; - status = vxge_hw_vpath_fw_api(vpath, - VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL, - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO, - 0, &data0, &data1, &steer_ctrl); + status = __vxge_hw_pio_mem_write64(val64, + &vp_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); exit: return status; } @@ -3131,38 +3013,63 @@ vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev, u64 on_off) * __vxge_hw_vpath_rts_table_get - Get the entries from RTS access tables */ enum vxge_hw_status -__vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp, - u32 action, u32 rts_table, u32 offset, - u64 *data0, u64 *data1) +__vxge_hw_vpath_rts_table_get( + struct __vxge_hw_vpath_handle *vp, + u32 action, u32 rts_table, u32 offset, u64 *data1, u64 *data2) { - enum vxge_hw_status status; - u64 steer_ctrl = 0; + u64 val64; + struct __vxge_hw_virtualpath *vpath; + struct vxge_hw_vpath_reg __iomem *vp_reg; + + enum vxge_hw_status status = VXGE_HW_OK; if (vp == NULL) { status = VXGE_HW_ERR_INVALID_HANDLE; goto exit; } + vpath = vp->vpath; + vp_reg = vpath->vp_reg; + + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset); + if ((rts_table == - VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) || + VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) || (rts_table == - VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) || + VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) || (rts_table == - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) || + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) || (rts_table == - VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) { - steer_ctrl = VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL; + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) { + val64 = val64 | VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL; } - status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset, - data0, data1, &steer_ctrl); + status = __vxge_hw_pio_mem_write64(val64, + &vp_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + vpath->hldev->config.device_poll_millis); + if (status != VXGE_HW_OK) goto exit; - if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || - (rts_table != - VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) - *data1 = 0; + val64 = readq(&vp_reg->rts_access_steer_ctrl); + + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { + + *data1 = readq(&vp_reg->rts_access_steer_data0); + + if ((rts_table == + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || + (rts_table == + VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) { + *data2 = readq(&vp_reg->rts_access_steer_data1); + } + status = VXGE_HW_OK; + } else + status = VXGE_HW_FAIL; exit: return status; } @@ -3171,27 +3078,107 @@ __vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp, * __vxge_hw_vpath_rts_table_set - Set the entries of RTS access tables */ enum vxge_hw_status -__vxge_hw_vpath_rts_table_set(struct __vxge_hw_vpath_handle *vp, u32 action, - u32 rts_table, u32 offset, u64 steer_data0, - u64 steer_data1) +__vxge_hw_vpath_rts_table_set( + struct __vxge_hw_vpath_handle *vp, u32 action, u32 rts_table, + u32 offset, u64 data1, u64 data2) { - u64 data0, data1 = 0, steer_ctrl = 0; - enum vxge_hw_status status; + u64 val64; + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status = VXGE_HW_OK; + struct vxge_hw_vpath_reg __iomem *vp_reg; if (vp == NULL) { status = VXGE_HW_ERR_INVALID_HANDLE; goto exit; } - data0 = steer_data0; + vpath = vp->vpath; + vp_reg = vpath->vp_reg; + + writeq(data1, &vp_reg->rts_access_steer_data0); + wmb(); if ((rts_table == VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || (rts_table == - VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) - data1 = steer_data1; + VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) { + writeq(data2, &vp_reg->rts_access_steer_data1); + wmb(); + } + + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset); + + status = __vxge_hw_pio_mem_write64(val64, + &vp_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + vpath->hldev->config.device_poll_millis); + + if (status != VXGE_HW_OK) + goto exit; + + val64 = readq(&vp_reg->rts_access_steer_ctrl); + + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) + status = VXGE_HW_OK; + else + status = VXGE_HW_FAIL; +exit: + return status; +} + +/* + * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath + * from MAC address table. + */ +static enum vxge_hw_status +__vxge_hw_vpath_addr_get( + u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg, + u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN]) +{ + u32 i; + u64 val64; + u64 data1 = 0ULL; + u64 data2 = 0ULL; + enum vxge_hw_status status = VXGE_HW_OK; + + val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION( + VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL( + VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) | + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE | + VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0); + + status = __vxge_hw_pio_mem_write64(val64, + &vpath_reg->rts_access_steer_ctrl, + VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE, + VXGE_HW_DEF_DEVICE_POLL_MILLIS); + + if (status != VXGE_HW_OK) + goto exit; + + val64 = readq(&vpath_reg->rts_access_steer_ctrl); - status = vxge_hw_vpath_fw_api(vp->vpath, action, rts_table, offset, - &data0, &data1, &steer_ctrl); + if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) { + + data1 = readq(&vpath_reg->rts_access_steer_data0); + data2 = readq(&vpath_reg->rts_access_steer_data1); + + data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1); + data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK( + data2); + + for (i = ETH_ALEN; i > 0; i--) { + macaddr[i-1] = (u8)(data1 & 0xFF); + data1 >>= 8; + + macaddr_mask[i-1] = (u8)(data2 & 0xFF); + data2 >>= 8; + } + status = VXGE_HW_OK; + } else + status = VXGE_HW_FAIL; exit: return status; } @@ -3217,8 +3204,6 @@ enum vxge_hw_status vxge_hw_vpath_rts_rth_set( VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY, VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG, 0, &data0, &data1); - if (status != VXGE_HW_OK) - goto exit; data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) | VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3)); @@ -4132,7 +4117,6 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, vpath = &hldev->virtual_paths[vp_id]; - spin_lock_init(&hldev->virtual_paths[vp_id].lock); vpath->vp_id = vp_id; vpath->vp_open = VXGE_HW_VP_OPEN; vpath->hldev = hldev; @@ -4143,12 +4127,14 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, __vxge_hw_vpath_reset(hldev, vp_id); status = __vxge_hw_vpath_reset_check(vpath); + if (status != VXGE_HW_OK) { memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); goto exit; } status = __vxge_hw_vpath_mgmt_read(hldev, vpath); + if (status != VXGE_HW_OK) { memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath)); goto exit; @@ -4162,6 +4148,7 @@ __vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id, hldev->tim_int_mask1, vp_id); status = __vxge_hw_vpath_initialize(hldev, vp_id); + if (status != VXGE_HW_OK) __vxge_hw_vp_terminate(hldev, vp_id); exit: @@ -4255,12 +4242,15 @@ vxge_hw_vpath_open(struct __vxge_hw_device *hldev, if (status != VXGE_HW_OK) goto vpath_open_exit1; - vp = vzalloc(sizeof(struct __vxge_hw_vpath_handle)); + vp = (struct __vxge_hw_vpath_handle *) + vmalloc(sizeof(struct __vxge_hw_vpath_handle)); if (vp == NULL) { status = VXGE_HW_ERR_OUT_OF_MEMORY; goto vpath_open_exit2; } + memset(vp, 0, sizeof(struct __vxge_hw_vpath_handle)); + vp->vpath = vpath; if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) { @@ -4345,18 +4335,16 @@ vxge_hw_vpath_open(struct __vxge_hw_device *hldev, void vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp) { - struct __vxge_hw_virtualpath *vpath = vp->vpath; - struct __vxge_hw_ring *ring = vpath->ringh; - struct vxgedev *vdev = netdev_priv(vpath->hldev->ndev); + struct __vxge_hw_virtualpath *vpath = NULL; u64 new_count, val64, val164; + struct __vxge_hw_ring *ring; - if (vdev->titan1) { - new_count = readq(&vpath->vp_reg->rxdmem_size); - new_count &= 0x1fff; - } else - new_count = ring->config->ring_blocks * VXGE_HW_BLOCK_SIZE / 8; + vpath = vp->vpath; + ring = vpath->ringh; - val164 = VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count); + new_count = readq(&vpath->vp_reg->rxdmem_size); + new_count &= 0x1fff; + val164 = (VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count)); writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164), &vpath->vp_reg->prc_rxd_doorbell); @@ -4426,9 +4414,7 @@ enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp) __vxge_hw_vp_terminate(devh, vp_id); - spin_lock(&vpath->lock); vpath->vp_open = VXGE_HW_VP_NOT_OPEN; - spin_unlock(&vpath->lock); vpath_close_exit: return status; @@ -4824,7 +4810,7 @@ static void vxge_os_dma_free(struct pci_dev *pdev, const void *vaddr, * __vxge_hw_blockpool_create - Create block pool */ -static enum vxge_hw_status +enum vxge_hw_status __vxge_hw_blockpool_create(struct __vxge_hw_device *hldev, struct __vxge_hw_blockpool *blockpool, u32 pool_size, @@ -4924,7 +4910,7 @@ __vxge_hw_blockpool_create(struct __vxge_hw_device *hldev, * __vxge_hw_blockpool_destroy - Deallocates the block pool */ -static void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool) +void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool) { struct __vxge_hw_device *hldev; @@ -5061,7 +5047,8 @@ static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh, item); if (entry == NULL) - entry = vmalloc(sizeof(struct __vxge_hw_blockpool_entry)); + entry = (struct __vxge_hw_blockpool_entry *) + vmalloc(sizeof(struct __vxge_hw_blockpool_entry)); else list_del(&entry->item); @@ -5089,7 +5076,7 @@ static void vxge_hw_blockpool_block_add(struct __vxge_hw_device *devh, * Allocates a block of memory of given size, either from block pool * or by calling vxge_os_dma_malloc() */ -static void * +void * __vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size, struct vxge_hw_mempool_dma *dma_object) { @@ -5153,7 +5140,7 @@ __vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size, * __vxge_hw_blockpool_free - Frees the memory allcoated with __vxge_hw_blockpool_malloc */ -static void +void __vxge_hw_blockpool_free(struct __vxge_hw_device *devh, void *memblock, u32 size, struct vxge_hw_mempool_dma *dma_object) @@ -5177,7 +5164,8 @@ __vxge_hw_blockpool_free(struct __vxge_hw_device *devh, item); if (entry == NULL) - entry = vmalloc(sizeof( + entry = (struct __vxge_hw_blockpool_entry *) + vmalloc(sizeof( struct __vxge_hw_blockpool_entry)); else list_del(&entry->item); @@ -5204,7 +5192,7 @@ __vxge_hw_blockpool_free(struct __vxge_hw_device *devh, * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool * This function allocates a block from block pool or from the system */ -static struct __vxge_hw_blockpool_entry * +struct __vxge_hw_blockpool_entry * __vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size) { struct __vxge_hw_blockpool_entry *entry = NULL; @@ -5239,7 +5227,7 @@ __vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size) * * This function frees a block from block pool */ -static void +void __vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh, struct __vxge_hw_blockpool_entry *entry) { diff --git a/trunk/drivers/net/vxge/vxge-config.h b/trunk/drivers/net/vxge/vxge-config.h index 5b2c8313426d..5c00861b6c2c 100644 --- a/trunk/drivers/net/vxge/vxge-config.h +++ b/trunk/drivers/net/vxge/vxge-config.h @@ -20,6 +20,13 @@ #define VXGE_CACHE_LINE_SIZE 128 #endif +#define vxge_os_vaprintf(level, mask, fmt, ...) { \ + char buff[255]; \ + snprintf(buff, 255, fmt, __VA_ARGS__); \ + printk(buff); \ + printk("\n"); \ +} + #ifndef VXGE_ALIGN #define VXGE_ALIGN(adrs, size) \ (((size) - (((u64)adrs) & ((size)-1))) & ((size)-1)) @@ -29,16 +36,8 @@ #define VXGE_HW_MAX_MTU 9600 #define VXGE_HW_DEFAULT_MTU 1500 -#define VXGE_HW_MAX_ROM_IMAGES 8 - -struct eprom_image { - u8 is_valid:1; - u8 index; - u8 type; - u16 version; -}; - #ifdef VXGE_DEBUG_ASSERT + /** * vxge_assert * @test: C-condition to check @@ -49,13 +48,16 @@ struct eprom_image { * compilation * time. */ -#define vxge_assert(test) BUG_ON(!(test)) +#define vxge_assert(test) { \ + if (!(test)) \ + vxge_os_bug("bad cond: "#test" at %s:%d\n", \ + __FILE__, __LINE__); } #else #define vxge_assert(test) #endif /* end of VXGE_DEBUG_ASSERT */ /** - * enum vxge_debug_level + * enum enum vxge_debug_level * @VXGE_NONE: debug disabled * @VXGE_ERR: all errors going to be logged out * @VXGE_TRACE: all errors plus all kind of verbose tracing print outs @@ -156,47 +158,6 @@ enum vxge_hw_device_link_state { VXGE_HW_LINK_UP }; -/** - * enum enum vxge_hw_fw_upgrade_code - FW upgrade return codes. - * @VXGE_HW_FW_UPGRADE_OK: All OK send next 16 bytes - * @VXGE_HW_FW_UPGRADE_DONE: upload completed - * @VXGE_HW_FW_UPGRADE_ERR: upload error - * @VXGE_FW_UPGRADE_BYTES2SKIP: skip bytes in the stream - * - */ -enum vxge_hw_fw_upgrade_code { - VXGE_HW_FW_UPGRADE_OK = 0, - VXGE_HW_FW_UPGRADE_DONE = 1, - VXGE_HW_FW_UPGRADE_ERR = 2, - VXGE_FW_UPGRADE_BYTES2SKIP = 3 -}; - -/** - * enum enum vxge_hw_fw_upgrade_err_code - FW upgrade error codes. - * @VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1: corrupt data - * @VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW: buffer overflow - * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3: invalid .ncf file - * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4: invalid .ncf file - * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5: invalid .ncf file - * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6: invalid .ncf file - * @VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7: corrupt data - * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8: invalid .ncf file - * @VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN: generic error unknown type - * @VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH: failed to flash image check failed - */ -enum vxge_hw_fw_upgrade_err_code { - VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1 = 1, - VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW = 2, - VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3 = 3, - VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4 = 4, - VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5 = 5, - VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6 = 6, - VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7 = 7, - VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8 = 8, - VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN = 9, - VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH = 10 -}; - /** * struct vxge_hw_device_date - Date Format * @day: Day @@ -504,6 +465,7 @@ struct vxge_hw_device_config { * See also: vxge_hw_driver_initialize(). */ struct vxge_hw_uld_cbs { + void (*link_up)(struct __vxge_hw_device *devh); void (*link_down)(struct __vxge_hw_device *devh); void (*crit_err)(struct __vxge_hw_device *devh, @@ -690,7 +652,6 @@ struct __vxge_hw_virtualpath { struct vxge_hw_vpath_stats_hw_info *hw_stats; struct vxge_hw_vpath_stats_hw_info *hw_stats_sav; struct vxge_hw_vpath_stats_sw_info *sw_stats; - spinlock_t lock; }; /* @@ -713,6 +674,9 @@ struct __vxge_hw_vpath_handle{ /** * struct __vxge_hw_device - Hal device object * @magic: Magic Number + * @device_id: PCI Device Id of the adapter + * @major_revision: PCI Device major revision + * @minor_revision: PCI Device minor revision * @bar0: BAR0 virtual address. * @pdev: Physical device handle * @config: Confguration passed by the LL driver at initialization @@ -724,6 +688,9 @@ struct __vxge_hw_device { u32 magic; #define VXGE_HW_DEVICE_MAGIC 0x12345678 #define VXGE_HW_DEVICE_DEAD 0xDEADDEAD + u16 device_id; + u8 major_revision; + u8 minor_revision; void __iomem *bar0; struct pci_dev *pdev; struct net_device *ndev; @@ -764,7 +731,6 @@ struct __vxge_hw_device { u32 debug_level; u32 level_err; u32 level_trace; - u16 eprom_versions[VXGE_HW_MAX_ROM_IMAGES]; }; #define VXGE_HW_INFO_LEN 64 @@ -1447,12 +1413,12 @@ enum vxge_hw_rth_algoritms { * See also: vxge_hw_vpath_rts_rth_set(), vxge_hw_vpath_rts_rth_get(). */ struct vxge_hw_rth_hash_types { - u8 hash_type_tcpipv4_en:1, - hash_type_ipv4_en:1, - hash_type_tcpipv6_en:1, - hash_type_ipv6_en:1, - hash_type_tcpipv6ex_en:1, - hash_type_ipv6ex_en:1; + u8 hash_type_tcpipv4_en; + u8 hash_type_ipv4_en; + u8 hash_type_tcpipv6_en; + u8 hash_type_ipv6_en; + u8 hash_type_tcpipv6ex_en; + u8 hash_type_ipv6ex_en; }; void vxge_hw_device_debug_set( @@ -2034,7 +2000,7 @@ enum vxge_hw_status vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask); /** - * vxge_debug_ll + * vxge_debug * @level: level of debug verbosity. * @mask: mask for the debug * @buf: Circular buffer for tracing @@ -2046,13 +2012,26 @@ vxge_hw_vpath_strip_fcs_check(struct __vxge_hw_device *hldev, u64 vpath_mask); * may be compiled out if DEBUG macro was never defined. * See also: enum vxge_debug_level{}. */ + +#define vxge_trace_aux(level, mask, fmt, ...) \ +{\ + vxge_os_vaprintf(level, mask, fmt, __VA_ARGS__);\ +} + +#define vxge_debug(module, level, mask, fmt, ...) { \ +if ((level >= VXGE_TRACE && ((module & VXGE_DEBUG_TRACE_MASK) == module)) || \ + (level >= VXGE_ERR && ((module & VXGE_DEBUG_ERR_MASK) == module))) {\ + if ((mask & VXGE_DEBUG_MASK) == mask)\ + vxge_trace_aux(level, mask, fmt, __VA_ARGS__); \ +} \ +} + #if (VXGE_COMPONENT_LL & VXGE_DEBUG_MODULE_MASK) -#define vxge_debug_ll(level, mask, fmt, ...) do { \ - if ((level >= VXGE_ERR && VXGE_COMPONENT_LL & VXGE_DEBUG_ERR_MASK) || \ - (level >= VXGE_TRACE && VXGE_COMPONENT_LL & VXGE_DEBUG_TRACE_MASK))\ - if ((mask & VXGE_DEBUG_MASK) == mask) \ - printk(fmt "\n", __VA_ARGS__); \ -} while (0) +#define vxge_debug_ll(level, mask, fmt, ...) \ +{\ + vxge_debug(VXGE_COMPONENT_LL, level, mask, fmt, __VA_ARGS__);\ +} + #else #define vxge_debug_ll(level, mask, fmt, ...) #endif @@ -2072,26 +2051,4 @@ enum vxge_hw_status vxge_hw_vpath_rts_rth_set( enum vxge_hw_status __vxge_hw_device_is_privilaged(u32 host_type, u32 func_id); - -#define VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT 5 -#define VXGE_HW_MAX_POLLING_COUNT 100 - -void -vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev); - -enum vxge_hw_status -vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major, - u32 *minor, u32 *build); - -enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev); - -enum vxge_hw_status -vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *filebuf, - int size); - -enum vxge_hw_status -vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev, - struct eprom_image *eprom_image_data); - -int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id); #endif diff --git a/trunk/drivers/net/vxge/vxge-ethtool.c b/trunk/drivers/net/vxge/vxge-ethtool.c index bc9bd1035706..b67746eef923 100644 --- a/trunk/drivers/net/vxge/vxge-ethtool.c +++ b/trunk/drivers/net/vxge/vxge-ethtool.c @@ -11,7 +11,7 @@ * Virtualized Server Adapter. * Copyright(c) 2002-2010 Exar Corp. ******************************************************************************/ -#include +#include #include #include #include @@ -29,6 +29,7 @@ * Return value: * 0 on success. */ + static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info) { /* We currently only support 10Gb/FULL */ @@ -78,9 +79,10 @@ static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) * Returns driver specefic information like name, version etc.. to ethtool. */ static void vxge_ethtool_gdrvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) + struct ethtool_drvinfo *info) { - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev; + vdev = (struct vxgedev *)netdev_priv(dev); strlcpy(info->driver, VXGE_DRIVER_NAME, sizeof(VXGE_DRIVER_NAME)); strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION)); strlcpy(info->fw_version, vdev->fw_version, VXGE_HW_FW_STRLEN); @@ -102,14 +104,15 @@ static void vxge_ethtool_gdrvinfo(struct net_device *dev, * buffer area. */ static void vxge_ethtool_gregs(struct net_device *dev, - struct ethtool_regs *regs, void *space) + struct ethtool_regs *regs, void *space) { int index, offset; enum vxge_hw_status status; u64 reg; - u64 *reg_space = (u64 *)space; - struct vxgedev *vdev = netdev_priv(dev); - struct __vxge_hw_device *hldev = vdev->devh; + u64 *reg_space = (u64 *) space; + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) + pci_get_drvdata(vdev->pdev); regs->len = sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath; regs->version = vdev->pdev->subsystem_device; @@ -144,8 +147,9 @@ static void vxge_ethtool_gregs(struct net_device *dev, */ static int vxge_ethtool_idnic(struct net_device *dev, u32 data) { - struct vxgedev *vdev = netdev_priv(dev); - struct __vxge_hw_device *hldev = vdev->devh; + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) + pci_get_drvdata(vdev->pdev); vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON); msleep_interruptible(data ? (data * HZ) : VXGE_MAX_FLICKER_TIME); @@ -164,10 +168,11 @@ static int vxge_ethtool_idnic(struct net_device *dev, u32 data) * void */ static void vxge_ethtool_getpause_data(struct net_device *dev, - struct ethtool_pauseparam *ep) + struct ethtool_pauseparam *ep) { - struct vxgedev *vdev = netdev_priv(dev); - struct __vxge_hw_device *hldev = vdev->devh; + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) + pci_get_drvdata(vdev->pdev); vxge_hw_device_getpause_data(hldev, 0, &ep->tx_pause, &ep->rx_pause); } @@ -183,10 +188,11 @@ static void vxge_ethtool_getpause_data(struct net_device *dev, * int, returns 0 on Success */ static int vxge_ethtool_setpause_data(struct net_device *dev, - struct ethtool_pauseparam *ep) + struct ethtool_pauseparam *ep) { - struct vxgedev *vdev = netdev_priv(dev); - struct __vxge_hw_device *hldev = vdev->devh; + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) + pci_get_drvdata(vdev->pdev); vxge_hw_device_setpause_data(hldev, 0, ep->tx_pause, ep->rx_pause); @@ -203,8 +209,9 @@ static void vxge_get_ethtool_stats(struct net_device *dev, enum vxge_hw_status status; enum vxge_hw_status swstatus; struct vxge_vpath *vpath = NULL; - struct vxgedev *vdev = netdev_priv(dev); - struct __vxge_hw_device *hldev = vdev->devh; + + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); + struct __vxge_hw_device *hldev = vdev->devh; struct vxge_hw_xmac_stats *xmac_stats; struct vxge_hw_device_stats_sw_info *sw_stats; struct vxge_hw_device_stats_hw_info *hw_stats; @@ -567,12 +574,12 @@ static void vxge_get_ethtool_stats(struct net_device *dev, kfree(hw_stats); } -static void vxge_ethtool_get_strings(struct net_device *dev, u32 stringset, - u8 *data) +static void vxge_ethtool_get_strings(struct net_device *dev, + u32 stringset, u8 *data) { int stat_size = 0; int i, j; - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); switch (stringset) { case ETH_SS_STATS: vxge_add_string("VPATH STATISTICS%s\t\t\t", @@ -1059,21 +1066,21 @@ static void vxge_ethtool_get_strings(struct net_device *dev, u32 stringset, static int vxge_ethtool_get_regs_len(struct net_device *dev) { - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath; } static u32 vxge_get_rx_csum(struct net_device *dev) { - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); return vdev->rx_csum; } static int vxge_set_rx_csum(struct net_device *dev, u32 data) { - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); if (data) vdev->rx_csum = 1; @@ -1095,7 +1102,7 @@ static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data) static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset) { - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); switch (sset) { case ETH_SS_STATS: @@ -1112,59 +1119,6 @@ static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset) } } -static int vxge_set_flags(struct net_device *dev, u32 data) -{ - struct vxgedev *vdev = netdev_priv(dev); - enum vxge_hw_status status; - - if (data & ~ETH_FLAG_RXHASH) - return -EOPNOTSUPP; - - if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en) - return 0; - - if (netif_running(dev) || (vdev->config.rth_steering == NO_STEERING)) - return -EINVAL; - - vdev->devh->config.rth_en = !!(data & ETH_FLAG_RXHASH); - - /* Enabling RTH requires some of the logic in vxge_device_register and a - * vpath reset. Due to these restrictions, only allow modification - * while the interface is down. - */ - status = vxge_reset_all_vpaths(vdev); - if (status != VXGE_HW_OK) { - vdev->devh->config.rth_en = !vdev->devh->config.rth_en; - return -EFAULT; - } - - if (vdev->devh->config.rth_en) - dev->features |= NETIF_F_RXHASH; - else - dev->features &= ~NETIF_F_RXHASH; - - return 0; -} - -static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms) -{ - struct vxgedev *vdev = netdev_priv(dev); - - if (vdev->max_vpath_supported != VXGE_HW_MAX_VIRTUAL_PATHS) { - printk(KERN_INFO "Single Function Mode is required to flash the" - " firmware\n"); - return -EINVAL; - } - - if (netif_running(dev)) { - printk(KERN_INFO "Interface %s must be down to flash the " - "firmware\n", dev->name); - return -EBUSY; - } - - return vxge_fw_upgrade(vdev, parms->data, 1); -} - static const struct ethtool_ops vxge_ethtool_ops = { .get_settings = vxge_ethtool_gset, .set_settings = vxge_ethtool_sset, @@ -1186,8 +1140,6 @@ static const struct ethtool_ops vxge_ethtool_ops = { .phys_id = vxge_ethtool_idnic, .get_sset_count = vxge_ethtool_get_sset_count, .get_ethtool_stats = vxge_get_ethtool_stats, - .set_flags = vxge_set_flags, - .flash_device = vxge_fw_flash, }; void vxge_initialize_ethtool_ops(struct net_device *ndev) diff --git a/trunk/drivers/net/vxge/vxge-main.c b/trunk/drivers/net/vxge/vxge-main.c index a21dae1183e0..813829f3d024 100644 --- a/trunk/drivers/net/vxge/vxge-main.c +++ b/trunk/drivers/net/vxge/vxge-main.c @@ -50,8 +50,6 @@ #include #include #include -#include -#include #include "vxge-main.h" #include "vxge-reg.h" @@ -92,6 +90,7 @@ static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac); static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac); static enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath); static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath); +static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); static inline int is_vxge_card_up(struct vxgedev *vdev) { @@ -153,7 +152,7 @@ static void vxge_callback_link_up(struct __vxge_hw_device *hldev) { struct net_device *dev = hldev->ndev; - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); @@ -177,7 +176,7 @@ static void vxge_callback_link_down(struct __vxge_hw_device *hldev) { struct net_device *dev = hldev->ndev; - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); @@ -370,7 +369,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, u8 t_code, void *userdata) { struct vxge_ring *ring = (struct vxge_ring *)userdata; - struct net_device *dev = ring->ndev; + struct net_device *dev = ring->ndev; unsigned int dma_sizes; void *first_dtr = NULL; int dtr_cnt = 0; @@ -514,23 +513,6 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, else skb_checksum_none_assert(skb); - - if (ring->rx_hwts) { - struct skb_shared_hwtstamps *skb_hwts; - u32 ns = *(u32 *)(skb->head + pkt_length); - - skb_hwts = skb_hwtstamps(skb); - skb_hwts->hwtstamp = ns_to_ktime(ns); - skb_hwts->syststamp.tv64 = 0; - } - - /* rth_hash_type and rth_it_hit are non-zero regardless of - * whether rss is enabled. Only the rth_value is zero/non-zero - * if rss is disabled/enabled, so key off of that. - */ - if (ext_info.rth_value) - skb->rxhash = ext_info.rth_value; - vxge_rx_complete(ring, skb, ext_info.vlan, pkt_length, &ext_info); @@ -688,7 +670,7 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header) struct vxge_vpath *vpath = NULL; struct __vxge_hw_device *hldev; - hldev = pci_get_drvdata(vdev->pdev); + hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); mac_address = (u8 *)&mac_addr; memcpy(mac_address, mac_header, ETH_ALEN); @@ -787,7 +769,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - vdev = netdev_priv(dev); + vdev = (struct vxgedev *)netdev_priv(dev); if (unlikely(!is_vxge_card_up(vdev))) { vxge_debug_tx(VXGE_ERR, @@ -1052,7 +1034,7 @@ static void vxge_set_multicast(struct net_device *dev) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = netdev_priv(dev); + vdev = (struct vxgedev *)netdev_priv(dev); hldev = (struct __vxge_hw_device *)vdev->devh; if (unlikely(!is_vxge_card_up(vdev))) @@ -1112,7 +1094,7 @@ static void vxge_set_multicast(struct net_device *dev) /* Delete previous MC's */ for (i = 0; i < mcast_cnt; i++) { list_for_each_safe(entry, next, list_head) { - mac_entry = (struct vxge_mac_addrs *)entry; + mac_entry = (struct vxge_mac_addrs *) entry; /* Copy the mac address to delete */ mac_address = (u8 *)&mac_entry->macaddr; memcpy(mac_info.macaddr, mac_address, ETH_ALEN); @@ -1155,7 +1137,7 @@ static void vxge_set_multicast(struct net_device *dev) /* Delete previous MC's */ for (i = 0; i < mcast_cnt; i++) { list_for_each_safe(entry, next, list_head) { - mac_entry = (struct vxge_mac_addrs *)entry; + mac_entry = (struct vxge_mac_addrs *) entry; /* Copy the mac address to delete */ mac_address = (u8 *)&mac_entry->macaddr; memcpy(mac_info.macaddr, mac_address, ETH_ALEN); @@ -1202,14 +1184,14 @@ static int vxge_set_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; struct vxgedev *vdev; - struct __vxge_hw_device *hldev; + struct __vxge_hw_device *hldev; enum vxge_hw_status status = VXGE_HW_OK; struct macInfo mac_info_new, mac_info_old; int vpath_idx = 0; vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = netdev_priv(dev); + vdev = (struct vxgedev *)netdev_priv(dev); hldev = vdev->devh; if (!is_valid_ether_addr(addr->sa_data)) @@ -1310,13 +1292,8 @@ static void vxge_vpath_intr_enable(struct vxgedev *vdev, int vp_id) static void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id) { struct vxge_vpath *vpath = &vdev->vpaths[vp_id]; - struct __vxge_hw_device *hldev; int msix_id; - hldev = pci_get_drvdata(vdev->pdev); - - vxge_hw_vpath_wait_receive_idle(hldev, vpath->device_id); - vxge_hw_vpath_intr_disable(vpath->handle); if (vdev->config.intr_type == INTA) @@ -1446,7 +1423,6 @@ static int do_vxge_reset(struct vxgedev *vdev, int event) } if (event == VXGE_LL_FULL_RESET) { - vxge_hw_device_wait_receive_idle(vdev->devh); vxge_hw_device_intr_disable(vdev->devh); switch (vdev->cric_err_event) { @@ -1632,7 +1608,8 @@ static int vxge_poll_inta(struct napi_struct *napi, int budget) int budget_org = budget; struct vxge_ring *ring; - struct __vxge_hw_device *hldev = pci_get_drvdata(vdev->pdev); + struct __vxge_hw_device *hldev = (struct __vxge_hw_device *) + pci_get_drvdata(vdev->pdev); for (i = 0; i < vdev->no_of_vpath; i++) { ring = &vdev->vpaths[i].ring; @@ -1668,11 +1645,11 @@ static int vxge_poll_inta(struct napi_struct *napi, int budget) */ static void vxge_netpoll(struct net_device *dev) { - struct __vxge_hw_device *hldev; + struct __vxge_hw_device *hldev; struct vxgedev *vdev; - vdev = netdev_priv(dev); - hldev = pci_get_drvdata(vdev->pdev); + vdev = (struct vxgedev *)netdev_priv(dev); + hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); @@ -1712,6 +1689,15 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev) mtable[index] = index % vdev->no_of_vpath; } + /* Fill RTH hash types */ + hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4; + hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4; + hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6; + hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6; + hash_types.hash_type_tcpipv6ex_en = + vdev->config.rth_hash_type_tcpipv6ex; + hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex; + /* set indirection table, bucket-to-vpath mapping */ status = vxge_hw_vpath_rts_rth_itable_set(vdev->vp_handles, vdev->no_of_vpath, @@ -1724,21 +1710,12 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev) return status; } - /* Fill RTH hash types */ - hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4; - hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4; - hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6; - hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6; - hash_types.hash_type_tcpipv6ex_en = - vdev->config.rth_hash_type_tcpipv6ex; - hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex; - /* - * Because the itable_set() method uses the active_table field - * for the target virtual path the RTH config should be updated - * for all VPATHs. The h/w only uses the lowest numbered VPATH - * when steering frames. - */ + * Because the itable_set() method uses the active_table field + * for the target virtual path the RTH config should be updated + * for all VPATHs. The h/w only uses the lowest numbered VPATH + * when steering frames. + */ for (index = 0; index < vdev->no_of_vpath; index++) { status = vxge_hw_vpath_rts_rth_set( vdev->vpaths[index].handle, @@ -1820,7 +1797,7 @@ static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac) { struct list_head *entry, *next; u64 del_mac = 0; - u8 *mac_address = (u8 *)(&del_mac); + u8 *mac_address = (u8 *) (&del_mac); /* Copy the mac address to delete from the list */ memcpy(mac_address, mac->macaddr, ETH_ALEN); @@ -1951,7 +1928,7 @@ static enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath) } /* reset vpaths */ -enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev) +static enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev) { enum vxge_hw_status status = VXGE_HW_OK; struct vxge_vpath *vpath; @@ -2011,23 +1988,8 @@ static int vxge_open_vpaths(struct vxgedev *vdev) for (i = 0; i < vdev->no_of_vpath; i++) { vpath = &vdev->vpaths[i]; - vxge_assert(vpath->is_configured); - - if (!vdev->titan1) { - struct vxge_hw_vp_config *vcfg; - vcfg = &vdev->devh->config.vp_config[vpath->device_id]; - - vcfg->rti.urange_a = RTI_T1A_RX_URANGE_A; - vcfg->rti.urange_b = RTI_T1A_RX_URANGE_B; - vcfg->rti.urange_c = RTI_T1A_RX_URANGE_C; - vcfg->tti.uec_a = TTI_T1A_TX_UFC_A; - vcfg->tti.uec_b = TTI_T1A_TX_UFC_B; - vcfg->tti.uec_c = TTI_T1A_TX_UFC_C(vdev->mtu); - vcfg->tti.uec_d = TTI_T1A_TX_UFC_D(vdev->mtu); - vcfg->tti.ltimer_val = VXGE_T1A_TTI_LTIMER_VAL; - vcfg->tti.rtimer_val = VXGE_T1A_TTI_RTIMER_VAL; - } + vxge_assert(vpath->is_configured); attr.vp_id = vpath->device_id; attr.fifo_attr.callback = vxge_xmit_compl; attr.fifo_attr.txdl_term = vxge_tx_term; @@ -2062,7 +2024,6 @@ static int vxge_open_vpaths(struct vxgedev *vdev) vdev->config.fifo_indicate_max_pkts; vpath->ring.rx_vector_no = 0; vpath->ring.rx_csum = vdev->rx_csum; - vpath->ring.rx_hwts = vdev->rx_hwts; vpath->is_open = 1; vdev->vp_handles[i] = vpath->handle; vpath->ring.gro_enable = vdev->config.gro_enable; @@ -2101,18 +2062,18 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id) struct __vxge_hw_device *hldev; u64 reason; enum vxge_hw_status status; - struct vxgedev *vdev = (struct vxgedev *)dev_id; + struct vxgedev *vdev = (struct vxgedev *) dev_id;; vxge_debug_intr(VXGE_TRACE, "%s:%d", __func__, __LINE__); dev = vdev->ndev; - hldev = pci_get_drvdata(vdev->pdev); + hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev); if (pci_channel_offline(vdev->pdev)) return IRQ_NONE; if (unlikely(!is_vxge_card_up(vdev))) - return IRQ_HANDLED; + return IRQ_NONE; status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode, &reason); @@ -2340,8 +2301,8 @@ static void vxge_rem_msix_isr(struct vxgedev *vdev) static void vxge_rem_isr(struct vxgedev *vdev) { - struct __vxge_hw_device *hldev; - hldev = pci_get_drvdata(vdev->pdev); + struct __vxge_hw_device *hldev; + hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); #ifdef CONFIG_PCI_MSI if (vdev->config.intr_type == MSI_X) { @@ -2581,8 +2542,8 @@ vxge_open(struct net_device *dev) vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", dev->name, __func__, __LINE__); - vdev = netdev_priv(dev); - hldev = pci_get_drvdata(vdev->pdev); + vdev = (struct vxgedev *)netdev_priv(dev); + hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); function_mode = vdev->config.device_hw_info.function_mode; /* make sure you have link off by default every time Nic is @@ -2637,8 +2598,6 @@ vxge_open(struct net_device *dev) goto out2; } } - printk(KERN_INFO "%s: Receive Hashing Offload %s\n", dev->name, - hldev->config.rth_en ? "enabled" : "disabled"); for (i = 0; i < vdev->no_of_vpath; i++) { vpath = &vdev->vpaths[i]; @@ -2724,10 +2683,9 @@ vxge_open(struct net_device *dev) vxge_os_timer(vdev->vp_reset_timer, vxge_poll_vp_reset, vdev, (HZ/2)); - /* There is no need to check for RxD leak and RxD lookup on Titan1A */ - if (vdev->titan1 && vdev->vp_lockup_timer.function == NULL) - vxge_os_timer(vdev->vp_lockup_timer, vxge_poll_vp_lockup, vdev, - HZ / 2); + if (vdev->vp_lockup_timer.function == NULL) + vxge_os_timer(vdev->vp_lockup_timer, + vxge_poll_vp_lockup, vdev, (HZ/2)); set_bit(__VXGE_STATE_CARD_UP, &vdev->state); @@ -2809,8 +2767,8 @@ static int do_vxge_close(struct net_device *dev, int do_io) vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d", dev->name, __func__, __LINE__); - vdev = netdev_priv(dev); - hldev = pci_get_drvdata(vdev->pdev); + vdev = (struct vxgedev *)netdev_priv(dev); + hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev); if (unlikely(!is_vxge_card_up(vdev))) return 0; @@ -2820,6 +2778,7 @@ static int do_vxge_close(struct net_device *dev, int do_io) while (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state)) msleep(50); + clear_bit(__VXGE_STATE_CARD_UP, &vdev->state); if (do_io) { /* Put the vpath back in normal mode */ vpath_vector = vxge_mBIT(vdev->vpaths[0].device_id); @@ -2859,17 +2818,10 @@ static int do_vxge_close(struct net_device *dev, int do_io) smp_wmb(); } - - if (vdev->titan1) - del_timer_sync(&vdev->vp_lockup_timer); + del_timer_sync(&vdev->vp_lockup_timer); del_timer_sync(&vdev->vp_reset_timer); - if (do_io) - vxge_hw_device_wait_receive_idle(hldev); - - clear_bit(__VXGE_STATE_CARD_UP, &vdev->state); - /* Disable napi */ if (vdev->config.intr_type != MSI_X) napi_disable(&vdev->napi); @@ -2886,6 +2838,8 @@ static int do_vxge_close(struct net_device *dev, int do_io) if (do_io) vxge_hw_device_intr_disable(vdev->devh); + mdelay(1000); + vxge_rem_isr(vdev); vxge_napi_del_all(vdev); @@ -3000,101 +2954,6 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) return net_stats; } -static enum vxge_hw_status vxge_timestamp_config(struct vxgedev *vdev, - int enable) -{ - enum vxge_hw_status status; - u64 val64; - - /* Timestamp is passed to the driver via the FCS, therefore we - * must disable the FCS stripping by the adapter. Since this is - * required for the driver to load (due to a hardware bug), - * there is no need to do anything special here. - */ - if (enable) - val64 = VXGE_HW_XMAC_TIMESTAMP_EN | - VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(0) | - VXGE_HW_XMAC_TIMESTAMP_INTERVAL(0); - else - val64 = 0; - - status = vxge_hw_mgmt_reg_write(vdev->devh, - vxge_hw_mgmt_reg_type_mrpcim, - 0, - offsetof(struct vxge_hw_mrpcim_reg, - xmac_timestamp), - val64); - vxge_hw_device_flush_io(vdev->devh); - return status; -} - -static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data) -{ - struct hwtstamp_config config; - enum vxge_hw_status status; - int i; - - if (copy_from_user(&config, data, sizeof(config))) - return -EFAULT; - - /* reserved for future extensions */ - if (config.flags) - return -EINVAL; - - /* Transmit HW Timestamp not supported */ - switch (config.tx_type) { - case HWTSTAMP_TX_OFF: - break; - case HWTSTAMP_TX_ON: - default: - return -ERANGE; - } - - switch (config.rx_filter) { - case HWTSTAMP_FILTER_NONE: - status = vxge_timestamp_config(vdev, 0); - if (status != VXGE_HW_OK) - return -EFAULT; - - vdev->rx_hwts = 0; - config.rx_filter = HWTSTAMP_FILTER_NONE; - break; - - case HWTSTAMP_FILTER_ALL: - case HWTSTAMP_FILTER_SOME: - case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: - case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: - case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: - case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: - case HWTSTAMP_FILTER_PTP_V2_EVENT: - case HWTSTAMP_FILTER_PTP_V2_SYNC: - case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: - status = vxge_timestamp_config(vdev, 1); - if (status != VXGE_HW_OK) - return -EFAULT; - - vdev->rx_hwts = 1; - config.rx_filter = HWTSTAMP_FILTER_ALL; - break; - - default: - return -ERANGE; - } - - for (i = 0; i < vdev->no_of_vpath; i++) - vdev->vpaths[i].ring.rx_hwts = vdev->rx_hwts; - - if (copy_to_user(data, &config, sizeof(config))) - return -EFAULT; - - return 0; -} - /** * vxge_ioctl * @dev: Device pointer. @@ -3107,20 +2966,7 @@ static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data) */ static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct vxgedev *vdev = netdev_priv(dev); - int ret; - - switch (cmd) { - case SIOCSHWTSTAMP: - ret = vxge_hwtstamp_ioctl(vdev, rq->ifr_data); - if (ret) - return ret; - break; - default: - return -EOPNOTSUPP; - } - - return 0; + return -EOPNOTSUPP; } /** @@ -3138,7 +2984,7 @@ vxge_tx_watchdog(struct net_device *dev) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = netdev_priv(dev); + vdev = (struct vxgedev *)netdev_priv(dev); vdev->cric_err_event = VXGE_HW_EVENT_RESET_START; @@ -3166,7 +3012,7 @@ vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = netdev_priv(dev); + vdev = (struct vxgedev *)netdev_priv(dev); vpath = &vdev->vpaths[0]; if ((NULL == grp) && (vpath->is_open)) { @@ -3215,7 +3061,7 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) struct vxge_vpath *vpath; int vp_id; - vdev = netdev_priv(dev); + vdev = (struct vxgedev *)netdev_priv(dev); /* Add these vlan to the vid table */ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) { @@ -3242,7 +3088,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - vdev = netdev_priv(dev); + vdev = (struct vxgedev *)netdev_priv(dev); vlan_group_set_device(vdev->vlgrp, vid, NULL); @@ -3279,19 +3125,6 @@ static const struct net_device_ops vxge_netdev_ops = { #endif }; -static int __devinit vxge_device_revision(struct vxgedev *vdev) -{ - int ret; - u8 revision; - - ret = pci_read_config_byte(vdev->pdev, PCI_REVISION_ID, &revision); - if (ret) - return -EIO; - - vdev->titan1 = (revision == VXGE_HW_TITAN1_PCI_REVISION); - return 0; -} - static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, struct vxge_config *config, int high_dma, int no_of_vpath, @@ -3330,11 +3163,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, vdev->pdev = hldev->pdev; memcpy(&vdev->config, config, sizeof(struct vxge_config)); vdev->rx_csum = 1; /* Enable Rx CSUM by default. */ - vdev->rx_hwts = 0; - - ret = vxge_device_revision(vdev); - if (ret < 0) - goto _out1; SET_NETDEV_DEV(ndev, &vdev->pdev->dev); @@ -3350,11 +3178,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, vxge_initialize_ethtool_ops(ndev); - if (vdev->config.rth_steering != NO_STEERING) { - ndev->features |= NETIF_F_RXHASH; - hldev->config.rth_en = VXGE_HW_RTH_ENABLE; - } - /* Allocate memory for vpath */ vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) * no_of_vpath, GFP_KERNEL); @@ -3404,7 +3227,6 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, "%s: Ethernet device registered", ndev->name); - hldev->ndev = ndev; *vdev_out = vdev; /* Resetting the Device stats */ @@ -3439,29 +3261,36 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev, * * This function will unregister and free network device */ -static void vxge_device_unregister(struct __vxge_hw_device *hldev) +static void +vxge_device_unregister(struct __vxge_hw_device *hldev) { struct vxgedev *vdev; struct net_device *dev; char buf[IFNAMSIZ]; +#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \ + (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)) + u32 level_trace; +#endif dev = hldev->ndev; vdev = netdev_priv(dev); +#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \ + (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)) + level_trace = vdev->level_trace; +#endif + vxge_debug_entryexit(level_trace, + "%s: %s:%d", vdev->ndev->name, __func__, __LINE__); - vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d", vdev->ndev->name, - __func__, __LINE__); - - memcpy(buf, dev->name, IFNAMSIZ); + memcpy(buf, vdev->ndev->name, IFNAMSIZ); /* in 2.6 will call stop() if device is up */ unregister_netdev(dev); flush_scheduled_work(); - vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", - buf); - vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, - __func__, __LINE__); + vxge_debug_init(level_trace, "%s: ethernet device unregistered", buf); + vxge_debug_entryexit(level_trace, + "%s: %s:%d Exiting...", buf, __func__, __LINE__); } /* @@ -3475,7 +3304,7 @@ vxge_callback_crit_err(struct __vxge_hw_device *hldev, enum vxge_hw_event type, u64 vp_id) { struct net_device *dev = hldev->ndev; - struct vxgedev *vdev = netdev_priv(dev); + struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev); struct vxge_vpath *vpath = NULL; int vpath_idx; @@ -3984,7 +3813,8 @@ static int vxge_pm_resume(struct pci_dev *pdev) static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct __vxge_hw_device *hldev = pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = + (struct __vxge_hw_device *) pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; netif_device_detach(netdev); @@ -4013,7 +3843,8 @@ static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev, */ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev) { - struct __vxge_hw_device *hldev = pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = + (struct __vxge_hw_device *) pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; struct vxgedev *vdev = netdev_priv(netdev); @@ -4038,7 +3869,8 @@ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev) */ static void vxge_io_resume(struct pci_dev *pdev) { - struct __vxge_hw_device *hldev = pci_get_drvdata(pdev); + struct __vxge_hw_device *hldev = + (struct __vxge_hw_device *) pci_get_drvdata(pdev); struct net_device *netdev = hldev->ndev; if (netif_running(netdev)) { @@ -4082,142 +3914,6 @@ static inline u32 vxge_get_num_vfs(u64 function_mode) return num_functions; } -int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override) -{ - struct __vxge_hw_device *hldev = vdev->devh; - u32 maj, min, bld, cmaj, cmin, cbld; - enum vxge_hw_status status; - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, fw_name, &vdev->pdev->dev); - if (ret) { - vxge_debug_init(VXGE_ERR, "%s: Firmware file '%s' not found", - VXGE_DRIVER_NAME, fw_name); - goto out; - } - - /* Load the new firmware onto the adapter */ - status = vxge_update_fw_image(hldev, fw->data, fw->size); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, - "%s: FW image download to adapter failed '%s'.", - VXGE_DRIVER_NAME, fw_name); - ret = -EIO; - goto out; - } - - /* Read the version of the new firmware */ - status = vxge_hw_upgrade_read_version(hldev, &maj, &min, &bld); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, - "%s: Upgrade read version failed '%s'.", - VXGE_DRIVER_NAME, fw_name); - ret = -EIO; - goto out; - } - - cmaj = vdev->config.device_hw_info.fw_version.major; - cmin = vdev->config.device_hw_info.fw_version.minor; - cbld = vdev->config.device_hw_info.fw_version.build; - /* It's possible the version in /lib/firmware is not the latest version. - * If so, we could get into a loop of trying to upgrade to the latest - * and flashing the older version. - */ - if (VXGE_FW_VER(maj, min, bld) == VXGE_FW_VER(cmaj, cmin, cbld) && - !override) { - ret = -EINVAL; - goto out; - } - - printk(KERN_NOTICE "Upgrade to firmware version %d.%d.%d commencing\n", - maj, min, bld); - - /* Flash the adapter with the new firmware */ - status = vxge_hw_flash_fw(hldev); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, "%s: Upgrade commit failed '%s'.", - VXGE_DRIVER_NAME, fw_name); - ret = -EIO; - goto out; - } - - printk(KERN_NOTICE "Upgrade of firmware successful! Adapter must be " - "hard reset before using, thus requiring a system reboot or a " - "hotplug event.\n"); - -out: - return ret; -} - -static int vxge_probe_fw_update(struct vxgedev *vdev) -{ - u32 maj, min, bld; - int ret, gpxe = 0; - char *fw_name; - - maj = vdev->config.device_hw_info.fw_version.major; - min = vdev->config.device_hw_info.fw_version.minor; - bld = vdev->config.device_hw_info.fw_version.build; - - if (VXGE_FW_VER(maj, min, bld) == VXGE_CERT_FW_VER) - return 0; - - /* Ignore the build number when determining if the current firmware is - * "too new" to load the driver - */ - if (VXGE_FW_VER(maj, min, 0) > VXGE_CERT_FW_VER) { - vxge_debug_init(VXGE_ERR, "%s: Firmware newer than last known " - "version, unable to load driver\n", - VXGE_DRIVER_NAME); - return -EINVAL; - } - - /* Firmware 1.4.4 and older cannot be upgraded, and is too ancient to - * work with this driver. - */ - if (VXGE_FW_VER(maj, min, bld) <= VXGE_FW_DEAD_VER) { - vxge_debug_init(VXGE_ERR, "%s: Firmware %d.%d.%d cannot be " - "upgraded\n", VXGE_DRIVER_NAME, maj, min, bld); - return -EINVAL; - } - - /* If file not specified, determine gPXE or not */ - if (VXGE_FW_VER(maj, min, bld) >= VXGE_EPROM_FW_VER) { - int i; - for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) - if (vdev->devh->eprom_versions[i]) { - gpxe = 1; - break; - } - } - if (gpxe) - fw_name = "vxge/X3fw-pxe.ncf"; - else - fw_name = "vxge/X3fw.ncf"; - - ret = vxge_fw_upgrade(vdev, fw_name, 0); - /* -EINVAL and -ENOENT are not fatal errors for flashing firmware on - * probe, so ignore them - */ - if (ret != -EINVAL && ret != -ENOENT) - return -EIO; - else - ret = 0; - - if (VXGE_FW_VER(VXGE_CERT_FW_VER_MAJOR, VXGE_CERT_FW_VER_MINOR, 0) > - VXGE_FW_VER(maj, min, 0)) { - vxge_debug_init(VXGE_ERR, "%s: Firmware %d.%d.%d is too old to" - " be used with this driver.\n" - "Please get the latest version from " - "ftp://ftp.s2io.com/pub/X3100-Drivers/FIRMWARE", - VXGE_DRIVER_NAME, maj, min, bld); - return -EINVAL; - } - - return ret; -} - /** * vxge_probe * @pdev : structure containing the PCI related information of the device. @@ -4232,7 +3928,7 @@ static int vxge_probe_fw_update(struct vxgedev *vdev) static int __devinit vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) { - struct __vxge_hw_device *hldev; + struct __vxge_hw_device *hldev; enum vxge_hw_status status; int ret; int high_dma = 0; @@ -4376,6 +4072,16 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit3; } + if (ll_config->device_hw_info.fw_version.major != + VXGE_DRIVER_FW_VERSION_MAJOR) { + vxge_debug_init(VXGE_ERR, + "%s: Incorrect firmware version." + "Please upgrade the firmware to version 1.x.x", + VXGE_DRIVER_NAME); + ret = -EINVAL; + goto _exit3; + } + vpath_mask = ll_config->device_hw_info.vpath_mask; if (vpath_mask == 0) { vxge_debug_ll_config(VXGE_TRACE, @@ -4439,37 +4145,11 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) goto _exit3; } - if (VXGE_FW_VER(ll_config->device_hw_info.fw_version.major, - ll_config->device_hw_info.fw_version.minor, - ll_config->device_hw_info.fw_version.build) >= - VXGE_EPROM_FW_VER) { - struct eprom_image img[VXGE_HW_MAX_ROM_IMAGES]; - - status = vxge_hw_vpath_eprom_img_ver_get(hldev, img); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, "%s: Reading of EPROM failed", - VXGE_DRIVER_NAME); - /* This is a non-fatal error, continue */ - } - - for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) { - hldev->eprom_versions[i] = img[i].version; - if (!img[i].is_valid) - break; - vxge_debug_init(VXGE_TRACE, "%s: EPROM %d, version " - "%d.%d.%d.%d\n", VXGE_DRIVER_NAME, i, - VXGE_EPROM_IMG_MAJOR(img[i].version), - VXGE_EPROM_IMG_MINOR(img[i].version), - VXGE_EPROM_IMG_FIX(img[i].version), - VXGE_EPROM_IMG_BUILD(img[i].version)); - } - } - /* if FCS stripping is not disabled in MAC fail driver load */ - status = vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask); - if (status != VXGE_HW_OK) { - vxge_debug_init(VXGE_ERR, "%s: FCS stripping is enabled in MAC" - " failing driver load", VXGE_DRIVER_NAME); + if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) { + vxge_debug_init(VXGE_ERR, + "%s: FCS stripping is not disabled in MAC" + " failing driver load", VXGE_DRIVER_NAME); ret = -EINVAL; goto _exit4; } @@ -4483,32 +4163,28 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) ll_config->fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS; ll_config->addr_learn_en = addr_learn_en; ll_config->rth_algorithm = RTH_ALG_JENKINS; - ll_config->rth_hash_type_tcpipv4 = 1; - ll_config->rth_hash_type_ipv4 = 0; - ll_config->rth_hash_type_tcpipv6 = 0; - ll_config->rth_hash_type_ipv6 = 0; - ll_config->rth_hash_type_tcpipv6ex = 0; - ll_config->rth_hash_type_ipv6ex = 0; + ll_config->rth_hash_type_tcpipv4 = VXGE_HW_RING_HASH_TYPE_TCP_IPV4; + ll_config->rth_hash_type_ipv4 = VXGE_HW_RING_HASH_TYPE_NONE; + ll_config->rth_hash_type_tcpipv6 = VXGE_HW_RING_HASH_TYPE_NONE; + ll_config->rth_hash_type_ipv6 = VXGE_HW_RING_HASH_TYPE_NONE; + ll_config->rth_hash_type_tcpipv6ex = VXGE_HW_RING_HASH_TYPE_NONE; + ll_config->rth_hash_type_ipv6ex = VXGE_HW_RING_HASH_TYPE_NONE; ll_config->rth_bkt_sz = RTH_BUCKET_SIZE; ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE; ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE; - ret = vxge_device_register(hldev, ll_config, high_dma, no_of_vpath, - &vdev); - if (ret) { + if (vxge_device_register(hldev, ll_config, high_dma, no_of_vpath, + &vdev)) { ret = -EINVAL; goto _exit4; } - ret = vxge_probe_fw_update(vdev); - if (ret) - goto _exit5; - vxge_hw_device_debug_set(hldev, VXGE_TRACE, VXGE_COMPONENT_LL); VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev), vxge_hw_device_trace_level_get(hldev)); /* set private HW device info */ + hldev->ndev = vdev->ndev; vdev->mtu = VXGE_HW_DEFAULT_MTU; vdev->bar0 = attr.bar0; vdev->max_vpath_supported = max_vpath_supported; @@ -4602,13 +4278,15 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) /* Copy the station mac address to the list */ for (i = 0; i < vdev->no_of_vpath; i++) { - entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_KERNEL); + entry = (struct vxge_mac_addrs *) + kzalloc(sizeof(struct vxge_mac_addrs), + GFP_KERNEL); if (NULL == entry) { vxge_debug_init(VXGE_ERR, "%s: mac_addr_list : memory allocation failed", vdev->ndev->name); ret = -EPERM; - goto _exit6; + goto _exit5; } macaddr = (u8 *)&entry->macaddr; memcpy(macaddr, vdev->ndev->dev_addr, ETH_ALEN); @@ -4648,10 +4326,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) kfree(ll_config); return 0; -_exit6: +_exit5: for (i = 0; i < vdev->no_of_vpath; i++) vxge_free_mac_add_list(&vdev->vpaths[i]); -_exit5: + vxge_device_unregister(hldev); _exit4: pci_disable_sriov(pdev); @@ -4676,25 +4354,34 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) * Description: This function is called by the Pci subsystem to release a * PCI device and free up all resource held up by the device. */ -static void __devexit vxge_remove(struct pci_dev *pdev) +static void __devexit +vxge_remove(struct pci_dev *pdev) { - struct __vxge_hw_device *hldev; + struct __vxge_hw_device *hldev; struct vxgedev *vdev = NULL; struct net_device *dev; int i = 0; +#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \ + (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)) + u32 level_trace; +#endif - hldev = pci_get_drvdata(pdev); + hldev = (struct __vxge_hw_device *) pci_get_drvdata(pdev); if (hldev == NULL) return; - dev = hldev->ndev; vdev = netdev_priv(dev); - vxge_debug_entryexit(vdev->level_trace, "%s:%d", __func__, __LINE__); +#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \ + (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)) + level_trace = vdev->level_trace; +#endif + vxge_debug_entryexit(level_trace, + "%s:%d", __func__, __LINE__); - vxge_debug_init(vdev->level_trace, "%s : removing PCI device...", - __func__); + vxge_debug_init(level_trace, + "%s : removing PCI device...", __func__); vxge_device_unregister(hldev); for (i = 0; i < vdev->no_of_vpath; i++) { @@ -4712,16 +4399,16 @@ static void __devexit vxge_remove(struct pci_dev *pdev) /* we are safe to free it now */ free_netdev(dev); - vxge_debug_init(vdev->level_trace, "%s:%d Device unregistered", - __func__, __LINE__); + vxge_debug_init(level_trace, + "%s:%d Device unregistered", __func__, __LINE__); vxge_hw_device_terminate(hldev); pci_disable_device(pdev); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); - vxge_debug_entryexit(vdev->level_trace, "%s:%d Exiting...", __func__, - __LINE__); + vxge_debug_entryexit(level_trace, + "%s:%d Exiting...", __func__, __LINE__); } static struct pci_error_handlers vxge_err_handler = { diff --git a/trunk/drivers/net/vxge/vxge-main.h b/trunk/drivers/net/vxge/vxge-main.h index 953cb0ded3e1..de64536cb7d0 100644 --- a/trunk/drivers/net/vxge/vxge-main.h +++ b/trunk/drivers/net/vxge/vxge-main.h @@ -29,9 +29,6 @@ #define PCI_DEVICE_ID_TITAN_WIN 0x5733 #define PCI_DEVICE_ID_TITAN_UNI 0x5833 -#define VXGE_HW_TITAN1_PCI_REVISION 1 -#define VXGE_HW_TITAN1A_PCI_REVISION 2 - #define VXGE_USE_DEFAULT 0xffffffff #define VXGE_HW_VPATH_MSIX_ACTIVE 4 #define VXGE_ALARM_MSIX_ID 2 @@ -56,13 +53,11 @@ #define VXGE_TTI_BTIMER_VAL 250000 -#define VXGE_TTI_LTIMER_VAL 1000 -#define VXGE_T1A_TTI_LTIMER_VAL 80 -#define VXGE_TTI_RTIMER_VAL 0 -#define VXGE_T1A_TTI_RTIMER_VAL 400 -#define VXGE_RTI_BTIMER_VAL 250 -#define VXGE_RTI_LTIMER_VAL 100 -#define VXGE_RTI_RTIMER_VAL 0 +#define VXGE_TTI_LTIMER_VAL 1000 +#define VXGE_TTI_RTIMER_VAL 0 +#define VXGE_RTI_BTIMER_VAL 250 +#define VXGE_RTI_LTIMER_VAL 100 +#define VXGE_RTI_RTIMER_VAL 0 #define VXGE_FIFO_INDICATE_MAX_PKTS VXGE_DEF_FIFO_LENGTH #define VXGE_ISR_POLLING_CNT 8 #define VXGE_MAX_CONFIG_DEV 0xFF @@ -81,32 +76,14 @@ #define TTI_TX_UFC_B 40 #define TTI_TX_UFC_C 60 #define TTI_TX_UFC_D 100 -#define TTI_T1A_TX_UFC_A 30 -#define TTI_T1A_TX_UFC_B 80 -/* Slope - (max_mtu - min_mtu)/(max_mtu_ufc - min_mtu_ufc) */ -/* Slope - 93 */ -/* 60 - 9k Mtu, 140 - 1.5k mtu */ -#define TTI_T1A_TX_UFC_C(mtu) (60 + ((VXGE_HW_MAX_MTU - mtu) / 93)) - -/* Slope - 37 */ -/* 100 - 9k Mtu, 300 - 1.5k mtu */ -#define TTI_T1A_TX_UFC_D(mtu) (100 + ((VXGE_HW_MAX_MTU - mtu) / 37)) - - -#define RTI_RX_URANGE_A 5 -#define RTI_RX_URANGE_B 15 -#define RTI_RX_URANGE_C 40 -#define RTI_T1A_RX_URANGE_A 1 -#define RTI_T1A_RX_URANGE_B 20 -#define RTI_T1A_RX_URANGE_C 50 -#define RTI_RX_UFC_A 1 -#define RTI_RX_UFC_B 5 -#define RTI_RX_UFC_C 10 -#define RTI_RX_UFC_D 15 -#define RTI_T1A_RX_UFC_B 20 -#define RTI_T1A_RX_UFC_C 50 -#define RTI_T1A_RX_UFC_D 60 +#define RTI_RX_URANGE_A 5 +#define RTI_RX_URANGE_B 15 +#define RTI_RX_URANGE_C 40 +#define RTI_RX_UFC_A 1 +#define RTI_RX_UFC_B 5 +#define RTI_RX_UFC_C 10 +#define RTI_RX_UFC_D 15 /* Milli secs timer period */ #define VXGE_TIMER_DELAY 10000 @@ -168,15 +145,15 @@ struct vxge_config { int addr_learn_en; - u32 rth_steering:2, - rth_algorithm:2, - rth_hash_type_tcpipv4:1, - rth_hash_type_ipv4:1, - rth_hash_type_tcpipv6:1, - rth_hash_type_ipv6:1, - rth_hash_type_tcpipv6ex:1, - rth_hash_type_ipv6ex:1, - rth_bkt_sz:8; + int rth_steering; + int rth_algorithm; + int rth_hash_type_tcpipv4; + int rth_hash_type_ipv4; + int rth_hash_type_tcpipv6; + int rth_hash_type_ipv6; + int rth_hash_type_tcpipv6ex; + int rth_hash_type_ipv6ex; + int rth_bkt_sz; int rth_jhash_golden_ratio; int tx_steering_type; int fifo_indicate_max_pkts; @@ -271,9 +248,8 @@ struct vxge_ring { */ int driver_id; - /* copy of the flag indicating whether rx_csum is to be used */ - u32 rx_csum:1, - rx_hwts:1; + /* copy of the flag indicating whether rx_csum is to be used */ + u32 rx_csum; int pkts_processed; int budget; @@ -351,9 +327,7 @@ struct vxgedev { u16 all_multi_flg; /* A flag indicating whether rx_csum is to be used or not. */ - u32 rx_csum:1, - rx_hwts:1, - titan1:1; + u32 rx_csum; struct vxge_msix_entry *vxge_entries; struct msix_entry *entries; @@ -413,6 +387,8 @@ struct vxge_tx_priv { static int p = val; \ module_param(p, int, 0) +#define vxge_os_bug(fmt...) { printk(fmt); BUG(); } + #define vxge_os_timer(timer, handle, arg, exp) do { \ init_timer(&timer); \ timer.function = handle; \ @@ -421,11 +397,6 @@ struct vxge_tx_priv { } while (0); extern void vxge_initialize_ethtool_ops(struct net_device *ndev); - -enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); - -int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override); - /** * #define VXGE_DEBUG_INIT: debug for initialization functions * #define VXGE_DEBUG_TX : debug transmit related functions diff --git a/trunk/drivers/net/vxge/vxge-reg.h b/trunk/drivers/net/vxge/vxge-reg.h index 3e658b175947..3dd5c9615ef9 100644 --- a/trunk/drivers/net/vxge/vxge-reg.h +++ b/trunk/drivers/net/vxge/vxge-reg.h @@ -49,33 +49,6 @@ #define VXGE_HW_TITAN_VPMGMT_REG_SPACES 17 #define VXGE_HW_TITAN_VPATH_REG_SPACES 17 -#define VXGE_HW_FW_API_GET_EPROM_REV 31 - -#define VXGE_EPROM_IMG_MAJOR(val) (u32) vxge_bVALn(val, 48, 4) -#define VXGE_EPROM_IMG_MINOR(val) (u32) vxge_bVALn(val, 52, 4) -#define VXGE_EPROM_IMG_FIX(val) (u32) vxge_bVALn(val, 56, 4) -#define VXGE_EPROM_IMG_BUILD(val) (u32) vxge_bVALn(val, 60, 4) - -#define VXGE_HW_GET_EPROM_IMAGE_INDEX(val) vxge_bVALn(val, 16, 8) -#define VXGE_HW_GET_EPROM_IMAGE_VALID(val) vxge_bVALn(val, 31, 1) -#define VXGE_HW_GET_EPROM_IMAGE_TYPE(val) vxge_bVALn(val, 40, 8) -#define VXGE_HW_GET_EPROM_IMAGE_REV(val) vxge_bVALn(val, 48, 16) -#define VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(val) vxge_vBIT(val, 16, 8) - -#define VXGE_HW_FW_API_GET_FUNC_MODE 29 -#define VXGE_HW_GET_FUNC_MODE_VAL(val) (val & 0xFF) - -#define VXGE_HW_FW_UPGRADE_MEMO 13 -#define VXGE_HW_FW_UPGRADE_ACTION 16 -#define VXGE_HW_FW_UPGRADE_OFFSET_START 2 -#define VXGE_HW_FW_UPGRADE_OFFSET_SEND 3 -#define VXGE_HW_FW_UPGRADE_OFFSET_COMMIT 4 -#define VXGE_HW_FW_UPGRADE_OFFSET_READ 5 - -#define VXGE_HW_FW_UPGRADE_BLK_SIZE 16 -#define VXGE_HW_UPGRADE_GET_RET_ERR_CODE(val) (val & 0xff) -#define VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(val) ((val >> 8) & 0xff) - #define VXGE_HW_ASIC_MODE_RESERVED 0 #define VXGE_HW_ASIC_MODE_NO_IOV 1 #define VXGE_HW_ASIC_MODE_SR_IOV 2 @@ -192,13 +165,13 @@ #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_ETYPE 2 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_PN 3 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG 5 -#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6 +#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG 7 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK 8 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY 9 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_QOS 10 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DS 11 -#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12 +#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12 #define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO 13 #define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(bits) \ @@ -464,7 +437,6 @@ #define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(bits) \ vxge_bVALn(bits, 48, 16) #define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_BUILD vxge_vBIT(val, 48, 16) -#define VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(bits) vxge_bVALn(bits, 0, 8) #define VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_GET_PPIF_SRPCIM_TO_VPATH_ALARM(bits)\ vxge_bVALn(bits, 0, 18) @@ -4026,7 +3998,6 @@ struct vxge_hw_vpath_reg { #define VXGE_HW_PRC_CFG6_L4_CPC_TRSFR_CODE_EN vxge_mBIT(9) #define VXGE_HW_PRC_CFG6_RXD_CRXDT(val) vxge_vBIT(val, 23, 9) #define VXGE_HW_PRC_CFG6_RXD_SPAT(val) vxge_vBIT(val, 36, 9) -#define VXGE_HW_PRC_CFG6_GET_RXD_SPAT(val) vxge_bVALn(val, 36, 9) /*0x00a78*/ u64 prc_cfg7; #define VXGE_HW_PRC_CFG7_SCATTER_MODE(val) vxge_vBIT(val, 6, 2) #define VXGE_HW_PRC_CFG7_SMART_SCAT_EN vxge_mBIT(11) diff --git a/trunk/drivers/net/vxge/vxge-traffic.h b/trunk/drivers/net/vxge/vxge-traffic.h index 1fceee876228..9890d4d596d0 100644 --- a/trunk/drivers/net/vxge/vxge-traffic.h +++ b/trunk/drivers/net/vxge/vxge-traffic.h @@ -1904,6 +1904,34 @@ enum vxge_hw_ring_tcode { VXGE_HW_RING_T_CODE_MULTI_ERR = 0xF }; +/** + * enum enum vxge_hw_ring_hash_type - RTH hash types + * @VXGE_HW_RING_HASH_TYPE_NONE: No Hash + * @VXGE_HW_RING_HASH_TYPE_TCP_IPV4: TCP IPv4 + * @VXGE_HW_RING_HASH_TYPE_UDP_IPV4: UDP IPv4 + * @VXGE_HW_RING_HASH_TYPE_IPV4: IPv4 + * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6: TCP IPv6 + * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6: UDP IPv6 + * @VXGE_HW_RING_HASH_TYPE_IPV6: IPv6 + * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX: TCP IPv6 extension + * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX: UDP IPv6 extension + * @VXGE_HW_RING_HASH_TYPE_IPV6_EX: IPv6 extension + * + * RTH hash types + */ +enum vxge_hw_ring_hash_type { + VXGE_HW_RING_HASH_TYPE_NONE = 0x0, + VXGE_HW_RING_HASH_TYPE_TCP_IPV4 = 0x1, + VXGE_HW_RING_HASH_TYPE_UDP_IPV4 = 0x2, + VXGE_HW_RING_HASH_TYPE_IPV4 = 0x3, + VXGE_HW_RING_HASH_TYPE_TCP_IPV6 = 0x4, + VXGE_HW_RING_HASH_TYPE_UDP_IPV6 = 0x5, + VXGE_HW_RING_HASH_TYPE_IPV6 = 0x6, + VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX = 0x7, + VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX = 0x8, + VXGE_HW_RING_HASH_TYPE_IPV6_EX = 0x9 +}; + enum vxge_hw_status vxge_hw_ring_rxd_reserve( struct __vxge_hw_ring *ring_handle, void **rxdh); diff --git a/trunk/drivers/net/vxge/vxge-version.h b/trunk/drivers/net/vxge/vxge-version.h index f05bb2f55e73..53fefe137368 100644 --- a/trunk/drivers/net/vxge/vxge-version.h +++ b/trunk/drivers/net/vxge/vxge-version.h @@ -16,34 +16,7 @@ #define VXGE_VERSION_MAJOR "2" #define VXGE_VERSION_MINOR "0" -#define VXGE_VERSION_FIX "10" -#define VXGE_VERSION_BUILD "21808" +#define VXGE_VERSION_FIX "9" +#define VXGE_VERSION_BUILD "20840" #define VXGE_VERSION_FOR "k" - -#define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld)) - -#define VXGE_DEAD_FW_VER_MAJOR 1 -#define VXGE_DEAD_FW_VER_MINOR 4 -#define VXGE_DEAD_FW_VER_BUILD 4 - -#define VXGE_FW_DEAD_VER VXGE_FW_VER(VXGE_DEAD_FW_VER_MAJOR, \ - VXGE_DEAD_FW_VER_MINOR, \ - VXGE_DEAD_FW_VER_BUILD) - -#define VXGE_EPROM_FW_VER_MAJOR 1 -#define VXGE_EPROM_FW_VER_MINOR 6 -#define VXGE_EPROM_FW_VER_BUILD 1 - -#define VXGE_EPROM_FW_VER VXGE_FW_VER(VXGE_EPROM_FW_VER_MAJOR, \ - VXGE_EPROM_FW_VER_MINOR, \ - VXGE_EPROM_FW_VER_BUILD) - -#define VXGE_CERT_FW_VER_MAJOR 1 -#define VXGE_CERT_FW_VER_MINOR 8 -#define VXGE_CERT_FW_VER_BUILD 1 - -#define VXGE_CERT_FW_VER VXGE_FW_VER(VXGE_CERT_FW_VER_MAJOR, \ - VXGE_CERT_FW_VER_MINOR, \ - VXGE_CERT_FW_VER_BUILD) - #endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 48261b7252d0..a0471f2e1c7a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -410,9 +410,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, val &= ~(AR_WA_BIT6 | AR_WA_BIT7); } - if (AR_SREV_9280(ah)) - val |= AR_WA_BIT22; - if (AR_SREV_9285E_20(ah)) val |= AR_WA_BIT23; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index b3180935875d..21433465bde4 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -671,7 +671,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) } extern struct ieee80211_ops ath9k_ops; -extern struct pm_qos_request_list ath9k_pm_qos_req; extern int modparam_nohwcrypt; extern int led_blink; diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 3ad1de253c8a..ebf7a89f547c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -37,7 +37,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) int addr, eep_start_loc; eep_data = (u16 *)eep; - if (AR9287_HTC_DEVID(ah)) + if (ah->hw_version.devid == 0x7015) eep_start_loc = AR9287_HTC_EEP_START_LOC; else eep_start_loc = AR9287_EEP_START_LOC; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c index dfb6560dab92..6576f683dba0 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -35,14 +35,8 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */ { USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */ { USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */ - { USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */ - { USB_DEVICE(0x13D3, 0x3348) }, /* Azurewave */ - { USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */ - { USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */ { USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */ { USB_DEVICE(0x083A, 0xA704) }, /* SMC Networks */ - { USB_DEVICE(0x040D, 0x3801) }, /* VIA */ - { USB_DEVICE(0x1668, 0x1200) }, /* Verizon */ { }, }; @@ -546,11 +540,11 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) return; } - usb_fill_bulk_urb(urb, hif_dev->udev, + usb_fill_int_urb(urb, hif_dev->udev, usb_rcvbulkpipe(hif_dev->udev, USB_REG_IN_PIPE), nskb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, nskb); + ath9k_hif_usb_reg_in_cb, nskb, 1); ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { @@ -726,11 +720,11 @@ static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) if (!skb) goto err; - usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev, + usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev, usb_rcvbulkpipe(hif_dev->udev, USB_REG_IN_PIPE), skb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, skb); + ath9k_hif_usb_reg_in_cb, skb, 1); if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) goto err; @@ -811,8 +805,6 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) case 0x7010: case 0x7015: case 0x9018: - case 0xA704: - case 0x1200: firm_offset = AR7010_FIRMWARE_TEXT; break; default: @@ -851,6 +843,14 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) goto err_fw_req; } + /* Alloc URBs */ + ret = ath9k_hif_usb_alloc_urbs(hif_dev); + if (ret) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Unable to allocate URBs\n"); + goto err_urb; + } + /* Download firmware */ ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { @@ -866,22 +866,16 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) */ for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) { endp = &alt->endpoint[idx].desc; - if ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_INT) { + if (((endp->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) + == 0x04) && + ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT)) { endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK; endp->bmAttributes |= USB_ENDPOINT_XFER_BULK; endp->bInterval = 0; } } - /* Alloc URBs */ - ret = ath9k_hif_usb_alloc_urbs(hif_dev); - if (ret) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: Unable to allocate URBs\n"); - goto err_urb; - } - return 0; err_fw_download: @@ -935,8 +929,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, case 0x7010: case 0x7015: case 0x9018: - case 0xA704: - case 0x1200: if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) hif_dev->fw_name = FIRMWARE_AR7010_1_1; else diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 7c8a38d04561..3d7b97f1b3ae 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -249,8 +249,6 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid) case 0x7010: case 0x7015: case 0x9018: - case 0xA704: - case 0x1200: priv->htc->credits = 45; break; default: diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 77958675b55f..5324ffd96ec7 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -128,7 +128,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) tx_hdr.data_type = ATH9K_HTC_NORMAL; } - if (ieee80211_is_data_qos(fc)) { + if (ieee80211_is_data(fc)) { qc = ieee80211_get_qos_ctl(hdr); tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 5fb1bf33faa0..e75d8e8cf4d2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -484,7 +484,6 @@ static int ath9k_hw_post_init(struct ath_hw *ah) ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, "Failed allocating banks for " "external radio\n"); - ath9k_hw_rf_free_ext_banks(ah); return ecode; } @@ -953,12 +952,9 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_MONITOR: REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); break; - default: - if (ah->is_monitoring) - REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); - break; } } @@ -1638,6 +1634,7 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) switch (ah->opmode) { case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_MONITOR: REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); @@ -1666,14 +1663,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; break; default: - if (ah->is_monitoring) { - REG_WRITE(ah, AR_NEXT_TBTT_TIMER, - TU_TO_USEC(next_beacon)); - REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); - REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); - flags |= AR_TBTT_TIMER_EN; - break; - } ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON, "%s: unsupported opmode: %d\n", __func__, ah->opmode); diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index e29c7122f466..f821a28bcda3 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -629,7 +629,6 @@ struct ath_hw { bool sw_mgmt_crypto; bool is_pciexpress; - bool is_monitoring; bool need_an_top2_fixup; u16 tx_trig_level; diff --git a/trunk/drivers/net/wireless/ath/ath9k/init.c b/trunk/drivers/net/wireless/ath/ath9k/init.c index 5c26818d79ec..498f62180f1c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/init.c @@ -15,7 +15,6 @@ */ #include -#include #include "ath9k.h" @@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = { .write = ath9k_iowrite32, }; -struct pm_qos_request_list ath9k_pm_qos_req; - /**************************/ /* Initialization */ /**************************/ @@ -753,9 +750,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ath_init_leds(sc); ath_start_rfkill_poll(sc); - pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - return 0; error_world: @@ -824,7 +818,6 @@ void ath9k_deinit_device(struct ath_softc *sc) } ieee80211_unregister_hw(hw); - pm_qos_remove_request(&ath9k_pm_qos_req); ath_rx_cleanup(sc); ath_tx_cleanup(sc); ath9k_deinit_softc(sc); diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index f8c811af312d..df7c62d9bec4 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -15,7 +15,6 @@ */ #include -#include #include "ath9k.h" #include "btcoex.h" @@ -94,13 +93,11 @@ void ath9k_ps_wakeup(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); unsigned long flags; - enum ath9k_power_mode power_mode; spin_lock_irqsave(&sc->sc_pm_lock, flags); if (++sc->ps_usecount != 1) goto unlock; - power_mode = sc->sc_ah->power_mode; ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); /* @@ -108,12 +105,10 @@ void ath9k_ps_wakeup(struct ath_softc *sc) * useful data. Better clear them now so that they don't mess up * survey data results. */ - if (power_mode != ATH9K_PM_AWAKE) { - spin_lock(&common->cc_lock); - ath_hw_cycle_counters_update(common); - memset(&common->cc_survey, 0, sizeof(common->cc_survey)); - spin_unlock(&common->cc_lock); - } + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + memset(&common->cc_survey, 0, sizeof(common->cc_survey)); + spin_unlock(&common->cc_lock); unlock: spin_unlock_irqrestore(&sc->sc_pm_lock, flags); @@ -1160,7 +1155,6 @@ static int ath9k_start(struct ieee80211_hw *hw) ah->imask |= ATH9K_INT_CST; sc->sc_flags &= ~SC_OP_INVALID; - sc->sc_ah->is_monitoring = false; /* Disable BMISS interrupt when we're not associated */ ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); @@ -1182,8 +1176,6 @@ static int ath9k_start(struct ieee80211_hw *hw) ath9k_btcoex_timer_resume(sc); } - pm_qos_update_request(&ath9k_pm_qos_req, 55); - mutex_unlock: mutex_unlock(&sc->mutex); @@ -1362,8 +1354,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) sc->sc_flags |= SC_OP_INVALID; - pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE); - mutex_unlock(&sc->mutex); ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); @@ -1442,7 +1432,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ath9k_hw_set_interrupts(ah, ah->imask); if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) { + vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MONITOR) { sc->sc_flags |= SC_OP_ANI_RUN; ath_start_ani(common); } @@ -1592,12 +1583,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (conf->flags & IEEE80211_CONF_MONITOR) { ath_print(common, ATH_DBG_CONFIG, - "Monitor mode is enabled\n"); - sc->sc_ah->is_monitoring = true; - } else { - ath_print(common, ATH_DBG_CONFIG, - "Monitor mode is disabled\n"); - sc->sc_ah->is_monitoring = false; + "HW opmode set to Monitor mode\n"); + sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; } } diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index c5c80764a94a..60300b225b6d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -441,7 +441,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) */ if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || - (sc->sc_ah->is_monitoring)) + (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) rfilt |= ATH9K_RX_FILTER_PROM; if (sc->rx.rxfilter & FIF_CONTROL) @@ -899,7 +899,7 @@ static bool ath9k_rx_accept(struct ath_common *common, * decryption and MIC failures. For monitor mode, * we also ignore the CRC error. */ - if (ah->is_monitoring) { + if (ah->opmode == NL80211_IFTYPE_MONITOR) { if (rx_stats->rs_status & ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | ATH9K_RXERR_CRC)) diff --git a/trunk/drivers/net/wireless/ath/ath9k/reg.h b/trunk/drivers/net/wireless/ath/ath9k/reg.h index dddf579aacf1..42976b0a01c1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/reg.h +++ b/trunk/drivers/net/wireless/ath/ath9k/reg.h @@ -703,7 +703,6 @@ #define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */ #define AR_WA_ANALOG_SHIFT (1 << 20) #define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ -#define AR_WA_BIT22 (1 << 22) #define AR9285_WA_DEFAULT 0x004a050b #define AR9280_WA_DEFAULT 0x0040073b #define AR_WA_DEFAULT 0x0000073f @@ -866,13 +865,7 @@ #define AR_DEVID_7010(_ah) \ (((_ah)->hw_version.devid == 0x7010) || \ ((_ah)->hw_version.devid == 0x7015) || \ - ((_ah)->hw_version.devid == 0x9018) || \ - ((_ah)->hw_version.devid == 0xA704) || \ - ((_ah)->hw_version.devid == 0x1200)) - -#define AR9287_HTC_DEVID(_ah) \ - (((_ah)->hw_version.devid == 0x7015) || \ - ((_ah)->hw_version.devid == 0x1200)) + ((_ah)->hw_version.devid == 0x9018)) #define AR_RADIO_SREV_MAJOR 0xf0 #define AR_RAD5133_SREV_MAJOR 0xc0 diff --git a/trunk/drivers/net/wireless/ath/carl9170/usb.c b/trunk/drivers/net/wireless/ath/carl9170/usb.c index a268053e18e5..ddf5373ee689 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/usb.c +++ b/trunk/drivers/net/wireless/ath/carl9170/usb.c @@ -82,11 +82,9 @@ static struct usb_device_id carl9170_usb_ids[] = { { USB_DEVICE(0x07d1, 0x3c10) }, /* D-Link DWA 160 A2 */ { USB_DEVICE(0x07d1, 0x3a09) }, - /* D-Link DWA 130 D */ - { USB_DEVICE(0x07d1, 0x3a0f) }, /* Netgear WNA1000 */ { USB_DEVICE(0x0846, 0x9040) }, - /* Netgear WNDA3100 (v1) */ + /* Netgear WNDA3100 */ { USB_DEVICE(0x0846, 0x9010) }, /* Netgear WN111 v2 */ { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED }, @@ -553,12 +551,12 @@ static int carl9170_usb_flush(struct ar9170 *ar) usb_free_urb(urb); } - ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, 1000); + ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ); if (ret == 0) err = -ETIMEDOUT; /* lets wait a while until the tx - queues are dried out */ - ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, 1000); + ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ); if (ret == 0) err = -ETIMEDOUT; diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_module.c b/trunk/drivers/net/wireless/ipw2x00/libipw_module.c index d5ef696298ee..32dee2ce5d31 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_module.c @@ -54,7 +54,6 @@ #define DRV_DESCRIPTION "802.11 data/management/control stack" #define DRV_NAME "libipw" -#define DRV_PROCNAME "ieee80211" #define DRV_VERSION LIBIPW_VERSION #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation " @@ -294,16 +293,16 @@ static int __init libipw_init(void) struct proc_dir_entry *e; libipw_debug_level = debug; - libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net); + libipw_proc = proc_mkdir("ieee80211", init_net.proc_net); if (libipw_proc == NULL) { - LIBIPW_ERROR("Unable to create " DRV_PROCNAME + LIBIPW_ERROR("Unable to create " DRV_NAME " proc directory\n"); return -EIO; } e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc, &debug_level_proc_fops); if (!e) { - remove_proc_entry(DRV_PROCNAME, init_net.proc_net); + remove_proc_entry(DRV_NAME, init_net.proc_net); libipw_proc = NULL; return -EIO; } @@ -320,7 +319,7 @@ static void __exit libipw_exit(void) #ifdef CONFIG_LIBIPW_DEBUG if (libipw_proc) { remove_proc_entry("debug_level", libipw_proc); - remove_proc_entry(DRV_PROCNAME, init_net.proc_net); + remove_proc_entry(DRV_NAME, init_net.proc_net); libipw_proc = NULL; } #endif /* CONFIG_LIBIPW_DEBUG */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index 931c546367ea..a55b4623e1c8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4004,8 +4004,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e * "the hard way", rather than using device's scan. */ if (iwl3945_mod_params.disable_hw_scan) { - dev_printk(KERN_DEBUG, &(pdev->dev), - "sw scan support is deprecated\n"); + IWL_ERR(priv, "sw scan support is deprecated\n"); iwl3945_hw_ops.hw_scan = NULL; } diff --git a/trunk/drivers/net/wireless/libertas/cfg.c b/trunk/drivers/net/wireless/libertas/cfg.c index 373930afc26b..5046a0005034 100644 --- a/trunk/drivers/net/wireless/libertas/cfg.c +++ b/trunk/drivers/net/wireless/libertas/cfg.c @@ -700,9 +700,8 @@ static void lbs_scan_worker(struct work_struct *work) if (priv->scan_channel < priv->scan_req->n_channels) { cancel_delayed_work(&priv->scan_work); - if (!priv->stopping) - queue_delayed_work(priv->work_thread, &priv->scan_work, - msecs_to_jiffies(300)); + queue_delayed_work(priv->work_thread, &priv->scan_work, + msecs_to_jiffies(300)); } /* This is the final data we are about to send */ diff --git a/trunk/drivers/net/wireless/libertas/dev.h b/trunk/drivers/net/wireless/libertas/dev.h index cb14c38caf3a..f062ed583901 100644 --- a/trunk/drivers/net/wireless/libertas/dev.h +++ b/trunk/drivers/net/wireless/libertas/dev.h @@ -36,7 +36,6 @@ struct lbs_private { /* CFG80211 */ struct wireless_dev *wdev; bool wiphy_registered; - bool stopping; struct cfg80211_scan_request *scan_req; u8 assoc_bss[ETH_ALEN]; u8 disassoc_reason; diff --git a/trunk/drivers/net/wireless/libertas/if_usb.c b/trunk/drivers/net/wireless/libertas/if_usb.c index efaf85032208..35931cf4d6db 100644 --- a/trunk/drivers/net/wireless/libertas/if_usb.c +++ b/trunk/drivers/net/wireless/libertas/if_usb.c @@ -1090,12 +1090,6 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) if (priv->psstate != PS_STATE_FULL_POWER) return -1; - if (priv->wol_criteria == EHS_REMOVE_WAKEUP) { - lbs_pr_info("Suspend attempt without " - "configuring wake params!\n"); - return -ENOSYS; - } - ret = lbs_suspend(priv); if (ret) goto out; diff --git a/trunk/drivers/net/wireless/libertas/main.c b/trunk/drivers/net/wireless/libertas/main.c index 46b88b118c99..47ce5a6ba120 100644 --- a/trunk/drivers/net/wireless/libertas/main.c +++ b/trunk/drivers/net/wireless/libertas/main.c @@ -104,7 +104,6 @@ static int lbs_dev_open(struct net_device *dev) lbs_deb_enter(LBS_DEB_NET); spin_lock_irq(&priv->driver_lock); - priv->stopping = false; if (priv->connect_status == LBS_CONNECTED) netif_carrier_on(dev); @@ -132,16 +131,10 @@ static int lbs_eth_stop(struct net_device *dev) lbs_deb_enter(LBS_DEB_NET); spin_lock_irq(&priv->driver_lock); - priv->stopping = true; netif_stop_queue(dev); spin_unlock_irq(&priv->driver_lock); schedule_work(&priv->mcast_work); - cancel_delayed_work_sync(&priv->scan_work); - if (priv->scan_req) { - cfg80211_scan_done(priv->scan_req, false); - priv->scan_req = NULL; - } lbs_deb_leave(LBS_DEB_NET); return 0; diff --git a/trunk/drivers/net/wireless/rt2x00/Kconfig b/trunk/drivers/net/wireless/rt2x00/Kconfig index 4396d4b9bfb9..eea1ef2f502b 100644 --- a/trunk/drivers/net/wireless/rt2x00/Kconfig +++ b/trunk/drivers/net/wireless/rt2x00/Kconfig @@ -221,6 +221,9 @@ config RT2X00_LIB_LEDS boolean default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) +comment "rt2x00 leds support disabled due to modularized LEDS_CLASS and built-in rt2x00" + depends on RT2X00_LIB=y && LEDS_CLASS=m + config RT2X00_LIB_DEBUGFS bool "Ralink debugfs support" depends on RT2X00_LIB && MAC80211_DEBUGFS diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_chip.c b/trunk/drivers/net/wireless/zd1211rw/zd_chip.c index dd0bb0cc22d9..87a95bcfee57 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_chip.c @@ -117,7 +117,6 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr /* Allocate a single memory block for values and addresses. */ count16 = 2*count; - /* zd_addr_t is __nocast, so the kmalloc needs an explicit cast */ a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)), GFP_KERNEL); if (!a16) { diff --git a/trunk/drivers/net/xilinx_emaclite.c b/trunk/drivers/net/xilinx_emaclite.c index 2de52d18152f..14f0955eca68 100644 --- a/trunk/drivers/net/xilinx_emaclite.c +++ b/trunk/drivers/net/xilinx_emaclite.c @@ -515,7 +515,7 @@ static void xemaclite_update_address(struct net_local *drvdata, */ static int xemaclite_set_mac_address(struct net_device *dev, void *address) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *) netdev_priv(dev); struct sockaddr *addr = address; if (netif_running(dev)) @@ -534,7 +534,7 @@ static int xemaclite_set_mac_address(struct net_device *dev, void *address) */ static void xemaclite_tx_timeout(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *) netdev_priv(dev); unsigned long flags; dev_err(&lp->ndev->dev, "Exceeded transmit timeout of %lu ms\n", @@ -578,7 +578,7 @@ static void xemaclite_tx_timeout(struct net_device *dev) */ static void xemaclite_tx_handler(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *) netdev_priv(dev); dev->stats.tx_packets++; if (lp->deferred_skb) { @@ -605,7 +605,7 @@ static void xemaclite_tx_handler(struct net_device *dev) */ static void xemaclite_rx_handler(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *) netdev_priv(dev); struct sk_buff *skb; unsigned int align; u32 len; @@ -661,7 +661,7 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) { bool tx_complete = 0; struct net_device *dev = dev_id; - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *) netdev_priv(dev); void __iomem *base_addr = lp->base_addr; u32 tx_status; @@ -918,7 +918,7 @@ void xemaclite_adjust_link(struct net_device *ndev) */ static int xemaclite_open(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *) netdev_priv(dev); int retval; /* Just to be safe, stop the device first */ @@ -987,7 +987,7 @@ static int xemaclite_open(struct net_device *dev) */ static int xemaclite_close(struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *) netdev_priv(dev); netif_stop_queue(dev); xemaclite_disable_interrupts(lp); @@ -1031,7 +1031,7 @@ static struct net_device_stats *xemaclite_get_stats(struct net_device *dev) */ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); + struct net_local *lp = (struct net_local *) netdev_priv(dev); struct sk_buff *new_skb; unsigned int len; unsigned long flags; @@ -1068,7 +1068,7 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) static void xemaclite_remove_ndev(struct net_device *ndev) { if (ndev) { - struct net_local *lp = netdev_priv(ndev); + struct net_local *lp = (struct net_local *) netdev_priv(ndev); if (lp->base_addr) iounmap((void __iomem __force *) (lp->base_addr)); @@ -1245,7 +1245,7 @@ static int __devexit xemaclite_of_remove(struct platform_device *of_dev) struct device *dev = &of_dev->dev; struct net_device *ndev = dev_get_drvdata(dev); - struct net_local *lp = netdev_priv(ndev); + struct net_local *lp = (struct net_local *) netdev_priv(ndev); /* Un-register the mii_bus, if configured */ if (lp->has_mdio) { diff --git a/trunk/drivers/net/znet.c b/trunk/drivers/net/znet.c index ae07b3dfbcc1..c3a329204511 100644 --- a/trunk/drivers/net/znet.c +++ b/trunk/drivers/net/znet.c @@ -124,7 +124,7 @@ MODULE_LICENSE("GPL"); #define TX_BUF_SIZE 8192 #define DMA_BUF_SIZE (RX_BUF_SIZE + 16) /* 8k + 16 bytes for trailers */ -#define TX_TIMEOUT (HZ/10) +#define TX_TIMEOUT 10 struct znet_private { int rx_dma, tx_dma; diff --git a/trunk/drivers/pci/xen-pcifront.c b/trunk/drivers/pci/xen-pcifront.c index 3a5a6fcc0ead..a87c4985326e 100644 --- a/trunk/drivers/pci/xen-pcifront.c +++ b/trunk/drivers/pci/xen-pcifront.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -575,9 +576,8 @@ static pci_ers_result_t pcifront_common_process(int cmd, pcidev = pci_get_bus_and_slot(bus, devfn); if (!pcidev || !pcidev->driver) { - dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n"); - if (pcidev) - pci_dev_put(pcidev); + dev_err(&pcidev->dev, + "device or driver is NULL\n"); return result; } pdrv = pcidev->driver; diff --git a/trunk/drivers/rapidio/rio.c b/trunk/drivers/rapidio/rio.c index 7b5080c45569..68cf0c99138a 100644 --- a/trunk/drivers/rapidio/rio.c +++ b/trunk/drivers/rapidio/rio.c @@ -1159,11 +1159,11 @@ int __devinit rio_init_mports(void) list_for_each_entry(port, &rio_mports, node) { if (!request_mem_region(port->iores.start, - resource_size(&port->iores), + port->iores.end - port->iores.start, port->name)) { printk(KERN_ERR "RIO: Error requesting master port region 0x%016llx-0x%016llx\n", - (u64)port->iores.start, (u64)port->iores.end); + (u64)port->iores.start, (u64)port->iores.end - 1); rc = -ENOMEM; goto out; } diff --git a/trunk/drivers/rtc/rtc-ds1302.c b/trunk/drivers/rtc/rtc-ds1302.c index f0d638922644..359d1e04626c 100644 --- a/trunk/drivers/rtc/rtc-ds1302.c +++ b/trunk/drivers/rtc/rtc-ds1302.c @@ -35,7 +35,7 @@ #ifdef CONFIG_SH_SECUREEDGE5410 #include -#include +#include #define RTC_RESET 0x1000 #define RTC_IODATA 0x0800 diff --git a/trunk/drivers/s390/net/lcs.c b/trunk/drivers/s390/net/lcs.c index c9f13b9ea339..0f19d540b655 100644 --- a/trunk/drivers/s390/net/lcs.c +++ b/trunk/drivers/s390/net/lcs.c @@ -1188,8 +1188,7 @@ lcs_remove_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) spin_lock_irqsave(&card->ipm_lock, flags); list_for_each(l, &card->ipm_list) { ipm = list_entry(l, struct lcs_ipm_list, list); - for (im4 = rcu_dereference(in4_dev->mc_list); - im4 != NULL; im4 = rcu_dereference(im4->next_rcu)) { + for (im4 = in4_dev->mc_list; im4 != NULL; im4 = im4->next) { lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); if ( (ipm->ipm.ip_addr == im4->multiaddr) && (memcmp(buf, &ipm->ipm.mac_addr, @@ -1234,8 +1233,7 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev) unsigned long flags; LCS_DBF_TEXT(4, trace, "setmclst"); - for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL; - im4 = rcu_dereference(im4->next_rcu)) { + for (im4 = in4_dev->mc_list; im4; im4 = im4->next) { lcs_get_mac_for_ipm(im4->multiaddr, buf, card->dev); ipm = lcs_check_addr_entry(card, im4, buf); if (ipm != NULL) @@ -1271,10 +1269,10 @@ lcs_register_mc_addresses(void *data) in4_dev = in_dev_get(card->dev); if (in4_dev == NULL) goto out; - rcu_read_lock(); + read_lock(&in4_dev->mc_list_lock); lcs_remove_mc_addresses(card,in4_dev); lcs_set_mc_addresses(card, in4_dev); - rcu_read_unlock(); + read_unlock(&in4_dev->mc_list_lock); in_dev_put(in4_dev); netif_carrier_off(card->dev); diff --git a/trunk/drivers/s390/net/qeth_core.h b/trunk/drivers/s390/net/qeth_core.h index f47a714538db..6be43eb126b4 100644 --- a/trunk/drivers/s390/net/qeth_core.h +++ b/trunk/drivers/s390/net/qeth_core.h @@ -440,6 +440,7 @@ struct qeth_qdio_out_q { * index of buffer to be filled by driver; state EMPTY or PACKING */ int next_buf_to_fill; + int sync_iqdio_error; /* * number of buffers that are currently filled (PRIMED) * -> these buffers are hardware-owned @@ -694,6 +695,14 @@ struct qeth_mc_mac { int is_vmac; }; +struct qeth_skb_data { + __u32 magic; + int count; +}; + +#define QETH_SKB_MAGIC 0x71657468 +#define QETH_SIGA_CC2_RETRIES 3 + struct qeth_rx { int b_count; int b_index; diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index e6b2df0e73f5..764267062601 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -877,8 +877,8 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, return; } -static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, - struct qeth_qdio_out_buffer *buf) +static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, + struct qeth_qdio_out_buffer *buf, unsigned int qeth_skip_skb) { int i; struct sk_buff *skb; @@ -887,11 +887,13 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, if (buf->buffer->element[0].flags & 0x40) atomic_dec(&queue->set_pci_flags_count); - skb = skb_dequeue(&buf->skb_list); - while (skb) { - atomic_dec(&skb->users); - dev_kfree_skb_any(skb); + if (!qeth_skip_skb) { skb = skb_dequeue(&buf->skb_list); + while (skb) { + atomic_dec(&skb->users); + dev_kfree_skb_any(skb); + skb = skb_dequeue(&buf->skb_list); + } } for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) { if (buf->buffer->element[i].addr && buf->is_header[i]) @@ -907,6 +909,12 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY); } +static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, + struct qeth_qdio_out_buffer *buf) +{ + __qeth_clear_output_buffer(queue, buf, 0); +} + void qeth_clear_qdio_buffers(struct qeth_card *card) { int i, j; @@ -2825,6 +2833,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, } } + queue->sync_iqdio_error = 0; queue->card->dev->trans_start = jiffies; if (queue->card->options.performance_stats) { queue->card->perf_stats.outbound_do_qdio_cnt++; @@ -2840,6 +2849,10 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, queue->card->perf_stats.outbound_do_qdio_time += qeth_get_micros() - queue->card->perf_stats.outbound_do_qdio_start_time; + if (rc > 0) { + if (!(rc & QDIO_ERROR_SIGA_BUSY)) + queue->sync_iqdio_error = rc & 3; + } if (rc) { queue->card->stats.tx_errors += count; /* ignore temporary SIGA errors without busy condition */ @@ -2903,7 +2916,7 @@ void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue, { struct qeth_card *card = (struct qeth_card *)card_ptr; - if (card->dev && (card->dev->flags & IFF_UP)) + if (card->dev) napi_schedule(&card->napi); } EXPORT_SYMBOL_GPL(qeth_qdio_start_poll); @@ -2927,6 +2940,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue]; struct qeth_qdio_out_buffer *buffer; int i; + unsigned qeth_send_err; QETH_CARD_TEXT(card, 6, "qdouhdl"); if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { @@ -2942,8 +2956,9 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, } for (i = first_element; i < (first_element + count); ++i) { buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; - qeth_handle_send_error(card, buffer, qdio_error); - qeth_clear_output_buffer(queue, buffer); + qeth_send_err = qeth_handle_send_error(card, buffer, qdio_error); + __qeth_clear_output_buffer(queue, buffer, + (qeth_send_err == QETH_SEND_ERROR_RETRY) ? 1 : 0); } atomic_sub(count, &queue->used_buffers); /* check if we need to do something on this outbound queue */ @@ -3168,7 +3183,10 @@ int qeth_do_send_packet_fast(struct qeth_card *card, int offset, int hd_len) { struct qeth_qdio_out_buffer *buffer; + struct sk_buff *skb1; + struct qeth_skb_data *retry_ctrl; int index; + int rc; /* spin until we get the queue ... */ while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, @@ -3187,6 +3205,25 @@ int qeth_do_send_packet_fast(struct qeth_card *card, atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len); qeth_flush_buffers(queue, index, 1); + if (queue->sync_iqdio_error == 2) { + skb1 = skb_dequeue(&buffer->skb_list); + while (skb1) { + atomic_dec(&skb1->users); + skb1 = skb_dequeue(&buffer->skb_list); + } + retry_ctrl = (struct qeth_skb_data *) &skb->cb[16]; + if (retry_ctrl->magic != QETH_SKB_MAGIC) { + retry_ctrl->magic = QETH_SKB_MAGIC; + retry_ctrl->count = 0; + } + if (retry_ctrl->count < QETH_SIGA_CC2_RETRIES) { + retry_ctrl->count++; + rc = dev_queue_xmit(skb); + } else { + dev_kfree_skb_any(skb); + QETH_CARD_TEXT(card, 2, "qrdrop"); + } + } return 0; out: atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); diff --git a/trunk/drivers/s390/net/qeth_core_sys.c b/trunk/drivers/s390/net/qeth_core_sys.c index b5e967cf7e2d..42fa783a70c8 100644 --- a/trunk/drivers/s390/net/qeth_core_sys.c +++ b/trunk/drivers/s390/net/qeth_core_sys.c @@ -372,7 +372,7 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev, i = simple_strtoul(buf, &tmp, 16); if ((i == 0) || (i == 1)) { if (i == card->options.performance_stats) - goto out; + goto out;; card->options.performance_stats = i; if (i == 0) memset(&card->perf_stats, 0, diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index 7a7a1b664781..847e8797073c 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -849,6 +849,8 @@ static int qeth_l2_open(struct net_device *dev) card->state = CARD_STATE_UP; netif_start_queue(dev); + if (!card->lan_online && netif_carrier_ok(dev)) + netif_carrier_off(dev); if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { napi_enable(&card->napi); napi_schedule(&card->napi); @@ -1011,14 +1013,13 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) dev_warn(&card->gdev->dev, "The LAN is offline\n"); card->lan_online = 0; - goto contin; + goto out; } rc = -ENODEV; goto out_remove; } else card->lan_online = 1; -contin: if ((card->info.type == QETH_CARD_TYPE_OSD) || (card->info.type == QETH_CARD_TYPE_OSX)) /* configure isolation level */ @@ -1037,10 +1038,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) goto out_remove; } card->state = CARD_STATE_SOFTSETUP; - if (card->lan_online) - netif_carrier_on(card->dev); - else - netif_carrier_off(card->dev); + netif_carrier_on(card->dev); qeth_set_allowed_threads(card, 0xffffffff, 0); if (recover_flag == CARD_STATE_RECOVER) { @@ -1057,6 +1055,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) } /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); +out: mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); return 0; diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index a1abb37db000..74d1401a5d5e 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -1796,8 +1796,7 @@ static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev) char buf[MAX_ADDR_LEN]; QETH_CARD_TEXT(card, 4, "addmc"); - for (im4 = rcu_dereference(in4_dev->mc_list); im4 != NULL; - im4 = rcu_dereference(im4->next_rcu)) { + for (im4 = in4_dev->mc_list; im4; im4 = im4->next) { qeth_l3_get_mac_for_ipm(im4->multiaddr, buf, in4_dev->dev); ipm = qeth_l3_get_addr_buffer(QETH_PROT_IPV4); if (!ipm) @@ -1829,9 +1828,9 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card) in_dev = in_dev_get(netdev); if (!in_dev) continue; - rcu_read_lock(); + read_lock(&in_dev->mc_list_lock); qeth_l3_add_mc(card, in_dev); - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); in_dev_put(in_dev); } } @@ -1844,10 +1843,10 @@ static void qeth_l3_add_multicast_ipv4(struct qeth_card *card) in4_dev = in_dev_get(card->dev); if (in4_dev == NULL) return; - rcu_read_lock(); + read_lock(&in4_dev->mc_list_lock); qeth_l3_add_mc(card, in4_dev); qeth_l3_add_vlan_mc(card); - rcu_read_unlock(); + read_unlock(&in4_dev->mc_list_lock); in_dev_put(in4_dev); } @@ -2939,7 +2938,6 @@ static void qeth_tso_fill_header(struct qeth_card *card, /*fix header to TSO values ...*/ hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO; - hdr->hdr.hdr.l3.length = skb->len - sizeof(struct qeth_hdr_tso); /*set values which are fix for the first approach ...*/ hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso); hdr->ext.imb_hdr_no = 1; @@ -3178,6 +3176,8 @@ static int qeth_l3_open(struct net_device *dev) card->state = CARD_STATE_UP; netif_start_queue(dev); + if (!card->lan_online && netif_carrier_ok(dev)) + netif_carrier_off(dev); if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { napi_enable(&card->napi); napi_schedule(&card->napi); @@ -3449,14 +3449,13 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) dev_warn(&card->gdev->dev, "The LAN is offline\n"); card->lan_online = 0; - goto contin; + goto out; } rc = -ENODEV; goto out_remove; } else card->lan_online = 1; -contin: rc = qeth_l3_setadapter_parms(card); if (rc) QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); @@ -3481,13 +3480,10 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) goto out_remove; } card->state = CARD_STATE_SOFTSETUP; + netif_carrier_on(card->dev); qeth_set_allowed_threads(card, 0xffffffff, 0); qeth_l3_set_ip_addr_list(card); - if (card->lan_online) - netif_carrier_on(card->dev); - else - netif_carrier_off(card->dev); if (recover_flag == CARD_STATE_RECOVER) { if (recovery_mode) qeth_l3_open(card->dev); @@ -3500,6 +3496,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) } /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); +out: mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); return 0; diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index f3cf924a2cd9..1de30eb83bb0 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -320,11 +320,19 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) "changed. The Linux SCSI layer does not " "automatically adjust these parameters.\n"); - /* - * Pass the UA upwards for a determination in the completion - * functions. - */ - return SUCCESS; + if (scmd->request->cmd_flags & REQ_HARDBARRIER) + /* + * barrier requests should always retry on UA + * otherwise block will get a spurious error + */ + return NEEDS_RETRY; + else + /* + * for normal (non barrier) commands, pass the + * UA upwards for a determination in the + * completion functions + */ + return SUCCESS; /* these three are not supported */ case COPY_ABORTED: diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index dd5e1ac22251..4d8e14b7aa93 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -2343,11 +2343,8 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, /* * CTS flow control flag and modem status interrupts - * Only disable MSI if no threads are waiting in - * serial_core::uart_wait_modem_status */ - if (!waitqueue_active(&up->port.state->port.delta_msr_wait)) - up->ier &= ~UART_IER_MSI; + up->ier &= ~UART_IER_MSI; if (!(up->bugs & UART_BUG_NOMSR) && UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index 842e3b2a02b1..53be4d35a0aa 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -2285,8 +2285,6 @@ static struct pciserial_board pci_boards[] __devinitdata = { static const struct pci_device_id softmodem_blacklist[] = { { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ - { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ - { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ }; /* @@ -2865,9 +2863,6 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL, 0, 0, pbn_b0_4_1152000 }, - { PCI_VENDOR_ID_OXSEMI, 0x9505, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_bt_2_921600 }, /* * The below card is a little controversial since it is the diff --git a/trunk/drivers/serial/bfin_5xx.c b/trunk/drivers/serial/bfin_5xx.c index 19cac9f610fd..a9eff2b18eab 100644 --- a/trunk/drivers/serial/bfin_5xx.c +++ b/trunk/drivers/serial/bfin_5xx.c @@ -23,7 +23,6 @@ #include #include #include -#include #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \ defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE) @@ -34,10 +33,12 @@ #include #include -#include +#ifdef CONFIG_SERIAL_BFIN_DMA +#include #include #include #include +#endif #ifdef CONFIG_SERIAL_BFIN_MODULE # undef CONFIG_EARLY_PRINTK @@ -359,6 +360,7 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) UART_PUT_CHAR(uart, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); uart->port.icount.tx++; + SSYNC(); } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) @@ -686,13 +688,6 @@ static int bfin_serial_startup(struct uart_port *port) # ifdef CONFIG_BF54x { - /* - * UART2 and UART3 on BF548 share interrupt PINs and DMA - * controllers with SPORT2 and SPORT3. UART rx and tx - * interrupts are generated in PIO mode only when configure - * their peripheral mapping registers properly, which means - * request corresponding DMA channels in PIO mode as well. - */ unsigned uart_dma_ch_rx, uart_dma_ch_tx; switch (uart->port.irq) { @@ -739,7 +734,8 @@ static int bfin_serial_startup(struct uart_port *port) IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED, "BFIN_UART_CTS", uart)) { uart->cts_pin = -1; - pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); + pr_info("Unable to attach BlackFin UART CTS interrupt.\ + So, disable it.\n"); } } if (uart->rts_pin >= 0) { @@ -751,7 +747,8 @@ static int bfin_serial_startup(struct uart_port *port) if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int, IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { - pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); + pr_info("Unable to attach BlackFin UART Modem \ + Status interrupt.\n"); } /* CTS RTS PINs are negative assertive. */ @@ -849,8 +846,6 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, if (termios->c_cflag & CMSPAR) lcr |= STP; - spin_lock_irqsave(&uart->port.lock, flags); - port->read_status_mask = OE; if (termios->c_iflag & INPCK) port->read_status_mask |= (FE | PE); @@ -880,6 +875,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, if (termios->c_line != N_IRDA) quot -= ANOMALY_05000230; + spin_lock_irqsave(&uart->port.lock, flags); + UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); /* Disable UART */ @@ -1324,14 +1321,6 @@ struct console __init *bfin_earlyserial_init(unsigned int port, struct bfin_serial_port *uart; struct ktermios t; -#ifdef CONFIG_SERIAL_BFIN_CONSOLE - /* - * If we are using early serial, don't let the normal console rewind - * log buffer, since that causes things to be printed multiple times - */ - bfin_serial_console.flags &= ~CON_PRINTBUFFER; -#endif - if (port == -1 || port >= nr_active_ports) port = 0; bfin_serial_init_ports(); diff --git a/trunk/drivers/serial/kgdboc.c b/trunk/drivers/serial/kgdboc.c index 3374618300af..d4b711c9a416 100644 --- a/trunk/drivers/serial/kgdboc.c +++ b/trunk/drivers/serial/kgdboc.c @@ -18,7 +18,6 @@ #include #include #include -#include #define MAX_CONFIG_LEN 40 @@ -38,61 +37,6 @@ static struct tty_driver *kgdb_tty_driver; static int kgdb_tty_line; #ifdef CONFIG_KDB_KEYBOARD -static int kgdboc_reset_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - input_reset_device(dev); - - /* Retrun an error - we do not want to bind, just to reset */ - return -ENODEV; -} - -static void kgdboc_reset_disconnect(struct input_handle *handle) -{ - /* We do not expect anyone to actually bind to us */ - BUG(); -} - -static const struct input_device_id kgdboc_reset_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT_MASK(EV_KEY) }, - }, - { } -}; - -static struct input_handler kgdboc_reset_handler = { - .connect = kgdboc_reset_connect, - .disconnect = kgdboc_reset_disconnect, - .name = "kgdboc_reset", - .id_table = kgdboc_reset_ids, -}; - -static DEFINE_MUTEX(kgdboc_reset_mutex); - -static void kgdboc_restore_input_helper(struct work_struct *dummy) -{ - /* - * We need to take a mutex to prevent several instances of - * this work running on different CPUs so they don't try - * to register again already registered handler. - */ - mutex_lock(&kgdboc_reset_mutex); - - if (input_register_handler(&kgdboc_reset_handler) == 0) - input_unregister_handler(&kgdboc_reset_handler); - - mutex_unlock(&kgdboc_reset_mutex); -} - -static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); - -static void kgdboc_restore_input(void) -{ - schedule_work(&kgdboc_restore_input_work); -} - static int kgdboc_register_kbd(char **cptr) { if (strncmp(*cptr, "kbd", 3) == 0) { @@ -120,12 +64,10 @@ static void kgdboc_unregister_kbd(void) i--; } } - flush_work_sync(&kgdboc_restore_input_work); } #else /* ! CONFIG_KDB_KEYBOARD */ #define kgdboc_register_kbd(x) 0 #define kgdboc_unregister_kbd() -#define kgdboc_restore_input() #endif /* ! CONFIG_KDB_KEYBOARD */ static int kgdboc_option_setup(char *opt) @@ -289,7 +231,6 @@ static void kgdboc_post_exp_handler(void) dbg_restore_graphics = 0; con_debug_leave(); } - kgdboc_restore_input(); } static struct kgdb_io kgdboc_io_ops = { diff --git a/trunk/drivers/sh/clk/core.c b/trunk/drivers/sh/clk/core.c index 09615b51d591..fd0d1b98901c 100644 --- a/trunk/drivers/sh/clk/core.c +++ b/trunk/drivers/sh/clk/core.c @@ -90,8 +90,8 @@ struct clk_rate_round_data { static long clk_rate_round_helper(struct clk_rate_round_data *rounder) { unsigned long rate_error, rate_error_prev = ~0UL; + unsigned long rate_best_fit = rounder->rate; unsigned long highest, lowest, freq; - long rate_best_fit = -ENOENT; int i; highest = 0; @@ -146,7 +146,7 @@ long clk_rate_table_round(struct clk *clk, }; if (clk->nr_freqs < 1) - return -ENOSYS; + return 0; return clk_rate_round_helper(&table_round); } @@ -541,98 +541,6 @@ long clk_round_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL_GPL(clk_round_rate); -long clk_round_parent(struct clk *clk, unsigned long target, - unsigned long *best_freq, unsigned long *parent_freq, - unsigned int div_min, unsigned int div_max) -{ - struct cpufreq_frequency_table *freq, *best = NULL; - unsigned long error = ULONG_MAX, freq_high, freq_low, div; - struct clk *parent = clk_get_parent(clk); - - if (!parent) { - *parent_freq = 0; - *best_freq = clk_round_rate(clk, target); - return abs(target - *best_freq); - } - - for (freq = parent->freq_table; freq->frequency != CPUFREQ_TABLE_END; - freq++) { - if (freq->frequency == CPUFREQ_ENTRY_INVALID) - continue; - - if (unlikely(freq->frequency / target <= div_min - 1)) { - unsigned long freq_max; - - freq_max = (freq->frequency + div_min / 2) / div_min; - if (error > target - freq_max) { - error = target - freq_max; - best = freq; - if (best_freq) - *best_freq = freq_max; - } - - pr_debug("too low freq %lu, error %lu\n", freq->frequency, - target - freq_max); - - if (!error) - break; - - continue; - } - - if (unlikely(freq->frequency / target >= div_max)) { - unsigned long freq_min; - - freq_min = (freq->frequency + div_max / 2) / div_max; - if (error > freq_min - target) { - error = freq_min - target; - best = freq; - if (best_freq) - *best_freq = freq_min; - } - - pr_debug("too high freq %lu, error %lu\n", freq->frequency, - freq_min - target); - - if (!error) - break; - - continue; - } - - div = freq->frequency / target; - freq_high = freq->frequency / div; - freq_low = freq->frequency / (div + 1); - - if (freq_high - target < error) { - error = freq_high - target; - best = freq; - if (best_freq) - *best_freq = freq_high; - } - - if (target - freq_low < error) { - error = target - freq_low; - best = freq; - if (best_freq) - *best_freq = freq_low; - } - - pr_debug("%u / %lu = %lu, / %lu = %lu, best %lu, parent %u\n", - freq->frequency, div, freq_high, div + 1, freq_low, - *best_freq, best->frequency); - - if (!error) - break; - } - - if (parent_freq) - *parent_freq = best->frequency; - - return error; -} -EXPORT_SYMBOL_GPL(clk_round_parent); - #ifdef CONFIG_PM static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) { diff --git a/trunk/drivers/sh/intc/core.c b/trunk/drivers/sh/intc/core.c index e5e9e6735f7d..873a99ff8f64 100644 --- a/trunk/drivers/sh/intc/core.c +++ b/trunk/drivers/sh/intc/core.c @@ -79,7 +79,7 @@ static void __init intc_register_irq(struct intc_desc *desc, * Register the IRQ position with the global IRQ map, then insert * it in to the radix tree. */ - irq_reserve_irq(irq); + irq_reserve_irqs(irq, 1); raw_spin_lock_irqsave(&intc_big_lock, flags); radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); diff --git a/trunk/drivers/sh/intc/dynamic.c b/trunk/drivers/sh/intc/dynamic.c index a3677c9dfe36..4187cce20ffd 100644 --- a/trunk/drivers/sh/intc/dynamic.c +++ b/trunk/drivers/sh/intc/dynamic.c @@ -60,5 +60,5 @@ void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) int i; for (i = 0; i < nr_vecs; i++) - irq_reserve_irq(evt2irq(vectors[i].vect)); + irq_reserve_irqs(evt2irq(vectors[i].vect), 1); } diff --git a/trunk/drivers/staging/ath6kl/Kconfig b/trunk/drivers/staging/ath6kl/Kconfig index 8a5caa30b85f..ae2cdf48b74c 100644 --- a/trunk/drivers/staging/ath6kl/Kconfig +++ b/trunk/drivers/staging/ath6kl/Kconfig @@ -102,7 +102,7 @@ config AR600x_BT_RESET_PIN config ATH6KL_CFG80211 bool "CFG80211 support" - depends on ATH6K_LEGACY && CFG80211 + depends on ATH6K_LEGACY help Enables support for CFG80211 APIs. The default option is to use WEXT. Even with this option enabled, WEXT is not explicitly disabled and the onus of not exercising WEXT lies on the application(s) running in the user space. diff --git a/trunk/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/trunk/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c index ee8b47746a15..22c6c6659f5b 100644 --- a/trunk/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ b/trunk/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c @@ -285,9 +285,9 @@ A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_I do { /* check if host supports scatter requests and it meets our requirements */ - if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) { + if (device->func->card->host->max_hw_segs < MAX_SCATTER_ENTRIES_PER_REQ) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n", - device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ)); + device->func->card->host->max_hw_segs, MAX_SCATTER_ENTRIES_PER_REQ)); status = A_ENOTSUP; break; } diff --git a/trunk/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/trunk/drivers/staging/ath6kl/os/linux/ar6000_drv.c index a659f7047373..c5a6d6c16735 100644 --- a/trunk/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/trunk/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -1126,7 +1126,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) { A_UINT32 param; - status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(fw_entry->data + board_data_size), board_ext_data_size); + status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(((A_UINT32)fw_entry->data) + board_data_size), board_ext_data_size); if (status != A_OK) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); @@ -3030,8 +3030,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) A_UINT8 csumDest=0; A_UINT8 csum=skb->ip_summed; if(csumOffload && (csum==CHECKSUM_PARTIAL)){ - csumStart = (skb->head + skb->csum_start - skb_network_header(skb) + - sizeof(ATH_LLC_SNAP_HDR)); + csumStart=skb->csum_start-(skb->network_header-skb->head)+sizeof(ATH_LLC_SNAP_HDR); csumDest=skb->csum_offset+csumStart; } #endif diff --git a/trunk/drivers/staging/ath6kl/os/linux/cfg80211.c b/trunk/drivers/staging/ath6kl/os/linux/cfg80211.c index 7269d0a1d618..c94ad29eeb4d 100644 --- a/trunk/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/trunk/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -808,7 +808,7 @@ ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status) static int ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr, + A_UINT8 key_index, const A_UINT8 *mac_addr, struct key_params *params) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); @@ -901,7 +901,7 @@ ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr) + A_UINT8 key_index, const A_UINT8 *mac_addr) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); @@ -936,8 +936,7 @@ ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, static int ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, - A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr, - void *cookie, + A_UINT8 key_index, const A_UINT8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params*)) { AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev); diff --git a/trunk/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h b/trunk/drivers/staging/ath6kl/os/linux/include/athendpack_linux.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/trunk/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h b/trunk/drivers/staging/ath6kl/os/linux/include/athstartpack_linux.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/trunk/drivers/staging/batman-adv/hard-interface.c b/trunk/drivers/staging/batman-adv/hard-interface.c index b68a7e5173be..80cfa8669585 100644 --- a/trunk/drivers/staging/batman-adv/hard-interface.c +++ b/trunk/drivers/staging/batman-adv/hard-interface.c @@ -165,7 +165,7 @@ static void update_mac_addresses(struct batman_if *batman_if) batman_if->net_dev->dev_addr, ETH_ALEN); } -static void check_known_mac_addr(struct net_device *net_dev) +static void check_known_mac_addr(uint8_t *addr) { struct batman_if *batman_if; @@ -175,16 +175,11 @@ static void check_known_mac_addr(struct net_device *net_dev) (batman_if->if_status != IF_TO_BE_ACTIVATED)) continue; - if (batman_if->net_dev == net_dev) - continue; - - if (!compare_orig(batman_if->net_dev->dev_addr, - net_dev->dev_addr)) + if (!compare_orig(batman_if->net_dev->dev_addr, addr)) continue; pr_warning("The newly added mac address (%pM) already exists " - "on: %s\n", net_dev->dev_addr, - batman_if->net_dev->name); + "on: %s\n", addr, batman_if->net_dev->name); pr_warning("It is strongly recommended to keep mac addresses " "unique to avoid problems!\n"); } @@ -435,7 +430,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) atomic_set(&batman_if->refcnt, 0); hardif_hold(batman_if); - check_known_mac_addr(batman_if->net_dev); + check_known_mac_addr(batman_if->net_dev->dev_addr); spin_lock(&if_list_lock); list_add_tail_rcu(&batman_if->list, &if_list); @@ -520,7 +515,7 @@ static int hard_if_event(struct notifier_block *this, goto out; } - check_known_mac_addr(batman_if->net_dev); + check_known_mac_addr(batman_if->net_dev->dev_addr); update_mac_addresses(batman_if); bat_priv = netdev_priv(batman_if->soft_iface); diff --git a/trunk/drivers/staging/batman-adv/routing.c b/trunk/drivers/staging/batman-adv/routing.c index 657b69e6b957..90102631330b 100644 --- a/trunk/drivers/staging/batman-adv/routing.c +++ b/trunk/drivers/staging/batman-adv/routing.c @@ -1000,10 +1000,10 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) /* find a suitable router for this originator, and use * bonding if possible. */ -struct neigh_node *find_router(struct bat_priv *bat_priv, - struct orig_node *orig_node, +struct neigh_node *find_router(struct orig_node *orig_node, struct batman_if *recv_if) { + struct bat_priv *bat_priv; struct orig_node *primary_orig_node; struct orig_node *router_orig; struct neigh_node *router, *first_candidate, *best_router; @@ -1019,9 +1019,13 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, /* without bonding, the first node should * always choose the default router. */ + if (!recv_if) + return orig_node->router; + + bat_priv = netdev_priv(recv_if->soft_iface); bonding_enabled = atomic_read(&bat_priv->bonding_enabled); - if ((!recv_if) && (!bonding_enabled)) + if (!bonding_enabled) return orig_node->router; router_orig = orig_node->router->orig_node; @@ -1150,7 +1154,7 @@ static int route_unicast_packet(struct sk_buff *skb, orig_node = ((struct orig_node *) hash_find(bat_priv->orig_hash, unicast_packet->dest)); - router = find_router(bat_priv, orig_node, recv_if); + router = find_router(orig_node, recv_if); if (!router) { spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); diff --git a/trunk/drivers/staging/batman-adv/routing.h b/trunk/drivers/staging/batman-adv/routing.h index 92674c8d9c03..06ea99df3706 100644 --- a/trunk/drivers/staging/batman-adv/routing.h +++ b/trunk/drivers/staging/batman-adv/routing.h @@ -38,8 +38,8 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if); -struct neigh_node *find_router(struct bat_priv *bat_priv, - struct orig_node *orig_node, struct batman_if *recv_if); +struct neigh_node *find_router(struct orig_node *orig_node, + struct batman_if *recv_if); void update_bonding_candidates(struct bat_priv *bat_priv, struct orig_node *orig_node); diff --git a/trunk/drivers/staging/batman-adv/unicast.c b/trunk/drivers/staging/batman-adv/unicast.c index 0459413ff67f..0dac50d69c03 100644 --- a/trunk/drivers/staging/batman-adv/unicast.c +++ b/trunk/drivers/staging/batman-adv/unicast.c @@ -224,7 +224,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) if (!orig_node) orig_node = transtable_search(bat_priv, ethhdr->h_dest); - router = find_router(bat_priv, orig_node, NULL); + router = find_router(orig_node, NULL); if (!router) goto unlock; diff --git a/trunk/drivers/staging/bcm/Bcmchar.c b/trunk/drivers/staging/bcm/Bcmchar.c index fead9c56162e..77fdfe24d999 100644 --- a/trunk/drivers/staging/bcm/Bcmchar.c +++ b/trunk/drivers/staging/bcm/Bcmchar.c @@ -1001,15 +1001,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } #endif case IOCTL_BE_BUCKET_SIZE: - Status = 0; - if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg)) - Status = -EFAULT; + Adapter->BEBucketSize = *(PULONG)arg; + Status = STATUS_SUCCESS; break; case IOCTL_RTPS_BUCKET_SIZE: - Status = 0; - if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg)) - Status = -EFAULT; + Adapter->rtPSBucketSize = *(PULONG)arg; + Status = STATUS_SUCCESS; break; case IOCTL_CHIP_RESET: { @@ -1030,15 +1028,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case IOCTL_QOS_THRESHOLD: { USHORT uiLoopIndex; - - Status = 0; - for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { - if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold, - (unsigned long __user *)arg)) { - Status = -EFAULT; - break; - } + for(uiLoopIndex = 0 ; uiLoopIndex < NO_OF_QUEUES ; uiLoopIndex++) + { + Adapter->PackInfo[uiLoopIndex].uiThreshold = *(PULONG)arg; } + Status = STATUS_SUCCESS; break; } @@ -1099,8 +1093,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } case IOCTL_BCM_GET_CURRENT_STATUS: { - LINK_STATE plink_state; - + LINK_STATE *plink_state = NULL; /* Copy Ioctl Buffer structure */ if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { @@ -1108,19 +1101,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = -EFAULT; break; } - if (IoBuffer.OutputLength != sizeof(plink_state)) { - Status = -EINVAL; - break; - } - - if (copy_from_user(&plink_state, (void __user *)arg, sizeof(plink_state))) { - Status = -EFAULT; - break; - } - plink_state.bIdleMode = (UCHAR)Adapter->IdleMode; - plink_state.bShutdownMode = Adapter->bShutStatus; - plink_state.ucLinkStatus = (UCHAR)Adapter->LinkStatus; - if (copy_to_user(IoBuffer.OutputBuffer, &plink_state, IoBuffer.OutputLength)) { + plink_state = (LINK_STATE*)arg; + plink_state->bIdleMode = (UCHAR)Adapter->IdleMode; + plink_state->bShutdownMode = Adapter->bShutStatus; + plink_state->ucLinkStatus = (UCHAR)Adapter->LinkStatus; + if(copy_to_user(IoBuffer.OutputBuffer, + (PUCHAR)plink_state, (UINT)IoBuffer.OutputLength)) + { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); Status = -EFAULT; break; @@ -1344,9 +1331,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status); return -EFAULT; } - if (get_user(uiSectorSize, (unsigned int __user *)IoBuffer.InputBuffer)) - return -EFAULT; - + uiSectorSize = *((PUINT)(IoBuffer.InputBuffer)); /* FIXME: unchecked __user access */ if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) { diff --git a/trunk/drivers/staging/brcm80211/README b/trunk/drivers/staging/brcm80211/README index c8f1cf1b4409..c3ba9bb9b116 100644 --- a/trunk/drivers/staging/brcm80211/README +++ b/trunk/drivers/staging/brcm80211/README @@ -90,5 +90,5 @@ Contact Info: ============= Brett Rudley brudley@broadcom.com Henry Ptasinski henryp@broadcom.com -Dowan Kim dowan@broadcom.com +Nohee Ko noheek@broadcom.com diff --git a/trunk/drivers/staging/brcm80211/TODO b/trunk/drivers/staging/brcm80211/TODO index dbf904184899..8803d300b531 100644 --- a/trunk/drivers/staging/brcm80211/TODO +++ b/trunk/drivers/staging/brcm80211/TODO @@ -45,5 +45,5 @@ Contact ===== Brett Rudley Henry Ptasinski -Dowan Kim +Nohee Ko diff --git a/trunk/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/trunk/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 9335f02029aa..bbbe7c5f7492 100644 --- a/trunk/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/trunk/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -2222,6 +2222,8 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) ASSERT(net); ASSERT(!net->netdev_ops); + net->netdev_ops = &dhd_ops_virt; + net->netdev_ops = &dhd_ops_pri; /* diff --git a/trunk/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/trunk/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index ea0825238d53..3f29488d9c72 100644 --- a/trunk/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/trunk/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -95,12 +95,12 @@ static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx); static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, + u8 key_idx, const u8 *mac_addr, struct key_params *params); static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr); + u8 key_idx, const u8 *mac_addr); static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, + u8 key_idx, const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params * @@ -1615,7 +1615,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, + u8 key_idx, const u8 *mac_addr, struct key_params *params) { struct wl_wsec_key key; @@ -1700,7 +1700,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr) + u8 key_idx, const u8 *mac_addr) { struct wl_wsec_key key; s32 err = 0; @@ -1756,7 +1756,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie, + u8 key_idx, const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params * params)) { struct key_params params; diff --git a/trunk/drivers/staging/cpia/cpia.c b/trunk/drivers/staging/cpia/cpia.c index 0e740b8dafc3..933ae4c8cb9a 100644 --- a/trunk/drivers/staging/cpia/cpia.c +++ b/trunk/drivers/staging/cpia/cpia.c @@ -3184,9 +3184,13 @@ static int cpia_open(struct file *file) goto oops; } + err = -EINTR; + if(signal_pending(current)) + goto oops; + /* Set ownership of /proc/cpia/videoX to current user */ if(cam->proc_entry) - cam->proc_entry->uid = current_euid(); + cam->proc_entry->uid = current_uid(); /* set mark for loading first frame uncompressed */ cam->first_frame = 1; diff --git a/trunk/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/trunk/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 20d509836d9e..87a6487531c2 100644 --- a/trunk/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/trunk/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -286,6 +286,7 @@ int ft1000_CreateDevice(struct ft1000_device *dev) pid = kernel_thread (exec_mknod, (void *)info, 0); // initialize application information + info->appcnt = 0; // if (ft1000_flarion_cnt == 0) { // diff --git a/trunk/drivers/staging/hv/hv_utils.c b/trunk/drivers/staging/hv/hv_utils.c index a99e900ec4c9..702a478d5542 100644 --- a/trunk/drivers/staging/hv/hv_utils.c +++ b/trunk/drivers/staging/hv/hv_utils.c @@ -211,6 +211,9 @@ static void heartbeat_onchannelcallback(void *context) DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", recvlen, requestid); + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + icmsghdrp = (struct icmsg_hdr *)&buf[ sizeof(struct vmbuspipe_hdr)]; diff --git a/trunk/drivers/staging/intel_sst/intel_sst_app_interface.c b/trunk/drivers/staging/intel_sst/intel_sst_app_interface.c index 9618c7997461..463e5cba8307 100644 --- a/trunk/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/trunk/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -244,12 +244,12 @@ static int intel_sst_mmap_play_capture(u32 str_id, int retval, i; struct stream_info *stream; struct snd_sst_mmap_buff_entry *buf_entry; - struct snd_sst_mmap_buff_entry *tmp_buf; pr_debug("sst:called for str_id %d\n", str_id); retval = sst_validate_strid(str_id); if (retval) return -EINVAL; + BUG_ON(!mmap_buf); stream = &sst_drv_ctx->streams[str_id]; if (stream->mmapped != true) @@ -262,24 +262,14 @@ static int intel_sst_mmap_play_capture(u32 str_id, stream->curr_bytes = 0; stream->cumm_bytes = 0; - tmp_buf = kcalloc(mmap_buf->entries, sizeof(*tmp_buf), GFP_KERNEL); - if (!tmp_buf) - return -ENOMEM; - if (copy_from_user(tmp_buf, (void __user *)mmap_buf->buff, - mmap_buf->entries * sizeof(*tmp_buf))) { - retval = -EFAULT; - goto out_free; - } - pr_debug("sst:new buffers count %d status %d\n", mmap_buf->entries, stream->status); - buf_entry = tmp_buf; + buf_entry = mmap_buf->buff; for (i = 0; i < mmap_buf->entries; i++) { + BUG_ON(!buf_entry); bufs = kzalloc(sizeof(*bufs), GFP_KERNEL); - if (!bufs) { - retval = -ENOMEM; - goto out_free; - } + if (!bufs) + return -ENOMEM; bufs->size = buf_entry->size; bufs->offset = buf_entry->offset; bufs->addr = sst_drv_ctx->mmap_mem; @@ -303,15 +293,13 @@ static int intel_sst_mmap_play_capture(u32 str_id, if (sst_play_frame(str_id) < 0) { pr_warn("sst: play frames fail\n"); mutex_unlock(&stream->lock); - retval = -EIO; - goto out_free; + return -EIO; } } else if (stream->ops == STREAM_OPS_CAPTURE) { if (sst_capture_frame(str_id) < 0) { pr_warn("sst: capture frame fail\n"); mutex_unlock(&stream->lock); - retval = -EIO; - goto out_free; + return -EIO; } } } @@ -326,9 +314,6 @@ static int intel_sst_mmap_play_capture(u32 str_id, if (retval >= 0) retval = stream->cumm_bytes; pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval); - -out_free: - kfree(tmp_buf); return retval; } @@ -392,7 +377,7 @@ static int snd_sst_fill_kernel_list(struct stream_info *stream, { struct sst_stream_bufs *stream_bufs; unsigned long index, mmap_len; - unsigned char __user *bufp; + unsigned char *bufp; unsigned long size, copied_size; int retval = 0, add_to_list = 0; static int sent_offset; @@ -527,7 +512,9 @@ static int snd_sst_copy_userbuf_capture(struct stream_info *stream, /* copy to user */ list_for_each_entry_safe(entry, _entry, copy_to_list, node) { - if (copy_to_user(iovec[entry->iov_index].iov_base + entry->iov_offset, + if (copy_to_user((void *) + iovec[entry->iov_index].iov_base + + entry->iov_offset, kbufs->addr + entry->offset, entry->size)) { /* Clean up the list and return error */ @@ -603,7 +590,7 @@ static int intel_sst_read_write(unsigned int str_id, char __user *buf, buf, (int) count, (int) stream->status); stream->buf_type = SST_BUF_USER_STATIC; - iovec.iov_base = buf; + iovec.iov_base = (void *)buf; iovec.iov_len = count; nr_segs = 1; @@ -851,7 +838,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): { - struct snd_sst_params str_param; + struct snd_sst_params *str_param = (struct snd_sst_params *)arg; pr_debug("sst: IOCTL_SET_PARAMS recieved!\n"); if (minor != STREAM_MODULE) { @@ -859,25 +846,17 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; } - if (copy_from_user(&str_param, (void __user *)arg, - sizeof(str_param))) { - retval = -EFAULT; - break; - } - if (!str_id) { - retval = sst_get_stream(&str_param); + retval = sst_get_stream(str_param); if (retval > 0) { struct stream_info *str_info; - char __user *dest; - sst_drv_ctx->stream_cnt++; data->str_id = retval; str_info = &sst_drv_ctx->streams[retval]; str_info->src = SST_DRV; - dest = (char __user *)arg + offsetof(struct snd_sst_params, stream_id); - retval = copy_to_user(dest, &retval, sizeof(__u32)); + retval = copy_to_user(&str_param->stream_id, + &retval, sizeof(__u32)); if (retval) retval = -EFAULT; } else { @@ -887,14 +866,16 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } else { pr_debug("sst: SET_STREAM_PARAMS recieved!\n"); /* allocated set params only */ - retval = sst_set_stream_param(str_id, &str_param); + retval = sst_set_stream_param(str_id, str_param); /* Block the call for reply */ if (!retval) { int sfreq = 0, word_size = 0, num_channel = 0; - sfreq = str_param.sparams.uc.pcm_params.sfreq; - word_size = str_param.sparams.uc.pcm_params.pcm_wd_sz; - num_channel = str_param.sparams.uc.pcm_params.num_chan; - if (str_param.ops == STREAM_OPS_CAPTURE) { + sfreq = str_param->sparams.uc.pcm_params.sfreq; + word_size = str_param->sparams. + uc.pcm_params.pcm_wd_sz; + num_channel = str_param-> + sparams.uc.pcm_params.num_chan; + if (str_param->ops == STREAM_OPS_CAPTURE) { sst_drv_ctx->scard_ops->\ set_pcm_audio_params(sfreq, word_size, num_channel); @@ -904,39 +885,41 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; } case _IOC_NR(SNDRV_SST_SET_VOL): { - struct snd_sst_vol set_vol; - - if (copy_from_user(&set_vol, (void __user *)arg, - sizeof(set_vol))) { - pr_debug("sst: copy failed\n"); - retval = -EFAULT; - break; - } + struct snd_sst_vol *set_vol; + struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg; pr_debug("sst: SET_VOLUME recieved for %d!\n", - set_vol.stream_id); - if (minor == STREAM_MODULE && set_vol.stream_id == 0) { + rec_vol->stream_id); + if (minor == STREAM_MODULE && rec_vol->stream_id == 0) { pr_debug("sst: invalid operation!\n"); retval = -EPERM; break; } - retval = sst_set_vol(&set_vol); + set_vol = kzalloc(sizeof(*set_vol), GFP_ATOMIC); + if (!set_vol) { + pr_debug("sst: mem allocation failed\n"); + retval = -ENOMEM; + break; + } + if (copy_from_user(set_vol, rec_vol, sizeof(*set_vol))) { + pr_debug("sst: copy failed\n"); + retval = -EFAULT; + break; + } + retval = sst_set_vol(set_vol); + kfree(set_vol); break; } case _IOC_NR(SNDRV_SST_GET_VOL): { + struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg; struct snd_sst_vol get_vol; - - if (copy_from_user(&get_vol, (void __user *)arg, - sizeof(get_vol))) { - retval = -EFAULT; - break; - } pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n", - get_vol.stream_id); - if (minor == STREAM_MODULE && get_vol.stream_id == 0) { + rec_vol->stream_id); + if (minor == STREAM_MODULE && rec_vol->stream_id == 0) { pr_debug("sst: invalid operation!\n"); retval = -EPERM; break; } + get_vol.stream_id = rec_vol->stream_id; retval = sst_get_vol(&get_vol); if (retval) { retval = -EIO; @@ -945,7 +928,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n", get_vol.stream_id, get_vol.volume, get_vol.ramp_duration, get_vol.ramp_type); - if (copy_to_user((struct snd_sst_vol __user *)arg, + if (copy_to_user((struct snd_sst_vol *)arg, &get_vol, sizeof(get_vol))) { retval = -EFAULT; break; @@ -955,20 +938,25 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } case _IOC_NR(SNDRV_SST_MUTE): { - struct snd_sst_mute set_mute; - - if (copy_from_user(&set_mute, (void __user *)arg, - sizeof(set_mute))) { - retval = -EFAULT; - break; - } + struct snd_sst_mute *set_mute; + struct snd_sst_vol *rec_mute = (struct snd_sst_vol *)arg; pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n", - set_mute.stream_id); - if (minor == STREAM_MODULE && set_mute.stream_id == 0) { + rec_mute->stream_id); + if (minor == STREAM_MODULE && rec_mute->stream_id == 0) { retval = -EPERM; break; } - retval = sst_set_mute(&set_mute); + set_mute = kzalloc(sizeof(*set_mute), GFP_ATOMIC); + if (!set_mute) { + retval = -ENOMEM; + break; + } + if (copy_from_user(set_mute, rec_mute, sizeof(*set_mute))) { + retval = -EFAULT; + break; + } + retval = sst_set_mute(set_mute); + kfree(set_mute); break; } case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): { @@ -985,7 +973,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) retval = -EIO; break; } - if (copy_to_user((struct snd_sst_get_stream_params __user *)arg, + if (copy_to_user((struct snd_sst_get_stream_params *)arg, &get_params, sizeof(get_params))) { retval = -EFAULT; break; @@ -995,22 +983,16 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } case _IOC_NR(SNDRV_SST_MMAP_PLAY): - case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): { - struct snd_sst_mmap_buffs mmap_buf; - + case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; } - if (copy_from_user(&mmap_buf, (void __user *)arg, - sizeof(mmap_buf))) { - retval = -EFAULT; - break; - } - retval = intel_sst_mmap_play_capture(str_id, &mmap_buf); + retval = intel_sst_mmap_play_capture(str_id, + (struct snd_sst_mmap_buffs *)arg); break; - } + case _IOC_NR(SNDRV_SST_STREAM_DROP): pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n"); if (minor != STREAM_MODULE) { @@ -1021,6 +1003,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP): { + unsigned long long *ms = (unsigned long long *)arg; struct snd_sst_tstamp tstamp = {0}; unsigned long long time, freq, mod; @@ -1030,14 +1013,14 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; } memcpy_fromio(&tstamp, - sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp), + ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP) + +(str_id * sizeof(tstamp))), sizeof(tstamp)); time = tstamp.samples_rendered; freq = (unsigned long long) tstamp.sampling_frequency; time = time * 1000; /* converting it to ms */ mod = do_div(time, freq); - if (copy_to_user((void __user *)arg, &time, - sizeof(unsigned long long))) + if (copy_to_user(ms, &time, sizeof(*ms))) retval = -EFAULT; break; } @@ -1082,118 +1065,92 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): { - struct snd_sst_target_device target_device; + struct snd_sst_target_device *target_device; pr_debug("sst: SET_TARGET_DEVICE recieved!\n"); - if (copy_from_user(&target_device, (void __user *)arg, - sizeof(target_device))) { - retval = -EFAULT; - break; - } + target_device = (struct snd_sst_target_device *)arg; + BUG_ON(!target_device); if (minor != AM_MODULE) { retval = -EBADRQC; break; } - retval = sst_target_device_select(&target_device); + retval = sst_target_device_select(target_device); break; } case _IOC_NR(SNDRV_SST_DRIVER_INFO): { - struct snd_sst_driver_info info; + struct snd_sst_driver_info *info = + (struct snd_sst_driver_info *)arg; pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n"); - info.version = SST_VERSION_NUM; + info->version = SST_VERSION_NUM; /* hard coding, shud get sumhow later */ - info.active_pcm_streams = sst_drv_ctx->stream_cnt - + info->active_pcm_streams = sst_drv_ctx->stream_cnt - sst_drv_ctx->encoded_cnt; - info.active_enc_streams = sst_drv_ctx->encoded_cnt; - info.max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM; - info.max_enc_streams = MAX_ENC_STREAM; - info.buf_per_stream = sst_drv_ctx->mmap_len; - if (copy_to_user((void __user *)arg, &info, - sizeof(info))) - retval = -EFAULT; + info->active_enc_streams = sst_drv_ctx->encoded_cnt; + info->max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM; + info->max_enc_streams = MAX_ENC_STREAM; + info->buf_per_stream = sst_drv_ctx->mmap_len; break; } case _IOC_NR(SNDRV_SST_STREAM_DECODE): { - struct snd_sst_dbufs param; - struct snd_sst_dbufs dbufs_local; + struct snd_sst_dbufs *param = + (struct snd_sst_dbufs *)arg, dbufs_local; + int i; struct snd_sst_buffs ibufs, obufs; - struct snd_sst_buff_entry *ibuf_tmp, *obuf_tmp; - char __user *dest; + struct snd_sst_buff_entry ibuf_temp[param->ibufs->entries], + obuf_temp[param->obufs->entries]; pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; } - if (copy_from_user(¶m, (void __user *)arg, - sizeof(param))) { - retval = -EFAULT; + if (!param) { + retval = -EINVAL; break; } - dbufs_local.input_bytes_consumed = param.input_bytes_consumed; + dbufs_local.input_bytes_consumed = param->input_bytes_consumed; dbufs_local.output_bytes_produced = - param.output_bytes_produced; - - if (copy_from_user(&ibufs, (void __user *)param.ibufs, sizeof(ibufs))) { - retval = -EFAULT; - break; - } - if (copy_from_user(&obufs, (void __user *)param.obufs, sizeof(obufs))) { - retval = -EFAULT; - break; - } - - ibuf_tmp = kcalloc(ibufs.entries, sizeof(*ibuf_tmp), GFP_KERNEL); - obuf_tmp = kcalloc(obufs.entries, sizeof(*obuf_tmp), GFP_KERNEL); - if (!ibuf_tmp || !obuf_tmp) { - retval = -ENOMEM; - goto free_iobufs; - } - - if (copy_from_user(ibuf_tmp, (void __user *)ibufs.buff_entry, - ibufs.entries * sizeof(*ibuf_tmp))) { - retval = -EFAULT; - goto free_iobufs; - } - ibufs.buff_entry = ibuf_tmp; + param->output_bytes_produced; dbufs_local.ibufs = &ibufs; - - if (copy_from_user(obuf_tmp, (void __user *)obufs.buff_entry, - obufs.entries * sizeof(*obuf_tmp))) { - retval = -EFAULT; - goto free_iobufs; - } - obufs.buff_entry = obuf_tmp; dbufs_local.obufs = &obufs; - - retval = sst_decode(str_id, &dbufs_local); - if (retval) { - retval = -EAGAIN; - goto free_iobufs; + dbufs_local.ibufs->entries = param->ibufs->entries; + dbufs_local.ibufs->type = param->ibufs->type; + dbufs_local.obufs->entries = param->obufs->entries; + dbufs_local.obufs->type = param->obufs->type; + + dbufs_local.ibufs->buff_entry = ibuf_temp; + for (i = 0; i < dbufs_local.ibufs->entries; i++) { + ibuf_temp[i].buffer = + param->ibufs->buff_entry[i].buffer; + ibuf_temp[i].size = + param->ibufs->buff_entry[i].size; } - - dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed); - if (copy_to_user(dest, + dbufs_local.obufs->buff_entry = obuf_temp; + for (i = 0; i < dbufs_local.obufs->entries; i++) { + obuf_temp[i].buffer = + param->obufs->buff_entry[i].buffer; + obuf_temp[i].size = + param->obufs->buff_entry[i].size; + } + retval = sst_decode(str_id, &dbufs_local); + if (retval) + retval = -EAGAIN; + if (copy_to_user(¶m->input_bytes_consumed, &dbufs_local.input_bytes_consumed, sizeof(unsigned long long))) { - retval = -EFAULT; - goto free_iobufs; + retval = -EFAULT; + break; } - - dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed); - if (copy_to_user(dest, + if (copy_to_user(¶m->output_bytes_produced, &dbufs_local.output_bytes_produced, sizeof(unsigned long long))) { - retval = -EFAULT; - goto free_iobufs; + retval = -EFAULT; + break; } -free_iobufs: - kfree(ibuf_tmp); - kfree(obuf_tmp); break; } @@ -1207,7 +1164,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED): { - unsigned long long __user *bytes = (unsigned long long __user *)arg; + unsigned long long *bytes = (unsigned long long *)arg; struct snd_sst_tstamp tstamp = {0}; pr_debug("sst: STREAM_BYTES_DECODED recieved!\n"); @@ -1216,7 +1173,8 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; } memcpy_fromio(&tstamp, - sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp), + ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP) + +(str_id * sizeof(tstamp))), sizeof(tstamp)); if (copy_to_user(bytes, &tstamp.bytes_processed, sizeof(*bytes))) @@ -1239,7 +1197,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) kfree(fw_info); break; } - if (copy_to_user((struct snd_sst_dbufs __user *)arg, + if (copy_to_user((struct snd_sst_dbufs *)arg, fw_info, sizeof(*fw_info))) { kfree(fw_info); retval = -EFAULT; diff --git a/trunk/drivers/staging/intel_sst/intel_sst_common.h b/trunk/drivers/staging/intel_sst/intel_sst_common.h index bf0ead78bfae..73a98c851e4a 100644 --- a/trunk/drivers/staging/intel_sst/intel_sst_common.h +++ b/trunk/drivers/staging/intel_sst/intel_sst_common.h @@ -231,8 +231,8 @@ struct stream_info { spinlock_t pcm_lock; bool mmapped; unsigned int sg_index; /* current buf Index */ - unsigned char __user *cur_ptr; /* Current static bufs */ - struct snd_sst_buf_entry __user *buf_entry; + unsigned char *cur_ptr; /* Current static bufs */ + struct snd_sst_buf_entry *buf_entry; struct sst_block data_blk; /* stream ops block */ struct sst_block ctrl_blk; /* stream control cmd block */ enum snd_sst_buf_type buf_type; diff --git a/trunk/drivers/staging/keucr/init.c b/trunk/drivers/staging/keucr/init.c index 978bf87ff13d..1934805844f2 100644 --- a/trunk/drivers/staging/keucr/init.c +++ b/trunk/drivers/staging/keucr/init.c @@ -22,7 +22,7 @@ int ENE_InitMedia(struct us_data *us) int result; BYTE MiscReg03 = 0; - printk("--- Init Media ---\n"); + printk("--- Initial Nedia ---\n"); result = ENE_Read_BYTE(us, REG_CARD_STATUS, &MiscReg03); if (result != USB_STOR_XFER_GOOD) { @@ -64,7 +64,7 @@ int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf) struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x01; bcb->Flags = 0x80; @@ -92,7 +92,7 @@ int ENE_SDInit(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->Flags = 0x80; bcb->CDB[0] = 0xF2; @@ -112,7 +112,7 @@ int ENE_SDInit(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -161,7 +161,7 @@ int ENE_MSInit(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -219,7 +219,7 @@ int ENE_SMInit(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -341,7 +341,7 @@ int ENE_LoadBinCode(struct us_data *us, BYTE flag) break; } - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x800; bcb->Flags =0x00; @@ -433,7 +433,7 @@ int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length) //printk("transport --- ENE_Read_Data\n"); // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = length; bcb->Flags =0x80; @@ -470,7 +470,7 @@ int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length) //printk("transport --- ENE_Write_Data\n"); // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = length; bcb->Flags =0x00; diff --git a/trunk/drivers/staging/keucr/ms.c b/trunk/drivers/staging/keucr/ms.c index 9a3fdb4e4fe4..d4340a9da87d 100644 --- a/trunk/drivers/staging/keucr/ms.c +++ b/trunk/drivers/staging/keucr/ms.c @@ -15,7 +15,7 @@ int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, WORD PhyBlo if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*len; bcb->Flags = 0x00; @@ -53,7 +53,7 @@ int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWO return USB_STOR_TRANSPORT_ERROR; // Read Page Data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -69,7 +69,7 @@ int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWO return USB_STOR_TRANSPORT_ERROR; // Read Extra Data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x4; bcb->Flags = 0x80; @@ -108,7 +108,7 @@ int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr) if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -673,7 +673,7 @@ int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, BYTE PageNum, BYTE //printk("MS_LibReadExtraBlock --- PhyBlock = %x, PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); // Read Extra Data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x4 * blen; bcb->Flags = 0x80; @@ -700,7 +700,7 @@ int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, BYTE PageNum, MS_LibType BYTE ExtBuf[4]; //printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x4; bcb->Flags = 0x80; @@ -807,7 +807,7 @@ int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, B if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x4; bcb->Flags = 0x80; diff --git a/trunk/drivers/staging/keucr/msscsi.c b/trunk/drivers/staging/keucr/msscsi.c index cb92d25acee0..ad0c5c629935 100644 --- a/trunk/drivers/staging/keucr/msscsi.c +++ b/trunk/drivers/staging/keucr/msscsi.c @@ -145,7 +145,7 @@ int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) } // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; bcb->Flags = 0x80; @@ -193,7 +193,7 @@ int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) blkno = phyblk * 0x20 + PageNum; // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200 * len; bcb->Flags = 0x80; @@ -250,7 +250,7 @@ int MS_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) } // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; bcb->Flags = 0x00; diff --git a/trunk/drivers/staging/keucr/sdscsi.c b/trunk/drivers/staging/keucr/sdscsi.c index d646507a3611..6c332f850ebe 100644 --- a/trunk/drivers/staging/keucr/sdscsi.c +++ b/trunk/drivers/staging/keucr/sdscsi.c @@ -152,7 +152,7 @@ int SD_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) bnByte = bn; // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; bcb->Flags = 0x80; @@ -192,7 +192,7 @@ int SD_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) bnByte = bn; // set up the command wrapper - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = blenByte; bcb->Flags = 0x00; diff --git a/trunk/drivers/staging/keucr/smilsub.c b/trunk/drivers/staging/keucr/smilsub.c index 1b52535a388f..844b65988636 100644 --- a/trunk/drivers/staging/keucr/smilsub.c +++ b/trunk/drivers/staging/keucr/smilsub.c @@ -266,7 +266,7 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; // Read sect data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -281,7 +281,7 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) return USB_STOR_TRANSPORT_ERROR; // Read redundant - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; bcb->Flags = 0x80; @@ -319,7 +319,7 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; // Read sect data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*count; bcb->Flags = 0x80; @@ -334,7 +334,7 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) return USB_STOR_TRANSPORT_ERROR; // Read redundant - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; bcb->Flags = 0x80; @@ -536,7 +536,7 @@ int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors; // Write sect data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*count; bcb->Flags = 0x00; @@ -754,7 +754,7 @@ int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant) addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; // Write sect data - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x00; @@ -791,7 +791,7 @@ int Ssfdc_D_EraseBlock(struct us_data *us) addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; addr=addr*(WORD)Ssfdc.MaxSectors; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; bcb->Flags = 0x80; @@ -827,7 +827,7 @@ int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant) addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; bcb->Flags = 0x80; @@ -870,7 +870,7 @@ int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant) addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + memset(bcb, 0, sizeof(bcb)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; bcb->Flags = 0x80; diff --git a/trunk/drivers/staging/keucr/transport.c b/trunk/drivers/staging/keucr/transport.c index 111160cce441..fd98df643ab0 100644 --- a/trunk/drivers/staging/keucr/transport.c +++ b/trunk/drivers/staging/keucr/transport.c @@ -40,7 +40,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout) us->current_urb->error_count = 0; us->current_urb->status = 0; - us->current_urb->transfer_flags = 0; +// us->current_urb->transfer_flags = URB_NO_SETUP_DMA_MAP; if (us->current_urb->transfer_buffer == us->iobuf) us->current_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; us->current_urb->transfer_dma = us->iobuf_dma; diff --git a/trunk/drivers/staging/rt2860/common/cmm_aes.c b/trunk/drivers/staging/rt2860/common/cmm_aes.c index a99879bada42..1d159ff82fd2 100644 --- a/trunk/drivers/staging/rt2860/common/cmm_aes.c +++ b/trunk/drivers/staging/rt2860/common/cmm_aes.c @@ -330,6 +330,8 @@ void construct_mic_iv(unsigned char *mic_iv, for (i = 8; i < 14; i++) mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ #endif + i = (payload_length / 256); + i = (payload_length % 256); mic_iv[14] = (unsigned char)(payload_length / 256); mic_iv[15] = (unsigned char)(payload_length % 256); diff --git a/trunk/drivers/staging/rt2860/usb_main_dev.c b/trunk/drivers/staging/rt2860/usb_main_dev.c index ddacfc6c4861..ebf9074a9083 100644 --- a/trunk/drivers/staging/rt2860/usb_main_dev.c +++ b/trunk/drivers/staging/rt2860/usb_main_dev.c @@ -65,7 +65,6 @@ struct usb_device_id rtusb_usb_id[] = { {USB_DEVICE(0x14B2, 0x3C07)}, /* AL */ {USB_DEVICE(0x050D, 0x8053)}, /* Belkin */ {USB_DEVICE(0x050D, 0x825B)}, /* Belkin */ - {USB_DEVICE(0x050D, 0x935A)}, /* Belkin F6D4050 v1 */ {USB_DEVICE(0x050D, 0x935B)}, /* Belkin F6D4050 v2 */ {USB_DEVICE(0x14B2, 0x3C23)}, /* Airlink */ {USB_DEVICE(0x14B2, 0x3C27)}, /* Airlink */ diff --git a/trunk/drivers/staging/rtl8192e/r8192E_core.c b/trunk/drivers/staging/rtl8192e/r8192E_core.c index b1786dcac245..a202194b5cbb 100644 --- a/trunk/drivers/staging/rtl8192e/r8192E_core.c +++ b/trunk/drivers/staging/rtl8192e/r8192E_core.c @@ -5829,9 +5829,6 @@ static void rtl8192_rx(struct net_device *dev) } } - pci_unmap_single(priv->pdev, *((dma_addr_t *) skb->cb), - priv->rxbuffersize, PCI_DMA_FROMDEVICE); - skb = new_skb; priv->rx_buf[priv->rx_idx] = skb; *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); diff --git a/trunk/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/trunk/drivers/staging/solo6x10/solo6010-v4l2-enc.c index 097e82bc7a63..bbf3d9c4abb0 100644 --- a/trunk/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/trunk/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -766,7 +766,7 @@ static int solo_enc_open(struct file *file) &solo_enc->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, - sizeof(struct videobuf_buffer), fh, NULL); + sizeof(struct videobuf_buffer), fh); spin_unlock(&solo_enc->lock); diff --git a/trunk/drivers/staging/solo6x10/solo6010-v4l2.c b/trunk/drivers/staging/solo6x10/solo6010-v4l2.c index 6ffd21de837d..9731fa02b5e8 100644 --- a/trunk/drivers/staging/solo6x10/solo6010-v4l2.c +++ b/trunk/drivers/staging/solo6x10/solo6010-v4l2.c @@ -437,7 +437,7 @@ static int solo_v4l2_open(struct file *file) &solo_dev->pdev->dev, &fh->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, SOLO_DISP_PIX_FIELD, - sizeof(struct videobuf_buffer), fh, NULL); + sizeof(struct videobuf_buffer), fh); return 0; } diff --git a/trunk/drivers/staging/stradis/stradis.c b/trunk/drivers/staging/stradis/stradis.c index 807dd7eb748f..a057824e7ebc 100644 --- a/trunk/drivers/staging/stradis/stradis.c +++ b/trunk/drivers/staging/stradis/stradis.c @@ -1286,7 +1286,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGCAP: { struct video_capability b; - memset(&b, 0, sizeof(b)); strcpy(b.name, saa->video_dev.name); b.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM | @@ -1417,7 +1416,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGWIN: { struct video_window vw; - memset(&vw, 0, sizeof(vw)); vw.x = saa->win.x; vw.y = saa->win.y; vw.width = saa->win.width; @@ -1450,7 +1448,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGFBUF: { struct video_buffer v; - memset(&v, 0, sizeof(v)); v.base = (void *)saa->win.vidadr; v.height = saa->win.sheight; v.width = saa->win.swidth; @@ -1495,7 +1492,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGAUDIO: { struct video_audio v; - memset(&v, 0, sizeof(v)); v = saa->audio_dev; v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; @@ -1538,7 +1534,6 @@ static long saa_ioctl(struct file *file, case VIDIOCGUNIT: { struct video_unit vu; - memset(&vu, 0, sizeof(vu)); vu.video = saa->video_dev.minor; vu.vbi = VIDEO_NO_UNIT; vu.radio = VIDEO_NO_UNIT; @@ -1893,7 +1888,6 @@ static int saa_open(struct file *file) saa->user++; if (saa->user > 1) { - saa->user--; unlock_kernel(); return 0; /* device open already, don't reset */ } @@ -2006,13 +2000,10 @@ static int __devinit configure_saa7146(struct pci_dev *pdev, int num) if (retval < 0) { dev_err(&pdev->dev, "%d: error in registering video device!\n", num); - goto errirq; + goto errio; } return 0; - -errirq: - free_irq(saa->irq, saa); errio: iounmap(saa->saa7146_mem); err: diff --git a/trunk/drivers/staging/tidspbridge/Kconfig b/trunk/drivers/staging/tidspbridge/Kconfig index 93de4f2e8bf8..ff64d464143c 100644 --- a/trunk/drivers/staging/tidspbridge/Kconfig +++ b/trunk/drivers/staging/tidspbridge/Kconfig @@ -6,6 +6,7 @@ menuconfig TIDSPBRIDGE tristate "DSP Bridge driver" depends on ARCH_OMAP3 select OMAP_MBOX_FWK + select OMAP_IOMMU help DSP/BIOS Bridge is designed for platforms that contain a GPP and one or more attached DSPs. The GPP is considered the master or diff --git a/trunk/drivers/staging/tidspbridge/Makefile b/trunk/drivers/staging/tidspbridge/Makefile index 41c644c3318f..50decc2935c5 100644 --- a/trunk/drivers/staging/tidspbridge/Makefile +++ b/trunk/drivers/staging/tidspbridge/Makefile @@ -2,19 +2,18 @@ obj-$(CONFIG_TIDSPBRIDGE) += bridgedriver.o libgen = gen/gb.o gen/gs.o gen/gh.o gen/uuidutil.o libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \ - core/tiomap3430_pwr.o core/tiomap_io.o \ + core/tiomap3430_pwr.o core/tiomap_io.o core/dsp-mmu.o \ core/ue_deh.o core/wdt.o core/dsp-clock.o core/sync.o libpmgr = pmgr/chnl.o pmgr/io.o pmgr/msg.o pmgr/cod.o pmgr/dev.o pmgr/dspapi.o \ - pmgr/dmm.o pmgr/cmm.o pmgr/dbll.o + pmgr/cmm.o pmgr/dbll.o librmgr = rmgr/dbdcd.o rmgr/disp.o rmgr/drv.o rmgr/mgr.o rmgr/node.o \ rmgr/proc.o rmgr/pwr.o rmgr/rmm.o rmgr/strm.o rmgr/dspdrv.o \ rmgr/nldr.o rmgr/drv_interface.o libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \ dynload/tramp.o -libhw = hw/hw_mmu.o bridgedriver-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \ - $(libdload) $(libhw) + $(libdload) #Machine dependent ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \ diff --git a/trunk/drivers/staging/tidspbridge/core/_deh.h b/trunk/drivers/staging/tidspbridge/core/_deh.h index 16723cd34831..8ae263387a87 100644 --- a/trunk/drivers/staging/tidspbridge/core/_deh.h +++ b/trunk/drivers/staging/tidspbridge/core/_deh.h @@ -27,9 +27,8 @@ struct deh_mgr { struct bridge_dev_context *hbridge_context; /* Bridge context. */ struct ntfy_object *ntfy_obj; /* NTFY object */ - - /* MMU Fault DPC */ - struct tasklet_struct dpc_tasklet; }; +int mmu_fault_isr(struct iommu *mmu); + #endif /* _DEH_ */ diff --git a/trunk/drivers/staging/tidspbridge/core/_tiomap.h b/trunk/drivers/staging/tidspbridge/core/_tiomap.h index 1c1f157e167a..e0a801c1cb98 100644 --- a/trunk/drivers/staging/tidspbridge/core/_tiomap.h +++ b/trunk/drivers/staging/tidspbridge/core/_tiomap.h @@ -23,8 +23,8 @@ #include #include #include +#include #include -#include #include /* for bridge_ioctl_extproc defn */ #include #include @@ -306,6 +306,18 @@ static const struct bpwr_clk_t bpwr_clks[] = { #define CLEAR_BIT_INDEX(reg, index) (reg &= ~(1 << (index))) +struct shm_segs { + u32 seg0_da; + u32 seg0_pa; + u32 seg0_va; + u32 seg0_size; + u32 seg1_da; + u32 seg1_pa; + u32 seg1_va; + u32 seg1_size; +}; + + /* This Bridge driver's device context: */ struct bridge_dev_context { struct dev_object *hdev_obj; /* Handle to Bridge device object. */ @@ -316,7 +328,6 @@ struct bridge_dev_context { */ u32 dw_dsp_ext_base_addr; /* See the comment above */ u32 dw_api_reg_base; /* API mem map'd registers */ - void __iomem *dw_dsp_mmu_base; /* DSP MMU Mapped registers */ u32 dw_api_clk_base; /* CLK Registers */ u32 dw_dsp_clk_m2_base; /* DSP Clock Module m2 */ u32 dw_public_rhea; /* Pub Rhea */ @@ -328,7 +339,8 @@ struct bridge_dev_context { u32 dw_internal_size; /* Internal memory size */ struct omap_mbox *mbox; /* Mail box handle */ - + struct iommu *dsp_mmu; /* iommu for iva2 handler */ + struct shm_segs sh_s; struct cfg_hostres *resources; /* Host Resources */ /* @@ -341,7 +353,6 @@ struct bridge_dev_context { /* TC Settings */ bool tc_word_swap_on; /* Traffic Controller Word Swap */ - struct pg_table_attrs *pt_attrs; u32 dsp_per_clks; }; diff --git a/trunk/drivers/staging/tidspbridge/core/dsp-mmu.c b/trunk/drivers/staging/tidspbridge/core/dsp-mmu.c new file mode 100644 index 000000000000..983c95adc8ff --- /dev/null +++ b/trunk/drivers/staging/tidspbridge/core/dsp-mmu.c @@ -0,0 +1,317 @@ +/* + * dsp-mmu.c + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * DSP iommu. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include +#include +#include +#include +#include "_tiomap.h" + +#include + +#define MMU_CNTL_TWL_EN (1 << 2) + +static struct tasklet_struct mmu_tasklet; + +#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE +static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) +{ + void *dummy_addr; + u32 fa, tmp; + struct iotlb_entry e; + struct iommu *mmu = dev_context->dsp_mmu; + dummy_addr = (void *)__get_free_page(GFP_ATOMIC); + + /* + * Before acking the MMU fault, let's make sure MMU can only + * access entry #0. Then add a new entry so that the DSP OS + * can continue in order to dump the stack. + */ + tmp = iommu_read_reg(mmu, MMU_CNTL); + tmp &= ~MMU_CNTL_TWL_EN; + iommu_write_reg(mmu, tmp, MMU_CNTL); + fa = iommu_read_reg(mmu, MMU_FAULT_AD); + e.da = fa & PAGE_MASK; + e.pa = virt_to_phys(dummy_addr); + e.valid = 1; + e.prsvd = 1; + e.pgsz = IOVMF_PGSZ_4K & MMU_CAM_PGSZ_MASK; + e.endian = MMU_RAM_ENDIAN_LITTLE; + e.elsz = MMU_RAM_ELSZ_32; + e.mixed = 0; + + load_iotlb_entry(mmu, &e); + + dsp_clk_enable(DSP_CLK_GPT8); + + dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe); + + /* Clear MMU interrupt */ + tmp = iommu_read_reg(mmu, MMU_IRQSTATUS); + iommu_write_reg(mmu, tmp, MMU_IRQSTATUS); + + dump_dsp_stack(dev_context); + dsp_clk_disable(DSP_CLK_GPT8); + + iopgtable_clear_entry(mmu, fa); + free_page((unsigned long)dummy_addr); +} +#endif + + +static void fault_tasklet(unsigned long data) +{ + struct iommu *mmu = (struct iommu *)data; + struct bridge_dev_context *dev_ctx; + struct deh_mgr *dm; + u32 fa; + dev_get_deh_mgr(dev_get_first(), &dm); + dev_get_bridge_context(dev_get_first(), &dev_ctx); + + if (!dm || !dev_ctx) + return; + + fa = iommu_read_reg(mmu, MMU_FAULT_AD); + +#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE + print_dsp_trace_buffer(dev_ctx); + dump_dl_modules(dev_ctx); + mmu_fault_print_stack(dev_ctx); +#endif + + bridge_deh_notify(dm, DSP_MMUFAULT, fa); +} + +/* + * ======== mmu_fault_isr ======== + * ISR to be triggered by a DSP MMU fault interrupt. + */ +static int mmu_fault_callback(struct iommu *mmu) +{ + if (!mmu) + return -EPERM; + + iommu_write_reg(mmu, 0, MMU_IRQENABLE); + tasklet_schedule(&mmu_tasklet); + return 0; +} + +/** + * dsp_mmu_init() - initialize dsp_mmu module and returns a handle + * + * This function initialize dsp mmu module and returns a struct iommu + * handle to use it for dsp maps. + * + */ +struct iommu *dsp_mmu_init() +{ + struct iommu *mmu; + + mmu = iommu_get("iva2"); + + if (!IS_ERR(mmu)) { + tasklet_init(&mmu_tasklet, fault_tasklet, (unsigned long)mmu); + mmu->isr = mmu_fault_callback; + } + + return mmu; +} + +/** + * dsp_mmu_exit() - destroy dsp mmu module + * @mmu: Pointer to iommu handle. + * + * This function destroys dsp mmu module. + * + */ +void dsp_mmu_exit(struct iommu *mmu) +{ + if (mmu) + iommu_put(mmu); + tasklet_kill(&mmu_tasklet); +} + +/** + * user_va2_pa() - get physical address from userspace address. + * @mm: mm_struct Pointer of the process. + * @address: Virtual user space address. + * + */ +static u32 user_va2_pa(struct mm_struct *mm, u32 address) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + + pgd = pgd_offset(mm, address); + if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { + pmd = pmd_offset(pgd, address); + if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { + ptep = pte_offset_map(pmd, address); + if (ptep) { + pte = *ptep; + if (pte_present(pte)) + return pte & PAGE_MASK; + } + } + } + + return 0; +} + +/** + * get_io_pages() - pin and get pages of io user's buffer. + * @mm: mm_struct Pointer of the process. + * @uva: Virtual user space address. + * @pages Pages to be pined. + * @usr_pgs struct page array pointer where the user pages will be stored + * + */ +static int get_io_pages(struct mm_struct *mm, u32 uva, unsigned pages, + struct page **usr_pgs) +{ + u32 pa; + int i; + struct page *pg; + + for (i = 0; i < pages; i++) { + pa = user_va2_pa(mm, uva); + + if (!pfn_valid(__phys_to_pfn(pa))) + break; + + pg = phys_to_page(pa); + usr_pgs[i] = pg; + get_page(pg); + } + return i; +} + +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgs struct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs) +{ + int res, w; + unsigned pages; + int i; + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; + struct sg_table *sgt; + struct scatterlist *sg; + + if (!size || !usr_pgs) + return -EINVAL; + + pages = size / PG_SIZE4K; + + down_read(&mm->mmap_sem); + vma = find_vma(mm, uva); + while (vma && (uva + size > vma->vm_end)) + vma = find_vma(mm, vma->vm_end + 1); + + if (!vma) { + pr_err("%s: Failed to get VMA region for 0x%x (%d)\n", + __func__, uva, size); + up_read(&mm->mmap_sem); + return -EINVAL; + } + if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) + w = 1; + + if (vma->vm_flags & VM_IO) + i = get_io_pages(mm, uva, pages, usr_pgs); + else + i = get_user_pages(current, mm, uva, pages, w, 1, + usr_pgs, NULL); + up_read(&mm->mmap_sem); + + if (i < 0) + return i; + + if (i < pages) { + res = -EFAULT; + goto err_pages; + } + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) { + res = -ENOMEM; + goto err_pages; + } + + res = sg_alloc_table(sgt, pages, GFP_KERNEL); + + if (res < 0) + goto err_sg; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) + sg_set_page(sg, usr_pgs[i], PAGE_SIZE, 0); + + da = iommu_vmap(mmu, da, sgt, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + + if (!IS_ERR_VALUE(da)) + return da; + res = (int)da; + + sg_free_table(sgt); +err_sg: + kfree(sgt); + i = pages; +err_pages: + while (i--) + put_page(usr_pgs[i]); + return res; +} + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da) +{ + unsigned i; + struct sg_table *sgt; + struct scatterlist *sg; + + sgt = iommu_vunmap(mmu, da); + if (!sgt) + return -EFAULT; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) + put_page(sg_page(sg)); + sg_free_table(sgt); + kfree(sgt); + + return 0; +} diff --git a/trunk/drivers/staging/tidspbridge/core/io_sm.c b/trunk/drivers/staging/tidspbridge/core/io_sm.c index 571864555ddd..194badaba0ed 100644 --- a/trunk/drivers/staging/tidspbridge/core/io_sm.c +++ b/trunk/drivers/staging/tidspbridge/core/io_sm.c @@ -39,10 +39,6 @@ #include #include -/* Hardware Abstraction Layer */ -#include -#include - /* Bridge Driver */ #include #include @@ -291,6 +287,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct cod_manager *cod_man; struct chnl_mgr *hchnl_mgr; struct msg_mgr *hmsg_mgr; + struct shm_segs *sm_sg; u32 ul_shm_base; u32 ul_shm_base_offset; u32 ul_shm_limit; @@ -313,18 +310,9 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) struct bridge_ioctl_extproc ae_proc[BRDIOCTL_NUMOFMMUTLB]; struct cfg_hostres *host_res; struct bridge_dev_context *pbridge_context; - u32 map_attrs; u32 shm0_end; u32 ul_dyn_ext_base; u32 ul_seg1_size = 0; - u32 pa_curr = 0; - u32 va_curr = 0; - u32 gpp_va_curr = 0; - u32 num_bytes = 0; - u32 all_bits = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; status = dev_get_bridge_context(hio_mgr->hdev_obj, &pbridge_context); if (!pbridge_context) { @@ -337,6 +325,8 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } + sm_sg = &pbridge_context->sh_s; + status = dev_get_cod_mgr(hio_mgr->hdev_obj, &cod_man); if (!cod_man) { status = -EFAULT; @@ -471,129 +461,14 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) if (status) goto func_end; - pa_curr = ul_gpp_pa; - va_curr = ul_dyn_ext_base * hio_mgr->word_size; - gpp_va_curr = ul_gpp_va; - num_bytes = ul_seg1_size; - - /* - * Try to fit into TLB entries. If not possible, push them to page - * tables. It is quite possible that if sections are not on - * bigger page boundary, we may end up making several small pages. - * So, push them onto page tables, if that is the case. - */ - map_attrs = 0x00000000; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; - - while (num_bytes) { - /* - * To find the max. page size with which both PA & VA are - * aligned. - */ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits %x, pa_curr %x, va_curr %x, " - "num_bytes %x\n", all_bits, pa_curr, va_curr, - num_bytes); - for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & - (page_size[i] - - 1)) == 0)) { - status = - hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - if (status) - goto func_end; - pa_curr += page_size[i]; - va_curr += page_size[i]; - gpp_va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* - * Don't try smaller sizes. Hopefully we have - * reached an address aligned to a bigger page - * size. - */ - break; - } - } - } - pa_curr += ul_pad_size; - va_curr += ul_pad_size; - gpp_va_curr += ul_pad_size; - - /* Configure the TLB entries for the next cacheable segment */ - num_bytes = ul_seg_size; - va_curr = ul_dsp_va * hio_mgr->word_size; - while (num_bytes) { - /* - * To find the max. page size with which both PA & VA are - * aligned. - */ - all_bits = pa_curr | va_curr; - dev_dbg(bridge, "all_bits for Seg1 %x, pa_curr %x, " - "va_curr %x, num_bytes %x\n", all_bits, pa_curr, - va_curr, num_bytes); - for (i = 0; i < 4; i++) { - if (!(num_bytes >= page_size[i]) || - !((all_bits & (page_size[i] - 1)) == 0)) - continue; - if (ndx < MAX_LOCK_TLB_ENTRIES) { - /* - * This is the physical address written to - * DSP MMU. - */ - ae_proc[ndx].ul_gpp_pa = pa_curr; - /* - * This is the virtual uncached ioremapped - * address!!! - */ - ae_proc[ndx].ul_gpp_va = gpp_va_curr; - ae_proc[ndx].ul_dsp_va = - va_curr / hio_mgr->word_size; - ae_proc[ndx].ul_size = page_size[i]; - ae_proc[ndx].endianism = HW_LITTLE_ENDIAN; - ae_proc[ndx].elem_size = HW_ELEM_SIZE16BIT; - ae_proc[ndx].mixed_mode = HW_MMU_CPUES; - dev_dbg(bridge, "shm MMU TLB entry PA %x" - " VA %x DSP_VA %x Size %x\n", - ae_proc[ndx].ul_gpp_pa, - ae_proc[ndx].ul_gpp_va, - ae_proc[ndx].ul_dsp_va * - hio_mgr->word_size, page_size[i]); - ndx++; - } else { - status = - hio_mgr->intf_fxns-> - pfn_brd_mem_map(hio_mgr->hbridge_context, - pa_curr, va_curr, - page_size[i], map_attrs, - NULL); - dev_dbg(bridge, - "shm MMU PTE entry PA %x" - " VA %x DSP_VA %x Size %x\n", - ae_proc[ndx].ul_gpp_pa, - ae_proc[ndx].ul_gpp_va, - ae_proc[ndx].ul_dsp_va * - hio_mgr->word_size, page_size[i]); - if (status) - goto func_end; - } - pa_curr += page_size[i]; - va_curr += page_size[i]; - gpp_va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* - * Don't try smaller sizes. Hopefully we have reached - * an address aligned to a bigger page size. - */ - break; - } - } + sm_sg->seg1_pa = ul_gpp_pa; + sm_sg->seg1_da = ul_dyn_ext_base; + sm_sg->seg1_va = ul_gpp_va; + sm_sg->seg1_size = ul_seg1_size; + sm_sg->seg0_pa = ul_gpp_pa + ul_pad_size + ul_seg1_size; + sm_sg->seg0_da = ul_dsp_va; + sm_sg->seg0_va = ul_gpp_va + ul_pad_size + ul_seg1_size; + sm_sg->seg0_size = ul_seg_size; /* * Copy remaining entries from CDB. All entries are 1 MB and @@ -634,38 +509,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) "DSP_VA 0x%x\n", ae_proc[ndx].ul_gpp_pa, ae_proc[ndx].ul_dsp_va); ndx++; - } else { - status = hio_mgr->intf_fxns->pfn_brd_mem_map - (hio_mgr->hbridge_context, - hio_mgr->ext_proc_info.ty_tlb[i]. - ul_gpp_phys, - hio_mgr->ext_proc_info.ty_tlb[i]. - ul_dsp_virt, 0x100000, map_attrs, - NULL); } } if (status) goto func_end; } - map_attrs = 0x00000000; - map_attrs = DSP_MAPLITTLEENDIAN; - map_attrs |= DSP_MAPPHYSICALADDR; - map_attrs |= DSP_MAPELEMSIZE32; - map_attrs |= DSP_MAPDONOTLOCK; - - /* Map the L4 peripherals */ - i = 0; - while (l4_peripheral_table[i].phys_addr) { - status = hio_mgr->intf_fxns->pfn_brd_mem_map - (hio_mgr->hbridge_context, l4_peripheral_table[i].phys_addr, - l4_peripheral_table[i].dsp_virt_addr, HW_PAGE_SIZE4KB, - map_attrs, NULL); - if (status) - goto func_end; - i++; - } - for (i = ndx; i < BRDIOCTL_NUMOFMMUTLB; i++) { ae_proc[i].ul_dsp_va = 0; ae_proc[i].ul_gpp_pa = 0; @@ -688,12 +537,12 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) status = -EFAULT; goto func_end; } else { - if (ae_proc[0].ul_dsp_va > ul_shm_base) { + if (sm_sg->seg0_da > ul_shm_base) { status = -EPERM; goto func_end; } /* ul_shm_base may not be at ul_dsp_va address */ - ul_shm_base_offset = (ul_shm_base - ae_proc[0].ul_dsp_va) * + ul_shm_base_offset = (ul_shm_base - sm_sg->seg0_da) * hio_mgr->word_size; /* * bridge_dev_ctrl() will set dev context dsp-mmu info. In @@ -717,8 +566,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr) goto func_end; } /* Register SM */ - status = - register_shm_segs(hio_mgr, cod_man, ae_proc[0].ul_gpp_pa); + status = register_shm_segs(hio_mgr, cod_man, sm_sg->seg0_pa); } hio_mgr->shared_mem = (struct shm *)ul_shm_base; diff --git a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c index 1be081f917a7..f22bc12bc0d3 100644 --- a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c @@ -23,6 +23,7 @@ #include #include #include +#include /* ----------------------------------- DSP/BIOS Bridge */ #include @@ -34,10 +35,6 @@ #include #include -/* ------------------------------------ Hardware Abstraction Layer */ -#include -#include - /* ----------------------------------- Link Driver */ #include #include @@ -50,7 +47,6 @@ /* ----------------------------------- Platform Manager */ #include #include -#include #include /* ----------------------------------- Local */ @@ -71,20 +67,6 @@ #define MMU_SMALL_PAGE_MASK 0xFFFFF000 #define OMAP3_IVA2_BOOTADDR_MASK 0xFFFFFC00 #define PAGES_II_LVL_TABLE 512 -#define PHYS_TO_PAGE(phys) pfn_to_page((phys) >> PAGE_SHIFT) - -/* - * This is a totally ugly layer violation, but needed until - * omap_ctrl_set_dsp_boot*() are provided. - */ -#define OMAP3_IVA2_BOOTMOD_IDLE 1 -#define OMAP2_CONTROL_GENERAL 0x270 -#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) -#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) - -#define OMAP343X_CTRL_REGADDR(reg) \ - OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) - /* Forward Declarations: */ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt); @@ -109,12 +91,6 @@ static int bridge_brd_mem_copy(struct bridge_dev_context *dev_ctxt, static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, u8 *host_buff, u32 dsp_addr, u32 ul_num_bytes, u32 mem_type); -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages); -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, - u32 virt_addr, u32 ul_num_bytes); static int bridge_dev_create(struct bridge_dev_context **dev_cntxt, struct dev_object *hdev_obj, @@ -122,57 +98,8 @@ static int bridge_dev_create(struct bridge_dev_context static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, u32 dw_cmd, void *pargs); static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt); -static u32 user_va2_pa(struct mm_struct *mm, u32 address); -static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, - u32 va, u32 size, - struct hw_mmu_map_attrs_t *map_attrs); -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs); -static int mem_map_vmalloc(struct bridge_dev_context *dev_context, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs); - bool wait_for_start(struct bridge_dev_context *dev_context, u32 dw_sync_addr); -/* ----------------------------------- Globals */ - -/* Attributes of L2 page tables for DSP MMU */ -struct page_info { - u32 num_entries; /* Number of valid PTEs in the L2 PT */ -}; - -/* Attributes used to manage the DSP MMU page tables */ -struct pg_table_attrs { - spinlock_t pg_lock; /* Critical section object handle */ - - u32 l1_base_pa; /* Physical address of the L1 PT */ - u32 l1_base_va; /* Virtual address of the L1 PT */ - u32 l1_size; /* Size of the L1 PT */ - u32 l1_tbl_alloc_pa; - /* Physical address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_va; - /* Virtual address of Allocated mem for L1 table. May not be aligned */ - u32 l1_tbl_alloc_sz; - /* Size of consistent memory allocated for L1 table. - * May not be aligned */ - - u32 l2_base_pa; /* Physical address of the L2 PT */ - u32 l2_base_va; /* Virtual address of the L2 PT */ - u32 l2_size; /* Size of the L2 PT */ - u32 l2_tbl_alloc_pa; - /* Physical address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_va; - /* Virtual address of Allocated mem for L2 table. May not be aligned */ - u32 l2_tbl_alloc_sz; - /* Size of consistent memory allocated for L2 table. - * May not be aligned */ - - u32 l2_num_pages; /* Number of allocated L2 PT */ - /* Array [l2_num_pages] of L2 PT info structs */ - struct page_info *pg_info; -}; - /* * This Bridge driver's function interface table. */ @@ -192,8 +119,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_brd_set_state, bridge_brd_mem_copy, bridge_brd_mem_write, - bridge_brd_mem_map, - bridge_brd_mem_un_map, /* The following CHNL functions are provided by chnl_io.lib: */ bridge_chnl_create, bridge_chnl_destroy, @@ -223,27 +148,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_msg_set_queue_id, }; -static inline void flush_all(struct bridge_dev_context *dev_context) -{ - if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION || - dev_context->dw_brd_state == BRD_HIBERNATION) - wake_dsp(dev_context, NULL); - - hw_mmu_tlb_flush_all(dev_context->dw_dsp_mmu_base); -} - -static void bad_page_dump(u32 pa, struct page *pg) -{ - pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa); - pr_emerg("Bad page state in process '%s'\n" - "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" - "Backtrace:\n", - current->comm, pg, (int)(2 * sizeof(unsigned long)), - (unsigned long)pg->flags, pg->mapping, - page_mapcount(pg), page_count(pg)); - dump_stack(); -} - /* * ======== bridge_drv_entry ======== * purpose: @@ -299,8 +203,7 @@ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt) (*pdata->dsp_cm_write)(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); } - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0, - OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); + dsp_clk_enable(DSP_CLK_IVA2); /* set the device state to IDLE */ @@ -371,14 +274,17 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, { int status = 0; struct bridge_dev_context *dev_context = dev_ctxt; + struct iommu *mmu = NULL; + struct shm_segs *sm_sg; + int l4_i = 0, tlb_i = 0; + u32 sg0_da = 0, sg1_da = 0; + struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry; u32 dw_sync_addr = 0; u32 ul_shm_base; /* Gpp Phys SM base addr(byte) */ u32 ul_shm_base_virt; /* Dsp Virt SM base addr */ u32 ul_tlb_base_virt; /* Base of MMU TLB entry */ /* Offset of shm_base_virt from tlb_base_virt */ u32 ul_shm_offset_virt; - s32 entry_ndx; - s32 itmp_entry_ndx = 0; /* DSP-MMU TLB entry base address */ struct cfg_hostres *resources = NULL; u32 temp; u32 ul_dsp_clk_rate; @@ -399,12 +305,12 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, ul_shm_base_virt *= DSPWORDSIZE; DBC_ASSERT(ul_shm_base_virt != 0); /* DSP Virtual address */ - ul_tlb_base_virt = dev_context->atlb_entry[0].ul_dsp_va; + ul_tlb_base_virt = dev_context->sh_s.seg0_da; DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); ul_shm_offset_virt = ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE); /* Kernel logical address */ - ul_shm_base = dev_context->atlb_entry[0].ul_gpp_va + ul_shm_offset_virt; + ul_shm_base = dev_context->sh_s.seg0_va + ul_shm_offset_virt; DBC_ASSERT(ul_shm_base != 0); /* 2nd wd is used as sync field */ @@ -439,78 +345,83 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, OMAP343X_CONTROL_IVA2_BOOTMOD)); } } + if (!status) { - /* Reset and Unreset the RST2, so that BOOTADDR is copied to - * IVA2 SYSC register */ - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, - OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - udelay(100); (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, 0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); - udelay(100); - - /* Disbale the DSP MMU */ - hw_mmu_disable(resources->dw_dmmu_base); - /* Disable TWL */ - hw_mmu_twl_disable(resources->dw_dmmu_base); - - /* Only make TLB entry if both addresses are non-zero */ - for (entry_ndx = 0; entry_ndx < BRDIOCTL_NUMOFMMUTLB; - entry_ndx++) { - struct bridge_ioctl_extproc *e = &dev_context->atlb_entry[entry_ndx]; - struct hw_mmu_map_attrs_t map_attrs = { - .endianism = e->endianism, - .element_size = e->elem_size, - .mixed_size = e->mixed_mode, - }; - - if (!e->ul_gpp_pa || !e->ul_dsp_va) + mmu = dev_context->dsp_mmu; + if (mmu) + dsp_mmu_exit(mmu); + mmu = dsp_mmu_init(); + if (IS_ERR(mmu)) { + dev_err(bridge, "dsp_mmu_init failed!\n"); + dev_context->dsp_mmu = NULL; + status = (int)mmu; + } + } + if (!status) { + dev_context->dsp_mmu = mmu; + sm_sg = &dev_context->sh_s; + sg0_da = iommu_kmap(mmu, sm_sg->seg0_da, sm_sg->seg0_pa, + sm_sg->seg0_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(sg0_da)) { + status = (int)sg0_da; + sg0_da = 0; + } + } + if (!status) { + sg1_da = iommu_kmap(mmu, sm_sg->seg1_da, sm_sg->seg1_pa, + sm_sg->seg1_size, IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(sg1_da)) { + status = (int)sg1_da; + sg1_da = 0; + } + } + if (!status) { + u32 da; + for (tlb_i = 0; tlb_i < BRDIOCTL_NUMOFMMUTLB; tlb_i++) { + if (!tlb[tlb_i].ul_gpp_pa) continue; - dev_dbg(bridge, - "MMU %d, pa: 0x%x, va: 0x%x, size: 0x%x", - itmp_entry_ndx, - e->ul_gpp_pa, - e->ul_dsp_va, - e->ul_size); - - hw_mmu_tlb_add(dev_context->dw_dsp_mmu_base, - e->ul_gpp_pa, - e->ul_dsp_va, - e->ul_size, - itmp_entry_ndx, - &map_attrs, 1, 1); - - itmp_entry_ndx++; + dev_dbg(bridge, "IOMMU %d GppPa: 0x%x DspVa 0x%x Size" + " 0x%x\n", tlb_i, tlb[tlb_i].ul_gpp_pa, + tlb[tlb_i].ul_dsp_va, tlb[tlb_i].ul_size); + + da = iommu_kmap(mmu, tlb[tlb_i].ul_dsp_va, + tlb[tlb_i].ul_gpp_pa, PAGE_SIZE, + IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(da)) { + status = (int)da; + break; + } + } + } + if (!status) { + u32 da; + l4_i = 0; + while (l4_peripheral_table[l4_i].phys_addr) { + da = iommu_kmap(mmu, l4_peripheral_table[l4_i]. + dsp_virt_addr, l4_peripheral_table[l4_i]. + phys_addr, PAGE_SIZE, + IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_32); + if (IS_ERR_VALUE(da)) { + status = (int)da; + break; + } + l4_i++; } } /* Lock the above TLB entries and get the BIOS and load monitor timer * information */ if (!status) { - hw_mmu_num_locked_set(resources->dw_dmmu_base, itmp_entry_ndx); - hw_mmu_victim_num_set(resources->dw_dmmu_base, itmp_entry_ndx); - hw_mmu_ttb_set(resources->dw_dmmu_base, - dev_context->pt_attrs->l1_base_pa); - hw_mmu_twl_enable(resources->dw_dmmu_base); - /* Enable the SmartIdle and AutoIdle bit for MMU_SYSCONFIG */ - - temp = __raw_readl((resources->dw_dmmu_base) + 0x10); - temp = (temp & 0xFFFFFFEF) | 0x11; - __raw_writel(temp, (resources->dw_dmmu_base) + 0x10); - - /* Let the DSP MMU run */ - hw_mmu_enable(resources->dw_dmmu_base); - /* Enable the BIOS clock */ (void)dev_get_symbol(dev_context->hdev_obj, BRIDGEINIT_BIOSGPTIMER, &ul_bios_gp_timer); (void)dev_get_symbol(dev_context->hdev_obj, BRIDGEINIT_LOADMON_GPTIMER, &ul_load_monitor_timer); - } - if (!status) { if (ul_load_monitor_timer != 0xFFFF) { clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) | ul_load_monitor_timer; @@ -519,9 +430,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, dev_dbg(bridge, "Not able to get the symbol for Load " "Monitor Timer\n"); } - } - if (!status) { if (ul_bios_gp_timer != 0xFFFF) { clk_cmd = (BPWR_ENABLE_CLOCK << MBX_PM_CLK_CMDSHIFT) | ul_bios_gp_timer; @@ -530,9 +439,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, dev_dbg(bridge, "Not able to get the symbol for BIOS Timer\n"); } - } - if (!status) { /* Set the DSP clock rate */ (void)dev_get_symbol(dev_context->hdev_obj, "_BRIDGEINIT_DSP_FREQ", &ul_dsp_clk_addr); @@ -585,9 +492,6 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Let DSP go */ dev_dbg(bridge, "%s Unreset\n", __func__); - /* Enable DSP MMU Interrupts */ - hw_mmu_event_enable(resources->dw_dmmu_base, - HW_MMU_ALL_INTERRUPTS); /* release the RST1, DSP starts executing now .. */ (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, 0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); @@ -617,11 +521,23 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* update board state */ dev_context->dw_brd_state = BRD_RUNNING; - /* (void)chnlsm_enable_interrupt(dev_context); */ + return 0; } else { dev_context->dw_brd_state = BRD_UNKNOWN; } } + + while (tlb_i--) { + if (!tlb[tlb_i].ul_gpp_pa) + continue; + iommu_kunmap(mmu, tlb[tlb_i].ul_gpp_va); + } + while (l4_i--) + iommu_kunmap(mmu, l4_peripheral_table[l4_i].dsp_virt_addr); + if (sg0_da) + iommu_kunmap(mmu, sg0_da); + if (sg1_da) + iommu_kunmap(mmu, sg1_da); return status; } @@ -637,8 +553,9 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt) { int status = 0; struct bridge_dev_context *dev_context = dev_ctxt; - struct pg_table_attrs *pt_attrs; u32 dsp_pwr_state; + int i; + struct bridge_ioctl_extproc *tlb = dev_context->atlb_entry; struct omap_dsp_platform_data *pdata = omap_dspbridge_dev->dev.platform_data; @@ -674,23 +591,37 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt) dsp_wdt_enable(false); - /* This is a good place to clear the MMU page tables as well */ - if (dev_context->pt_attrs) { - pt_attrs = dev_context->pt_attrs; - memset((u8 *) pt_attrs->l1_base_va, 0x00, pt_attrs->l1_size); - memset((u8 *) pt_attrs->l2_base_va, 0x00, pt_attrs->l2_size); - memset((u8 *) pt_attrs->pg_info, 0x00, - (pt_attrs->l2_num_pages * sizeof(struct page_info))); - } + /* Reset DSP */ + (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, + OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); + /* Disable the mailbox interrupts */ if (dev_context->mbox) { omap_mbox_disable_irq(dev_context->mbox, IRQ_RX); omap_mbox_put(dev_context->mbox); dev_context->mbox = NULL; } - /* Reset IVA2 clocks*/ - (*pdata->dsp_prm_write)(OMAP3430_RST1_IVA2_MASK | OMAP3430_RST2_IVA2_MASK | - OMAP3430_RST3_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); + if (dev_context->dsp_mmu) { + pr_err("Proc stop mmu if statement\n"); + for (i = 0; i < BRDIOCTL_NUMOFMMUTLB; i++) { + if (!tlb[i].ul_gpp_pa) + continue; + iommu_kunmap(dev_context->dsp_mmu, tlb[i].ul_gpp_va); + } + i = 0; + while (l4_peripheral_table[i].phys_addr) { + iommu_kunmap(dev_context->dsp_mmu, + l4_peripheral_table[i].dsp_virt_addr); + i++; + } + iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg0_da); + iommu_kunmap(dev_context->dsp_mmu, dev_context->sh_s.seg1_da); + dsp_mmu_exit(dev_context->dsp_mmu); + dev_context->dsp_mmu = NULL; + } + /* Reset IVA IOMMU*/ + (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST2_IVA2_MASK, + OMAP3430_RST2_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); dsp_clock_disable_all(dev_context->dsp_per_clks); dsp_clk_disable(DSP_CLK_IVA2); @@ -750,10 +681,6 @@ static int bridge_dev_create(struct bridge_dev_context struct bridge_dev_context *dev_context = NULL; s32 entry_ndx; struct cfg_hostres *resources = config_param; - struct pg_table_attrs *pt_attrs; - u32 pg_tbl_pa; - u32 pg_tbl_va; - u32 align_size; struct drv_data *drv_datap = dev_get_drvdata(bridge); /* Allocate and initialize a data structure to contain the bridge driver @@ -784,97 +711,8 @@ static int bridge_dev_create(struct bridge_dev_context if (!dev_context->dw_dsp_base_addr) status = -EPERM; - pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL); - if (pt_attrs != NULL) { - /* Assuming that we use only DSP's memory map - * until 0x4000:0000 , we would need only 1024 - * L1 enties i.e L1 size = 4K */ - pt_attrs->l1_size = 0x1000; - align_size = pt_attrs->l1_size; - /* Align sizes are expected to be power of 2 */ - /* we like to get aligned on L1 table size */ - pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l1_size, - align_size, &pg_tbl_pa); - - /* Check if the PA is aligned for us */ - if ((pg_tbl_pa) & (align_size - 1)) { - /* PA not aligned to page table size , - * try with more allocation and align */ - mem_free_phys_mem((void *)pg_tbl_va, pg_tbl_pa, - pt_attrs->l1_size); - /* we like to get aligned on L1 table size */ - pg_tbl_va = - (u32) mem_alloc_phys_mem((pt_attrs->l1_size) * 2, - align_size, &pg_tbl_pa); - /* We should be able to get aligned table now */ - pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l1_tbl_alloc_va = pg_tbl_va; - pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size * 2; - /* Align the PA to the next 'align' boundary */ - pt_attrs->l1_base_pa = - ((pg_tbl_pa) + - (align_size - 1)) & (~(align_size - 1)); - pt_attrs->l1_base_va = - pg_tbl_va + (pt_attrs->l1_base_pa - pg_tbl_pa); - } else { - /* We got aligned PA, cool */ - pt_attrs->l1_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l1_tbl_alloc_va = pg_tbl_va; - pt_attrs->l1_tbl_alloc_sz = pt_attrs->l1_size; - pt_attrs->l1_base_pa = pg_tbl_pa; - pt_attrs->l1_base_va = pg_tbl_va; - } - if (pt_attrs->l1_base_va) - memset((u8 *) pt_attrs->l1_base_va, 0x00, - pt_attrs->l1_size); - - /* number of L2 page tables = DMM pool used + SHMMEM +EXTMEM + - * L4 pages */ - pt_attrs->l2_num_pages = ((DMMPOOLSIZE >> 20) + 6); - pt_attrs->l2_size = HW_MMU_COARSE_PAGE_SIZE * - pt_attrs->l2_num_pages; - align_size = 4; /* Make it u32 aligned */ - /* we like to get aligned on L1 table size */ - pg_tbl_va = (u32) mem_alloc_phys_mem(pt_attrs->l2_size, - align_size, &pg_tbl_pa); - pt_attrs->l2_tbl_alloc_pa = pg_tbl_pa; - pt_attrs->l2_tbl_alloc_va = pg_tbl_va; - pt_attrs->l2_tbl_alloc_sz = pt_attrs->l2_size; - pt_attrs->l2_base_pa = pg_tbl_pa; - pt_attrs->l2_base_va = pg_tbl_va; - - if (pt_attrs->l2_base_va) - memset((u8 *) pt_attrs->l2_base_va, 0x00, - pt_attrs->l2_size); - - pt_attrs->pg_info = kzalloc(pt_attrs->l2_num_pages * - sizeof(struct page_info), GFP_KERNEL); - dev_dbg(bridge, - "L1 pa %x, va %x, size %x\n L2 pa %x, va " - "%x, size %x\n", pt_attrs->l1_base_pa, - pt_attrs->l1_base_va, pt_attrs->l1_size, - pt_attrs->l2_base_pa, pt_attrs->l2_base_va, - pt_attrs->l2_size); - dev_dbg(bridge, "pt_attrs %p L2 NumPages %x pg_info %p\n", - pt_attrs, pt_attrs->l2_num_pages, pt_attrs->pg_info); - } - if ((pt_attrs != NULL) && (pt_attrs->l1_base_va != 0) && - (pt_attrs->l2_base_va != 0) && (pt_attrs->pg_info != NULL)) - dev_context->pt_attrs = pt_attrs; - else - status = -ENOMEM; - if (!status) { - spin_lock_init(&pt_attrs->pg_lock); dev_context->tc_word_swap_on = drv_datap->tc_wordswapon; - - /* Set the Clock Divisor for the DSP module */ - udelay(5); - /* MMU address is obtained from the host - * resources struct */ - dev_context->dw_dsp_mmu_base = resources->dw_dmmu_base; - } - if (!status) { dev_context->hdev_obj = hdev_obj; /* Store current board state. */ dev_context->dw_brd_state = BRD_UNKNOWN; @@ -884,23 +722,6 @@ static int bridge_dev_create(struct bridge_dev_context /* Return ptr to our device state to the DSP API for storage */ *dev_cntxt = dev_context; } else { - if (pt_attrs != NULL) { - kfree(pt_attrs->pg_info); - - if (pt_attrs->l2_tbl_alloc_va) { - mem_free_phys_mem((void *) - pt_attrs->l2_tbl_alloc_va, - pt_attrs->l2_tbl_alloc_pa, - pt_attrs->l2_tbl_alloc_sz); - } - if (pt_attrs->l1_tbl_alloc_va) { - mem_free_phys_mem((void *) - pt_attrs->l1_tbl_alloc_va, - pt_attrs->l1_tbl_alloc_pa, - pt_attrs->l1_tbl_alloc_sz); - } - } - kfree(pt_attrs); kfree(dev_context); } func_end: @@ -968,7 +789,6 @@ static int bridge_dev_ctrl(struct bridge_dev_context *dev_context, */ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) { - struct pg_table_attrs *pt_attrs; int status = 0; struct bridge_dev_context *dev_context = (struct bridge_dev_context *) dev_ctxt; @@ -982,23 +802,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) /* first put the device to stop state */ bridge_brd_stop(dev_context); - if (dev_context->pt_attrs) { - pt_attrs = dev_context->pt_attrs; - kfree(pt_attrs->pg_info); - - if (pt_attrs->l2_tbl_alloc_va) { - mem_free_phys_mem((void *)pt_attrs->l2_tbl_alloc_va, - pt_attrs->l2_tbl_alloc_pa, - pt_attrs->l2_tbl_alloc_sz); - } - if (pt_attrs->l1_tbl_alloc_va) { - mem_free_phys_mem((void *)pt_attrs->l1_tbl_alloc_va, - pt_attrs->l1_tbl_alloc_pa, - pt_attrs->l1_tbl_alloc_sz); - } - kfree(pt_attrs); - - } if (dev_context->resources) { host_res = dev_context->resources; @@ -1029,8 +832,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) iounmap((void *)host_res->dw_mem_base[3]); if (host_res->dw_mem_base[4]) iounmap((void *)host_res->dw_mem_base[4]); - if (host_res->dw_dmmu_base) - iounmap(host_res->dw_dmmu_base); if (host_res->dw_per_base) iounmap(host_res->dw_per_base); if (host_res->dw_per_pm_base) @@ -1044,7 +845,6 @@ static int bridge_dev_destroy(struct bridge_dev_context *dev_ctxt) host_res->dw_mem_base[2] = (u32) NULL; host_res->dw_mem_base[3] = (u32) NULL; host_res->dw_mem_base[4] = (u32) NULL; - host_res->dw_dmmu_base = NULL; host_res->dw_sys_ctrl_base = NULL; kfree(host_res); @@ -1127,673 +927,6 @@ static int bridge_brd_mem_write(struct bridge_dev_context *dev_ctxt, return status; } -/* - * ======== bridge_brd_mem_map ======== - * This function maps MPU buffer to the DSP address space. It performs - * linear to physical address translation if required. It translates each - * page since linear addresses can be physically non-contiguous - * All address & size arguments are assumed to be page aligned (in proc.c) - * - * TODO: Disable MMU while updating the page tables (but that'll stall DSP) - */ -static int bridge_brd_mem_map(struct bridge_dev_context *dev_ctxt, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, u32 ul_map_attr, - struct page **mapped_pages) -{ - u32 attrs; - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - struct hw_mmu_map_attrs_t hw_attrs; - struct vm_area_struct *vma; - struct mm_struct *mm = current->mm; - u32 write = 0; - u32 num_usr_pgs = 0; - struct page *mapped_page, *pg; - s32 pg_num; - u32 va = virt_addr; - struct task_struct *curr_task = current; - u32 pg_i = 0; - u32 mpu_addr, pa; - - dev_dbg(bridge, - "%s hDevCtxt %p, pa %x, va %x, size %x, ul_map_attr %x\n", - __func__, dev_ctxt, ul_mpu_addr, virt_addr, ul_num_bytes, - ul_map_attr); - if (ul_num_bytes == 0) - return -EINVAL; - - if (ul_map_attr & DSP_MAP_DIR_MASK) { - attrs = ul_map_attr; - } else { - /* Assign default attributes */ - attrs = ul_map_attr | (DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE16); - } - /* Take mapping properties */ - if (attrs & DSP_MAPBIGENDIAN) - hw_attrs.endianism = HW_BIG_ENDIAN; - else - hw_attrs.endianism = HW_LITTLE_ENDIAN; - - hw_attrs.mixed_size = (enum hw_mmu_mixed_size_t) - ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2); - /* Ignore element_size if mixed_size is enabled */ - if (hw_attrs.mixed_size == 0) { - if (attrs & DSP_MAPELEMSIZE8) { - /* Size is 8 bit */ - hw_attrs.element_size = HW_ELEM_SIZE8BIT; - } else if (attrs & DSP_MAPELEMSIZE16) { - /* Size is 16 bit */ - hw_attrs.element_size = HW_ELEM_SIZE16BIT; - } else if (attrs & DSP_MAPELEMSIZE32) { - /* Size is 32 bit */ - hw_attrs.element_size = HW_ELEM_SIZE32BIT; - } else if (attrs & DSP_MAPELEMSIZE64) { - /* Size is 64 bit */ - hw_attrs.element_size = HW_ELEM_SIZE64BIT; - } else { - /* - * Mixedsize isn't enabled, so size can't be - * zero here - */ - return -EINVAL; - } - } - if (attrs & DSP_MAPDONOTLOCK) - hw_attrs.donotlockmpupage = 1; - else - hw_attrs.donotlockmpupage = 0; - - if (attrs & DSP_MAPVMALLOCADDR) { - return mem_map_vmalloc(dev_ctxt, ul_mpu_addr, virt_addr, - ul_num_bytes, &hw_attrs); - } - /* - * Do OS-specific user-va to pa translation. - * Combine physically contiguous regions to reduce TLBs. - * Pass the translated pa to pte_update. - */ - if ((attrs & DSP_MAPPHYSICALADDR)) { - status = pte_update(dev_context, ul_mpu_addr, virt_addr, - ul_num_bytes, &hw_attrs); - goto func_cont; - } - - /* - * Important Note: ul_mpu_addr is mapped from user application process - * to current process - it must lie completely within the current - * virtual memory address space in order to be of use to us here! - */ - down_read(&mm->mmap_sem); - vma = find_vma(mm, ul_mpu_addr); - if (vma) - dev_dbg(bridge, - "VMAfor UserBuf: ul_mpu_addr=%x, ul_num_bytes=%x, " - "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr, - ul_num_bytes, vma->vm_start, vma->vm_end, - vma->vm_flags); - - /* - * It is observed that under some circumstances, the user buffer is - * spread across several VMAs. So loop through and check if the entire - * user buffer is covered - */ - while ((vma) && (ul_mpu_addr + ul_num_bytes > vma->vm_end)) { - /* jump to the next VMA region */ - vma = find_vma(mm, vma->vm_end + 1); - dev_dbg(bridge, - "VMA for UserBuf ul_mpu_addr=%x ul_num_bytes=%x, " - "vm_start=%lx, vm_end=%lx, vm_flags=%lx\n", ul_mpu_addr, - ul_num_bytes, vma->vm_start, vma->vm_end, - vma->vm_flags); - } - if (!vma) { - pr_err("%s: Failed to get VMA region for 0x%x (%d)\n", - __func__, ul_mpu_addr, ul_num_bytes); - status = -EINVAL; - up_read(&mm->mmap_sem); - goto func_cont; - } - - if (vma->vm_flags & VM_IO) { - num_usr_pgs = ul_num_bytes / PG_SIZE4K; - mpu_addr = ul_mpu_addr; - - /* Get the physical addresses for user buffer */ - for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) { - pa = user_va2_pa(mm, mpu_addr); - if (!pa) { - status = -EPERM; - pr_err("DSPBRIDGE: VM_IO mapping physical" - "address is invalid\n"); - break; - } - if (pfn_valid(__phys_to_pfn(pa))) { - pg = PHYS_TO_PAGE(pa); - get_page(pg); - if (page_count(pg) < 1) { - pr_err("Bad page in VM_IO buffer\n"); - bad_page_dump(pa, pg); - } - } - status = pte_set(dev_context->pt_attrs, pa, - va, HW_PAGE_SIZE4KB, &hw_attrs); - if (status) - break; - - va += HW_PAGE_SIZE4KB; - mpu_addr += HW_PAGE_SIZE4KB; - pa += HW_PAGE_SIZE4KB; - } - } else { - num_usr_pgs = ul_num_bytes / PG_SIZE4K; - if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) - write = 1; - - for (pg_i = 0; pg_i < num_usr_pgs; pg_i++) { - pg_num = get_user_pages(curr_task, mm, ul_mpu_addr, 1, - write, 1, &mapped_page, NULL); - if (pg_num > 0) { - if (page_count(mapped_page) < 1) { - pr_err("Bad page count after doing" - "get_user_pages on" - "user buffer\n"); - bad_page_dump(page_to_phys(mapped_page), - mapped_page); - } - status = pte_set(dev_context->pt_attrs, - page_to_phys(mapped_page), va, - HW_PAGE_SIZE4KB, &hw_attrs); - if (status) - break; - - if (mapped_pages) - mapped_pages[pg_i] = mapped_page; - - va += HW_PAGE_SIZE4KB; - ul_mpu_addr += HW_PAGE_SIZE4KB; - } else { - pr_err("DSPBRIDGE: get_user_pages FAILED," - "MPU addr = 0x%x," - "vma->vm_flags = 0x%lx," - "get_user_pages Err" - "Value = %d, Buffer" - "size=0x%x\n", ul_mpu_addr, - vma->vm_flags, pg_num, ul_num_bytes); - status = -EPERM; - break; - } - } - } - up_read(&mm->mmap_sem); -func_cont: - if (status) { - /* - * Roll out the mapped pages incase it failed in middle of - * mapping - */ - if (pg_i) { - bridge_brd_mem_un_map(dev_context, virt_addr, - (pg_i * PG_SIZE4K)); - } - status = -EPERM; - } - /* - * In any case, flush the TLB - * This is called from here instead from pte_update to avoid unnecessary - * repetition while mapping non-contiguous physical regions of a virtual - * region - */ - flush_all(dev_context); - dev_dbg(bridge, "%s status %x\n", __func__, status); - return status; -} - -/* - * ======== bridge_brd_mem_un_map ======== - * Invalidate the PTEs for the DSP VA block to be unmapped. - * - * PTEs of a mapped memory block are contiguous in any page table - * So, instead of looking up the PTE address for every 4K block, - * we clear consecutive PTEs until we unmap all the bytes - */ -static int bridge_brd_mem_un_map(struct bridge_dev_context *dev_ctxt, - u32 virt_addr, u32 ul_num_bytes) -{ - u32 l1_base_va; - u32 l2_base_va; - u32 l2_base_pa; - u32 l2_page_num; - u32 pte_val; - u32 pte_size; - u32 pte_count; - u32 pte_addr_l1; - u32 pte_addr_l2 = 0; - u32 rem_bytes; - u32 rem_bytes_l2; - u32 va_curr; - struct page *pg = NULL; - int status = 0; - struct bridge_dev_context *dev_context = dev_ctxt; - struct pg_table_attrs *pt = dev_context->pt_attrs; - u32 temp; - u32 paddr; - u32 numof4k_pages = 0; - - va_curr = virt_addr; - rem_bytes = ul_num_bytes; - rem_bytes_l2 = 0; - l1_base_va = pt->l1_base_va; - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr); - dev_dbg(bridge, "%s dev_ctxt %p, va %x, NumBytes %x l1_base_va %x, " - "pte_addr_l1 %x\n", __func__, dev_ctxt, virt_addr, - ul_num_bytes, l1_base_va, pte_addr_l1); - - while (rem_bytes && !status) { - u32 va_curr_orig = va_curr; - /* Find whether the L1 PTE points to a valid L2 PT */ - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va_curr); - pte_val = *(u32 *) pte_addr_l1; - pte_size = hw_mmu_pte_size_l1(pte_val); - - if (pte_size != HW_MMU_COARSE_PAGE_SIZE) - goto skip_coarse_page; - - /* - * Get the L2 PA from the L1 PTE, and find - * corresponding L2 VA - */ - l2_base_pa = hw_mmu_pte_coarse_l1(pte_val); - l2_base_va = l2_base_pa - pt->l2_base_pa + pt->l2_base_va; - l2_page_num = - (l2_base_pa - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE; - /* - * Find the L2 PTE address from which we will start - * clearing, the number of PTEs to be cleared on this - * page, and the size of VA space that needs to be - * cleared on this L2 page - */ - pte_addr_l2 = hw_mmu_pte_addr_l2(l2_base_va, va_curr); - pte_count = pte_addr_l2 & (HW_MMU_COARSE_PAGE_SIZE - 1); - pte_count = (HW_MMU_COARSE_PAGE_SIZE - pte_count) / sizeof(u32); - if (rem_bytes < (pte_count * PG_SIZE4K)) - pte_count = rem_bytes / PG_SIZE4K; - rem_bytes_l2 = pte_count * PG_SIZE4K; - - /* - * Unmap the VA space on this L2 PT. A quicker way - * would be to clear pte_count entries starting from - * pte_addr_l2. However, below code checks that we don't - * clear invalid entries or less than 64KB for a 64KB - * entry. Similar checking is done for L1 PTEs too - * below - */ - while (rem_bytes_l2 && !status) { - pte_val = *(u32 *) pte_addr_l2; - pte_size = hw_mmu_pte_size_l2(pte_val); - /* va_curr aligned to pte_size? */ - if (pte_size == 0 || rem_bytes_l2 < pte_size || - va_curr & (pte_size - 1)) { - status = -EPERM; - break; - } - - /* Collect Physical addresses from VA */ - paddr = (pte_val & ~(pte_size - 1)); - if (pte_size == HW_PAGE_SIZE64KB) - numof4k_pages = 16; - else - numof4k_pages = 1; - temp = 0; - while (temp++ < numof4k_pages) { - if (!pfn_valid(__phys_to_pfn(paddr))) { - paddr += HW_PAGE_SIZE4KB; - continue; - } - pg = PHYS_TO_PAGE(paddr); - if (page_count(pg) < 1) { - pr_info("DSPBRIDGE: UNMAP function: " - "COUNT 0 FOR PA 0x%x, size = " - "0x%x\n", paddr, ul_num_bytes); - bad_page_dump(paddr, pg); - } else { - set_page_dirty(pg); - page_cache_release(pg); - } - paddr += HW_PAGE_SIZE4KB; - } - if (hw_mmu_pte_clear(pte_addr_l2, va_curr, pte_size)) { - status = -EPERM; - goto EXIT_LOOP; - } - - status = 0; - rem_bytes_l2 -= pte_size; - va_curr += pte_size; - pte_addr_l2 += (pte_size >> 12) * sizeof(u32); - } - spin_lock(&pt->pg_lock); - if (rem_bytes_l2 == 0) { - pt->pg_info[l2_page_num].num_entries -= pte_count; - if (pt->pg_info[l2_page_num].num_entries == 0) { - /* - * Clear the L1 PTE pointing to the L2 PT - */ - if (!hw_mmu_pte_clear(l1_base_va, va_curr_orig, - HW_MMU_COARSE_PAGE_SIZE)) - status = 0; - else { - status = -EPERM; - spin_unlock(&pt->pg_lock); - goto EXIT_LOOP; - } - } - rem_bytes -= pte_count * PG_SIZE4K; - } else - status = -EPERM; - - spin_unlock(&pt->pg_lock); - continue; -skip_coarse_page: - /* va_curr aligned to pte_size? */ - /* pte_size = 1 MB or 16 MB */ - if (pte_size == 0 || rem_bytes < pte_size || - va_curr & (pte_size - 1)) { - status = -EPERM; - break; - } - - if (pte_size == HW_PAGE_SIZE1MB) - numof4k_pages = 256; - else - numof4k_pages = 4096; - temp = 0; - /* Collect Physical addresses from VA */ - paddr = (pte_val & ~(pte_size - 1)); - while (temp++ < numof4k_pages) { - if (pfn_valid(__phys_to_pfn(paddr))) { - pg = PHYS_TO_PAGE(paddr); - if (page_count(pg) < 1) { - pr_info("DSPBRIDGE: UNMAP function: " - "COUNT 0 FOR PA 0x%x, size = " - "0x%x\n", paddr, ul_num_bytes); - bad_page_dump(paddr, pg); - } else { - set_page_dirty(pg); - page_cache_release(pg); - } - } - paddr += HW_PAGE_SIZE4KB; - } - if (!hw_mmu_pte_clear(l1_base_va, va_curr, pte_size)) { - status = 0; - rem_bytes -= pte_size; - va_curr += pte_size; - } else { - status = -EPERM; - goto EXIT_LOOP; - } - } - /* - * It is better to flush the TLB here, so that any stale old entries - * get flushed - */ -EXIT_LOOP: - flush_all(dev_context); - dev_dbg(bridge, - "%s: va_curr %x, pte_addr_l1 %x pte_addr_l2 %x rem_bytes %x," - " rem_bytes_l2 %x status %x\n", __func__, va_curr, pte_addr_l1, - pte_addr_l2, rem_bytes, rem_bytes_l2, status); - return status; -} - -/* - * ======== user_va2_pa ======== - * Purpose: - * This function walks through the page tables to convert a userland - * virtual address to physical address - */ -static u32 user_va2_pa(struct mm_struct *mm, u32 address) -{ - pgd_t *pgd; - pmd_t *pmd; - pte_t *ptep, pte; - - pgd = pgd_offset(mm, address); - if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { - pmd = pmd_offset(pgd, address); - if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { - ptep = pte_offset_map(pmd, address); - if (ptep) { - pte = *ptep; - if (pte_present(pte)) - return pte & PAGE_MASK; - } - } - } - - return 0; -} - -/* - * ======== pte_update ======== - * This function calculates the optimum page-aligned addresses and sizes - * Caller must pass page-aligned values - */ -static int pte_update(struct bridge_dev_context *dev_ctxt, u32 pa, - u32 va, u32 size, - struct hw_mmu_map_attrs_t *map_attrs) -{ - u32 i; - u32 all_bits; - u32 pa_curr = pa; - u32 va_curr = va; - u32 num_bytes = size; - struct bridge_dev_context *dev_context = dev_ctxt; - int status = 0; - u32 page_size[] = { HW_PAGE_SIZE16MB, HW_PAGE_SIZE1MB, - HW_PAGE_SIZE64KB, HW_PAGE_SIZE4KB - }; - - while (num_bytes && !status) { - /* To find the max. page size with which both PA & VA are - * aligned */ - all_bits = pa_curr | va_curr; - - for (i = 0; i < 4; i++) { - if ((num_bytes >= page_size[i]) && ((all_bits & - (page_size[i] - - 1)) == 0)) { - status = - pte_set(dev_context->pt_attrs, pa_curr, - va_curr, page_size[i], map_attrs); - pa_curr += page_size[i]; - va_curr += page_size[i]; - num_bytes -= page_size[i]; - /* Don't try smaller sizes. Hopefully we have - * reached an address aligned to a bigger page - * size */ - break; - } - } - } - - return status; -} - -/* - * ======== pte_set ======== - * This function calculates PTE address (MPU virtual) to be updated - * It also manages the L2 page tables - */ -static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, - u32 size, struct hw_mmu_map_attrs_t *attrs) -{ - u32 i; - u32 pte_val; - u32 pte_addr_l1; - u32 pte_size; - /* Base address of the PT that will be updated */ - u32 pg_tbl_va; - u32 l1_base_va; - /* Compiler warns that the next three variables might be used - * uninitialized in this function. Doesn't seem so. Working around, - * anyways. */ - u32 l2_base_va = 0; - u32 l2_base_pa = 0; - u32 l2_page_num = 0; - int status = 0; - - l1_base_va = pt->l1_base_va; - pg_tbl_va = l1_base_va; - if ((size == HW_PAGE_SIZE64KB) || (size == HW_PAGE_SIZE4KB)) { - /* Find whether the L1 PTE points to a valid L2 PT */ - pte_addr_l1 = hw_mmu_pte_addr_l1(l1_base_va, va); - if (pte_addr_l1 <= (pt->l1_base_va + pt->l1_size)) { - pte_val = *(u32 *) pte_addr_l1; - pte_size = hw_mmu_pte_size_l1(pte_val); - } else { - return -EPERM; - } - spin_lock(&pt->pg_lock); - if (pte_size == HW_MMU_COARSE_PAGE_SIZE) { - /* Get the L2 PA from the L1 PTE, and find - * corresponding L2 VA */ - l2_base_pa = hw_mmu_pte_coarse_l1(pte_val); - l2_base_va = - l2_base_pa - pt->l2_base_pa + pt->l2_base_va; - l2_page_num = - (l2_base_pa - - pt->l2_base_pa) / HW_MMU_COARSE_PAGE_SIZE; - } else if (pte_size == 0) { - /* L1 PTE is invalid. Allocate a L2 PT and - * point the L1 PTE to it */ - /* Find a free L2 PT. */ - for (i = 0; (i < pt->l2_num_pages) && - (pt->pg_info[i].num_entries != 0); i++) - ;; - if (i < pt->l2_num_pages) { - l2_page_num = i; - l2_base_pa = pt->l2_base_pa + (l2_page_num * - HW_MMU_COARSE_PAGE_SIZE); - l2_base_va = pt->l2_base_va + (l2_page_num * - HW_MMU_COARSE_PAGE_SIZE); - /* Endianness attributes are ignored for - * HW_MMU_COARSE_PAGE_SIZE */ - status = - hw_mmu_pte_set(l1_base_va, l2_base_pa, va, - HW_MMU_COARSE_PAGE_SIZE, - attrs); - } else { - status = -ENOMEM; - } - } else { - /* Found valid L1 PTE of another size. - * Should not overwrite it. */ - status = -EPERM; - } - if (!status) { - pg_tbl_va = l2_base_va; - if (size == HW_PAGE_SIZE64KB) - pt->pg_info[l2_page_num].num_entries += 16; - else - pt->pg_info[l2_page_num].num_entries++; - dev_dbg(bridge, "PTE: L2 BaseVa %x, BasePa %x, PageNum " - "%x, num_entries %x\n", l2_base_va, - l2_base_pa, l2_page_num, - pt->pg_info[l2_page_num].num_entries); - } - spin_unlock(&pt->pg_lock); - } - if (!status) { - dev_dbg(bridge, "PTE: pg_tbl_va %x, pa %x, va %x, size %x\n", - pg_tbl_va, pa, va, size); - dev_dbg(bridge, "PTE: endianism %x, element_size %x, " - "mixed_size %x\n", attrs->endianism, - attrs->element_size, attrs->mixed_size); - status = hw_mmu_pte_set(pg_tbl_va, pa, va, size, attrs); - } - - return status; -} - -/* Memory map kernel VA -- memory allocated with vmalloc */ -static int mem_map_vmalloc(struct bridge_dev_context *dev_context, - u32 ul_mpu_addr, u32 virt_addr, - u32 ul_num_bytes, - struct hw_mmu_map_attrs_t *hw_attrs) -{ - int status = 0; - struct page *page[1]; - u32 i; - u32 pa_curr; - u32 pa_next; - u32 va_curr; - u32 size_curr; - u32 num_pages; - u32 pa; - u32 num_of4k_pages; - u32 temp = 0; - - /* - * Do Kernel va to pa translation. - * Combine physically contiguous regions to reduce TLBs. - * Pass the translated pa to pte_update. - */ - num_pages = ul_num_bytes / PAGE_SIZE; /* PAGE_SIZE = OS page size */ - i = 0; - va_curr = ul_mpu_addr; - page[0] = vmalloc_to_page((void *)va_curr); - pa_next = page_to_phys(page[0]); - while (!status && (i < num_pages)) { - /* - * Reuse pa_next from the previous iteraion to avoid - * an extra va2pa call - */ - pa_curr = pa_next; - size_curr = PAGE_SIZE; - /* - * If the next page is physically contiguous, - * map it with the current one by increasing - * the size of the region to be mapped - */ - while (++i < num_pages) { - page[0] = - vmalloc_to_page((void *)(va_curr + size_curr)); - pa_next = page_to_phys(page[0]); - - if (pa_next == (pa_curr + size_curr)) - size_curr += PAGE_SIZE; - else - break; - - } - if (pa_next == 0) { - status = -ENOMEM; - break; - } - pa = pa_curr; - num_of4k_pages = size_curr / HW_PAGE_SIZE4KB; - while (temp++ < num_of4k_pages) { - get_page(PHYS_TO_PAGE(pa)); - pa += HW_PAGE_SIZE4KB; - } - status = pte_update(dev_context, pa_curr, virt_addr + - (va_curr - ul_mpu_addr), size_curr, - hw_attrs); - va_curr += size_curr; - } - /* - * In any case, flush the TLB - * This is called from here instead from pte_update to avoid unnecessary - * repetition while mapping non-contiguous physical regions of a virtual - * region - */ - flush_all(dev_context); - dev_dbg(bridge, "%s status %x\n", __func__, status); - return status; -} - /* * ======== wait_for_start ======== * Wait for the singal from DSP that it has started, or time out. diff --git a/trunk/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/trunk/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index fb9026e1403c..b57a9fd5e757 100644 --- a/trunk/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/trunk/drivers/staging/tidspbridge/core/tiomap3430_pwr.c @@ -31,10 +31,6 @@ #include #include -/* ------------------------------------ Hardware Abstraction Layer */ -#include -#include - #include /* ----------------------------------- Bridge Driver */ diff --git a/trunk/drivers/staging/tidspbridge/core/tiomap_io.c b/trunk/drivers/staging/tidspbridge/core/tiomap_io.c index ba2961049dad..66dbf02549e4 100644 --- a/trunk/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/trunk/drivers/staging/tidspbridge/core/tiomap_io.c @@ -134,17 +134,16 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt, if (!status) { ul_tlb_base_virt = - dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE; + dev_context->sh_s.seg0_da * DSPWORDSIZE; DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); - dw_ext_prog_virt_mem = - dev_context->atlb_entry[0].ul_gpp_va; + dw_ext_prog_virt_mem = dev_context->sh_s.seg0_va; if (!trace_read) { ul_shm_offset_virt = ul_shm_base_virt - ul_tlb_base_virt; ul_shm_offset_virt += PG_ALIGN_HIGH(ul_ext_end - ul_dyn_ext_base + - 1, HW_PAGE_SIZE64KB); + 1, PAGE_SIZE * 16); dw_ext_prog_virt_mem -= ul_shm_offset_virt; dw_ext_prog_virt_mem += (ul_ext_base - ul_dyn_ext_base); @@ -318,8 +317,9 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, ret = -EPERM; if (!ret) { - ul_tlb_base_virt = - dev_context->atlb_entry[0].ul_dsp_va * DSPWORDSIZE; + ul_tlb_base_virt = dev_context->sh_s.seg0_da * + DSPWORDSIZE; + DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt); if (symbols_reloaded) { @@ -337,7 +337,7 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context, ul_shm_base_virt - ul_tlb_base_virt; if (trace_load) { dw_ext_prog_virt_mem = - dev_context->atlb_entry[0].ul_gpp_va; + dev_context->sh_s.seg0_va; } else { dw_ext_prog_virt_mem = host_res->dw_mem_base[1]; dw_ext_prog_virt_mem += @@ -393,7 +393,6 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_dspbridge_dev->dev.platform_data; struct cfg_hostres *resources = dev_context->resources; int status = 0; - u32 temp; if (!dev_context->mbox) return 0; @@ -437,7 +436,7 @@ int sm_interrupt_dsp(struct bridge_dev_context *dev_context, u16 mb_val) omap_mbox_restore_ctx(dev_context->mbox); /* Access MMU SYS CONFIG register to generate a short wakeup */ - temp = readl(resources->dw_dmmu_base + 0x10); + iommu_read_reg(dev_context->dsp_mmu, MMU_SYSCONFIG); dev_context->dw_brd_state = BRD_RUNNING; } else if (dev_context->dw_brd_state == BRD_RETENTION) { diff --git a/trunk/drivers/staging/tidspbridge/core/ue_deh.c b/trunk/drivers/staging/tidspbridge/core/ue_deh.c index 3430418190da..e24ea0c73914 100644 --- a/trunk/drivers/staging/tidspbridge/core/ue_deh.c +++ b/trunk/drivers/staging/tidspbridge/core/ue_deh.c @@ -31,57 +31,6 @@ #include #include -static u32 fault_addr; - -static void mmu_fault_dpc(unsigned long data) -{ - struct deh_mgr *deh = (void *)data; - - if (!deh) - return; - - bridge_deh_notify(deh, DSP_MMUFAULT, 0); -} - -static irqreturn_t mmu_fault_isr(int irq, void *data) -{ - struct deh_mgr *deh = data; - struct cfg_hostres *resources; - u32 event; - - if (!deh) - return IRQ_HANDLED; - - resources = deh->hbridge_context->resources; - if (!resources) { - dev_dbg(bridge, "%s: Failed to get Host Resources\n", - __func__); - return IRQ_HANDLED; - } - - hw_mmu_event_status(resources->dw_dmmu_base, &event); - if (event == HW_MMU_TRANSLATION_FAULT) { - hw_mmu_fault_addr_read(resources->dw_dmmu_base, &fault_addr); - dev_dbg(bridge, "%s: event=0x%x, fault_addr=0x%x\n", __func__, - event, fault_addr); - /* - * Schedule a DPC directly. In the future, it may be - * necessary to check if DSP MMU fault is intended for - * Bridge. - */ - tasklet_schedule(&deh->dpc_tasklet); - - /* Disable the MMU events, else once we clear it will - * start to raise INTs again */ - hw_mmu_event_disable(resources->dw_dmmu_base, - HW_MMU_TRANSLATION_FAULT); - } else { - hw_mmu_event_disable(resources->dw_dmmu_base, - HW_MMU_ALL_INTERRUPTS); - } - return IRQ_HANDLED; -} - int bridge_deh_create(struct deh_mgr **ret_deh, struct dev_object *hdev_obj) { @@ -109,18 +58,9 @@ int bridge_deh_create(struct deh_mgr **ret_deh, } ntfy_init(deh->ntfy_obj); - /* Create a MMUfault DPC */ - tasklet_init(&deh->dpc_tasklet, mmu_fault_dpc, (u32) deh); - /* Fill in context structure */ deh->hbridge_context = hbridge_context; - /* Install ISR function for DSP MMU fault */ - status = request_irq(INT_DSP_MMU_IRQ, mmu_fault_isr, 0, - "DspBridge\tiommu fault", deh); - if (status < 0) - goto err; - *ret_deh = deh; return 0; @@ -140,11 +80,6 @@ int bridge_deh_destroy(struct deh_mgr *deh) ntfy_delete(deh->ntfy_obj); kfree(deh->ntfy_obj); } - /* Disable DSP MMU fault */ - free_irq(INT_DSP_MMU_IRQ, deh); - - /* Free DPC object */ - tasklet_kill(&deh->dpc_tasklet); /* Deallocate the DEH manager object */ kfree(deh); @@ -166,48 +101,6 @@ int bridge_deh_register_notify(struct deh_mgr *deh, u32 event_mask, return ntfy_unregister(deh->ntfy_obj, hnotification); } -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE -static void mmu_fault_print_stack(struct bridge_dev_context *dev_context) -{ - struct cfg_hostres *resources; - struct hw_mmu_map_attrs_t map_attrs = { - .endianism = HW_LITTLE_ENDIAN, - .element_size = HW_ELEM_SIZE16BIT, - .mixed_size = HW_MMU_CPUES, - }; - void *dummy_va_addr; - - resources = dev_context->resources; - dummy_va_addr = (void*)__get_free_page(GFP_ATOMIC); - - /* - * Before acking the MMU fault, let's make sure MMU can only - * access entry #0. Then add a new entry so that the DSP OS - * can continue in order to dump the stack. - */ - hw_mmu_twl_disable(resources->dw_dmmu_base); - hw_mmu_tlb_flush_all(resources->dw_dmmu_base); - - hw_mmu_tlb_add(resources->dw_dmmu_base, - virt_to_phys(dummy_va_addr), fault_addr, - HW_PAGE_SIZE4KB, 1, - &map_attrs, HW_SET, HW_SET); - - dsp_clk_enable(DSP_CLK_GPT8); - - dsp_gpt_wait_overflow(DSP_CLK_GPT8, 0xfffffffe); - - /* Clear MMU interrupt */ - hw_mmu_event_ack(resources->dw_dmmu_base, - HW_MMU_TRANSLATION_FAULT); - dump_dsp_stack(dev_context); - dsp_clk_disable(DSP_CLK_GPT8); - - hw_mmu_disable(resources->dw_dmmu_base); - free_page((unsigned long)dummy_va_addr); -} -#endif - static inline const char *event_to_string(int event) { switch (event) { @@ -240,13 +133,7 @@ void bridge_deh_notify(struct deh_mgr *deh, int event, int info) #endif break; case DSP_MMUFAULT: - dev_err(bridge, "%s: %s, addr=0x%x", __func__, - str, fault_addr); -#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE - print_dsp_trace_buffer(dev_context); - dump_dl_modules(dev_context); - mmu_fault_print_stack(dev_context); -#endif + dev_err(bridge, "%s: %s, addr=0x%x", __func__, str, info); break; default: dev_err(bridge, "%s: %s", __func__, str); diff --git a/trunk/drivers/staging/tidspbridge/hw/EasiGlobal.h b/trunk/drivers/staging/tidspbridge/hw/EasiGlobal.h deleted file mode 100644 index e48d7f67c60a..000000000000 --- a/trunk/drivers/staging/tidspbridge/hw/EasiGlobal.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * EasiGlobal.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _EASIGLOBAL_H -#define _EASIGLOBAL_H -#include - -/* - * DEFINE: READ_ONLY, WRITE_ONLY & READ_WRITE - * - * DESCRIPTION: Defines used to describe register types for EASI-checker tests. - */ - -#define READ_ONLY 1 -#define WRITE_ONLY 2 -#define READ_WRITE 3 - -/* - * MACRO: _DEBUG_LEVEL1_EASI - * - * DESCRIPTION: A MACRO which can be used to indicate that a particular beach - * register access function was called. - * - * NOTE: We currently dont use this functionality. - */ -#define _DEBUG_LEVEL1_EASI(easi_num) ((void)0) - -#endif /* _EASIGLOBAL_H */ diff --git a/trunk/drivers/staging/tidspbridge/hw/MMUAccInt.h b/trunk/drivers/staging/tidspbridge/hw/MMUAccInt.h deleted file mode 100644 index 1cefca321d71..000000000000 --- a/trunk/drivers/staging/tidspbridge/hw/MMUAccInt.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * MMUAccInt.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _MMU_ACC_INT_H -#define _MMU_ACC_INT_H - -/* Mappings of level 1 EASI function numbers to function names */ - -#define EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32 (MMU_BASE_EASIL1 + 3) -#define EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32 (MMU_BASE_EASIL1 + 17) -#define EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32 (MMU_BASE_EASIL1 + 39) -#define EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 51) -#define EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32 (MMU_BASE_EASIL1 + 102) -#define EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 103) -#define EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32 (MMU_BASE_EASIL1 + 156) -#define EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32 (MMU_BASE_EASIL1 + 174) -#define EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 180) -#define EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32 (MMU_BASE_EASIL1 + 190) -#define EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32 (MMU_BASE_EASIL1 + 194) -#define EASIL1_MMUMMU_TTB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 198) -#define EASIL1_MMUMMU_LOCK_READ_REGISTER32 (MMU_BASE_EASIL1 + 203) -#define EASIL1_MMUMMU_LOCK_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 204) -#define EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32 (MMU_BASE_EASIL1 + 205) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32 (MMU_BASE_EASIL1 + 209) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32 (MMU_BASE_EASIL1 + 211) -#define EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32 (MMU_BASE_EASIL1 + 212) -#define EASIL1_MMUMMU_LD_TLB_READ_REGISTER32 (MMU_BASE_EASIL1 + 213) -#define EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 214) -#define EASIL1_MMUMMU_CAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 226) -#define EASIL1_MMUMMU_RAM_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 268) -#define EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32 (MMU_BASE_EASIL1 + 322) - -/* Register offset address definitions */ -#define MMU_MMU_SYSCONFIG_OFFSET 0x10 -#define MMU_MMU_IRQSTATUS_OFFSET 0x18 -#define MMU_MMU_IRQENABLE_OFFSET 0x1c -#define MMU_MMU_WALKING_ST_OFFSET 0x40 -#define MMU_MMU_CNTL_OFFSET 0x44 -#define MMU_MMU_FAULT_AD_OFFSET 0x48 -#define MMU_MMU_TTB_OFFSET 0x4c -#define MMU_MMU_LOCK_OFFSET 0x50 -#define MMU_MMU_LD_TLB_OFFSET 0x54 -#define MMU_MMU_CAM_OFFSET 0x58 -#define MMU_MMU_RAM_OFFSET 0x5c -#define MMU_MMU_GFLUSH_OFFSET 0x60 -#define MMU_MMU_FLUSH_ENTRY_OFFSET 0x64 -/* Bitfield mask and offset declarations */ -#define MMU_MMU_SYSCONFIG_IDLE_MODE_MASK 0x18 -#define MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET 3 -#define MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK 0x1 -#define MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET 0 -#define MMU_MMU_WALKING_ST_TWL_RUNNING_MASK 0x1 -#define MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET 0 -#define MMU_MMU_CNTL_TWL_ENABLE_MASK 0x4 -#define MMU_MMU_CNTL_TWL_ENABLE_OFFSET 2 -#define MMU_MMU_CNTL_MMU_ENABLE_MASK 0x2 -#define MMU_MMU_CNTL_MMU_ENABLE_OFFSET 1 -#define MMU_MMU_LOCK_BASE_VALUE_MASK 0xfc00 -#define MMU_MMU_LOCK_BASE_VALUE_OFFSET 10 -#define MMU_MMU_LOCK_CURRENT_VICTIM_MASK 0x3f0 -#define MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET 4 - -#endif /* _MMU_ACC_INT_H */ diff --git a/trunk/drivers/staging/tidspbridge/hw/MMURegAcM.h b/trunk/drivers/staging/tidspbridge/hw/MMURegAcM.h deleted file mode 100644 index ab1a16da731c..000000000000 --- a/trunk/drivers/staging/tidspbridge/hw/MMURegAcM.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * MMURegAcM.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _MMU_REG_ACM_H -#define _MMU_REG_ACM_H - -#include -#include - -#include "MMUAccInt.h" - -#if defined(USE_LEVEL_1_MACROS) - -#define MMUMMU_SYSCONFIG_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_SYSCONFIG_OFFSET)) - -#define MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_IDLE_MODE_WRITE32);\ - data &= ~(MMU_MMU_SYSCONFIG_IDLE_MODE_MASK);\ - new_value <<= MMU_MMU_SYSCONFIG_IDLE_MODE_OFFSET;\ - new_value &= MMU_MMU_SYSCONFIG_IDLE_MODE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_SYSCONFIG_AUTO_IDLE_WRITE32);\ - data &= ~(MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK);\ - new_value <<= MMU_MMU_SYSCONFIG_AUTO_IDLE_OFFSET;\ - new_value &= MMU_MMU_SYSCONFIG_AUTO_IDLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_IRQSTATUS_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(easil1_mmummu_irqstatus_read_register32),\ - __raw_readl((base_address)+MMU_MMU_IRQSTATUS_OFFSET)) - -#define MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQSTATUS_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_IRQENABLE_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_IRQENABLE_OFFSET)) - -#define MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_IRQENABLE_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_WALKING_STTWL_RUNNING_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_WALKING_STTWL_RUNNING_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_WALKING_ST_OFFSET))))\ - & MMU_MMU_WALKING_ST_TWL_RUNNING_MASK) >>\ - MMU_MMU_WALKING_ST_TWL_RUNNING_OFFSET)) - -#define MMUMMU_CNTLTWL_ENABLE_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_CNTL_OFFSET)))) &\ - MMU_MMU_CNTL_TWL_ENABLE_MASK) >>\ - MMU_MMU_CNTL_TWL_ENABLE_OFFSET)) - -#define MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CNTL_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLTWL_ENABLE_WRITE32);\ - data &= ~(MMU_MMU_CNTL_TWL_ENABLE_MASK);\ - new_value <<= MMU_MMU_CNTL_TWL_ENABLE_OFFSET;\ - new_value &= MMU_MMU_CNTL_TWL_ENABLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CNTL_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CNTLMMU_ENABLE_WRITE32);\ - data &= ~(MMU_MMU_CNTL_MMU_ENABLE_MASK);\ - new_value <<= MMU_MMU_CNTL_MMU_ENABLE_OFFSET;\ - new_value &= MMU_MMU_CNTL_MMU_ENABLE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_FAULT_AD_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FAULT_AD_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_FAULT_AD_OFFSET)) - -#define MMUMMU_TTB_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_TTB_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_TTB_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_LOCK_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_LOCK_OFFSET)) - -#define MMUMMU_LOCK_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_LOCK_BASE_VALUE_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_BASE_VALUE_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\ - MMU_MMU_LOCK_BASE_VALUE_MASK) >>\ - MMU_MMU_LOCK_BASE_VALUE_OFFSET)) - -#define MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(easil1_mmummu_lock_base_value_write32);\ - data &= ~(MMU_MMU_LOCK_BASE_VALUE_MASK);\ - new_value <<= MMU_MMU_LOCK_BASE_VALUE_OFFSET;\ - new_value &= MMU_MMU_LOCK_BASE_VALUE_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_LOCK_CURRENT_VICTIM_READ32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_READ32),\ - (((__raw_readl(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\ - MMU_MMU_LOCK_CURRENT_VICTIM_MASK) >>\ - MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET)) - -#define MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LOCK_OFFSET;\ - register u32 data = __raw_readl((base_address)+offset);\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_WRITE32);\ - data &= ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK);\ - new_value <<= MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET;\ - new_value &= MMU_MMU_LOCK_CURRENT_VICTIM_MASK;\ - new_value |= data;\ - __raw_writel(new_value, base_address+offset);\ -} - -#define MMUMMU_LOCK_CURRENT_VICTIM_SET32(var, value)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LOCK_CURRENT_VICTIM_SET32),\ - (((var) & ~(MMU_MMU_LOCK_CURRENT_VICTIM_MASK)) |\ - (((value) << MMU_MMU_LOCK_CURRENT_VICTIM_OFFSET) &\ - MMU_MMU_LOCK_CURRENT_VICTIM_MASK))) - -#define MMUMMU_LD_TLB_READ_REGISTER32(base_address)\ - (_DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_READ_REGISTER32),\ - __raw_readl((base_address)+MMU_MMU_LD_TLB_OFFSET)) - -#define MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_LD_TLB_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_LD_TLB_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_CAM_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_CAM_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_CAM_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_RAM_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_RAM_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_RAM_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#define MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, value)\ -{\ - const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\ - register u32 new_value = (value);\ - _DEBUG_LEVEL1_EASI(EASIL1_MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32);\ - __raw_writel(new_value, (base_address)+offset);\ -} - -#endif /* USE_LEVEL_1_MACROS */ - -#endif /* _MMU_REG_ACM_H */ diff --git a/trunk/drivers/staging/tidspbridge/hw/hw_defs.h b/trunk/drivers/staging/tidspbridge/hw/hw_defs.h deleted file mode 100644 index d5266d4c163f..000000000000 --- a/trunk/drivers/staging/tidspbridge/hw/hw_defs.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * hw_defs.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Global HW definitions - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _HW_DEFS_H -#define _HW_DEFS_H - -/* Page size */ -#define HW_PAGE_SIZE4KB 0x1000 -#define HW_PAGE_SIZE64KB 0x10000 -#define HW_PAGE_SIZE1MB 0x100000 -#define HW_PAGE_SIZE16MB 0x1000000 - -/* hw_status: return type for HW API */ -typedef long hw_status; - -/* Macro used to set and clear any bit */ -#define HW_CLEAR 0 -#define HW_SET 1 - -/* hw_endianism_t: Enumerated Type used to specify the endianism - * Do NOT change these values. They are used as bit fields. */ -enum hw_endianism_t { - HW_LITTLE_ENDIAN, - HW_BIG_ENDIAN -}; - -/* hw_element_size_t: Enumerated Type used to specify the element size - * Do NOT change these values. They are used as bit fields. */ -enum hw_element_size_t { - HW_ELEM_SIZE8BIT, - HW_ELEM_SIZE16BIT, - HW_ELEM_SIZE32BIT, - HW_ELEM_SIZE64BIT -}; - -/* hw_idle_mode_t: Enumerated Type used to specify Idle modes */ -enum hw_idle_mode_t { - HW_FORCE_IDLE, - HW_NO_IDLE, - HW_SMART_IDLE -}; - -#endif /* _HW_DEFS_H */ diff --git a/trunk/drivers/staging/tidspbridge/hw/hw_mmu.c b/trunk/drivers/staging/tidspbridge/hw/hw_mmu.c deleted file mode 100644 index 014f5d5293ae..000000000000 --- a/trunk/drivers/staging/tidspbridge/hw/hw_mmu.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * hw_mmu.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * API definitions to setup MMU TLB and PTE - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include "MMURegAcM.h" -#include -#include -#include -#include - -#define MMU_BASE_VAL_MASK 0xFC00 -#define MMU_PAGE_MAX 3 -#define MMU_ELEMENTSIZE_MAX 3 -#define MMU_ADDR_MASK 0xFFFFF000 -#define MMU_TTB_MASK 0xFFFFC000 -#define MMU_SECTION_ADDR_MASK 0xFFF00000 -#define MMU_SSECTION_ADDR_MASK 0xFF000000 -#define MMU_PAGE_TABLE_MASK 0xFFFFFC00 -#define MMU_LARGE_PAGE_MASK 0xFFFF0000 -#define MMU_SMALL_PAGE_MASK 0xFFFFF000 - -#define MMU_LOAD_TLB 0x00000001 -#define MMU_GFLUSH 0x60 - -/* - * hw_mmu_page_size_t: Enumerated Type used to specify the MMU Page Size(SLSS) - */ -enum hw_mmu_page_size_t { - HW_MMU_SECTION, - HW_MMU_LARGE_PAGE, - HW_MMU_SMALL_PAGE, - HW_MMU_SUPERSECTION -}; - -/* - * FUNCTION : mmu_flush_entry - * - * INPUTS: - * - * Identifier : base_address - * Type : const u32 - * Description : Base Address of instance of MMU module - * - * RETURNS: - * - * Type : hw_status - * Description : 0 -- No errors occured - * RET_BAD_NULL_PARAM -- A Pointer - * Paramater was set to NULL - * - * PURPOSE: : Flush the TLB entry pointed by the - * lock counter register - * even if this entry is set protected - * - * METHOD: : Check the Input parameter and Flush a - * single entry in the TLB. - */ -static hw_status mmu_flush_entry(const void __iomem *base_address); - -/* - * FUNCTION : mmu_set_cam_entry - * - * INPUTS: - * - * Identifier : base_address - * TypE : const u32 - * Description : Base Address of instance of MMU module - * - * Identifier : page_sz - * TypE : const u32 - * Description : It indicates the page size - * - * Identifier : preserved_bit - * Type : const u32 - * Description : It indicates the TLB entry is preserved entry - * or not - * - * Identifier : valid_bit - * Type : const u32 - * Description : It indicates the TLB entry is valid entry or not - * - * - * Identifier : virtual_addr_tag - * Type : const u32 - * Description : virtual Address - * - * RETURNS: - * - * Type : hw_status - * Description : 0 -- No errors occured - * RET_BAD_NULL_PARAM -- A Pointer Paramater - * was set to NULL - * RET_PARAM_OUT_OF_RANGE -- Input Parameter out - * of Range - * - * PURPOSE: : Set MMU_CAM reg - * - * METHOD: : Check the Input parameters and set the CAM entry. - */ -static hw_status mmu_set_cam_entry(const void __iomem *base_address, - const u32 page_sz, - const u32 preserved_bit, - const u32 valid_bit, - const u32 virtual_addr_tag); - -/* - * FUNCTION : mmu_set_ram_entry - * - * INPUTS: - * - * Identifier : base_address - * Type : const u32 - * Description : Base Address of instance of MMU module - * - * Identifier : physical_addr - * Type : const u32 - * Description : Physical Address to which the corresponding - * virtual Address shouldpoint - * - * Identifier : endianism - * Type : hw_endianism_t - * Description : endianism for the given page - * - * Identifier : element_size - * Type : hw_element_size_t - * Description : The element size ( 8,16, 32 or 64 bit) - * - * Identifier : mixed_size - * Type : hw_mmu_mixed_size_t - * Description : Element Size to follow CPU or TLB - * - * RETURNS: - * - * Type : hw_status - * Description : 0 -- No errors occured - * RET_BAD_NULL_PARAM -- A Pointer Paramater - * was set to NULL - * RET_PARAM_OUT_OF_RANGE -- Input Parameter - * out of Range - * - * PURPOSE: : Set MMU_CAM reg - * - * METHOD: : Check the Input parameters and set the RAM entry. - */ -static hw_status mmu_set_ram_entry(const void __iomem *base_address, - const u32 physical_addr, - enum hw_endianism_t endianism, - enum hw_element_size_t element_size, - enum hw_mmu_mixed_size_t mixed_size); - -/* HW FUNCTIONS */ - -hw_status hw_mmu_enable(const void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_SET); - - return status; -} - -hw_status hw_mmu_disable(const void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_CLEAR); - - return status; -} - -hw_status hw_mmu_num_locked_set(const void __iomem *base_address, - u32 num_locked_entries) -{ - hw_status status = 0; - - MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, num_locked_entries); - - return status; -} - -hw_status hw_mmu_victim_num_set(const void __iomem *base_address, - u32 victim_entry_num) -{ - hw_status status = 0; - - MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, victim_entry_num); - - return status; -} - -hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - - MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, irq_mask); - - return status; -} - -hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - u32 irq_reg; - - irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address); - - MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg & ~irq_mask); - - return status; -} - -hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irq_mask) -{ - hw_status status = 0; - u32 irq_reg; - - irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address); - - MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg | irq_mask); - - return status; -} - -hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irq_mask) -{ - hw_status status = 0; - - *irq_mask = MMUMMU_IRQSTATUS_READ_REGISTER32(base_address); - - return status; -} - -hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr) -{ - hw_status status = 0; - - /* read values from register */ - *addr = MMUMMU_FAULT_AD_READ_REGISTER32(base_address); - - return status; -} - -hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 ttb_phys_addr) -{ - hw_status status = 0; - u32 load_ttb; - - load_ttb = ttb_phys_addr & ~0x7FUL; - /* write values to register */ - MMUMMU_TTB_WRITE_REGISTER32(base_address, load_ttb); - - return status; -} - -hw_status hw_mmu_twl_enable(const void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_SET); - - return status; -} - -hw_status hw_mmu_twl_disable(const void __iomem *base_address) -{ - hw_status status = 0; - - MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_CLEAR); - - return status; -} - -hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtual_addr, - u32 page_sz) -{ - hw_status status = 0; - u32 virtual_addr_tag; - enum hw_mmu_page_size_t pg_size_bits; - - switch (page_sz) { - case HW_PAGE_SIZE4KB: - pg_size_bits = HW_MMU_SMALL_PAGE; - break; - - case HW_PAGE_SIZE64KB: - pg_size_bits = HW_MMU_LARGE_PAGE; - break; - - case HW_PAGE_SIZE1MB: - pg_size_bits = HW_MMU_SECTION; - break; - - case HW_PAGE_SIZE16MB: - pg_size_bits = HW_MMU_SUPERSECTION; - break; - - default: - return -EINVAL; - } - - /* Generate the 20-bit tag from virtual address */ - virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); - - mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag); - - mmu_flush_entry(base_address); - - return status; -} - -hw_status hw_mmu_tlb_add(const void __iomem *base_address, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - u32 entry_num, - struct hw_mmu_map_attrs_t *map_attrs, - s8 preserved_bit, s8 valid_bit) -{ - hw_status status = 0; - u32 lock_reg; - u32 virtual_addr_tag; - enum hw_mmu_page_size_t mmu_pg_size; - - /*Check the input Parameters */ - switch (page_sz) { - case HW_PAGE_SIZE4KB: - mmu_pg_size = HW_MMU_SMALL_PAGE; - break; - - case HW_PAGE_SIZE64KB: - mmu_pg_size = HW_MMU_LARGE_PAGE; - break; - - case HW_PAGE_SIZE1MB: - mmu_pg_size = HW_MMU_SECTION; - break; - - case HW_PAGE_SIZE16MB: - mmu_pg_size = HW_MMU_SUPERSECTION; - break; - - default: - return -EINVAL; - } - - lock_reg = MMUMMU_LOCK_READ_REGISTER32(base_address); - - /* Generate the 20-bit tag from virtual address */ - virtual_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); - - /* Write the fields in the CAM Entry Register */ - mmu_set_cam_entry(base_address, mmu_pg_size, preserved_bit, valid_bit, - virtual_addr_tag); - - /* Write the different fields of the RAM Entry Register */ - /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */ - mmu_set_ram_entry(base_address, physical_addr, map_attrs->endianism, - map_attrs->element_size, map_attrs->mixed_size); - - /* Update the MMU Lock Register */ - /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */ - MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, entry_num); - - /* Enable loading of an entry in TLB by writing 1 - into LD_TLB_REG register */ - MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, MMU_LOAD_TLB); - - MMUMMU_LOCK_WRITE_REGISTER32(base_address, lock_reg); - - return status; -} - -hw_status hw_mmu_pte_set(const u32 pg_tbl_va, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, struct hw_mmu_map_attrs_t *map_attrs) -{ - hw_status status = 0; - u32 pte_addr, pte_val; - s32 num_entries = 1; - - switch (page_sz) { - case HW_PAGE_SIZE4KB: - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_SMALL_PAGE_MASK); - pte_val = - ((physical_addr & MMU_SMALL_PAGE_MASK) | - (map_attrs->endianism << 9) | (map_attrs-> - element_size << 4) | - (map_attrs->mixed_size << 11) | 2); - break; - - case HW_PAGE_SIZE64KB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_LARGE_PAGE_MASK); - pte_val = - ((physical_addr & MMU_LARGE_PAGE_MASK) | - (map_attrs->endianism << 9) | (map_attrs-> - element_size << 4) | - (map_attrs->mixed_size << 11) | 1); - break; - - case HW_PAGE_SIZE1MB: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - pte_val = - ((((physical_addr & MMU_SECTION_ADDR_MASK) | - (map_attrs->endianism << 15) | (map_attrs-> - element_size << 10) | - (map_attrs->mixed_size << 17)) & ~0x40000) | 0x2); - break; - - case HW_PAGE_SIZE16MB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SSECTION_ADDR_MASK); - pte_val = - (((physical_addr & MMU_SSECTION_ADDR_MASK) | - (map_attrs->endianism << 15) | (map_attrs-> - element_size << 10) | - (map_attrs->mixed_size << 17) - ) | 0x40000 | 0x2); - break; - - case HW_MMU_COARSE_PAGE_SIZE: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - pte_val = (physical_addr & MMU_PAGE_TABLE_MASK) | 1; - break; - - default: - return -EINVAL; - } - - while (--num_entries >= 0) - ((u32 *) pte_addr)[num_entries] = pte_val; - - return status; -} - -hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtual_addr, u32 page_size) -{ - hw_status status = 0; - u32 pte_addr; - s32 num_entries = 1; - - switch (page_size) { - case HW_PAGE_SIZE4KB: - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_SMALL_PAGE_MASK); - break; - - case HW_PAGE_SIZE64KB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, - virtual_addr & - MMU_LARGE_PAGE_MASK); - break; - - case HW_PAGE_SIZE1MB: - case HW_MMU_COARSE_PAGE_SIZE: - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SECTION_ADDR_MASK); - break; - - case HW_PAGE_SIZE16MB: - num_entries = 16; - pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, - virtual_addr & - MMU_SSECTION_ADDR_MASK); - break; - - default: - return -EINVAL; - } - - while (--num_entries >= 0) - ((u32 *) pte_addr)[num_entries] = 0; - - return status; -} - -/* mmu_flush_entry */ -static hw_status mmu_flush_entry(const void __iomem *base_address) -{ - hw_status status = 0; - u32 flush_entry_data = 0x1; - - /* write values to register */ - MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data); - - return status; -} - -/* mmu_set_cam_entry */ -static hw_status mmu_set_cam_entry(const void __iomem *base_address, - const u32 page_sz, - const u32 preserved_bit, - const u32 valid_bit, - const u32 virtual_addr_tag) -{ - hw_status status = 0; - u32 mmu_cam_reg; - - mmu_cam_reg = (virtual_addr_tag << 12); - mmu_cam_reg = (mmu_cam_reg) | (page_sz) | (valid_bit << 2) | - (preserved_bit << 3); - - /* write values to register */ - MMUMMU_CAM_WRITE_REGISTER32(base_address, mmu_cam_reg); - - return status; -} - -/* mmu_set_ram_entry */ -static hw_status mmu_set_ram_entry(const void __iomem *base_address, - const u32 physical_addr, - enum hw_endianism_t endianism, - enum hw_element_size_t element_size, - enum hw_mmu_mixed_size_t mixed_size) -{ - hw_status status = 0; - u32 mmu_ram_reg; - - mmu_ram_reg = (physical_addr & MMU_ADDR_MASK); - mmu_ram_reg = (mmu_ram_reg) | ((endianism << 9) | (element_size << 7) | - (mixed_size << 6)); - - /* write values to register */ - MMUMMU_RAM_WRITE_REGISTER32(base_address, mmu_ram_reg); - - return status; - -} - -void hw_mmu_tlb_flush_all(const void __iomem *base) -{ - __raw_writeb(1, base + MMU_GFLUSH); -} diff --git a/trunk/drivers/staging/tidspbridge/hw/hw_mmu.h b/trunk/drivers/staging/tidspbridge/hw/hw_mmu.h deleted file mode 100644 index 1458a2c6027b..000000000000 --- a/trunk/drivers/staging/tidspbridge/hw/hw_mmu.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * hw_mmu.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * MMU types and API declarations - * - * Copyright (C) 2007 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _HW_MMU_H -#define _HW_MMU_H - -#include - -/* Bitmasks for interrupt sources */ -#define HW_MMU_TRANSLATION_FAULT 0x2 -#define HW_MMU_ALL_INTERRUPTS 0x1F - -#define HW_MMU_COARSE_PAGE_SIZE 0x400 - -/* hw_mmu_mixed_size_t: Enumerated Type used to specify whether to follow - CPU/TLB Element size */ -enum hw_mmu_mixed_size_t { - HW_MMU_TLBES, - HW_MMU_CPUES -}; - -/* hw_mmu_map_attrs_t: Struct containing MMU mapping attributes */ -struct hw_mmu_map_attrs_t { - enum hw_endianism_t endianism; - enum hw_element_size_t element_size; - enum hw_mmu_mixed_size_t mixed_size; - bool donotlockmpupage; -}; - -extern hw_status hw_mmu_enable(const void __iomem *base_address); - -extern hw_status hw_mmu_disable(const void __iomem *base_address); - -extern hw_status hw_mmu_num_locked_set(const void __iomem *base_address, - u32 num_locked_entries); - -extern hw_status hw_mmu_victim_num_set(const void __iomem *base_address, - u32 victim_entry_num); - -/* For MMU faults */ -extern hw_status hw_mmu_event_ack(const void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_disable(const void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_enable(const void __iomem *base_address, - u32 irq_mask); - -extern hw_status hw_mmu_event_status(const void __iomem *base_address, - u32 *irq_mask); - -extern hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, - u32 *addr); - -/* Set the TT base address */ -extern hw_status hw_mmu_ttb_set(const void __iomem *base_address, - u32 ttb_phys_addr); - -extern hw_status hw_mmu_twl_enable(const void __iomem *base_address); - -extern hw_status hw_mmu_twl_disable(const void __iomem *base_address); - -extern hw_status hw_mmu_tlb_flush(const void __iomem *base_address, - u32 virtual_addr, u32 page_sz); - -extern hw_status hw_mmu_tlb_add(const void __iomem *base_address, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - u32 entry_num, - struct hw_mmu_map_attrs_t *map_attrs, - s8 preserved_bit, s8 valid_bit); - -/* For PTEs */ -extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va, - u32 physical_addr, - u32 virtual_addr, - u32 page_sz, - struct hw_mmu_map_attrs_t *map_attrs); - -extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, - u32 virtual_addr, u32 page_size); - -void hw_mmu_tlb_flush_all(const void __iomem *base); - -static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va) -{ - u32 pte_addr; - u32 va31_to20; - - va31_to20 = va >> (20 - 2); /* Left-shift by 2 here itself */ - va31_to20 &= 0xFFFFFFFCUL; - pte_addr = l1_base + va31_to20; - - return pte_addr; -} - -static inline u32 hw_mmu_pte_addr_l2(u32 l2_base, u32 va) -{ - u32 pte_addr; - - pte_addr = (l2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC); - - return pte_addr; -} - -static inline u32 hw_mmu_pte_coarse_l1(u32 pte_val) -{ - u32 pte_coarse; - - pte_coarse = pte_val & 0xFFFFFC00; - - return pte_coarse; -} - -static inline u32 hw_mmu_pte_size_l1(u32 pte_val) -{ - u32 pte_size = 0; - - if ((pte_val & 0x3) == 0x1) { - /* Points to L2 PT */ - pte_size = HW_MMU_COARSE_PAGE_SIZE; - } - - if ((pte_val & 0x3) == 0x2) { - if (pte_val & (1 << 18)) - pte_size = HW_PAGE_SIZE16MB; - else - pte_size = HW_PAGE_SIZE1MB; - } - - return pte_size; -} - -static inline u32 hw_mmu_pte_size_l2(u32 pte_val) -{ - u32 pte_size = 0; - - if (pte_val & 0x2) - pte_size = HW_PAGE_SIZE4KB; - else if (pte_val & 0x1) - pte_size = HW_PAGE_SIZE64KB; - - return pte_size; -} - -#endif /* _HW_MMU_H */ diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h index 38122dbf877a..dfb55cca34c7 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/cfgdefs.h @@ -68,7 +68,6 @@ struct cfg_hostres { void __iomem *dw_per_base; u32 dw_per_pm_base; u32 dw_core_pm_base; - void __iomem *dw_dmmu_base; void __iomem *dw_sys_ctrl_base; }; diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/dev.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/dev.h index 357458fadd2a..9bdd48f57429 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/dev.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/dev.h @@ -27,7 +27,6 @@ #include #include #include -#include #include /* ----------------------------------- This */ @@ -233,29 +232,6 @@ extern int dev_get_chnl_mgr(struct dev_object *hdev_obj, extern int dev_get_cmm_mgr(struct dev_object *hdev_obj, struct cmm_object **mgr); -/* - * ======== dev_get_dmm_mgr ======== - * Purpose: - * Retrieve the handle to the dynamic memory manager created for this - * device. - * Parameters: - * hdev_obj: Handle to device object created with - * dev_create_device(). - * *mgr: Ptr to location to store handle. - * Returns: - * 0: Success. - * -EFAULT: Invalid hdev_obj. - * Requires: - * mgr != NULL. - * DEV Initialized. - * Ensures: - * 0: *mgr contains a handle to a channel manager object, - * or NULL. - * else: *mgr is NULL. - */ -extern int dev_get_dmm_mgr(struct dev_object *hdev_obj, - struct dmm_object **mgr); - /* * ======== dev_get_cod_mgr ======== * Purpose: diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/dmm.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/dmm.h deleted file mode 100644 index 6c58335c5f60..000000000000 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/dmm.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * dmm.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address - * space that can be directly mapped to any MPU buffer or memory region. - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef DMM_ -#define DMM_ - -#include - -struct dmm_object; - -/* DMM attributes used in dmm_create() */ -struct dmm_mgrattrs { - u32 reserved; -}; - -#define DMMPOOLSIZE 0x4000000 - -/* - * ======== dmm_get_handle ======== - * Purpose: - * Return the dynamic memory manager object for this device. - * This is typically called from the client process. - */ - -extern int dmm_get_handle(void *hprocessor, - struct dmm_object **dmm_manager); - -extern int dmm_reserve_memory(struct dmm_object *dmm_mgr, - u32 size, u32 *prsv_addr); - -extern int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, - u32 rsv_addr); - -extern int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, - u32 size); - -extern int dmm_un_map_memory(struct dmm_object *dmm_mgr, - u32 addr, u32 *psize); - -extern int dmm_destroy(struct dmm_object *dmm_mgr); - -extern int dmm_delete_tables(struct dmm_object *dmm_mgr); - -extern int dmm_create(struct dmm_object **dmm_manager, - struct dev_object *hdev_obj, - const struct dmm_mgrattrs *mgr_attrts); - -extern bool dmm_init(void); - -extern void dmm_exit(void); - -extern int dmm_create_tables(struct dmm_object *dmm_mgr, - u32 addr, u32 size); - -#ifdef DSP_DMM_DEBUG -u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr); -#endif - -#endif /* DMM_ */ diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/drv.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/drv.h index c1f363ec9afa..75a2c9b5c6f2 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/drv.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/drv.h @@ -108,12 +108,6 @@ struct dmm_map_object { struct bridge_dma_map_info dma_info; }; -/* Used for DMM reserved memory accounting */ -struct dmm_rsv_object { - struct list_head link; - u32 dsp_reserved_addr; -}; - /* New structure (member of process context) abstracts DMM resource info */ struct dspheap_res_object { s32 heap_allocated; /* DMM status */ @@ -165,10 +159,6 @@ struct process_context { struct list_head dmm_map_list; spinlock_t dmm_map_lock; - /* DMM reserved memory resources */ - struct list_head dmm_rsv_list; - spinlock_t dmm_rsv_lock; - /* DSP Heap resources */ struct dspheap_res_object *pdspheap_list; diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h new file mode 100644 index 000000000000..cb38d4cc0734 --- /dev/null +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/dsp-mmu.h @@ -0,0 +1,67 @@ +/* + * dsp-mmu.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * DSP iommu. + * + * Copyright (C) 2005-2010 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _DSP_MMU_ +#define _DSP_MMU_ + +#include +#include + +/** + * dsp_mmu_init() - initialize dsp_mmu module and returns a handle + * + * This function initialize dsp mmu module and returns a struct iommu + * handle to use it for dsp maps. + * + */ +struct iommu *dsp_mmu_init(void); + +/** + * dsp_mmu_exit() - destroy dsp mmu module + * @mmu: Pointer to iommu handle. + * + * This function destroys dsp mmu module. + * + */ +void dsp_mmu_exit(struct iommu *mmu); + +/** + * user_to_dsp_map() - maps user to dsp virtual address + * @mmu: Pointer to iommu handle. + * @uva: Virtual user space address. + * @da DSP address + * @size Buffer size to map. + * @usr_pgs struct page array pointer where the user pages will be stored + * + * This function maps a user space buffer into DSP virtual address. + * + */ +u32 user_to_dsp_map(struct iommu *mmu, u32 uva, u32 da, u32 size, + struct page **usr_pgs); + +/** + * user_to_dsp_unmap() - unmaps DSP virtual buffer. + * @mmu: Pointer to iommu handle. + * @da DSP address + * + * This function unmaps a user space buffer into DSP virtual address. + * + */ +int user_to_dsp_unmap(struct iommu *mmu, u32 da); + +#endif diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h index 0ae7d1646a1b..615363474810 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/dspdefs.h @@ -161,48 +161,6 @@ typedef int(*fxn_brd_memwrite) (struct bridge_dev_context u32 dsp_addr, u32 ul_num_bytes, u32 mem_type); -/* - * ======== bridge_brd_mem_map ======== - * Purpose: - * Map a MPU memory region to a DSP/IVA memory space - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * ul_mpu_addr: MPU memory region start address. - * virt_addr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to map. - * map_attrs: Mapping attributes (e.g. endianness). - * Returns: - * 0: Success. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memmap) (struct bridge_dev_context - * dev_ctxt, u32 ul_mpu_addr, - u32 virt_addr, u32 ul_num_bytes, - u32 map_attr, - struct page **mapped_pages); - -/* - * ======== bridge_brd_mem_un_map ======== - * Purpose: - * UnMap an MPU memory region from DSP/IVA memory space - * Parameters: - * dev_ctxt: Handle to Bridge driver defined device info. - * virt_addr: DSP/IVA memory region u8 address. - * ul_num_bytes: Number of bytes to unmap. - * Returns: - * 0: Success. - * -EPERM: Other, unspecified error. - * Requires: - * dev_ctxt != NULL; - * Ensures: - */ -typedef int(*fxn_brd_memunmap) (struct bridge_dev_context - * dev_ctxt, - u32 virt_addr, u32 ul_num_bytes); - /* * ======== bridge_brd_stop ======== * Purpose: @@ -993,8 +951,6 @@ struct bridge_drv_interface { fxn_brd_setstate pfn_brd_set_state; /* Sets the Board State */ fxn_brd_memcopy pfn_brd_mem_copy; /* Copies DSP Memory */ fxn_brd_memwrite pfn_brd_mem_write; /* Write DSP Memory w/o halt */ - fxn_brd_memmap pfn_brd_mem_map; /* Maps MPU mem to DSP mem */ - fxn_brd_memunmap pfn_brd_mem_un_map; /* Unmaps MPU mem to DSP mem */ fxn_chnl_create pfn_chnl_create; /* Create channel manager. */ fxn_chnl_destroy pfn_chnl_destroy; /* Destroy channel manager. */ fxn_chnl_open pfn_chnl_open; /* Create a new channel. */ diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h index 41e0594dff34..bad180108ada 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/dspioctl.h @@ -19,10 +19,6 @@ #ifndef DSPIOCTL_ #define DSPIOCTL_ -/* ------------------------------------ Hardware Abstraction Layer */ -#include -#include - /* * Any IOCTLS at or above this value are reserved for standard Bridge driver * interfaces. @@ -65,9 +61,6 @@ struct bridge_ioctl_extproc { /* GPP virtual address. __va does not work for ioremapped addresses */ u32 ul_gpp_va; u32 ul_size; /* Size of the mapped memory in bytes */ - enum hw_endianism_t endianism; - enum hw_mmu_mixed_size_t mixed_mode; - enum hw_element_size_t elem_size; }; #endif /* DSPIOCTL_ */ diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/proc.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/proc.h index 5e09fd165d9d..2d12aab6b5bf 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/proc.h @@ -550,29 +550,6 @@ extern int proc_map(void *hprocessor, void **pp_map_addr, u32 ul_map_attr, struct process_context *pr_ctxt); -/* - * ======== proc_reserve_memory ======== - * Purpose: - * Reserve a virtually contiguous region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * ul_size : Size of the address space to reserve. - * pp_rsv_addr : Ptr to DSP side reserved u8 address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOMEM : Cannot reserve chunk of this size. - * Requires: - * pp_rsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_reserve_memory(void *hprocessor, - u32 ul_size, void **pp_rsv_addr, - struct process_context *pr_ctxt); - /* * ======== proc_un_map ======== * Purpose: @@ -595,27 +572,4 @@ extern int proc_reserve_memory(void *hprocessor, extern int proc_un_map(void *hprocessor, void *map_addr, struct process_context *pr_ctxt); -/* - * ======== proc_un_reserve_memory ======== - * Purpose: - * Frees a previously reserved region of DSP address space. - * Parameters: - * hprocessor : The processor handle. - * prsv_addr : Ptr to DSP side reservedBYTE address. - * Returns: - * 0 : Success. - * -EFAULT : Invalid processor handle. - * -EPERM : General failure. - * -ENOENT : Cannot find a reserved region starting with this - * : address. - * Requires: - * prsv_addr is not NULL - * PROC Initialized. - * Ensures: - * Details: - */ -extern int proc_un_reserve_memory(void *hprocessor, - void *prsv_addr, - struct process_context *pr_ctxt); - #endif /* PROC_ */ diff --git a/trunk/drivers/staging/tidspbridge/pmgr/dev.c b/trunk/drivers/staging/tidspbridge/pmgr/dev.c index 132e960967b9..7b30267ef0e2 100644 --- a/trunk/drivers/staging/tidspbridge/pmgr/dev.c +++ b/trunk/drivers/staging/tidspbridge/pmgr/dev.c @@ -34,7 +34,6 @@ #include #include #include -#include /* ----------------------------------- Resource Manager */ #include @@ -75,7 +74,6 @@ struct dev_object { struct msg_mgr *hmsg_mgr; /* Message manager. */ struct io_mgr *hio_mgr; /* IO manager (CHNL, msg_ctrl) */ struct cmm_object *hcmm_mgr; /* SM memory manager. */ - struct dmm_object *dmm_mgr; /* Dynamic memory manager. */ struct ldr_module *module_obj; /* Bridge Module handle. */ u32 word_size; /* DSP word size: quick access. */ struct drv_object *hdrv_obj; /* Driver Object */ @@ -250,9 +248,6 @@ int dev_create_device(struct dev_object **device_obj, /* Instantiate the DEH module */ status = bridge_deh_create(&dev_obj->hdeh_mgr, dev_obj); } - /* Create DMM mgr . */ - status = dmm_create(&dev_obj->dmm_mgr, - (struct dev_object *)dev_obj, NULL); } /* Add the new DEV_Object to the global list: */ if (!status) { @@ -278,8 +273,6 @@ int dev_create_device(struct dev_object **device_obj, kfree(dev_obj->proc_list); if (dev_obj->cod_mgr) cod_delete(dev_obj->cod_mgr); - if (dev_obj->dmm_mgr) - dmm_destroy(dev_obj->dmm_mgr); kfree(dev_obj); } @@ -389,11 +382,6 @@ int dev_destroy_device(struct dev_object *hdev_obj) dev_obj->hcmm_mgr = NULL; } - if (dev_obj->dmm_mgr) { - dmm_destroy(dev_obj->dmm_mgr); - dev_obj->dmm_mgr = NULL; - } - /* Call the driver's bridge_dev_destroy() function: */ /* Require of DevDestroy */ if (dev_obj->hbridge_context) { @@ -473,32 +461,6 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj, return status; } -/* - * ======== dev_get_dmm_mgr ======== - * Purpose: - * Retrieve the handle to the dynamic memory manager created for this - * device. - */ -int dev_get_dmm_mgr(struct dev_object *hdev_obj, - struct dmm_object **mgr) -{ - int status = 0; - struct dev_object *dev_obj = hdev_obj; - - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(mgr != NULL); - - if (hdev_obj) { - *mgr = dev_obj->dmm_mgr; - } else { - *mgr = NULL; - status = -EFAULT; - } - - DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL)); - return status; -} - /* * ======== dev_get_cod_mgr ======== * Purpose: @@ -751,10 +713,8 @@ void dev_exit(void) refs--; - if (refs == 0) { + if (refs == 0) cmm_exit(); - dmm_exit(); - } DBC_ENSURE(refs >= 0); } @@ -766,25 +726,12 @@ void dev_exit(void) */ bool dev_init(void) { - bool cmm_ret, dmm_ret, ret = true; + bool ret = true; DBC_REQUIRE(refs >= 0); - if (refs == 0) { - cmm_ret = cmm_init(); - dmm_ret = dmm_init(); - - ret = cmm_ret && dmm_ret; - - if (!ret) { - if (cmm_ret) - cmm_exit(); - - if (dmm_ret) - dmm_exit(); - - } - } + if (refs == 0) + ret = cmm_init(); if (ret) refs++; @@ -1118,8 +1065,6 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns, STORE_FXN(fxn_brd_setstate, pfn_brd_set_state); STORE_FXN(fxn_brd_memcopy, pfn_brd_mem_copy); STORE_FXN(fxn_brd_memwrite, pfn_brd_mem_write); - STORE_FXN(fxn_brd_memmap, pfn_brd_mem_map); - STORE_FXN(fxn_brd_memunmap, pfn_brd_mem_un_map); STORE_FXN(fxn_chnl_create, pfn_chnl_create); STORE_FXN(fxn_chnl_destroy, pfn_chnl_destroy); STORE_FXN(fxn_chnl_open, pfn_chnl_open); diff --git a/trunk/drivers/staging/tidspbridge/pmgr/dmm.c b/trunk/drivers/staging/tidspbridge/pmgr/dmm.c deleted file mode 100644 index 8685233d7627..000000000000 --- a/trunk/drivers/staging/tidspbridge/pmgr/dmm.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * dmm.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * The Dynamic Memory Manager (DMM) module manages the DSP Virtual address - * space that can be directly mapped to any MPU buffer or memory region - * - * Notes: - * Region: Generic memory entitiy having a start address and a size - * Chunk: Reserved region - * - * Copyright (C) 2005-2006 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ -#include - -/* ----------------------------------- Host OS */ -#include - -/* ----------------------------------- DSP/BIOS Bridge */ -#include - -/* ----------------------------------- Trace & Debug */ -#include - -/* ----------------------------------- OS Adaptation Layer */ -#include - -/* ----------------------------------- Platform Manager */ -#include -#include - -/* ----------------------------------- This */ -#include - -/* ----------------------------------- Defines, Data Structures, Typedefs */ -#define DMM_ADDR_VIRTUAL(a) \ - (((struct map_page *)(a) - virtual_mapping_table) * PG_SIZE4K +\ - dyn_mem_map_beg) -#define DMM_ADDR_TO_INDEX(a) (((a) - dyn_mem_map_beg) / PG_SIZE4K) - -/* DMM Mgr */ -struct dmm_object { - /* Dmm Lock is used to serialize access mem manager for - * multi-threads. */ - spinlock_t dmm_lock; /* Lock to access dmm mgr */ -}; - -/* ----------------------------------- Globals */ -static u32 refs; /* module reference count */ -struct map_page { - u32 region_size:15; - u32 mapped_size:15; - u32 reserved:1; - u32 mapped:1; -}; - -/* Create the free list */ -static struct map_page *virtual_mapping_table; -static u32 free_region; /* The index of free region */ -static u32 free_size; -static u32 dyn_mem_map_beg; /* The Beginning of dynamic memory mapping */ -static u32 table_size; /* The size of virt and phys pages tables */ - -/* ----------------------------------- Function Prototypes */ -static struct map_page *get_region(u32 addr); -static struct map_page *get_free_region(u32 len); -static struct map_page *get_mapped_region(u32 addrs); - -/* ======== dmm_create_tables ======== - * Purpose: - * Create table to hold the information of physical address - * the buffer pages that is passed by the user, and the table - * to hold the information of the virtual memory that is reserved - * for DSP. - */ -int dmm_create_tables(struct dmm_object *dmm_mgr, u32 addr, u32 size) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - int status = 0; - - status = dmm_delete_tables(dmm_obj); - if (!status) { - dyn_mem_map_beg = addr; - table_size = PG_ALIGN_HIGH(size, PG_SIZE4K) / PG_SIZE4K; - /* Create the free list */ - virtual_mapping_table = __vmalloc(table_size * - sizeof(struct map_page), GFP_KERNEL | - __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); - if (virtual_mapping_table == NULL) - status = -ENOMEM; - else { - /* On successful allocation, - * all entries are zero ('free') */ - free_region = 0; - free_size = table_size * PG_SIZE4K; - virtual_mapping_table[0].region_size = table_size; - } - } - - if (status) - pr_err("%s: failure, status 0x%x\n", __func__, status); - - return status; -} - -/* - * ======== dmm_create ======== - * Purpose: - * Create a dynamic memory manager object. - */ -int dmm_create(struct dmm_object **dmm_manager, - struct dev_object *hdev_obj, - const struct dmm_mgrattrs *mgr_attrts) -{ - struct dmm_object *dmm_obj = NULL; - int status = 0; - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dmm_manager != NULL); - - *dmm_manager = NULL; - /* create, zero, and tag a cmm mgr object */ - dmm_obj = kzalloc(sizeof(struct dmm_object), GFP_KERNEL); - if (dmm_obj != NULL) { - spin_lock_init(&dmm_obj->dmm_lock); - *dmm_manager = dmm_obj; - } else { - status = -ENOMEM; - } - - return status; -} - -/* - * ======== dmm_destroy ======== - * Purpose: - * Release the communication memory manager resources. - */ -int dmm_destroy(struct dmm_object *dmm_mgr) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - int status = 0; - - DBC_REQUIRE(refs > 0); - if (dmm_mgr) { - status = dmm_delete_tables(dmm_obj); - if (!status) - kfree(dmm_obj); - } else - status = -EFAULT; - - return status; -} - -/* - * ======== dmm_delete_tables ======== - * Purpose: - * Delete DMM Tables. - */ -int dmm_delete_tables(struct dmm_object *dmm_mgr) -{ - int status = 0; - - DBC_REQUIRE(refs > 0); - /* Delete all DMM tables */ - if (dmm_mgr) - vfree(virtual_mapping_table); - else - status = -EFAULT; - return status; -} - -/* - * ======== dmm_exit ======== - * Purpose: - * Discontinue usage of module; free resources when reference count - * reaches 0. - */ -void dmm_exit(void) -{ - DBC_REQUIRE(refs > 0); - - refs--; -} - -/* - * ======== dmm_get_handle ======== - * Purpose: - * Return the dynamic memory manager object for this device. - * This is typically called from the client process. - */ -int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager) -{ - int status = 0; - struct dev_object *hdev_obj; - - DBC_REQUIRE(refs > 0); - DBC_REQUIRE(dmm_manager != NULL); - if (hprocessor != NULL) - status = proc_get_dev_object(hprocessor, &hdev_obj); - else - hdev_obj = dev_get_first(); /* default */ - - if (!status) - status = dev_get_dmm_mgr(hdev_obj, dmm_manager); - - return status; -} - -/* - * ======== dmm_init ======== - * Purpose: - * Initializes private state of DMM module. - */ -bool dmm_init(void) -{ - bool ret = true; - - DBC_REQUIRE(refs >= 0); - - if (ret) - refs++; - - DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); - - virtual_mapping_table = NULL; - table_size = 0; - - return ret; -} - -/* - * ======== dmm_map_memory ======== - * Purpose: - * Add a mapping block to the reserved chunk. DMM assumes that this block - * will be mapped in the DSP/IVA's address space. DMM returns an error if a - * mapping overlaps another one. This function stores the info that will be - * required later while unmapping the block. - */ -int dmm_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 size) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - int status = 0; - - spin_lock(&dmm_obj->dmm_lock); - /* Find the Reserved memory chunk containing the DSP block to - * be mapped */ - chunk = (struct map_page *)get_region(addr); - if (chunk != NULL) { - /* Mark the region 'mapped', leave the 'reserved' info as-is */ - chunk->mapped = true; - chunk->mapped_size = (size / PG_SIZE4K); - } else - status = -ENOENT; - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s dmm_mgr %p, addr %x, size %x\n\tstatus %x, " - "chunk %p", __func__, dmm_mgr, addr, size, status, chunk); - - return status; -} - -/* - * ======== dmm_reserve_memory ======== - * Purpose: - * Reserve a chunk of virtually contiguous DSP/IVA address space. - */ -int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size, - u32 *prsv_addr) -{ - int status = 0; - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *node; - u32 rsv_addr = 0; - u32 rsv_size = 0; - - spin_lock(&dmm_obj->dmm_lock); - - /* Try to get a DSP chunk from the free list */ - node = get_free_region(size); - if (node != NULL) { - /* DSP chunk of given size is available. */ - rsv_addr = DMM_ADDR_VIRTUAL(node); - /* Calculate the number entries to use */ - rsv_size = size / PG_SIZE4K; - if (rsv_size < node->region_size) { - /* Mark remainder of free region */ - node[rsv_size].mapped = false; - node[rsv_size].reserved = false; - node[rsv_size].region_size = - node->region_size - rsv_size; - node[rsv_size].mapped_size = 0; - } - /* get_region will return first fit chunk. But we only use what - is requested. */ - node->mapped = false; - node->reserved = true; - node->region_size = rsv_size; - node->mapped_size = 0; - /* Return the chunk's starting address */ - *prsv_addr = rsv_addr; - } else - /*dSP chunk of given size is not available */ - status = -ENOMEM; - - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, " - "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size, - prsv_addr, status, rsv_addr, rsv_size); - - return status; -} - -/* - * ======== dmm_un_map_memory ======== - * Purpose: - * Remove the mapped block from the reserved chunk. - */ -int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - int status = 0; - - spin_lock(&dmm_obj->dmm_lock); - chunk = get_mapped_region(addr); - if (chunk == NULL) - status = -ENOENT; - - if (!status) { - /* Unmap the region */ - *psize = chunk->mapped_size * PG_SIZE4K; - chunk->mapped = false; - chunk->mapped_size = 0; - } - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, " - "chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk); - - return status; -} - -/* - * ======== dmm_un_reserve_memory ======== - * Purpose: - * Free a chunk of reserved DSP/IVA address space. - */ -int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr) -{ - struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; - struct map_page *chunk; - u32 i; - int status = 0; - u32 chunk_size; - - spin_lock(&dmm_obj->dmm_lock); - - /* Find the chunk containing the reserved address */ - chunk = get_mapped_region(rsv_addr); - if (chunk == NULL) - status = -ENOENT; - - if (!status) { - /* Free all the mapped pages for this reserved region */ - i = 0; - while (i < chunk->region_size) { - if (chunk[i].mapped) { - /* Remove mapping from the page tables. */ - chunk_size = chunk[i].mapped_size; - /* Clear the mapping flags */ - chunk[i].mapped = false; - chunk[i].mapped_size = 0; - i += chunk_size; - } else - i++; - } - /* Clear the flags (mark the region 'free') */ - chunk->reserved = false; - /* NOTE: We do NOT coalesce free regions here. - * Free regions are coalesced in get_region(), as it traverses - *the whole mapping table - */ - } - spin_unlock(&dmm_obj->dmm_lock); - - dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p", - __func__, dmm_mgr, rsv_addr, status, chunk); - - return status; -} - -/* - * ======== get_region ======== - * Purpose: - * Returns a region containing the specified memory region - */ -static struct map_page *get_region(u32 addr) -{ - struct map_page *curr_region = NULL; - u32 i = 0; - - if (virtual_mapping_table != NULL) { - /* find page mapped by this address */ - i = DMM_ADDR_TO_INDEX(addr); - if (i < table_size) - curr_region = virtual_mapping_table + i; - } - - dev_dbg(bridge, "%s: curr_region %p, free_region %d, free_size %d\n", - __func__, curr_region, free_region, free_size); - return curr_region; -} - -/* - * ======== get_free_region ======== - * Purpose: - * Returns the requested free region - */ -static struct map_page *get_free_region(u32 len) -{ - struct map_page *curr_region = NULL; - u32 i = 0; - u32 region_size = 0; - u32 next_i = 0; - - if (virtual_mapping_table == NULL) - return curr_region; - if (len > free_size) { - /* Find the largest free region - * (coalesce during the traversal) */ - while (i < table_size) { - region_size = virtual_mapping_table[i].region_size; - next_i = i + region_size; - if (virtual_mapping_table[i].reserved == false) { - /* Coalesce, if possible */ - if (next_i < table_size && - virtual_mapping_table[next_i].reserved - == false) { - virtual_mapping_table[i].region_size += - virtual_mapping_table - [next_i].region_size; - continue; - } - region_size *= PG_SIZE4K; - if (region_size > free_size) { - free_region = i; - free_size = region_size; - } - } - i = next_i; - } - } - if (len <= free_size) { - curr_region = virtual_mapping_table + free_region; - free_region += (len / PG_SIZE4K); - free_size -= len; - } - return curr_region; -} - -/* - * ======== get_mapped_region ======== - * Purpose: - * Returns the requestedmapped region - */ -static struct map_page *get_mapped_region(u32 addrs) -{ - u32 i = 0; - struct map_page *curr_region = NULL; - - if (virtual_mapping_table == NULL) - return curr_region; - - i = DMM_ADDR_TO_INDEX(addrs); - if (i < table_size && (virtual_mapping_table[i].mapped || - virtual_mapping_table[i].reserved)) - curr_region = virtual_mapping_table + i; - return curr_region; -} - -#ifdef DSP_DMM_DEBUG -u32 dmm_mem_map_dump(struct dmm_object *dmm_mgr) -{ - struct map_page *curr_node = NULL; - u32 i; - u32 freemem = 0; - u32 bigsize = 0; - - spin_lock(&dmm_mgr->dmm_lock); - - if (virtual_mapping_table != NULL) { - for (i = 0; i < table_size; i += - virtual_mapping_table[i].region_size) { - curr_node = virtual_mapping_table + i; - if (curr_node->reserved) { - /*printk("RESERVED size = 0x%x, " - "Map size = 0x%x\n", - (curr_node->region_size * PG_SIZE4K), - (curr_node->mapped == false) ? 0 : - (curr_node->mapped_size * PG_SIZE4K)); - */ - } else { -/* printk("UNRESERVED size = 0x%x\n", - (curr_node->region_size * PG_SIZE4K)); - */ - freemem += (curr_node->region_size * PG_SIZE4K); - if (curr_node->region_size > bigsize) - bigsize = curr_node->region_size; - } - } - } - spin_unlock(&dmm_mgr->dmm_lock); - printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n", - freemem / (1024 * 1024)); - printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n", - (((table_size * PG_SIZE4K) - freemem)) / (1024 * 1024)); - printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n", - (bigsize * PG_SIZE4K / (1024 * 1024))); - - return 0; -} -#endif diff --git a/trunk/drivers/staging/tidspbridge/pmgr/dspapi.c b/trunk/drivers/staging/tidspbridge/pmgr/dspapi.c index 86ca785f1913..981551ce4d78 100644 --- a/trunk/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/trunk/drivers/staging/tidspbridge/pmgr/dspapi.c @@ -993,27 +993,10 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) /* * ======== procwrap_reserve_memory ======== */ -u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) +u32 __deprecated procwrap_reserve_memory(union trapped_args *args, + void *pr_ctxt) { - int status; - void *prsv_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - - if ((args->args_proc_rsvmem.ul_size <= 0) || - (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0) - return -EINVAL; - - status = proc_reserve_memory(hprocessor, - args->args_proc_rsvmem.ul_size, &prsv_addr, - pr_ctxt); - if (!status) { - if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) { - status = -EINVAL; - proc_un_reserve_memory(args->args_proc_rsvmem. - hprocessor, prsv_addr, pr_ctxt); - } - } - return status; + return 0; } /* @@ -1042,15 +1025,10 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) /* * ======== procwrap_un_reserve_memory ======== */ -u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) +u32 __deprecated procwrap_un_reserve_memory(union trapped_args *args, + void *pr_ctxt) { - int status; - void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; - - status = proc_un_reserve_memory(hprocessor, - args->args_proc_unrsvmem.prsv_addr, - pr_ctxt); - return status; + return 0; } /* diff --git a/trunk/drivers/staging/tidspbridge/rmgr/drv.c b/trunk/drivers/staging/tidspbridge/rmgr/drv.c index 81b1b9013550..91cc168516e5 100644 --- a/trunk/drivers/staging/tidspbridge/rmgr/drv.c +++ b/trunk/drivers/staging/tidspbridge/rmgr/drv.c @@ -146,7 +146,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) struct process_context *ctxt = (struct process_context *)process_ctxt; int status = 0; struct dmm_map_object *temp_map, *map_obj; - struct dmm_rsv_object *temp_rsv, *rsv_obj; /* Free DMM mapped memory resources */ list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) { @@ -156,16 +155,6 @@ int drv_remove_all_dmm_res_elements(void *process_ctxt) pr_err("%s: proc_un_map failed!" " status = 0x%xn", __func__, status); } - - /* Free DMM reserved memory resources */ - list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) { - status = proc_un_reserve_memory(ctxt->hprocessor, (void *) - rsv_obj->dsp_reserved_addr, - ctxt); - if (status) - pr_err("%s: proc_un_reserve_memory failed!" - " status = 0x%xn", __func__, status); - } return status; } @@ -743,7 +732,6 @@ static int request_bridge_resources(struct cfg_hostres *res) host_res->dw_sys_ctrl_base = ioremap(OMAP_SYSC_BASE, OMAP_SYSC_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); dev_dbg(bridge, "dw_mem_base[3] 0x%x\n", host_res->dw_mem_base[3]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); /* for 24xx base port is not mapping the mamory for DSP * internal memory TODO Do a ioremap here */ @@ -797,8 +785,6 @@ int drv_request_bridge_res_dsp(void **phost_resources) OMAP_PER_PRM_SIZE); host_res->dw_core_pm_base = (u32) ioremap(OMAP_CORE_PRM_BASE, OMAP_CORE_PRM_SIZE); - host_res->dw_dmmu_base = ioremap(OMAP_DMMU_BASE, - OMAP_DMMU_SIZE); dev_dbg(bridge, "dw_mem_base[0] 0x%x\n", host_res->dw_mem_base[0]); @@ -810,7 +796,6 @@ int drv_request_bridge_res_dsp(void **phost_resources) host_res->dw_mem_base[3]); dev_dbg(bridge, "dw_mem_base[4] 0x%x\n", host_res->dw_mem_base[4]); - dev_dbg(bridge, "dw_dmmu_base %p\n", host_res->dw_dmmu_base); shm_size = drv_datap->shm_size; if (shm_size >= 0x10000) { diff --git a/trunk/drivers/staging/tidspbridge/rmgr/drv_interface.c b/trunk/drivers/staging/tidspbridge/rmgr/drv_interface.c index 324fcdffb3b3..34be43fec044 100644 --- a/trunk/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/trunk/drivers/staging/tidspbridge/rmgr/drv_interface.c @@ -509,8 +509,6 @@ static int bridge_open(struct inode *ip, struct file *filp) pr_ctxt->res_state = PROC_RES_ALLOCATED; spin_lock_init(&pr_ctxt->dmm_map_lock); INIT_LIST_HEAD(&pr_ctxt->dmm_map_list); - spin_lock_init(&pr_ctxt->dmm_rsv_lock); - INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list); pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL); if (pr_ctxt->node_id) { diff --git a/trunk/drivers/staging/tidspbridge/rmgr/node.c b/trunk/drivers/staging/tidspbridge/rmgr/node.c index 1562f3c1281c..a660247f527a 100644 --- a/trunk/drivers/staging/tidspbridge/rmgr/node.c +++ b/trunk/drivers/staging/tidspbridge/rmgr/node.c @@ -56,7 +56,6 @@ /* ----------------------------------- This */ #include #include -#include /* Static/Dynamic Loader includes */ #include @@ -317,10 +316,6 @@ int node_allocate(struct proc_object *hprocessor, u32 mapped_addr = 0; u32 map_attrs = 0x0; struct dsp_processorstate proc_state; -#ifdef DSP_DMM_DEBUG - struct dmm_object *dmm_mgr; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; -#endif void *node_res; @@ -430,34 +425,12 @@ int node_allocate(struct proc_object *hprocessor, if (status) goto func_cont; - status = proc_reserve_memory(hprocessor, - pnode->create_args.asa.task_arg_obj. - heap_size + PAGE_SIZE, - (void **)&(pnode->create_args.asa. - task_arg_obj.udsp_heap_res_addr), - pr_ctxt); - if (status) { - pr_err("%s: Failed to reserve memory for heap: 0x%x\n", - __func__, status); - goto func_cont; - } -#ifdef DSP_DMM_DEBUG - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = DSP_EHANDLE; - goto func_cont; - } - - dmm_mem_map_dump(dmm_mgr); -#endif - map_attrs |= DSP_MAPLITTLEENDIAN; map_attrs |= DSP_MAPELEMSIZE32; map_attrs |= DSP_MAPVIRTUALADDR; status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr, pnode->create_args.asa.task_arg_obj.heap_size, - (void *)pnode->create_args.asa.task_arg_obj. - udsp_heap_res_addr, (void **)&mapped_addr, map_attrs, + NULL, (void **)&mapped_addr, map_attrs, pr_ctxt); if (status) pr_err("%s: Failed to map memory for Heap: 0x%x\n", @@ -2511,11 +2484,7 @@ static void delete_node(struct node_object *hnode, struct stream_chnl stream; struct node_msgargs node_msg_args; struct node_taskargs task_arg_obj; -#ifdef DSP_DMM_DEBUG - struct dmm_object *dmm_mgr; - struct proc_object *p_proc_object = - (struct proc_object *)hnode->hprocessor; -#endif + int status; if (!hnode) goto func_end; @@ -2576,19 +2545,6 @@ static void delete_node(struct node_object *hnode, status = proc_un_map(hnode->hprocessor, (void *) task_arg_obj.udsp_heap_addr, pr_ctxt); - - status = proc_un_reserve_memory(hnode->hprocessor, - (void *) - task_arg_obj. - udsp_heap_res_addr, - pr_ctxt); -#ifdef DSP_DMM_DEBUG - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (dmm_mgr) - dmm_mem_map_dump(dmm_mgr); - else - status = DSP_EHANDLE; -#endif } } if (node_type != NODE_MESSAGE) { diff --git a/trunk/drivers/staging/tidspbridge/rmgr/proc.c b/trunk/drivers/staging/tidspbridge/rmgr/proc.c index b47d7aa747b1..7a15a02efedf 100644 --- a/trunk/drivers/staging/tidspbridge/rmgr/proc.c +++ b/trunk/drivers/staging/tidspbridge/rmgr/proc.c @@ -39,7 +39,6 @@ #include #include #include -#include /* ----------------------------------- Resource Manager */ #include @@ -52,6 +51,7 @@ #include #include #include +#include <_tiomap.h> /* ----------------------------------- This */ #include @@ -151,34 +151,21 @@ static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt, return map_obj; } -static int match_exact_map_obj(struct dmm_map_object *map_obj, - u32 dsp_addr, u32 size) -{ - if (map_obj->dsp_addr == dsp_addr && map_obj->size != size) - pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n", - __func__, dsp_addr, map_obj->size, size); - - return map_obj->dsp_addr == dsp_addr && - map_obj->size == size; -} - static void remove_mapping_information(struct process_context *pr_ctxt, - u32 dsp_addr, u32 size) + u32 dsp_addr) { struct dmm_map_object *map_obj; - pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__, - dsp_addr, size); + pr_debug("%s: looking for virt 0x%x\n", __func__, dsp_addr); spin_lock(&pr_ctxt->dmm_map_lock); list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) { - pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n", + pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x\n", __func__, map_obj->mpu_addr, - map_obj->dsp_addr, - map_obj->size); + map_obj->dsp_addr); - if (match_exact_map_obj(map_obj, dsp_addr, size)) { + if (map_obj->dsp_addr == dsp_addr) { pr_debug("%s: match, deleting map info\n", __func__); list_del(&map_obj->link); kfree(map_obj->dma_info.sg); @@ -1090,7 +1077,6 @@ int proc_load(void *hprocessor, const s32 argc_index, s32 cnew_envp; /* " " in new_envp[] */ s32 nproc_id = 0; /* Anticipate MP version. */ struct dcd_manager *hdcd_handle; - struct dmm_object *dmm_mgr; u32 dw_ext_end; u32 proc_id; int brd_state; @@ -1281,25 +1267,6 @@ int proc_load(void *hprocessor, const s32 argc_index, if (!status) status = cod_get_sym_value(cod_mgr, EXTEND, &dw_ext_end); - - /* Reset DMM structs and add an initial free chunk */ - if (!status) { - status = - dev_get_dmm_mgr(p_proc_object->hdev_obj, - &dmm_mgr); - if (dmm_mgr) { - /* Set dw_ext_end to DMM START u8 - * address */ - dw_ext_end = - (dw_ext_end + 1) * DSPWORDSIZE; - /* DMM memory is from EXT_END */ - status = dmm_create_tables(dmm_mgr, - dw_ext_end, - DMMPOOLSIZE); - } else { - status = -EFAULT; - } - } } } /* Restore the original argv[0] */ @@ -1352,12 +1319,10 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, { u32 va_align; u32 pa_align; - struct dmm_object *dmm_mgr; u32 size_align; int status = 0; struct proc_object *p_proc_object = (struct proc_object *)hprocessor; struct dmm_map_object *map_obj; - u32 tmp_addr = 0; #ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK if ((ul_map_attr & BUFMODE_MASK) != RBUF) { @@ -1382,33 +1347,30 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, } /* Critical section */ mutex_lock(&proc_lock); - dmm_get_handle(p_proc_object, &dmm_mgr); - if (dmm_mgr) - status = dmm_map_memory(dmm_mgr, va_align, size_align); - else - status = -EFAULT; /* Add mapping to the page tables. */ if (!status) { - - /* Mapped address = MSB of VA | LSB of PA */ - tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1))); /* mapped memory resource tracking */ - map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr, + map_obj = add_mapping_info(pr_ctxt, pa_align, va_align, size_align); - if (!map_obj) + if (!map_obj) { status = -ENOMEM; - else - status = (*p_proc_object->intf_fxns->pfn_brd_mem_map) - (p_proc_object->hbridge_context, pa_align, va_align, - size_align, ul_map_attr, map_obj->pages); + } else { + va_align = user_to_dsp_map( + p_proc_object->hbridge_context->dsp_mmu, + pa_align, va_align, size_align, + map_obj->pages); + if (IS_ERR_VALUE(va_align)) + status = (int)va_align; + } } if (!status) { /* Mapped address = MSB of VA | LSB of PA */ - *pp_map_addr = (void *) tmp_addr; + map_obj->dsp_addr = (va_align | + ((u32)pmpu_addr & (PG_SIZE4K - 1))); + *pp_map_addr = (void *)map_obj->dsp_addr; } else { - remove_mapping_information(pr_ctxt, tmp_addr, size_align); - dmm_un_map_memory(dmm_mgr, va_align, &size_align); + remove_mapping_information(pr_ctxt, va_align); } mutex_unlock(&proc_lock); @@ -1500,55 +1462,6 @@ int proc_register_notify(void *hprocessor, u32 event_mask, return status; } -/* - * ======== proc_reserve_memory ======== - * Purpose: - * Reserve a virtually contiguous region of DSP address space. - */ -int proc_reserve_memory(void *hprocessor, u32 ul_size, - void **pp_rsv_addr, - struct process_context *pr_ctxt) -{ - struct dmm_object *dmm_mgr; - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_rsv_object *rsv_obj; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - - status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr); - if (status != 0) - goto func_end; - - /* - * A successful reserve should be followed by insertion of rsv_obj - * into dmm_rsv_list, so that reserved memory resource tracking - * remains uptodate - */ - rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL); - if (rsv_obj) { - rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr; - spin_lock(&pr_ctxt->dmm_rsv_lock); - list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list); - spin_unlock(&pr_ctxt->dmm_rsv_lock); - } - -func_end: - dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p " - "status 0x%x\n", __func__, hprocessor, - ul_size, pp_rsv_addr, status); - return status; -} - /* * ======== proc_start ======== * Purpose: @@ -1697,9 +1610,7 @@ int proc_un_map(void *hprocessor, void *map_addr, { int status = 0; struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_object *dmm_mgr; u32 va_align; - u32 size_align; va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K); if (!p_proc_object) { @@ -1707,24 +1618,11 @@ int proc_un_map(void *hprocessor, void *map_addr, goto func_end; } - status = dmm_get_handle(hprocessor, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - /* Critical section */ mutex_lock(&proc_lock); - /* - * Update DMM structures. Get the size to unmap. - * This function returns error if the VA is not mapped - */ - status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align); /* Remove mapping from the page tables. */ - if (!status) { - status = (*p_proc_object->intf_fxns->pfn_brd_mem_un_map) - (p_proc_object->hbridge_context, va_align, size_align); - } + status = user_to_dsp_unmap(p_proc_object->hbridge_context->dsp_mmu, + va_align); mutex_unlock(&proc_lock); if (status) @@ -1735,7 +1633,7 @@ int proc_un_map(void *hprocessor, void *map_addr, * from dmm_map_list, so that mapped memory resource tracking * remains uptodate */ - remove_mapping_information(pr_ctxt, (u32) map_addr, size_align); + remove_mapping_information(pr_ctxt, (u32) map_addr); func_end: dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n", @@ -1743,55 +1641,6 @@ int proc_un_map(void *hprocessor, void *map_addr, return status; } -/* - * ======== proc_un_reserve_memory ======== - * Purpose: - * Frees a previously reserved region of DSP address space. - */ -int proc_un_reserve_memory(void *hprocessor, void *prsv_addr, - struct process_context *pr_ctxt) -{ - struct dmm_object *dmm_mgr; - int status = 0; - struct proc_object *p_proc_object = (struct proc_object *)hprocessor; - struct dmm_rsv_object *rsv_obj; - - if (!p_proc_object) { - status = -EFAULT; - goto func_end; - } - - status = dmm_get_handle(p_proc_object, &dmm_mgr); - if (!dmm_mgr) { - status = -EFAULT; - goto func_end; - } - - status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr); - if (status != 0) - goto func_end; - - /* - * A successful unreserve should be followed by removal of rsv_obj - * from dmm_rsv_list, so that reserved memory resource tracking - * remains uptodate - */ - spin_lock(&pr_ctxt->dmm_rsv_lock); - list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) { - if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) { - list_del(&rsv_obj->link); - kfree(rsv_obj); - break; - } - } - spin_unlock(&pr_ctxt->dmm_rsv_lock); - -func_end: - dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n", - __func__, hprocessor, prsv_addr, status); - return status; -} - /* * ======== = proc_monitor ======== == * Purpose: diff --git a/trunk/drivers/staging/udlfb/udlfb.c b/trunk/drivers/staging/udlfb/udlfb.c index fed25105970a..5969e848d297 100644 --- a/trunk/drivers/staging/udlfb/udlfb.c +++ b/trunk/drivers/staging/udlfb/udlfb.c @@ -887,7 +887,7 @@ static int dlfb_ops_open(struct fb_info *info, int user) struct fb_deferred_io *fbdefio; - fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); + fbdefio = kmalloc(GFP_KERNEL, sizeof(struct fb_deferred_io)); if (fbdefio) { fbdefio->delay = DL_DEFIO_WRITE_DELAY; diff --git a/trunk/drivers/staging/vt6656/main_usb.c b/trunk/drivers/staging/vt6656/main_usb.c index 7cc3d2407d1b..e992d5d9e15b 100644 --- a/trunk/drivers/staging/vt6656/main_usb.c +++ b/trunk/drivers/staging/vt6656/main_usb.c @@ -1675,14 +1675,13 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { { char essid[IW_ESSID_MAX_SIZE+1]; - if (wrq->u.essid.pointer) { + if (wrq->u.essid.pointer) rc = iwctl_giwessid(dev, NULL, &(wrq->u.essid), essid); if (copy_to_user(wrq->u.essid.pointer, essid, wrq->u.essid.length) ) rc = -EFAULT; - } } break; diff --git a/trunk/drivers/staging/westbridge/astoria/api/src/cyasusb.c b/trunk/drivers/staging/westbridge/astoria/api/src/cyasusb.c index 7777d9a60a52..5a2197012065 100644 --- a/trunk/drivers/staging/westbridge/astoria/api/src/cyasusb.c +++ b/trunk/drivers/staging/westbridge/astoria/api/src/cyasusb.c @@ -1417,6 +1417,7 @@ cy_as_usb_set_enum_config(cy_as_device_handle handle, */ bus_mask = 0; media_mask = 0; + media_mask = 0; for (bus = 0; bus < CY_AS_MAX_BUSES; bus++) { for (device = 0; device < CY_AS_MAX_STORAGE_DEVICES; device++) { if (config_p->devices_to_enumerate[bus][device] == diff --git a/trunk/drivers/staging/wlan-ng/cfg80211.c b/trunk/drivers/staging/wlan-ng/cfg80211.c index 6a71f52c59b1..4af83d5318f2 100644 --- a/trunk/drivers/staging/wlan-ng/cfg80211.c +++ b/trunk/drivers/staging/wlan-ng/cfg80211.c @@ -139,7 +139,7 @@ int prism2_change_virtual_intf(struct wiphy *wiphy, } int prism2_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_index, bool pairwise, const u8 *mac_addr, + u8 key_index, const u8 *mac_addr, struct key_params *params) { wlandevice_t *wlandev = dev->ml_priv; @@ -198,7 +198,7 @@ int prism2_add_key(struct wiphy *wiphy, struct net_device *dev, } int prism2_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, + u8 key_index, const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params*)) { wlandevice_t *wlandev = dev->ml_priv; @@ -227,7 +227,7 @@ int prism2_get_key(struct wiphy *wiphy, struct net_device *dev, } int prism2_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_index, bool pairwise, const u8 *mac_addr) + u8 key_index, const u8 *mac_addr) { wlandevice_t *wlandev = dev->ml_priv; u32 did; diff --git a/trunk/drivers/staging/wlan-ng/p80211netdev.c b/trunk/drivers/staging/wlan-ng/p80211netdev.c index b7b4a733b467..aa1792c8429e 100644 --- a/trunk/drivers/staging/wlan-ng/p80211netdev.c +++ b/trunk/drivers/staging/wlan-ng/p80211netdev.c @@ -522,8 +522,8 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr) if (copy_to_user(useraddr, &edata, sizeof(edata))) return -EFAULT; return 0; -#endif } +#endif return -EOPNOTSUPP; } diff --git a/trunk/drivers/tty/Makefile b/trunk/drivers/tty/Makefile deleted file mode 100644 index c43ef48b1a0f..000000000000 --- a/trunk/drivers/tty/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -obj-y += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ - tty_buffer.o tty_port.o tty_mutex.o -obj-$(CONFIG_LEGACY_PTYS) += pty.o -obj-$(CONFIG_UNIX98_PTYS) += pty.o -obj-$(CONFIG_AUDIT) += tty_audit.o -obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o -obj-$(CONFIG_N_HDLC) += n_hdlc.o -obj-$(CONFIG_N_GSM) += n_gsm.o -obj-$(CONFIG_R3964) += n_r3964.o - -obj-y += vt/ diff --git a/trunk/drivers/tty/vt/Makefile b/trunk/drivers/tty/vt/Makefile deleted file mode 100644 index 14a51c9960df..000000000000 --- a/trunk/drivers/tty/vt/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# -# This file contains the font map for the default (hardware) font -# -FONTMAPFILE = cp437.uni - -obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o \ - selection.o keyboard.o -obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o -obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o - -# Files generated that shall be removed upon make clean -clean-files := consolemap_deftbl.c defkeymap.c - -quiet_cmd_conmk = CONMK $@ - cmd_conmk = scripts/conmakehash $< > $@ - -$(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE) - $(call cmd,conmk) - -$(obj)/defkeymap.o: $(obj)/defkeymap.c - -# Uncomment if you're changing the keymap and have an appropriate -# loadkeys version for the map. By default, we'll use the shipped -# versions. -# GENERATE_KEYMAP := 1 - -ifdef GENERATE_KEYMAP - -$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map - loadkeys --mktable $< > $@.tmp - sed -e 's/^static *//' $@.tmp > $@ - rm $@.tmp - -endif diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index 045bb4b823e1..f1aaff6202a5 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -965,11 +965,10 @@ static int proc_getdriver(struct dev_state *ps, void __user *arg) static int proc_connectinfo(struct dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; return 0; diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 607d0db4a988..b739ca814651 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -158,7 +158,7 @@ config USB_GADGET_FSL_USB2 boolean "Freescale Highspeed USB DR Peripheral Controller" depends on FSL_SOC || ARCH_MXC select USB_GADGET_DUALSPEED - select USB_FSL_MPH_DR_OF if OF + select USB_FSL_MPH_DR_OF help Some of Freescale PowerPC processors have a High Speed Dual-Role(DR) USB controller, which supports device mode. diff --git a/trunk/drivers/usb/gadget/goku_udc.h b/trunk/drivers/usb/gadget/goku_udc.h index e7e0c69d3b1f..566cb2319056 100644 --- a/trunk/drivers/usb/gadget/goku_udc.h +++ b/trunk/drivers/usb/gadget/goku_udc.h @@ -251,8 +251,7 @@ struct goku_udc { got_region:1, req_config:1, configured:1, - enabled:1, - registered:1; + enabled:1; /* pci state used to access those endpoints */ struct pci_dev *pdev; diff --git a/trunk/drivers/usb/gadget/u_ether.c b/trunk/drivers/usb/gadget/u_ether.c index fbe86ca95802..cb23355f52d3 100644 --- a/trunk/drivers/usb/gadget/u_ether.c +++ b/trunk/drivers/usb/gadget/u_ether.c @@ -811,6 +811,7 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); + netif_stop_queue(net); the_dev = dev; } diff --git a/trunk/drivers/usb/gadget/u_serial.c b/trunk/drivers/usb/gadget/u_serial.c index 40f7716b31fc..01e5354a4c20 100644 --- a/trunk/drivers/usb/gadget/u_serial.c +++ b/trunk/drivers/usb/gadget/u_serial.c @@ -105,15 +105,11 @@ struct gs_port { wait_queue_head_t close_wait; /* wait for last close */ struct list_head read_pool; - int read_started; - int read_allocated; struct list_head read_queue; unsigned n_read; struct tasklet_struct push; struct list_head write_pool; - int write_started; - int write_allocated; struct gs_buf port_write_buf; wait_queue_head_t drain_wait; /* wait while writes drain */ @@ -367,9 +363,6 @@ __acquires(&port->port_lock) struct usb_request *req; int len; - if (port->write_started >= QUEUE_SIZE) - break; - req = list_entry(pool->next, struct usb_request, list); len = gs_send_packet(port, req->buf, in->maxpacket); if (len == 0) { @@ -404,8 +397,6 @@ __acquires(&port->port_lock) break; } - port->write_started++; - /* abort immediately after disconnect */ if (!port->port_usb) break; @@ -427,6 +418,7 @@ __acquires(&port->port_lock) { struct list_head *pool = &port->read_pool; struct usb_ep *out = port->port_usb->out; + unsigned started = 0; while (!list_empty(pool)) { struct usb_request *req; @@ -438,9 +430,6 @@ __acquires(&port->port_lock) if (!tty) break; - if (port->read_started >= QUEUE_SIZE) - break; - req = list_entry(pool->next, struct usb_request, list); list_del(&req->list); req->length = out->maxpacket; @@ -458,13 +447,13 @@ __acquires(&port->port_lock) list_add(&req->list, pool); break; } - port->read_started++; + started++; /* abort immediately after disconnect */ if (!port->port_usb) break; } - return port->read_started; + return started; } /* @@ -546,7 +535,6 @@ static void gs_rx_push(unsigned long _port) } recycle: list_move(&req->list, &port->read_pool); - port->read_started--; } /* Push from tty to ldisc; without low_latency set this is handled by @@ -599,7 +587,6 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) spin_lock(&port->port_lock); list_add(&req->list, &port->write_pool); - port->write_started--; switch (req->status) { default: @@ -621,8 +608,7 @@ static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) spin_unlock(&port->port_lock); } -static void gs_free_requests(struct usb_ep *ep, struct list_head *head, - int *allocated) +static void gs_free_requests(struct usb_ep *ep, struct list_head *head) { struct usb_request *req; @@ -630,31 +616,25 @@ static void gs_free_requests(struct usb_ep *ep, struct list_head *head, req = list_entry(head->next, struct usb_request, list); list_del(&req->list); gs_free_req(ep, req); - if (allocated) - (*allocated)--; } } static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head, - void (*fn)(struct usb_ep *, struct usb_request *), - int *allocated) + void (*fn)(struct usb_ep *, struct usb_request *)) { int i; struct usb_request *req; - int n = allocated ? QUEUE_SIZE - *allocated : QUEUE_SIZE; /* Pre-allocate up to QUEUE_SIZE transfers, but if we can't * do quite that many this time, don't fail ... we just won't * be as speedy as we might otherwise be. */ - for (i = 0; i < n; i++) { + for (i = 0; i < QUEUE_SIZE; i++) { req = gs_alloc_req(ep, ep->maxpacket, GFP_ATOMIC); if (!req) return list_empty(head) ? -ENOMEM : 0; req->complete = fn; list_add_tail(&req->list, head); - if (allocated) - (*allocated)++; } return 0; } @@ -681,15 +661,14 @@ static int gs_start_io(struct gs_port *port) * configurations may use different endpoints with a given port; * and high speed vs full speed changes packet sizes too. */ - status = gs_alloc_requests(ep, head, gs_read_complete, - &port->read_allocated); + status = gs_alloc_requests(ep, head, gs_read_complete); if (status) return status; status = gs_alloc_requests(port->port_usb->in, &port->write_pool, - gs_write_complete, &port->write_allocated); + gs_write_complete); if (status) { - gs_free_requests(ep, head, &port->read_allocated); + gs_free_requests(ep, head); return status; } @@ -701,9 +680,8 @@ static int gs_start_io(struct gs_port *port) if (started) { tty_wakeup(port->port_tty); } else { - gs_free_requests(ep, head, &port->read_allocated); - gs_free_requests(port->port_usb->in, &port->write_pool, - &port->write_allocated); + gs_free_requests(ep, head); + gs_free_requests(port->port_usb->in, &port->write_pool); status = -EIO; } @@ -1337,12 +1315,8 @@ void gserial_disconnect(struct gserial *gser) spin_lock_irqsave(&port->port_lock, flags); if (port->open_count == 0 && !port->openclose) gs_buf_free(&port->port_write_buf); - gs_free_requests(gser->out, &port->read_pool, NULL); - gs_free_requests(gser->out, &port->read_queue, NULL); - gs_free_requests(gser->in, &port->write_pool, NULL); - - port->read_allocated = port->read_started = - port->write_allocated = port->write_started = 0; - + gs_free_requests(gser->out, &port->read_pool); + gs_free_requests(gser->out, &port->read_queue); + gs_free_requests(gser->in, &port->write_pool); spin_unlock_irqrestore(&port->port_lock, flags); } diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index 6f4f8e6a40c7..2391c396ca32 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -122,7 +122,7 @@ config USB_EHCI_FSL bool "Support for Freescale on-chip EHCI USB controller" depends on USB_EHCI_HCD && FSL_SOC select USB_EHCI_ROOT_HUB_TT - select USB_FSL_MPH_DR_OF if OF + select USB_FSL_MPH_DR_OF ---help--- Variation of ARC USB block used in some Freescale chips. diff --git a/trunk/drivers/usb/host/ehci-mxc.c b/trunk/drivers/usb/host/ehci-mxc.c index bce85055019a..ac9c4d7c44af 100644 --- a/trunk/drivers/usb/host/ehci-mxc.c +++ b/trunk/drivers/usb/host/ehci-mxc.c @@ -36,8 +36,6 @@ struct ehci_mxc_priv { static int ehci_mxc_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - struct device *dev = hcd->self.controller; - struct mxc_usbh_platform_data *pdata = dev_get_platdata(dev); int retval; /* EHCI registers start at offset 0x100 */ @@ -65,12 +63,6 @@ static int ehci_mxc_setup(struct usb_hcd *hcd) ehci_reset(ehci); - /* set up the PORTSCx register */ - ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); - - /* is this really needed? */ - msleep(10); - ehci_port_power(ehci, 0); return 0; } @@ -122,7 +114,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; struct resource *res; - int irq, ret; + int irq, ret, temp; struct ehci_mxc_priv *priv; struct device *dev = &pdev->dev; @@ -196,6 +188,10 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) clk_enable(priv->ahbclk); } + /* set up the PORTSCx register */ + ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); + mdelay(10); + /* setup specific usb hw */ ret = mxc_initialize_usb_hw(pdev->id, pdata->flags); if (ret < 0) diff --git a/trunk/drivers/usb/host/ohci-jz4740.c b/trunk/drivers/usb/host/ohci-jz4740.c index 931d588c3fb5..10e1872f3ab9 100644 --- a/trunk/drivers/usb/host/ohci-jz4740.c +++ b/trunk/drivers/usb/host/ohci-jz4740.c @@ -273,4 +273,4 @@ static struct platform_driver ohci_hcd_jz4740_driver = { }, }; -MODULE_ALIAS("platform:jz4740-ohci"); +MODULE_ALIAS("platfrom:jz4740-ohci"); diff --git a/trunk/drivers/usb/misc/iowarrior.c b/trunk/drivers/usb/misc/iowarrior.c index c9078e4e1f4d..375664198776 100644 --- a/trunk/drivers/usb/misc/iowarrior.c +++ b/trunk/drivers/usb/misc/iowarrior.c @@ -553,7 +553,6 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, /* needed for power consumption */ struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc; - memset(&info, 0, sizeof(info)); /* directly from the descriptor */ info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); info.product = dev->product_id; diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb.c b/trunk/drivers/usb/misc/sisusbvga/sisusb.c index dd573abd2d1e..70d00e99a4b4 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb.c +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb.c @@ -3008,7 +3008,6 @@ sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) #else x.sisusb_conactive = 0; #endif - memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved)); if (copy_to_user((void __user *)arg, &x, sizeof(x))) retval = -EFAULT; diff --git a/trunk/drivers/usb/musb/blackfin.c b/trunk/drivers/usb/musb/blackfin.c index fcb5206a65bd..611a9d274363 100644 --- a/trunk/drivers/usb/musb/blackfin.c +++ b/trunk/drivers/usb/musb/blackfin.c @@ -171,9 +171,8 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci) } /* Start sampling ID pin, when plug is removed from MUSB */ - if ((is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE - || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) || - (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) { + if (is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE + || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); musb->a_wait_bcon = TIMER_DELAY; } @@ -324,8 +323,30 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) return -EIO; } -static void musb_platform_reg_init(struct musb *musb) +int __init musb_platform_init(struct musb *musb, void *board_data) { + + /* + * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE + * and OTG HOST modes, while rev 1.1 and greater require PE7 to + * be low for DEVICE mode and high for HOST mode. We set it high + * here because we are in host mode + */ + + if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { + printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n", + musb->config->gpio_vrsel); + return -ENODEV; + } + gpio_direction_output(musb->config->gpio_vrsel, 0); + + usb_nop_xceiv_register(); + musb->xceiv = otg_get_transceiver(); + if (!musb->xceiv) { + gpio_free(musb->config->gpio_vrsel); + return -ENODEV; + } + if (ANOMALY_05000346) { bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); SSYNC(); @@ -337,8 +358,7 @@ static void musb_platform_reg_init(struct musb *musb) } /* Configure PLL oscillator register */ - bfin_write_USB_PLLOSC_CTRL(0x3080 | - ((480/musb->config->clkin) << 1)); + bfin_write_USB_PLLOSC_CTRL(0x30a8); SSYNC(); bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1); @@ -360,33 +380,6 @@ static void musb_platform_reg_init(struct musb *musb) EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); SSYNC(); -} - -int __init musb_platform_init(struct musb *musb, void *board_data) -{ - - /* - * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE - * and OTG HOST modes, while rev 1.1 and greater require PE7 to - * be low for DEVICE mode and high for HOST mode. We set it high - * here because we are in host mode - */ - - if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { - printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d\n", - musb->config->gpio_vrsel); - return -ENODEV; - } - gpio_direction_output(musb->config->gpio_vrsel, 0); - - usb_nop_xceiv_register(); - musb->xceiv = otg_get_transceiver(); - if (!musb->xceiv) { - gpio_free(musb->config->gpio_vrsel); - return -ENODEV; - } - - musb_platform_reg_init(musb); if (is_host_enabled(musb)) { musb->board_set_vbus = bfin_set_vbus; @@ -401,27 +394,6 @@ int __init musb_platform_init(struct musb *musb, void *board_data) return 0; } -#ifdef CONFIG_PM -void musb_platform_save_context(struct musb *musb, - struct musb_context_registers *musb_context) -{ - if (is_host_active(musb)) - /* - * During hibernate gpio_vrsel will change from high to low - * low which will generate wakeup event resume the system - * immediately. Set it to 0 before hibernate to avoid this - * wakeup event. - */ - gpio_set_value(musb->config->gpio_vrsel, 0); -} - -void musb_platform_restore_context(struct musb *musb, - struct musb_context_registers *musb_context) -{ - musb_platform_reg_init(musb); -} -#endif - int musb_platform_exit(struct musb *musb) { gpio_free(musb->config->gpio_vrsel); diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index e6669fc3b804..c9f9024c5515 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -552,8 +552,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (int_usb & MUSB_INTR_SESSREQ) { void __iomem *mbase = musb->mregs; - if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS - && (devctl & MUSB_DEVCTL_BDEVICE)) { + if (devctl & MUSB_DEVCTL_BDEVICE) { DBG(3, "SessReq while on B state\n"); return IRQ_HANDLED; } @@ -1053,11 +1052,6 @@ static void musb_shutdown(struct platform_device *pdev) clk_put(musb->clock); spin_unlock_irqrestore(&musb->lock, flags); - if (!is_otg_enabled(musb) && is_host_enabled(musb)) - usb_remove_hcd(musb_to_hcd(musb)); - musb_writeb(musb->mregs, MUSB_DEVCTL, 0); - musb_platform_exit(musb); - /* FIXME power down */ } @@ -2250,6 +2244,13 @@ static int __exit musb_remove(struct platform_device *pdev) */ musb_exit_debugfs(musb); musb_shutdown(pdev); +#ifdef CONFIG_USB_MUSB_HDRC_HCD + if (musb->board_mode == MUSB_HOST) + usb_remove_hcd(musb_to_hcd(musb)); +#endif + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + musb_platform_exit(musb); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0); musb_free(musb); iounmap(ctrl_base); @@ -2410,6 +2411,9 @@ static int musb_suspend(struct device *dev) unsigned long flags; struct musb *musb = dev_to_musb(&pdev->dev); + if (!musb->clock) + return 0; + spin_lock_irqsave(&musb->lock, flags); if (is_peripheral_active(musb)) { @@ -2424,12 +2428,10 @@ static int musb_suspend(struct device *dev) musb_save_context(musb); - if (musb->clock) { - if (musb->set_clock) - musb->set_clock(musb->clock, 0); - else - clk_disable(musb->clock); - } + if (musb->set_clock) + musb->set_clock(musb->clock, 0); + else + clk_disable(musb->clock); spin_unlock_irqrestore(&musb->lock, flags); return 0; } @@ -2439,12 +2441,13 @@ static int musb_resume_noirq(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct musb *musb = dev_to_musb(&pdev->dev); - if (musb->clock) { - if (musb->set_clock) - musb->set_clock(musb->clock, 1); - else - clk_enable(musb->clock); - } + if (!musb->clock) + return 0; + + if (musb->set_clock) + musb->set_clock(musb->clock, 1); + else + clk_enable(musb->clock); musb_restore_context(musb); diff --git a/trunk/drivers/usb/musb/musb_core.h b/trunk/drivers/usb/musb/musb_core.h index febaabcc2b35..69797e5b46a7 100644 --- a/trunk/drivers/usb/musb/musb_core.h +++ b/trunk/drivers/usb/musb/musb_core.h @@ -487,7 +487,7 @@ struct musb_context_registers { }; #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_BLACKFIN) + defined(CONFIG_ARCH_OMAP4) extern void musb_platform_save_context(struct musb *musb, struct musb_context_registers *musb_context); extern void musb_platform_restore_context(struct musb *musb, diff --git a/trunk/drivers/usb/musb/musb_gadget.c b/trunk/drivers/usb/musb/musb_gadget.c index 36cfd060dbe5..5d815049cbaa 100644 --- a/trunk/drivers/usb/musb/musb_gadget.c +++ b/trunk/drivers/usb/musb/musb_gadget.c @@ -644,8 +644,10 @@ static void rxstate(struct musb *musb, struct musb_request *req) */ csr |= MUSB_RXCSR_DMAENAB; + if (!musb_ep->hb_mult && + musb_ep->hw_ep->rx_double_buffered) + csr |= MUSB_RXCSR_AUTOCLEAR; #ifdef USE_MODE1 - csr |= MUSB_RXCSR_AUTOCLEAR; /* csr |= MUSB_RXCSR_DMAMODE; */ /* this special sequence (enabling and then @@ -654,10 +656,6 @@ static void rxstate(struct musb *musb, struct musb_request *req) */ musb_writew(epio, MUSB_RXCSR, csr | MUSB_RXCSR_DMAMODE); -#else - if (!musb_ep->hb_mult && - musb_ep->hw_ep->rx_double_buffered) - csr |= MUSB_RXCSR_AUTOCLEAR; #endif musb_writew(epio, MUSB_RXCSR, csr); @@ -809,7 +807,7 @@ void musb_g_rx(struct musb *musb, u8 epnum) #if defined(CONFIG_USB_INVENTRA_DMA) || defined(CONFIG_USB_TUSB_OMAP_DMA) /* Autoclear doesn't clear RxPktRdy for short packets */ - if ((dma->desired_mode == 0 && !hw_ep->rx_double_buffered) + if ((dma->desired_mode == 0) || (dma->actual_len & (musb_ep->packet_sz - 1))) { /* ack the read! */ @@ -820,16 +818,8 @@ void musb_g_rx(struct musb *musb, u8 epnum) /* incomplete, and not short? wait for next IN packet */ if ((request->actual < request->length) && (musb_ep->dma->actual_len - == musb_ep->packet_sz)) { - /* In double buffer case, continue to unload fifo if - * there is Rx packet in FIFO. - **/ - csr = musb_readw(epio, MUSB_RXCSR); - if ((csr & MUSB_RXCSR_RXPKTRDY) && - hw_ep->rx_double_buffered) - goto exit; + == musb_ep->packet_sz)) return; - } #endif musb_g_giveback(musb_ep, request, 0); @@ -837,7 +827,7 @@ void musb_g_rx(struct musb *musb, u8 epnum) if (!request) return; } -exit: + /* Analyze request */ rxstate(musb, to_musb_request(request)); } @@ -926,9 +916,13 @@ static int musb_gadget_enable(struct usb_ep *ep, * likewise high bandwidth periodic tx */ /* Set TXMAXP with the FIFO size of the endpoint - * to disable double buffering mode. + * to disable double buffering mode. Currently, It seems that double + * buffering has problem if musb RTL revision number < 2.0. */ - musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); + if (musb->hwvers < MUSB_HWVERS_2000) + musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx); + else + musb_writew(regs, MUSB_TXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG; if (musb_readw(regs, MUSB_TXCSR) @@ -964,7 +958,10 @@ static int musb_gadget_enable(struct usb_ep *ep, /* Set RXMAXP with the FIFO size of the endpoint * to disable double buffering mode. */ - musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); + if (musb->hwvers < MUSB_HWVERS_2000) + musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx); + else + musb_writew(regs, MUSB_RXMAXP, musb_ep->packet_sz | (musb_ep->hb_mult << 11)); /* force shared fifo to OUT-only mode */ if (hw_ep->is_shared_fifo) { @@ -1169,6 +1166,8 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, : DMA_FROM_DEVICE); request->mapped = 0; } + } else if (!req->buf) { + return -ENODATA; } else request->mapped = 0; @@ -1696,10 +1695,8 @@ int __init musb_gadget_setup(struct musb *musb) musb_platform_try_idle(musb, 0); status = device_register(&musb->g.dev); - if (status != 0) { - put_device(&musb->g.dev); + if (status != 0) the_gadget = NULL; - } return status; } diff --git a/trunk/drivers/usb/musb/musb_regs.h b/trunk/drivers/usb/musb/musb_regs.h index 5a727c5b8676..244267527a60 100644 --- a/trunk/drivers/usb/musb/musb_regs.h +++ b/trunk/drivers/usb/musb/musb_regs.h @@ -633,9 +633,8 @@ static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) return 0; } -static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) +static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) { - return 0; } #endif /* CONFIG_BLACKFIN */ diff --git a/trunk/drivers/usb/musb/musbhsdma.c b/trunk/drivers/usb/musb/musbhsdma.c index 563114d613d6..6f771af5cbdb 100644 --- a/trunk/drivers/usb/musb/musbhsdma.c +++ b/trunk/drivers/usb/musb/musbhsdma.c @@ -158,8 +158,6 @@ static int dma_channel_program(struct dma_channel *channel, dma_addr_t dma_addr, u32 len) { struct musb_dma_channel *musb_channel = channel->private_data; - struct musb_dma_controller *controller = musb_channel->controller; - struct musb *musb = controller->private_data; DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n", musb_channel->epnum, @@ -169,18 +167,6 @@ static int dma_channel_program(struct dma_channel *channel, BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || channel->status == MUSB_DMA_STATUS_BUSY); - /* - * The DMA engine in RTL1.8 and above cannot handle - * DMA addresses that are not aligned to a 4 byte boundary. - * It ends up masking the last two bits of the address - * programmed in DMA_ADDR. - * - * Fail such DMA transfers, so that the backup PIO mode - * can carry out the transfer - */ - if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr % 4)) - return false; - channel->actual_len = 0; musb_channel->start_addr = dma_addr; musb_channel->len = len; diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 76f8b3556672..89a9a5847803 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -794,8 +794,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, - { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index 263f62551197..7dfe02f1fb6a 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -1100,10 +1100,3 @@ #define FTDI_SCIENCESCOPE_LOGBOOKML_PID 0xFF18 #define FTDI_SCIENCESCOPE_LS_LOGBOOK_PID 0xFF1C #define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID 0xFF1D - -/* - * Milkymist One JTAG/Serial - */ -#define QIHARDWARE_VID 0x20B7 -#define MILKYMISTONE_JTAGSERIAL_PID 0x0713 - diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index ef2977d3a613..2297fb1bcf65 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -518,7 +518,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, + { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, diff --git a/trunk/drivers/usb/storage/uas.c b/trunk/drivers/usb/storage/uas.c index d1268191acbd..2054b1e25a65 100644 --- a/trunk/drivers/usb/storage/uas.c +++ b/trunk/drivers/usb/storage/uas.c @@ -331,7 +331,10 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, iu->iu_id = IU_ID_COMMAND; iu->tag = cpu_to_be16(stream_id); - iu->prio_attr = UAS_SIMPLE_TAG; + if (sdev->ordered_tags && (cmnd->request->cmd_flags & REQ_HARDBARRIER)) + iu->prio_attr = UAS_ORDERED_TAG; + else + iu->prio_attr = UAS_SIMPLE_TAG; iu->len = len; int_to_scsilun(sdev->lun, &iu->lun); memcpy(iu->cdb, cmnd->cmnd, cmnd->cmd_len); diff --git a/trunk/drivers/uwb/allocator.c b/trunk/drivers/uwb/allocator.c index e45e673b8770..436e4f7110cb 100644 --- a/trunk/drivers/uwb/allocator.c +++ b/trunk/drivers/uwb/allocator.c @@ -326,8 +326,7 @@ int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *availab int bit_index; ai = kzalloc(sizeof(struct uwb_rsv_alloc_info), GFP_KERNEL); - if (!ai) - return UWB_RSV_ALLOC_NOT_FOUND; + ai->min_mas = rsv->min_mas; ai->max_mas = rsv->max_mas; ai->max_interval = rsv->max_interval; diff --git a/trunk/drivers/video/backlight/adp8860_bl.c b/trunk/drivers/video/backlight/adp8860_bl.c index 734c650a47c4..3ec24609151e 100644 --- a/trunk/drivers/video/backlight/adp8860_bl.c +++ b/trunk/drivers/video/backlight/adp8860_bl.c @@ -502,10 +502,8 @@ static ssize_t adp8860_bl_l1_daylight_max_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct adp8860_bl *data = dev_get_drvdata(dev); - int ret = strict_strtoul(buf, 10, &data->cached_daylight_max); - if (ret) - return ret; + strict_strtoul(buf, 10, &data->cached_daylight_max); return adp8860_store(dev, buf, count, ADP8860_BLMX1); } static DEVICE_ATTR(l1_daylight_max, 0664, adp8860_bl_l1_daylight_max_show, @@ -616,7 +614,7 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, if (val == 0) { /* Enable automatic ambient light sensing */ adp8860_set_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); - } else if ((val > 0) && (val <= 3)) { + } else if ((val > 0) && (val < 6)) { /* Disable automatic ambient light sensing */ adp8860_clr_bits(data->client, ADP8860_MDCR, CMP_AUTOEN); @@ -624,7 +622,7 @@ static ssize_t adp8860_bl_ambient_light_zone_store(struct device *dev, mutex_lock(&data->lock); adp8860_read(data->client, ADP8860_CFGR, ®_val); reg_val &= ~(CFGR_BLV_MASK << CFGR_BLV_SHIFT); - reg_val |= (val - 1) << CFGR_BLV_SHIFT; + reg_val |= val << CFGR_BLV_SHIFT; adp8860_write(data->client, ADP8860_CFGR, reg_val); mutex_unlock(&data->lock); } diff --git a/trunk/drivers/video/backlight/l4f00242t03.c b/trunk/drivers/video/backlight/l4f00242t03.c index c67801e57aaf..9093ef0fa869 100644 --- a/trunk/drivers/video/backlight/l4f00242t03.c +++ b/trunk/drivers/video/backlight/l4f00242t03.c @@ -78,7 +78,7 @@ static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) const u16 slpin = 0x10; const u16 disoff = 0x28; - if (power <= FB_BLANK_NORMAL) { + if (power) { if (priv->lcd_on) return 0; diff --git a/trunk/drivers/video/backlight/lms283gf05.c b/trunk/drivers/video/backlight/lms283gf05.c index 5d3cf33953ac..abc43a0eb97d 100644 --- a/trunk/drivers/video/backlight/lms283gf05.c +++ b/trunk/drivers/video/backlight/lms283gf05.c @@ -129,7 +129,7 @@ static int lms283gf05_power_set(struct lcd_device *ld, int power) struct spi_device *spi = st->spi; struct lms283gf05_pdata *pdata = spi->dev.platform_data; - if (power <= FB_BLANK_NORMAL) { + if (power) { if (pdata) lms283gf05_reset(pdata->reset_gpio, pdata->reset_inverted); diff --git a/trunk/drivers/video/backlight/mbp_nvidia_bl.c b/trunk/drivers/video/backlight/mbp_nvidia_bl.c index 1485f7345f49..9fb533f6373e 100644 --- a/trunk/drivers/video/backlight/mbp_nvidia_bl.c +++ b/trunk/drivers/video/backlight/mbp_nvidia_bl.c @@ -335,24 +335,6 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { }, .driver_data = (void *)&nvidia_chipset_data, }, - { - .callback = mbp_dmi_match, - .ident = "MacBookAir 3,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,1"), - }, - .driver_data = (void *)&nvidia_chipset_data, - }, - { - .callback = mbp_dmi_match, - .ident = "MacBookAir 3,2", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir3,2"), - }, - .driver_data = (void *)&nvidia_chipset_data, - }, { } }; diff --git a/trunk/drivers/video/backlight/pwm_bl.c b/trunk/drivers/video/backlight/pwm_bl.c index 21866ec69656..550443518891 100644 --- a/trunk/drivers/video/backlight/pwm_bl.c +++ b/trunk/drivers/video/backlight/pwm_bl.c @@ -25,7 +25,6 @@ struct pwm_bl_data { struct pwm_device *pwm; struct device *dev; unsigned int period; - unsigned int lth_brightness; int (*notify)(struct device *, int brightness); }; @@ -49,9 +48,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) pwm_config(pb->pwm, 0, pb->period); pwm_disable(pb->pwm); } else { - brightness = pb->lth_brightness + - (brightness * (pb->period - pb->lth_brightness) / max); - pwm_config(pb->pwm, brightness, pb->period); + pwm_config(pb->pwm, brightness * pb->period / max, pb->period); pwm_enable(pb->pwm); } return 0; @@ -95,8 +92,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->period = data->pwm_period_ns; pb->notify = data->notify; - pb->lth_brightness = data->lth_brightness * - (data->pwm_period_ns / data->max_brightness); pb->dev = &pdev->dev; pb->pwm = pwm_request(data->pwm_id, "backlight"); diff --git a/trunk/drivers/video/backlight/s6e63m0.c b/trunk/drivers/video/backlight/s6e63m0.c index 5927db0da999..a3128c9cb7ad 100644 --- a/trunk/drivers/video/backlight/s6e63m0.c +++ b/trunk/drivers/video/backlight/s6e63m0.c @@ -729,10 +729,10 @@ static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev, return strlen(buf); } -static DEVICE_ATTR(gamma_table, 0444, +static DEVICE_ATTR(gamma_table, 0644, s6e63m0_sysfs_show_gamma_table, NULL); -static int __devinit s6e63m0_probe(struct spi_device *spi) +static int __init s6e63m0_probe(struct spi_device *spi) { int ret = 0; struct s6e63m0 *lcd = NULL; @@ -829,9 +829,6 @@ static int __devexit s6e63m0_remove(struct spi_device *spi) struct s6e63m0 *lcd = dev_get_drvdata(&spi->dev); s6e63m0_power(lcd, FB_BLANK_POWERDOWN); - device_remove_file(&spi->dev, &dev_attr_gamma_table); - device_remove_file(&spi->dev, &dev_attr_gamma_mode); - backlight_device_unregister(lcd->bd); lcd_device_unregister(lcd->ld); kfree(lcd); diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 321a0c8346e5..97612f548a8e 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -1299,6 +1299,9 @@ static void restore_cpu_virqs(unsigned int cpu) evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_virq_info(evtchn, virq); bind_evtchn_to_cpu(evtchn, cpu); + + /* Ready for use. */ + unmask_evtchn(evtchn); } } @@ -1324,6 +1327,10 @@ static void restore_cpu_ipis(unsigned int cpu) evtchn_to_irq[evtchn] = irq; irq_info[irq] = mk_ipi_info(evtchn, ipi); bind_evtchn_to_cpu(evtchn, cpu); + + /* Ready for use. */ + unmask_evtchn(evtchn); + } } @@ -1383,7 +1390,6 @@ void xen_poll_irq(int irq) void xen_irq_resume(void) { unsigned int cpu, irq, evtchn; - struct irq_desc *desc; init_evtchn_cpu_bindings(); @@ -1402,23 +1408,6 @@ void xen_irq_resume(void) restore_cpu_virqs(cpu); restore_cpu_ipis(cpu); } - - /* - * Unmask any IRQF_NO_SUSPEND IRQs which are enabled. These - * are not handled by the IRQ core. - */ - for_each_irq_desc(irq, desc) { - if (!desc->action || !(desc->action->flags & IRQF_NO_SUSPEND)) - continue; - if (desc->status & IRQ_DISABLED) - continue; - - evtchn = evtchn_from_irq(irq); - if (evtchn == -1) - continue; - - unmask_evtchn(evtchn); - } } static struct irq_chip xen_dynamic_chip __read_mostly = { diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index 4bd454fa844e..8abb2dfb2e7c 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -370,9 +370,6 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs) { struct bio *bio; - if (nr_iovecs > UIO_MAXIOV) - return NULL; - bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec), gfp_mask); if (unlikely(!bio)) @@ -700,12 +697,8 @@ static void bio_free_map_data(struct bio_map_data *bmd) static struct bio_map_data *bio_alloc_map_data(int nr_segs, int iov_count, gfp_t gfp_mask) { - struct bio_map_data *bmd; + struct bio_map_data *bmd = kmalloc(sizeof(*bmd), gfp_mask); - if (iov_count > UIO_MAXIOV) - return NULL; - - bmd = kmalloc(sizeof(*bmd), gfp_mask); if (!bmd) return NULL; @@ -834,12 +827,6 @@ struct bio *bio_copy_user_iov(struct request_queue *q, end = (uaddr + iov[i].iov_len + PAGE_SIZE - 1) >> PAGE_SHIFT; start = uaddr >> PAGE_SHIFT; - /* - * Overflow, abort - */ - if (end < start) - return ERR_PTR(-EINVAL); - nr_pages += end - start; len += iov[i].iov_len; } @@ -968,12 +955,6 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; unsigned long start = uaddr >> PAGE_SHIFT; - /* - * Overflow, abort - */ - if (end < start) - return ERR_PTR(-EINVAL); - nr_pages += end - start; /* * buffer must be aligned to at least hardsector size for now @@ -1001,7 +982,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q, unsigned long start = uaddr >> PAGE_SHIFT; const int local_nr_pages = end - start; const int page_limit = cur_page + local_nr_pages; - + ret = get_user_pages_fast(uaddr, local_nr_pages, write_to_vm, &pages[cur_page]); if (ret < local_nr_pages) { diff --git a/trunk/fs/cifs/TODO b/trunk/fs/cifs/TODO index 355abcdcda98..5aff46c61e52 100644 --- a/trunk/fs/cifs/TODO +++ b/trunk/fs/cifs/TODO @@ -81,7 +81,7 @@ u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for v) mount check for unmatched uids -w) Add support for new vfs entry point for fallocate +w) Add support for new vfs entry points for setlease and fallocate x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of processes can proceed better in parallel (on the server) diff --git a/trunk/fs/cifs/cifs_fs_sb.h b/trunk/fs/cifs/cifs_fs_sb.h index e9a393c9c2ca..525ba59a4105 100644 --- a/trunk/fs/cifs/cifs_fs_sb.h +++ b/trunk/fs/cifs/cifs_fs_sb.h @@ -15,7 +15,7 @@ * the GNU Lesser General Public License for more details. * */ -#include +#include #ifndef _CIFS_FS_SB_H #define _CIFS_FS_SB_H @@ -42,9 +42,9 @@ #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ struct cifs_sb_info { - struct rb_root tlink_tree; + struct radix_tree_root tlink_tree; +#define CIFS_TLINK_MASTER_TAG 0 /* is "master" (mount) tcon */ spinlock_t tlink_tree_lock; - struct tcon_link *master_tlink; struct nls_table *local_nls; unsigned int rsize; unsigned int wsize; diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 9c3789762ab7..75c4eaa79588 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -116,7 +116,7 @@ cifs_read_super(struct super_block *sb, void *data, return -ENOMEM; spin_lock_init(&cifs_sb->tlink_tree_lock); - cifs_sb->tlink_tree = RB_ROOT; + INIT_RADIX_TREE(&cifs_sb->tlink_tree, GFP_KERNEL); rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); if (rc) { @@ -321,7 +321,8 @@ cifs_alloc_inode(struct super_block *sb) /* Until the file is open and we have gotten oplock info back from the server, can not assume caching of file data or metadata */ - cifs_set_oplock_level(cifs_inode, 0); + cifs_inode->clientCanCacheRead = false; + cifs_inode->clientCanCacheAll = false; cifs_inode->delete_pending = false; cifs_inode->invalid_mapping = false; cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index b577bf0a1bb3..f259e4d7612d 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -336,8 +336,7 @@ struct cifsTconInfo { * "get" on the container. */ struct tcon_link { - struct rb_node tl_rbnode; - uid_t tl_uid; + unsigned long tl_index; unsigned long tl_flags; #define TCON_LINK_MASTER 0 #define TCON_LINK_PENDING 1 diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index 7ed69b6b5fe6..edb6d90efdf2 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -104,7 +104,6 @@ extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); extern u64 cifs_UnixTimeToNT(struct timespec); extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset); -extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, struct file *file, struct tcon_link *tlink, diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 251a17c03545..9eb327defa1d 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -116,7 +116,6 @@ struct smb_vol { static int ipv4_connect(struct TCP_Server_Info *server); static int ipv6_connect(struct TCP_Server_Info *server); -static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); static void cifs_prune_tlinks(struct work_struct *work); /* @@ -2901,16 +2900,24 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, goto mount_fail_check; } - tlink->tl_uid = pSesInfo->linux_uid; + tlink->tl_index = pSesInfo->linux_uid; tlink->tl_tcon = tcon; tlink->tl_time = jiffies; set_bit(TCON_LINK_MASTER, &tlink->tl_flags); set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); - cifs_sb->master_tlink = tlink; + rc = radix_tree_preload(GFP_KERNEL); + if (rc == -ENOMEM) { + kfree(tlink); + goto mount_fail_check; + } + spin_lock(&cifs_sb->tlink_tree_lock); - tlink_rb_insert(&cifs_sb->tlink_tree, tlink); + radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink); + radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid, + CIFS_TLINK_MASTER_TAG); spin_unlock(&cifs_sb->tlink_tree_lock); + radix_tree_preload_end(); queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, TLINK_IDLE_EXPIRE); @@ -3100,25 +3107,32 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, int cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) { - struct rb_root *root = &cifs_sb->tlink_tree; - struct rb_node *node; - struct tcon_link *tlink; + int i, ret; char *tmp; + struct tcon_link *tlink[8]; + unsigned long index = 0; cancel_delayed_work_sync(&cifs_sb->prune_tlinks); - spin_lock(&cifs_sb->tlink_tree_lock); - while ((node = rb_first(root))) { - tlink = rb_entry(node, struct tcon_link, tl_rbnode); - cifs_get_tlink(tlink); - clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); - rb_erase(node, root); - - spin_unlock(&cifs_sb->tlink_tree_lock); - cifs_put_tlink(tlink); + do { spin_lock(&cifs_sb->tlink_tree_lock); - } - spin_unlock(&cifs_sb->tlink_tree_lock); + ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree, + (void **)tlink, index, + ARRAY_SIZE(tlink)); + /* increment index for next pass */ + if (ret > 0) + index = tlink[ret - 1]->tl_index + 1; + for (i = 0; i < ret; i++) { + cifs_get_tlink(tlink[i]); + clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags); + radix_tree_delete(&cifs_sb->tlink_tree, + tlink[i]->tl_index); + } + spin_unlock(&cifs_sb->tlink_tree_lock); + + for (i = 0; i < ret; i++) + cifs_put_tlink(tlink[i]); + } while (ret != 0); tmp = cifs_sb->prepath; cifs_sb->prepathlen = 0; @@ -3257,10 +3271,22 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) return tcon; } -static inline struct tcon_link * +static struct tcon_link * cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) { - return cifs_sb->master_tlink; + struct tcon_link *tlink; + unsigned int ret; + + spin_lock(&cifs_sb->tlink_tree_lock); + ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink, + 0, 1, CIFS_TLINK_MASTER_TAG); + spin_unlock(&cifs_sb->tlink_tree_lock); + + /* the master tcon should always be present */ + if (ret == 0) + BUG(); + + return tlink; } struct cifsTconInfo * @@ -3276,47 +3302,6 @@ cifs_sb_tcon_pending_wait(void *unused) return signal_pending(current) ? -ERESTARTSYS : 0; } -/* find and return a tlink with given uid */ -static struct tcon_link * -tlink_rb_search(struct rb_root *root, uid_t uid) -{ - struct rb_node *node = root->rb_node; - struct tcon_link *tlink; - - while (node) { - tlink = rb_entry(node, struct tcon_link, tl_rbnode); - - if (tlink->tl_uid > uid) - node = node->rb_left; - else if (tlink->tl_uid < uid) - node = node->rb_right; - else - return tlink; - } - return NULL; -} - -/* insert a tcon_link into the tree */ -static void -tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) -{ - struct rb_node **new = &(root->rb_node), *parent = NULL; - struct tcon_link *tlink; - - while (*new) { - tlink = rb_entry(*new, struct tcon_link, tl_rbnode); - parent = *new; - - if (tlink->tl_uid > new_tlink->tl_uid) - new = &((*new)->rb_left); - else - new = &((*new)->rb_right); - } - - rb_link_node(&new_tlink->tl_rbnode, parent, new); - rb_insert_color(&new_tlink->tl_rbnode, root); -} - /* * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the * current task. @@ -3324,7 +3309,7 @@ tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) * If the superblock doesn't refer to a multiuser mount, then just return * the master tcon for the mount. * - * First, search the rbtree for an existing tcon for this fsuid. If one + * First, search the radix tree for an existing tcon for this fsuid. If one * exists, then check to see if it's pending construction. If it is then wait * for construction to complete. Once it's no longer pending, check to see if * it failed and either return an error or retry construction, depending on @@ -3337,14 +3322,14 @@ struct tcon_link * cifs_sb_tlink(struct cifs_sb_info *cifs_sb) { int ret; - uid_t fsuid = current_fsuid(); + unsigned long fsuid = (unsigned long) current_fsuid(); struct tcon_link *tlink, *newtlink; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); spin_lock(&cifs_sb->tlink_tree_lock); - tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); + tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid); if (tlink) cifs_get_tlink(tlink); spin_unlock(&cifs_sb->tlink_tree_lock); @@ -3353,24 +3338,36 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb) newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); if (newtlink == NULL) return ERR_PTR(-ENOMEM); - newtlink->tl_uid = fsuid; + newtlink->tl_index = fsuid; newtlink->tl_tcon = ERR_PTR(-EACCES); set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); cifs_get_tlink(newtlink); + ret = radix_tree_preload(GFP_KERNEL); + if (ret != 0) { + kfree(newtlink); + return ERR_PTR(ret); + } + spin_lock(&cifs_sb->tlink_tree_lock); /* was one inserted after previous search? */ - tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); + tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid); if (tlink) { cifs_get_tlink(tlink); spin_unlock(&cifs_sb->tlink_tree_lock); + radix_tree_preload_end(); kfree(newtlink); goto wait_for_construction; } - tlink = newtlink; - tlink_rb_insert(&cifs_sb->tlink_tree, tlink); + ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink); spin_unlock(&cifs_sb->tlink_tree_lock); + radix_tree_preload_end(); + if (ret) { + kfree(newtlink); + return ERR_PTR(ret); + } + tlink = newtlink; } else { wait_for_construction: ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, @@ -3416,39 +3413,39 @@ cifs_prune_tlinks(struct work_struct *work) { struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info, prune_tlinks.work); - struct rb_root *root = &cifs_sb->tlink_tree; - struct rb_node *node = rb_first(root); - struct rb_node *tmp; - struct tcon_link *tlink; + struct tcon_link *tlink[8]; + unsigned long now = jiffies; + unsigned long index = 0; + int i, ret; - /* - * Because we drop the spinlock in the loop in order to put the tlink - * it's not guarded against removal of links from the tree. The only - * places that remove entries from the tree are this function and - * umounts. Because this function is non-reentrant and is canceled - * before umount can proceed, this is safe. - */ - spin_lock(&cifs_sb->tlink_tree_lock); - node = rb_first(root); - while (node != NULL) { - tmp = node; - node = rb_next(tmp); - tlink = rb_entry(tmp, struct tcon_link, tl_rbnode); - - if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) || - atomic_read(&tlink->tl_count) != 0 || - time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies)) - continue; - - cifs_get_tlink(tlink); - clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); - rb_erase(tmp, root); - - spin_unlock(&cifs_sb->tlink_tree_lock); - cifs_put_tlink(tlink); + do { spin_lock(&cifs_sb->tlink_tree_lock); - } - spin_unlock(&cifs_sb->tlink_tree_lock); + ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree, + (void **)tlink, index, + ARRAY_SIZE(tlink)); + /* increment index for next pass */ + if (ret > 0) + index = tlink[ret - 1]->tl_index + 1; + for (i = 0; i < ret; i++) { + if (test_bit(TCON_LINK_MASTER, &tlink[i]->tl_flags) || + atomic_read(&tlink[i]->tl_count) != 0 || + time_after(tlink[i]->tl_time + TLINK_IDLE_EXPIRE, + now)) { + tlink[i] = NULL; + continue; + } + cifs_get_tlink(tlink[i]); + clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags); + radix_tree_delete(&cifs_sb->tlink_tree, + tlink[i]->tl_index); + } + spin_unlock(&cifs_sb->tlink_tree_lock); + + for (i = 0; i < ret; i++) { + if (tlink[i] != NULL) + cifs_put_tlink(tlink[i]); + } + } while (ret != 0); queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, TLINK_IDLE_EXPIRE); diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 06c3e83fa387..ae82159cf7fa 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -146,7 +146,12 @@ static inline int cifs_open_inode_helper(struct inode *inode, rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, xid, NULL); - cifs_set_oplock_level(pCifsInode, oplock); + if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { + pCifsInode->clientCanCacheAll = true; + pCifsInode->clientCanCacheRead = true; + cFYI(1, "Exclusive Oplock granted on inode %p", inode); + } else if ((oplock & 0xF) == OPLOCK_READ) + pCifsInode->clientCanCacheRead = true; return rc; } @@ -248,7 +253,12 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); spin_unlock(&cifs_file_list_lock); - cifs_set_oplock_level(pCifsInode, oplock); + if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { + pCifsInode->clientCanCacheAll = true; + pCifsInode->clientCanCacheRead = true; + cFYI(1, "Exclusive Oplock inode %p", inode); + } else if ((oplock & 0xF) == OPLOCK_READ) + pCifsInode->clientCanCacheRead = true; file->private_data = pCifsFile; return pCifsFile; @@ -261,9 +271,8 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, */ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) { - struct inode *inode = cifs_file->dentry->d_inode; struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); - struct cifsInodeInfo *cifsi = CIFS_I(inode); + struct cifsInodeInfo *cifsi = CIFS_I(cifs_file->dentry->d_inode); struct cifsLockInfo *li, *tmp; spin_lock(&cifs_file_list_lock); @@ -279,7 +288,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) if (list_empty(&cifsi->openFileList)) { cFYI(1, "closing last open instance for inode %p", cifs_file->dentry->d_inode); - cifs_set_oplock_level(cifsi, 0); + cifsi->clientCanCacheRead = false; + cifsi->clientCanCacheAll = false; } spin_unlock(&cifs_file_list_lock); @@ -597,6 +607,8 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush) rc = filemap_write_and_wait(inode->i_mapping); mapping_set_error(inode->i_mapping, rc); + pCifsInode->clientCanCacheAll = false; + pCifsInode->clientCanCacheRead = false; if (tcon->unix_ext) rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, xid); @@ -610,9 +622,18 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush) invalidate the current end of file on the server we can not go to the server to get the new inod info */ - - cifs_set_oplock_level(pCifsInode, oplock); - + if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { + pCifsInode->clientCanCacheAll = true; + pCifsInode->clientCanCacheRead = true; + cFYI(1, "Exclusive Oplock granted on inode %p", + pCifsFile->dentry->d_inode); + } else if ((oplock & 0xF) == OPLOCK_READ) { + pCifsInode->clientCanCacheRead = true; + pCifsInode->clientCanCacheAll = false; + } else { + pCifsInode->clientCanCacheRead = false; + pCifsInode->clientCanCacheAll = false; + } cifs_relock_file(pCifsFile); reopen_error_exit: @@ -754,6 +775,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); + + if (file->private_data == NULL) { + rc = -EBADF; + FreeXid(xid); + return rc; + } netfid = ((struct cifsFileInfo *)file->private_data)->netfid; if ((tcon->ses->capabilities & CAP_UNIX) && @@ -929,7 +956,6 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, ssize_t cifs_user_write(struct file *file, const char __user *write_data, size_t write_size, loff_t *poffset) { - struct inode *inode = file->f_path.dentry->d_inode; int rc = 0; unsigned int bytes_written = 0; unsigned int total_written; @@ -937,7 +963,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, struct cifsTconInfo *pTcon; int xid, long_op; struct cifsFileInfo *open_file; - struct cifsInodeInfo *cifsi = CIFS_I(inode); + struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); @@ -1003,17 +1029,21 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, cifs_stats_bytes_written(pTcon, total_written); + /* since the write may have blocked check these pointers again */ + if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { + struct inode *inode = file->f_path.dentry->d_inode; /* Do not update local mtime - server will set its actual value on write - * inode->i_ctime = inode->i_mtime = - * current_fs_time(inode->i_sb);*/ - if (total_written > 0) { - spin_lock(&inode->i_lock); - if (*poffset > inode->i_size) - i_size_write(inode, *poffset); - spin_unlock(&inode->i_lock); + * inode->i_ctime = inode->i_mtime = + * current_fs_time(inode->i_sb);*/ + if (total_written > 0) { + spin_lock(&inode->i_lock); + if (*poffset > file->f_path.dentry->d_inode->i_size) + i_size_write(file->f_path.dentry->d_inode, + *poffset); + spin_unlock(&inode->i_lock); + } + mark_inode_dirty_sync(file->f_path.dentry->d_inode); } - mark_inode_dirty_sync(inode); - FreeXid(xid); return total_written; } @@ -1148,7 +1178,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only) { struct cifsFileInfo *open_file; - struct cifs_sb_info *cifs_sb; + struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); bool any_available = false; int rc; @@ -1162,8 +1192,6 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, return NULL; } - cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); - /* only filter by fsuid on multiuser mounts */ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) fsuid_only = false; diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index ef3a55bf86b6..39869c3c3efb 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -2177,6 +2177,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) setattr_copy(inode, attrs); mark_inode_dirty(inode); + return 0; cifs_setattr_exit: kfree(full_path); diff --git a/trunk/fs/cifs/ioctl.c b/trunk/fs/cifs/ioctl.c index 0c98672d0122..077bf756f342 100644 --- a/trunk/fs/cifs/ioctl.c +++ b/trunk/fs/cifs/ioctl.c @@ -38,10 +38,10 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) struct cifs_sb_info *cifs_sb; #ifdef CONFIG_CIFS_POSIX struct cifsFileInfo *pSMBFile = filep->private_data; - struct cifsTconInfo *tcon; + struct cifsTconInfo *tcon = tlink_tcon(pSMBFile->tlink); __u64 ExtAttrBits = 0; __u64 ExtAttrMask = 0; - __u64 caps; + __u64 caps = le64_to_cpu(tcon->fsUnixInfo.Capability); #endif /* CONFIG_CIFS_POSIX */ xid = GetXid(); @@ -62,11 +62,9 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) break; #ifdef CONFIG_CIFS_POSIX case FS_IOC_GETFLAGS: - if (pSMBFile == NULL) - break; - tcon = tlink_tcon(pSMBFile->tlink); - caps = le64_to_cpu(tcon->fsUnixInfo.Capability); if (CIFS_UNIX_EXTATTR_CAP & caps) { + if (pSMBFile == NULL) + break; rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, &ExtAttrBits, &ExtAttrMask); if (rc == 0) @@ -77,15 +75,13 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) break; case FS_IOC_SETFLAGS: - if (pSMBFile == NULL) - break; - tcon = tlink_tcon(pSMBFile->tlink); - caps = le64_to_cpu(tcon->fsUnixInfo.Capability); if (CIFS_UNIX_EXTATTR_CAP & caps) { if (get_user(ExtAttrBits, (int __user *)arg)) { rc = -EFAULT; break; } + if (pSMBFile == NULL) + break; /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, extAttrBits, &ExtAttrMask);*/ } diff --git a/trunk/fs/cifs/misc.c b/trunk/fs/cifs/misc.c index 43f10281bc19..c4e296fe3518 100644 --- a/trunk/fs/cifs/misc.c +++ b/trunk/fs/cifs/misc.c @@ -569,9 +569,10 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) cFYI(1, "file id match, oplock break"); pCifsInode = CIFS_I(netfile->dentry->d_inode); + pCifsInode->clientCanCacheAll = false; + if (pSMB->OplockLevel == 0) + pCifsInode->clientCanCacheRead = false; - cifs_set_oplock_level(pCifsInode, - pSMB->OplockLevel); /* * cifs_oplock_break_put() can't be called * from here. Get reference after queueing @@ -721,23 +722,3 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) cifs_sb_master_tcon(cifs_sb)->treeName); } } - -void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) -{ - oplock &= 0xF; - - if (oplock == OPLOCK_EXCLUSIVE) { - cinode->clientCanCacheAll = true; - cinode->clientCanCacheRead = true; - cFYI(1, "Exclusive Oplock granted on inode %p", - &cinode->vfs_inode); - } else if (oplock == OPLOCK_READ) { - cinode->clientCanCacheAll = false; - cinode->clientCanCacheRead = true; - cFYI(1, "Level II Oplock granted on inode %p", - &cinode->vfs_inode); - } else { - cinode->clientCanCacheAll = false; - cinode->clientCanCacheRead = false; - } -} diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 6a5edea2d70b..8b5dd6369f82 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -177,7 +177,7 @@ struct mpage_da_data { struct ext4_io_page { struct page *p_page; - atomic_t p_count; + int p_count; }; #define MAX_IO_PAGES 128 @@ -858,7 +858,6 @@ struct ext4_inode_info { spinlock_t i_completed_io_lock; /* current io_end structure for async DIO write*/ ext4_io_end_t *cur_aio_dio; - atomic_t i_ioend_count; /* Number of outstanding io_end structs */ /* * Transactions that contain inode's metadata needed to complete @@ -2061,7 +2060,6 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, /* page-io.c */ extern int __init ext4_init_pageio(void); extern void ext4_exit_pageio(void); -extern void ext4_ioend_wait(struct inode *); extern void ext4_free_io_end(ext4_io_end_t *io); extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); extern int ext4_end_io_nolock(ext4_io_end_t *io); diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index bdbe69902207..191616470466 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -53,7 +53,6 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode, loff_t new_size) { - trace_ext4_begin_ordered_truncate(inode, new_size); return jbd2_journal_begin_ordered_truncate( EXT4_SB(inode->i_sb)->s_journal, &EXT4_I(inode)->jinode, @@ -179,7 +178,6 @@ void ext4_evict_inode(struct inode *inode) handle_t *handle; int err; - trace_ext4_evict_inode(inode); if (inode->i_nlink) { truncate_inode_pages(&inode->i_data, 0); goto no_delete; @@ -5412,7 +5410,9 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, * will return the blocks that include the delayed allocation * blocks for this file. */ + spin_lock(&EXT4_I(inode)->i_block_reservation_lock); delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; + spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; return 0; @@ -5649,7 +5649,6 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) int err, ret; might_sleep(); - trace_ext4_mark_inode_dirty(inode, _RET_IP_); err = ext4_reserve_inode_write(handle, inode, &iloc); if (ext4_handle_valid(handle) && EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index 5b4d4e3a4d58..c58eba34724a 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -4640,6 +4640,8 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, * with group lock held. generate_buddy look at * them with group lock_held */ + if (test_opt(sb, DISCARD)) + ext4_issue_discard(sb, block_group, bit, count); ext4_lock_group(sb, block_group); mb_clear_bits(bitmap_bh->b_data, bit, count); mb_free_blocks(inode, &e4b, bit, count); diff --git a/trunk/fs/ext4/page-io.c b/trunk/fs/ext4/page-io.c index 7f5451cd1d38..46a7d6a9d976 100644 --- a/trunk/fs/ext4/page-io.c +++ b/trunk/fs/ext4/page-io.c @@ -32,14 +32,8 @@ static struct kmem_cache *io_page_cachep, *io_end_cachep; -#define WQ_HASH_SZ 37 -#define to_ioend_wq(v) (&ioend_wq[((unsigned long)v) % WQ_HASH_SZ]) -static wait_queue_head_t ioend_wq[WQ_HASH_SZ]; - int __init ext4_init_pageio(void) { - int i; - io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT); if (io_page_cachep == NULL) return -ENOMEM; @@ -48,8 +42,6 @@ int __init ext4_init_pageio(void) kmem_cache_destroy(io_page_cachep); return -ENOMEM; } - for (i = 0; i < WQ_HASH_SZ; i++) - init_waitqueue_head(&ioend_wq[i]); return 0; } @@ -60,37 +52,24 @@ void ext4_exit_pageio(void) kmem_cache_destroy(io_page_cachep); } -void ext4_ioend_wait(struct inode *inode) -{ - wait_queue_head_t *wq = to_ioend_wq(inode); - - wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0)); -} - -static void put_io_page(struct ext4_io_page *io_page) -{ - if (atomic_dec_and_test(&io_page->p_count)) { - end_page_writeback(io_page->p_page); - put_page(io_page->p_page); - kmem_cache_free(io_page_cachep, io_page); - } -} - void ext4_free_io_end(ext4_io_end_t *io) { int i; - wait_queue_head_t *wq; BUG_ON(!io); if (io->page) put_page(io->page); - for (i = 0; i < io->num_io_pages; i++) - put_io_page(io->pages[i]); + for (i = 0; i < io->num_io_pages; i++) { + if (--io->pages[i]->p_count == 0) { + struct page *page = io->pages[i]->p_page; + + end_page_writeback(page); + put_page(page); + kmem_cache_free(io_page_cachep, io->pages[i]); + } + } io->num_io_pages = 0; - wq = to_ioend_wq(io->inode); - if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count) && - waitqueue_active(wq)) - wake_up_all(wq); + iput(io->inode); kmem_cache_free(io_end_cachep, io); } @@ -163,8 +142,8 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags) io = kmem_cache_alloc(io_end_cachep, flags); if (io) { memset(io, 0, sizeof(*io)); - atomic_inc(&EXT4_I(inode)->i_ioend_count); - io->inode = inode; + io->inode = igrab(inode); + BUG_ON(!io->inode); INIT_WORK(&io->work, ext4_end_io_work); INIT_LIST_HEAD(&io->list); } @@ -192,15 +171,35 @@ static void ext4_end_bio(struct bio *bio, int error) struct workqueue_struct *wq; struct inode *inode; unsigned long flags; + ext4_fsblk_t err_block; int i; BUG_ON(!io_end); + inode = io_end->inode; bio->bi_private = NULL; bio->bi_end_io = NULL; if (test_bit(BIO_UPTODATE, &bio->bi_flags)) error = 0; + err_block = bio->bi_sector >> (inode->i_blkbits - 9); bio_put(bio); + if (!(inode->i_sb->s_flags & MS_ACTIVE)) { + pr_err("sb umounted, discard end_io request for inode %lu\n", + io_end->inode->i_ino); + ext4_free_io_end(io_end); + return; + } + + if (error) { + io_end->flag |= EXT4_IO_END_ERROR; + ext4_warning(inode->i_sb, "I/O error writing to inode %lu " + "(offset %llu size %ld starting block %llu)", + inode->i_ino, + (unsigned long long) io_end->offset, + (long) io_end->size, + (unsigned long long) err_block); + } + for (i = 0; i < io_end->num_io_pages; i++) { struct page *page = io_end->pages[i]->p_page; struct buffer_head *bh, *head; @@ -237,7 +236,13 @@ static void ext4_end_bio(struct bio *bio, int error) } while (bh != head); } - put_io_page(io_end->pages[i]); + if (--io_end->pages[i]->p_count == 0) { + struct page *page = io_end->pages[i]->p_page; + + end_page_writeback(page); + put_page(page); + kmem_cache_free(io_page_cachep, io_end->pages[i]); + } /* * If this is a partial write which happened to make @@ -249,19 +254,8 @@ static void ext4_end_bio(struct bio *bio, int error) if (!partial_write) SetPageUptodate(page); } - io_end->num_io_pages = 0; - inode = io_end->inode; - if (error) { - io_end->flag |= EXT4_IO_END_ERROR; - ext4_warning(inode->i_sb, "I/O error writing to inode %lu " - "(offset %llu size %ld starting block %llu)", - inode->i_ino, - (unsigned long long) io_end->offset, - (long) io_end->size, - (unsigned long long) - bio->bi_sector >> (inode->i_blkbits - 9)); - } + io_end->num_io_pages = 0; /* Add the io_end to per-inode completed io list*/ spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); @@ -311,6 +305,7 @@ static int io_submit_init(struct ext4_io_submit *io, bio->bi_private = io->io_end = io_end; bio->bi_end_io = ext4_end_bio; + io_end->inode = inode; io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh); io->io_bio = bio; @@ -365,7 +360,7 @@ static int io_submit_add_bh(struct ext4_io_submit *io, if ((io_end->num_io_pages == 0) || (io_end->pages[io_end->num_io_pages-1] != io_page)) { io_end->pages[io_end->num_io_pages++] = io_page; - atomic_inc(&io_page->p_count); + io_page->p_count++; } return 0; } @@ -394,7 +389,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, return -ENOMEM; } io_page->p_page = page; - atomic_set(&io_page->p_count, 1); + io_page->p_count = 0; get_page(page); for (bh = head = page_buffers(page), block_start = 0; @@ -426,6 +421,10 @@ int ext4_bio_write_page(struct ext4_io_submit *io, * PageWriteback bit from the page to prevent the system from * wedging later on. */ - put_io_page(io_page); + if (io_page->p_count == 0) { + put_page(page); + end_page_writeback(page); + kmem_cache_free(io_page_cachep, io_page); + } return ret; } diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 61182fe6254e..40131b777af6 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -828,22 +828,12 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) ei->cur_aio_dio = NULL; ei->i_sync_tid = 0; ei->i_datasync_tid = 0; - atomic_set(&ei->i_ioend_count, 0); return &ei->vfs_inode; } -static int ext4_drop_inode(struct inode *inode) -{ - int drop = generic_drop_inode(inode); - - trace_ext4_drop_inode(inode, drop); - return drop; -} - static void ext4_destroy_inode(struct inode *inode) { - ext4_ioend_wait(inode); if (!list_empty(&(EXT4_I(inode)->i_orphan))) { ext4_msg(inode->i_sb, KERN_ERR, "Inode %lu (%p): orphan list check failed!", @@ -1183,7 +1173,6 @@ static const struct super_operations ext4_sops = { .destroy_inode = ext4_destroy_inode, .write_inode = ext4_write_inode, .dirty_inode = ext4_dirty_inode, - .drop_inode = ext4_drop_inode, .evict_inode = ext4_evict_inode, .put_super = ext4_put_super, .sync_fs = ext4_sync_fs, @@ -1205,7 +1194,6 @@ static const struct super_operations ext4_nojournal_sops = { .destroy_inode = ext4_destroy_inode, .write_inode = ext4_write_inode, .dirty_inode = ext4_dirty_inode, - .drop_inode = ext4_drop_inode, .evict_inode = ext4_evict_inode, .write_super = ext4_write_super, .put_super = ext4_put_super, @@ -2711,6 +2699,7 @@ static int ext4_lazyinit_thread(void *arg) struct ext4_li_request *elr; unsigned long next_wakeup; DEFINE_WAIT(wait); + int ret; BUG_ON(NULL == eli); @@ -2734,12 +2723,13 @@ static int ext4_lazyinit_thread(void *arg) elr = list_entry(pos, struct ext4_li_request, lr_request); - if (time_after_eq(jiffies, elr->lr_next_sched)) { - if (ext4_run_li_request(elr) != 0) { - /* error, remove the lazy_init job */ - ext4_remove_li_request(elr); - continue; - } + if (time_after_eq(jiffies, elr->lr_next_sched)) + ret = ext4_run_li_request(elr); + + if (ret) { + ret = 0; + ext4_remove_li_request(elr); + continue; } if (time_before(elr->lr_next_sched, next_wakeup)) @@ -2750,8 +2740,7 @@ static int ext4_lazyinit_thread(void *arg) if (freezing(current)) refrigerator(); - if ((time_after_eq(jiffies, next_wakeup)) || - (MAX_JIFFY_OFFSET == next_wakeup)) { + if (time_after_eq(jiffies, next_wakeup)) { cond_resched(); continue; } @@ -3359,24 +3348,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) get_random_bytes(&sbi->s_next_generation, sizeof(u32)); spin_lock_init(&sbi->s_next_gen_lock); - err = percpu_counter_init(&sbi->s_freeblocks_counter, - ext4_count_free_blocks(sb)); - if (!err) { - err = percpu_counter_init(&sbi->s_freeinodes_counter, - ext4_count_free_inodes(sb)); - } - if (!err) { - err = percpu_counter_init(&sbi->s_dirs_counter, - ext4_count_dirs(sb)); - } - if (!err) { - err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); - } - if (err) { - ext4_msg(sb, KERN_ERR, "insufficient memory"); - goto failed_mount3; - } - sbi->s_stripe = ext4_get_stripe_size(sbi); sbi->s_max_writeback_mb_bump = 128; @@ -3475,19 +3446,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) } set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); - /* - * The journal may have updated the bg summary counts, so we - * need to update the global counters. - */ - percpu_counter_set(&sbi->s_freeblocks_counter, - ext4_count_free_blocks(sb)); - percpu_counter_set(&sbi->s_freeinodes_counter, - ext4_count_free_inodes(sb)); - percpu_counter_set(&sbi->s_dirs_counter, - ext4_count_dirs(sb)); - percpu_counter_set(&sbi->s_dirtyblocks_counter, 0); - no_journal: + err = percpu_counter_init(&sbi->s_freeblocks_counter, + ext4_count_free_blocks(sb)); + if (!err) + err = percpu_counter_init(&sbi->s_freeinodes_counter, + ext4_count_free_inodes(sb)); + if (!err) + err = percpu_counter_init(&sbi->s_dirs_counter, + ext4_count_dirs(sb)); + if (!err) + err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); + if (err) { + ext4_msg(sb, KERN_ERR, "insufficient memory"); + goto failed_mount_wq; + } + EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); if (!EXT4_SB(sb)->dio_unwritten_wq) { printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); @@ -3637,6 +3611,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) jbd2_journal_destroy(sbi->s_journal); sbi->s_journal = NULL; } + percpu_counter_destroy(&sbi->s_freeblocks_counter); + percpu_counter_destroy(&sbi->s_freeinodes_counter); + percpu_counter_destroy(&sbi->s_dirs_counter); + percpu_counter_destroy(&sbi->s_dirtyblocks_counter); failed_mount3: if (sbi->s_flex_groups) { if (is_vmalloc_addr(sbi->s_flex_groups)) @@ -3644,10 +3622,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) else kfree(sbi->s_flex_groups); } - percpu_counter_destroy(&sbi->s_freeblocks_counter); - percpu_counter_destroy(&sbi->s_freeinodes_counter); - percpu_counter_destroy(&sbi->s_dirs_counter); - percpu_counter_destroy(&sbi->s_dirtyblocks_counter); failed_mount2: for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); @@ -3975,11 +3949,13 @@ static int ext4_commit_super(struct super_block *sb, int sync) else es->s_kbytes_written = cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); - ext4_free_blocks_count_set(es, percpu_counter_sum_positive( - &EXT4_SB(sb)->s_freeblocks_counter)); - es->s_free_inodes_count = - cpu_to_le32(percpu_counter_sum_positive( - &EXT4_SB(sb)->s_freeinodes_counter)); + if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeblocks_counter)) + ext4_free_blocks_count_set(es, percpu_counter_sum_positive( + &EXT4_SB(sb)->s_freeblocks_counter)); + if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter)) + es->s_free_inodes_count = + cpu_to_le32(percpu_counter_sum_positive( + &EXT4_SB(sb)->s_freeinodes_counter)); sb->s_dirt = 0; BUFFER_TRACE(sbh, "marking dirty"); mark_buffer_dirty(sbh); @@ -4580,10 +4556,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, static int ext4_quota_off(struct super_block *sb, int type) { - /* Force all delayed allocation blocks to be allocated. - * Caller already holds s_umount sem */ - if (test_opt(sb, DELALLOC)) + /* Force all delayed allocation blocks to be allocated */ + if (test_opt(sb, DELALLOC)) { + down_read(&sb->s_umount); sync_filesystem(sb); + up_read(&sb->s_umount); + } return dquot_quota_off(sb, type); } diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index a5fe68189eed..d6cfac1f0a40 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -932,7 +932,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { *user = current_user(); if (user_shm_lock(size, *user)) { - printk_once(KERN_WARNING "Using mlock ulimits for SHM_HUGETLB is deprecated\n"); + WARN_ONCE(1, + "Using mlock ulimits for SHM_HUGETLB deprecated\n"); } else { *user = NULL; return ERR_PTR(-EPERM); diff --git a/trunk/fs/ioprio.c b/trunk/fs/ioprio.c index 2f7d05c89922..748cfb92dcc6 100644 --- a/trunk/fs/ioprio.c +++ b/trunk/fs/ioprio.c @@ -111,14 +111,12 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) read_lock(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: - rcu_read_lock(); if (!who) p = current; else p = find_task_by_vpid(who); if (p) ret = set_task_ioprio(p, ioprio); - rcu_read_unlock(); break; case IOPRIO_WHO_PGRP: if (!who) @@ -141,12 +139,7 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) break; do_each_thread(g, p) { - int match; - - rcu_read_lock(); - match = __task_cred(p)->uid == who; - rcu_read_unlock(); - if (!match) + if (__task_cred(p)->uid != who) continue; ret = set_task_ioprio(p, ioprio); if (ret) @@ -207,14 +200,12 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) read_lock(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: - rcu_read_lock(); if (!who) p = current; else p = find_task_by_vpid(who); if (p) ret = get_task_ioprio(p); - rcu_read_unlock(); break; case IOPRIO_WHO_PGRP: if (!who) @@ -241,12 +232,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) break; do_each_thread(g, p) { - int match; - - rcu_read_lock(); - match = __task_cred(p)->uid == user->uid; - rcu_read_unlock(); - if (!match) + if (__task_cred(p)->uid != user->uid) continue; tmpio = get_task_ioprio(p); if (tmpio < 0) diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 0e62dd35d088..65765cb6afed 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -1504,8 +1504,9 @@ static int do_fcntl_delete_lease(struct file *filp) static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) { - struct file_lock *fl, *ret; + struct file_lock *fl; struct fasync_struct *new; + struct inode *inode = filp->f_path.dentry->d_inode; int error; fl = lease_alloc(filp, arg); @@ -1517,16 +1518,13 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) locks_free_lock(fl); return -ENOMEM; } - ret = fl; lock_flocks(); - error = __vfs_setlease(filp, arg, &ret); + error = __vfs_setlease(filp, arg, &fl); if (error) { unlock_flocks(); locks_free_lock(fl); goto out_free_fasync; } - if (ret != fl) - locks_free_lock(fl); /* * fasync_insert_entry() returns the old entry if any. @@ -1534,10 +1532,17 @@ static int do_fcntl_add_lease(unsigned int fd, struct file *filp, long arg) * inserted it into the fasync list. Clear new so that * we don't release it here. */ - if (!fasync_insert_entry(fd, filp, &ret->fl_fasync, new)) + if (!fasync_insert_entry(fd, filp, &fl->fl_fasync, new)) new = NULL; - error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); + if (error < 0) { + /* remove lease just inserted by setlease */ + fl->fl_type = F_UNLCK | F_INPROGRESS; + fl->fl_break_time = jiffies - 10; + time_out_leases(inode); + } else { + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); + } unlock_flocks(); out_free_fasync: diff --git a/trunk/fs/logfs/logfs.h b/trunk/fs/logfs/logfs.h index 57afd4a6fabb..cd51a36b37f0 100644 --- a/trunk/fs/logfs/logfs.h +++ b/trunk/fs/logfs/logfs.h @@ -486,7 +486,7 @@ static inline int logfs_get_sb_bdev(struct logfs_super *s, /* dev_mtd.c */ #ifdef CONFIG_MTD -int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr); +int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) #else static inline int logfs_get_sb_mtd(struct logfs_super *s, int mtdnr) { diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index ad2bfa68d534..f1e5ec6b5105 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -673,17 +673,16 @@ static void nfsd4_hash_conn(struct nfsd4_conn *conn, struct nfsd4_session *ses) spin_unlock(&clp->cl_lock); } -static int nfsd4_register_conn(struct nfsd4_conn *conn) +static void nfsd4_register_conn(struct nfsd4_conn *conn) { conn->cn_xpt_user.callback = nfsd4_conn_lost; - return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); + register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user); } static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) { struct nfsd4_conn *conn; u32 flags = NFS4_CDFC4_FORE; - int ret; if (ses->se_flags & SESSION4_BACK_CHAN) flags |= NFS4_CDFC4_BACK; @@ -691,10 +690,7 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses) if (!conn) return nfserr_jukebox; nfsd4_hash_conn(conn, ses); - ret = nfsd4_register_conn(conn); - if (ret) - /* oops; xprt is already down: */ - nfsd4_conn_lost(&conn->cn_xpt_user); + nfsd4_register_conn(conn); return nfs_ok; } @@ -1648,7 +1644,6 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi { struct nfs4_client *clp = ses->se_client; struct nfsd4_conn *c; - int ret; spin_lock(&clp->cl_lock); c = __nfsd4_find_conn(new->cn_xprt, ses); @@ -1659,10 +1654,7 @@ static void nfsd4_sequence_check_conn(struct nfsd4_conn *new, struct nfsd4_sessi } __nfsd4_hash_conn(new, ses); spin_unlock(&clp->cl_lock); - ret = nfsd4_register_conn(new); - if (ret) - /* oops; xprt is already down: */ - nfsd4_conn_lost(&new->cn_xpt_user); + nfsd4_register_conn(new); return; } diff --git a/trunk/fs/openpromfs/inode.c b/trunk/fs/openpromfs/inode.c index 911e61f348fc..ddb1f41376e5 100644 --- a/trunk/fs/openpromfs/inode.c +++ b/trunk/fs/openpromfs/inode.c @@ -418,7 +418,7 @@ static int openprom_fill_super(struct super_block *s, void *data, int silent) static struct dentry *openprom_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - return mount_single(fs_type, flags, data, openprom_fill_super); + return mount_single(fs_type, flags, data, openprom_fill_super) } static struct file_system_type openprom_fs_type = { diff --git a/trunk/fs/xfs/linux-2.6/xfs_aops.c b/trunk/fs/xfs/linux-2.6/xfs_aops.c index 7d287afccde5..c9af48fffcd7 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_aops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_aops.c @@ -1111,12 +1111,11 @@ xfs_vm_writepage( uptodate = 0; /* - * set_page_dirty dirties all buffers in a page, independent - * of their state. The dirty state however is entirely - * meaningless for holes (!mapped && uptodate), so skip - * buffers covering holes here. + * A hole may still be marked uptodate because discard_buffer + * leaves the flag set. */ if (!buffer_mapped(bh) && buffer_uptodate(bh)) { + ASSERT(!buffer_dirty(bh)); imap_valid = 0; continue; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index aa1d353def29..63fd2c07cb57 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -1781,6 +1781,7 @@ xfs_buf_delwri_split( INIT_LIST_HEAD(list); spin_lock(dwlk); list_for_each_entry_safe(bp, n, dwq, b_list) { + trace_xfs_buf_delwri_split(bp, _RET_IP_); ASSERT(bp->b_flags & XBF_DELWRI); if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) { @@ -1794,7 +1795,6 @@ xfs_buf_delwri_split( _XBF_RUN_QUEUES); bp->b_flags |= XBF_WRITE; list_move_tail(&bp->b_list, list); - trace_xfs_buf_delwri_split(bp, _RET_IP_); } else skipped++; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index ad442d9e392e..2ea238f6d38e 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -416,7 +416,7 @@ xfs_attrlist_by_handle( if (IS_ERR(dentry)) return PTR_ERR(dentry); - kbuf = kzalloc(al_hreq.buflen, GFP_KERNEL); + kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL); if (!kbuf) goto out_dput; diff --git a/trunk/fs/xfs/linux-2.6/xfs_iops.c b/trunk/fs/xfs/linux-2.6/xfs_iops.c index 94d5fd6a2973..96107efc0c61 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_iops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_iops.c @@ -762,8 +762,7 @@ xfs_setup_inode( inode->i_state = I_NEW; inode_sb_list_add(inode); - /* make the inode look hashed for the writeback code */ - hlist_add_fake(&inode->i_hash); + insert_inode_hash(inode); inode->i_mode = ip->i_d.di_mode; inode->i_nlink = ip->i_d.di_nlink; diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c index 064f964d4f3c..9f3a78fe6ae4 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_super.c +++ b/trunk/fs/xfs/linux-2.6/xfs_super.c @@ -353,6 +353,9 @@ xfs_parseargs( mp->m_qflags &= ~XFS_OQUOTA_ENFD; } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { mp->m_flags |= XFS_MOUNT_DELAYLOG; + cmn_err(CE_WARN, + "Enabling EXPERIMENTAL delayed logging feature " + "- use at your own risk.\n"); } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { mp->m_flags &= ~XFS_MOUNT_DELAYLOG; } else if (!strcmp(this_char, "ihashsize")) { diff --git a/trunk/fs/xfs/linux-2.6/xfs_sync.c b/trunk/fs/xfs/linux-2.6/xfs_sync.c index afb0d7cfad1c..37d33254981d 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_sync.c +++ b/trunk/fs/xfs/linux-2.6/xfs_sync.c @@ -853,7 +853,6 @@ xfs_reclaim_inodes_ag( if (trylock) { if (!mutex_trylock(&pag->pag_ici_reclaim_lock)) { skipped++; - xfs_perag_put(pag); continue; } first_index = pag->pag_ici_reclaim_cursor; diff --git a/trunk/fs/xfs/xfs_filestream.c b/trunk/fs/xfs/xfs_filestream.c index 9124425b7f2f..9b715dce5699 100644 --- a/trunk/fs/xfs/xfs_filestream.c +++ b/trunk/fs/xfs/xfs_filestream.c @@ -744,15 +744,9 @@ xfs_filestream_new_ag( * If the file's parent directory is known, take its iolock in exclusive * mode to prevent two sibling files from racing each other to migrate * themselves and their parent to different AGs. - * - * Note that we lock the parent directory iolock inside the child - * iolock here. That's fine as we never hold both parent and child - * iolock in any other place. This is different from the ilock, - * which requires locking of the child after the parent for namespace - * operations. */ if (pip) - xfs_ilock(pip, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT); + xfs_ilock(pip, XFS_IOLOCK_EXCL); /* * A new AG needs to be found for the file. If the file's parent diff --git a/trunk/fs/xfs/xfs_mount.c b/trunk/fs/xfs/xfs_mount.c index 19e9dfa1c254..b1498ab5a399 100644 --- a/trunk/fs/xfs/xfs_mount.c +++ b/trunk/fs/xfs/xfs_mount.c @@ -275,7 +275,6 @@ xfs_free_perag( pag = radix_tree_delete(&mp->m_perag_tree, agno); spin_unlock(&mp->m_perag_lock); ASSERT(pag); - ASSERT(atomic_read(&pag->pag_ref) == 0); call_rcu(&pag->rcu_head, __xfs_free_perag); } } diff --git a/trunk/fs/xfs/xfs_quota.h b/trunk/fs/xfs/xfs_quota.h index 9bb6eda4cd21..e0e64b113bd6 100644 --- a/trunk/fs/xfs/xfs_quota.h +++ b/trunk/fs/xfs/xfs_quota.h @@ -346,17 +346,8 @@ xfs_qm_vop_dqalloc(struct xfs_inode *ip, uid_t uid, gid_t gid, prid_t prid, #define xfs_trans_mod_dquot_byino(tp, ip, fields, delta) #define xfs_trans_apply_dquot_deltas(tp) #define xfs_trans_unreserve_and_mod_dquots(tp) -static inline int xfs_trans_reserve_quota_nblks(struct xfs_trans *tp, - struct xfs_inode *ip, long nblks, long ninos, uint flags) -{ - return 0; -} -static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp, - struct xfs_mount *mp, struct xfs_dquot *udqp, - struct xfs_dquot *gdqp, long nblks, long nions, uint flags) -{ - return 0; -} +#define xfs_trans_reserve_quota_nblks(tp, ip, nblks, ninos, flags) (0) +#define xfs_trans_reserve_quota_bydquots(tp, mp, u, g, nb, ni, fl) (0) #define xfs_qm_vop_create_dqattach(tp, ip, u, g) #define xfs_qm_vop_rename_dqattach(it) (0) #define xfs_qm_vop_chown(tp, ip, old, new) (NULL) @@ -366,14 +357,11 @@ static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp, #define xfs_qm_dqdetach(ip) #define xfs_qm_dqrele(d) #define xfs_qm_statvfs(ip, s) -static inline int xfs_qm_sync(struct xfs_mount *mp, int flags) -{ - return 0; -} +#define xfs_qm_sync(mp, fl) (0) #define xfs_qm_newmount(mp, a, b) (0) #define xfs_qm_mount_quotas(mp) #define xfs_qm_unmount(mp) -#define xfs_qm_unmount_quotas(mp) +#define xfs_qm_unmount_quotas(mp) (0) #endif /* CONFIG_XFS_QUOTA */ #define xfs_trans_unreserve_quota_nblks(tp, ip, nblks, ninos, flags) \ diff --git a/trunk/include/asm-generic/stat.h b/trunk/include/asm-generic/stat.h index bd8cad21998e..47e64170305d 100644 --- a/trunk/include/asm-generic/stat.h +++ b/trunk/include/asm-generic/stat.h @@ -33,18 +33,18 @@ struct stat { int st_blksize; /* Optimal block size for I/O. */ int __pad2; long st_blocks; /* Number 512-byte blocks allocated. */ - long st_atime; /* Time of last access. */ - unsigned long st_atime_nsec; - long st_mtime; /* Time of last modification. */ - unsigned long st_mtime_nsec; - long st_ctime; /* Time of last status change. */ - unsigned long st_ctime_nsec; + int st_atime; /* Time of last access. */ + unsigned int st_atime_nsec; + int st_mtime; /* Time of last modification. */ + unsigned int st_mtime_nsec; + int st_ctime; /* Time of last status change. */ + unsigned int st_ctime_nsec; unsigned int __unused4; unsigned int __unused5; }; +#if __BITS_PER_LONG != 64 /* This matches struct stat64 in glibc2.1. Only used for 32 bit. */ -#if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64) struct stat64 { unsigned long long st_dev; /* Device. */ unsigned long long st_ino; /* File serial number. */ diff --git a/trunk/include/drm/ttm/ttm_bo_api.h b/trunk/include/drm/ttm/ttm_bo_api.h index beafc156a535..5afa5b52063e 100644 --- a/trunk/include/drm/ttm/ttm_bo_api.h +++ b/trunk/include/drm/ttm/ttm_bo_api.h @@ -432,10 +432,6 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); * together with the @destroy function, * enables driver-specific objects derived from a ttm_buffer_object. * On successful return, the object kref and list_kref are set to 1. - * If a failure occurs, the function will call the @destroy function, or - * kfree() if @destroy is NULL. Thus, after a failure, dereferencing @bo is - * illegal and will likely cause memory corruption. - * * Returns * -ENOMEM: Out of memory. * -EINVAL: Invalid placement flags. diff --git a/trunk/include/drm/ttm/ttm_bo_driver.h b/trunk/include/drm/ttm/ttm_bo_driver.h index 8e0c848326b6..d01b4ddbdc56 100644 --- a/trunk/include/drm/ttm/ttm_bo_driver.h +++ b/trunk/include/drm/ttm/ttm_bo_driver.h @@ -206,84 +206,14 @@ struct ttm_tt { struct ttm_mem_type_manager; struct ttm_mem_type_manager_func { - /** - * struct ttm_mem_type_manager member init - * - * @man: Pointer to a memory type manager. - * @p_size: Implementation dependent, but typically the size of the - * range to be managed in pages. - * - * Called to initialize a private range manager. The function is - * expected to initialize the man::priv member. - * Returns 0 on success, negative error code on failure. - */ int (*init)(struct ttm_mem_type_manager *man, unsigned long p_size); - - /** - * struct ttm_mem_type_manager member takedown - * - * @man: Pointer to a memory type manager. - * - * Called to undo the setup done in init. All allocated resources - * should be freed. - */ int (*takedown)(struct ttm_mem_type_manager *man); - - /** - * struct ttm_mem_type_manager member get_node - * - * @man: Pointer to a memory type manager. - * @bo: Pointer to the buffer object we're allocating space for. - * @placement: Placement details. - * @mem: Pointer to a struct ttm_mem_reg to be filled in. - * - * This function should allocate space in the memory type managed - * by @man. Placement details if - * applicable are given by @placement. If successful, - * @mem::mm_node should be set to a non-null value, and - * @mem::start should be set to a value identifying the beginning - * of the range allocated, and the function should return zero. - * If the memory region accomodate the buffer object, @mem::mm_node - * should be set to NULL, and the function should return 0. - * If a system error occured, preventing the request to be fulfilled, - * the function should return a negative error code. - * - * Note that @mem::mm_node will only be dereferenced by - * struct ttm_mem_type_manager functions and optionally by the driver, - * which has knowledge of the underlying type. - * - * This function may not be called from within atomic context, so - * an implementation can and must use either a mutex or a spinlock to - * protect any data structures managing the space. - */ int (*get_node)(struct ttm_mem_type_manager *man, struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_mem_reg *mem); - - /** - * struct ttm_mem_type_manager member put_node - * - * @man: Pointer to a memory type manager. - * @mem: Pointer to a struct ttm_mem_reg to be filled in. - * - * This function frees memory type resources previously allocated - * and that are identified by @mem::mm_node and @mem::start. May not - * be called from within atomic context. - */ void (*put_node)(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem); - - /** - * struct ttm_mem_type_manager member debug - * - * @man: Pointer to a memory type manager. - * @prefix: Prefix to be used in printout to identify the caller. - * - * This function is called to print out the state of the memory - * type manager to aid debugging of out-of-memory conditions. - * It may not be called from within atomic context. - */ void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); }; @@ -301,13 +231,14 @@ struct ttm_mem_type_manager { uint64_t size; uint32_t available_caching; uint32_t default_caching; - const struct ttm_mem_type_manager_func *func; - void *priv; /* - * Protected by the global->lru_lock. + * Protected by the bdev->lru_lock. + * TODO: Consider one lru_lock per ttm_mem_type_manager. + * Plays ill with list removal, though. */ - + const struct ttm_mem_type_manager_func *func; + void *priv; struct list_head lru; }; diff --git a/trunk/include/linux/atomic.h b/trunk/include/linux/atomic.h deleted file mode 100644 index 96c038e43d66..000000000000 --- a/trunk/include/linux/atomic.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _LINUX_ATOMIC_H -#define _LINUX_ATOMIC_H -#include - -/** - * atomic_inc_not_zero_hint - increment if not null - * @v: pointer of type atomic_t - * @hint: probable value of the atomic before the increment - * - * This version of atomic_inc_not_zero() gives a hint of probable - * value of the atomic. This helps processor to not read the memory - * before doing the atomic read/modify/write cycle, lowering - * number of bus transactions on some arches. - * - * Returns: 0 if increment was not done, 1 otherwise. - */ -#ifndef atomic_inc_not_zero_hint -static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) -{ - int val, c = hint; - - /* sanity test, should be removed by compiler if hint is a constant */ - if (!hint) - return atomic_inc_not_zero(v); - - do { - val = atomic_cmpxchg(v, c, c + 1); - if (val == c) - return 1; - c = val; - } while (c); - - return 0; -} -#endif - -#endif /* _LINUX_ATOMIC_H */ diff --git a/trunk/include/linux/bio.h b/trunk/include/linux/bio.h index 35dcdb3589bc..ba679992d39b 100644 --- a/trunk/include/linux/bio.h +++ b/trunk/include/linux/bio.h @@ -66,6 +66,10 @@ #define bio_offset(bio) bio_iovec((bio))->bv_offset #define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) #define bio_sectors(bio) ((bio)->bi_size >> 9) +#define bio_empty_barrier(bio) \ + ((bio->bi_rw & REQ_HARDBARRIER) && \ + !bio_has_data(bio) && \ + !(bio->bi_rw & REQ_DISCARD)) static inline unsigned int bio_cur_bytes(struct bio *bio) { diff --git a/trunk/include/linux/blk_types.h b/trunk/include/linux/blk_types.h index 46ad5197537a..0437ab6bb54c 100644 --- a/trunk/include/linux/blk_types.h +++ b/trunk/include/linux/blk_types.h @@ -122,6 +122,7 @@ enum rq_flag_bits { __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ + __REQ_HARDBARRIER, /* may not be passed by drive either */ __REQ_SYNC, /* request is sync (sync write or read) */ __REQ_META, /* metadata io request */ __REQ_DISCARD, /* request to discard sectors */ @@ -158,6 +159,7 @@ enum rq_flag_bits { #define REQ_FAILFAST_DEV (1 << __REQ_FAILFAST_DEV) #define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT) #define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER) +#define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER) #define REQ_SYNC (1 << __REQ_SYNC) #define REQ_META (1 << __REQ_META) #define REQ_DISCARD (1 << __REQ_DISCARD) @@ -166,8 +168,8 @@ enum rq_flag_bits { #define REQ_FAILFAST_MASK \ (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER) #define REQ_COMMON_MASK \ - (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_DISCARD | \ - REQ_NOIDLE | REQ_FLUSH | REQ_FUA) + (REQ_WRITE | REQ_FAILFAST_MASK | REQ_HARDBARRIER | REQ_SYNC | \ + REQ_META | REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA) #define REQ_CLONE_MASK REQ_COMMON_MASK #define REQ_UNPLUG (1 << __REQ_UNPLUG) diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index aae86fd10c4f..5027a599077d 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -552,7 +552,8 @@ static inline void blk_clear_queue_full(struct request_queue *q, int sync) * it already be started by driver. */ #define RQ_NOMERGE_FLAGS \ - (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) + (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER | \ + REQ_FLUSH | REQ_FUA) #define rq_mergeable(rq) \ (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ (((rq)->cmd_flags & REQ_DISCARD) || \ diff --git a/trunk/include/linux/dccp.h b/trunk/include/linux/dccp.h index eed52bcd35d0..749f01ccd26e 100644 --- a/trunk/include/linux/dccp.h +++ b/trunk/include/linux/dccp.h @@ -462,7 +462,6 @@ struct dccp_ackvec; * @dccps_hc_rx_insert_options - receiver wants to add options when acking * @dccps_hc_tx_insert_options - sender wants to add options when sending * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3) - * @dccps_sync_scheduled - flag which signals "send out-of-band message soon" * @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets * @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing) * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs) @@ -504,7 +503,6 @@ struct dccp_sock { __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; __u8 dccps_server_timewait:1; - __u8 dccps_sync_scheduled:1; struct tasklet_struct dccps_xmitlet; struct timer_list dccps_xmit_timer; }; diff --git a/trunk/include/linux/drbd.h b/trunk/include/linux/drbd.h index ef44c7a0638c..9b2a0158f399 100644 --- a/trunk/include/linux/drbd.h +++ b/trunk/include/linux/drbd.h @@ -53,7 +53,7 @@ extern const char *drbd_buildtag(void); -#define REL_VERSION "8.3.9" +#define REL_VERSION "8.3.9rc2" #define API_VERSION 88 #define PRO_VERSION_MIN 86 #define PRO_VERSION_MAX 95 diff --git a/trunk/include/linux/filter.h b/trunk/include/linux/filter.h index 447a775878fb..69b43dbea6c6 100644 --- a/trunk/include/linux/filter.h +++ b/trunk/include/linux/filter.h @@ -91,6 +91,54 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ #define BPF_TAX 0x00 #define BPF_TXA 0x80 +enum { + BPF_S_RET_K = 0, + BPF_S_RET_A, + BPF_S_ALU_ADD_K, + BPF_S_ALU_ADD_X, + BPF_S_ALU_SUB_K, + BPF_S_ALU_SUB_X, + BPF_S_ALU_MUL_K, + BPF_S_ALU_MUL_X, + BPF_S_ALU_DIV_X, + BPF_S_ALU_AND_K, + BPF_S_ALU_AND_X, + BPF_S_ALU_OR_K, + BPF_S_ALU_OR_X, + BPF_S_ALU_LSH_K, + BPF_S_ALU_LSH_X, + BPF_S_ALU_RSH_K, + BPF_S_ALU_RSH_X, + BPF_S_ALU_NEG, + BPF_S_LD_W_ABS, + BPF_S_LD_H_ABS, + BPF_S_LD_B_ABS, + BPF_S_LD_W_LEN, + BPF_S_LD_W_IND, + BPF_S_LD_H_IND, + BPF_S_LD_B_IND, + BPF_S_LD_IMM, + BPF_S_LDX_W_LEN, + BPF_S_LDX_B_MSH, + BPF_S_LDX_IMM, + BPF_S_MISC_TAX, + BPF_S_MISC_TXA, + BPF_S_ALU_DIV_K, + BPF_S_LD_MEM, + BPF_S_LDX_MEM, + BPF_S_ST, + BPF_S_STX, + BPF_S_JMP_JA, + BPF_S_JMP_JEQ_K, + BPF_S_JMP_JEQ_X, + BPF_S_JMP_JGE_K, + BPF_S_JMP_JGE_X, + BPF_S_JMP_JGT_K, + BPF_S_JMP_JGT_X, + BPF_S_JMP_JSET_K, + BPF_S_JMP_JSET_X, +}; + #ifndef BPF_MAXINSNS #define BPF_MAXINSNS 4096 #endif @@ -147,7 +195,7 @@ struct sock; extern int sk_filter(struct sock *sk, struct sk_buff *skb); extern unsigned int sk_run_filter(struct sk_buff *skb, - const struct sock_filter *filter); + struct sock_filter *filter, int flen); extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); extern int sk_detach_filter(struct sock *sk); extern int sk_chk_filter(struct sock_filter *filter, int flen); diff --git a/trunk/include/linux/hardirq.h b/trunk/include/linux/hardirq.h index 41cb31f14ee3..8a389b608ce3 100644 --- a/trunk/include/linux/hardirq.h +++ b/trunk/include/linux/hardirq.h @@ -96,15 +96,11 @@ */ #define in_nmi() (preempt_count() & NMI_MASK) -#if defined(CONFIG_PREEMPT) && defined(CONFIG_BKL) -# define PREEMPT_INATOMIC_BASE kernel_locked() -#else -# define PREEMPT_INATOMIC_BASE 0 -#endif - #if defined(CONFIG_PREEMPT) +# define PREEMPT_INATOMIC_BASE kernel_locked() # define PREEMPT_CHECK_OFFSET 1 #else +# define PREEMPT_INATOMIC_BASE 0 # define PREEMPT_CHECK_OFFSET 0 #endif diff --git a/trunk/include/linux/highmem.h b/trunk/include/linux/highmem.h index b676c585574e..e9138198e823 100644 --- a/trunk/include/linux/highmem.h +++ b/trunk/include/linux/highmem.h @@ -5,7 +5,6 @@ #include #include #include -#include #include diff --git a/trunk/include/linux/i2c/adp5588.h b/trunk/include/linux/i2c/adp5588.h index cec17cf6cac2..3c5d6b6e765c 100644 --- a/trunk/include/linux/i2c/adp5588.h +++ b/trunk/include/linux/i2c/adp5588.h @@ -1,7 +1,7 @@ /* * Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller * - * Copyright 2009-2010 Analog Devices Inc. + * Copyright 2009 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -77,26 +77,13 @@ /* Configuration Register1 */ #define ADP5588_AUTO_INC (1 << 7) #define ADP5588_GPIEM_CFG (1 << 6) -#define ADP5588_OVR_FLOW_M (1 << 5) #define ADP5588_INT_CFG (1 << 4) -#define ADP5588_OVR_FLOW_IEN (1 << 3) -#define ADP5588_K_LCK_IM (1 << 2) #define ADP5588_GPI_IEN (1 << 1) -#define ADP5588_KE_IEN (1 << 0) /* Interrupt Status Register */ -#define ADP5588_CMP2_INT (1 << 5) -#define ADP5588_CMP1_INT (1 << 4) -#define ADP5588_OVR_FLOW_INT (1 << 3) -#define ADP5588_K_LCK_INT (1 << 2) #define ADP5588_GPI_INT (1 << 1) #define ADP5588_KE_INT (1 << 0) -/* Key Lock and Event Counter Register */ -#define ADP5588_K_LCK_EN (1 << 6) -#define ADP5588_LCK21 0x30 -#define ADP5588_KEC 0xF - #define ADP5588_MAXGPIO 18 #define ADP5588_BANK(offs) ((offs) >> 3) #define ADP5588_BIT(offs) (1u << ((offs) & 0x7)) diff --git a/trunk/include/linux/if_bridge.h b/trunk/include/linux/if_bridge.h index f7e73c338c40..0d241a5c4909 100644 --- a/trunk/include/linux/if_bridge.h +++ b/trunk/include/linux/if_bridge.h @@ -102,9 +102,7 @@ struct __fdb_entry { #include extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); - -typedef int (*br_should_route_hook_t)(struct sk_buff *skb); -extern br_should_route_hook_t __rcu *br_should_route_hook; +extern int (*br_should_route_hook)(struct sk_buff *skb); #endif diff --git a/trunk/include/linux/if_link.h b/trunk/include/linux/if_link.h index 6485d2a89bec..2fc66dd783ee 100644 --- a/trunk/include/linux/if_link.h +++ b/trunk/include/linux/if_link.h @@ -80,24 +80,6 @@ struct rtnl_link_ifmap { __u8 port; }; -/* - * IFLA_AF_SPEC - * Contains nested attributes for address family specific attributes. - * Each address family may create a attribute with the address family - * number as type and create its own attribute structure in it. - * - * Example: - * [IFLA_AF_SPEC] = { - * [AF_INET] = { - * [IFLA_INET_CONF] = ..., - * }, - * [AF_INET6] = { - * [IFLA_INET6_FLAGS] = ..., - * [IFLA_INET6_CONF] = ..., - * } - * } - */ - enum { IFLA_UNSPEC, IFLA_ADDRESS, @@ -134,7 +116,6 @@ enum { IFLA_STATS64, IFLA_VF_PORTS, IFLA_PORT_SELF, - IFLA_AF_SPEC, __IFLA_MAX }; @@ -147,14 +128,6 @@ enum { #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) #endif -enum { - IFLA_INET_UNSPEC, - IFLA_INET_CONF, - __IFLA_INET_MAX, -}; - -#define IFLA_INET_MAX (__IFLA_INET_MAX - 1) - /* ifi_flags. IFF_* flags. @@ -259,7 +232,6 @@ enum macvlan_mode { MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */ MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */ MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */ - MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */ }; /* SR-IOV virtual function management section */ diff --git a/trunk/include/linux/if_macvlan.h b/trunk/include/linux/if_macvlan.h index e28b2e4959d4..8a2fd66a8b5f 100644 --- a/trunk/include/linux/if_macvlan.h +++ b/trunk/include/linux/if_macvlan.h @@ -25,25 +25,19 @@ struct macvlan_port; struct macvtap_queue; /** - * struct macvlan_pcpu_stats - MACVLAN percpu stats + * struct macvlan_rx_stats - MACVLAN percpu rx stats * @rx_packets: number of received packets * @rx_bytes: number of received bytes * @rx_multicast: number of received multicast packets - * @tx_packets: number of transmitted packets - * @tx_bytes: number of transmitted bytes * @syncp: synchronization point for 64bit counters - * @rx_errors: number of rx errors - * @tx_dropped: number of tx dropped packets + * @rx_errors: number of errors */ -struct macvlan_pcpu_stats { +struct macvlan_rx_stats { u64 rx_packets; u64 rx_bytes; u64 rx_multicast; - u64 tx_packets; - u64 tx_bytes; struct u64_stats_sync syncp; - u32 rx_errors; - u32 tx_dropped; + unsigned long rx_errors; }; /* @@ -58,7 +52,7 @@ struct macvlan_dev { struct hlist_node hlist; struct macvlan_port *port; struct net_device *lowerdev; - struct macvlan_pcpu_stats __percpu *pcpu_stats; + struct macvlan_rx_stats __percpu *rx_stats; enum macvlan_mode mode; int (*receive)(struct sk_buff *skb); int (*forward)(struct net_device *dev, struct sk_buff *skb); @@ -70,18 +64,18 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan, unsigned int len, bool success, bool multicast) { - if (likely(success)) { - struct macvlan_pcpu_stats *pcpu_stats; + struct macvlan_rx_stats *rx_stats; - pcpu_stats = this_cpu_ptr(vlan->pcpu_stats); - u64_stats_update_begin(&pcpu_stats->syncp); - pcpu_stats->rx_packets++; - pcpu_stats->rx_bytes += len; + rx_stats = this_cpu_ptr(vlan->rx_stats); + if (likely(success)) { + u64_stats_update_begin(&rx_stats->syncp); + rx_stats->rx_packets++;; + rx_stats->rx_bytes += len; if (multicast) - pcpu_stats->rx_multicast++; - u64_stats_update_end(&pcpu_stats->syncp); + rx_stats->rx_multicast++; + u64_stats_update_end(&rx_stats->syncp); } else { - this_cpu_inc(vlan->pcpu_stats->rx_errors); + rx_stats->rx_errors++; } } diff --git a/trunk/include/linux/if_vlan.h b/trunk/include/linux/if_vlan.h index 635e1faec412..c2f3a72712ce 100644 --- a/trunk/include/linux/if_vlan.h +++ b/trunk/include/linux/if_vlan.h @@ -339,31 +339,6 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) } } -/** - * vlan_get_protocol - get protocol EtherType. - * @skb: skbuff to query - * - * Returns the EtherType of the packet, regardless of whether it is - * vlan encapsulated (normal or hardware accelerated) or not. - */ -static inline __be16 vlan_get_protocol(const struct sk_buff *skb) -{ - __be16 protocol = 0; - - if (vlan_tx_tag_present(skb) || - skb->protocol != cpu_to_be16(ETH_P_8021Q)) - protocol = skb->protocol; - else { - __be16 proto, *protop; - protop = skb_header_pointer(skb, offsetof(struct vlan_ethhdr, - h_vlan_encapsulated_proto), - sizeof(proto), &proto); - if (likely(protop)) - protocol = *protop; - } - - return protocol; -} #endif /* __KERNEL__ */ /* VLAN IOCTLs are found in sockios.h */ diff --git a/trunk/include/linux/igmp.h b/trunk/include/linux/igmp.h index c4987f265109..93fc2449af10 100644 --- a/trunk/include/linux/igmp.h +++ b/trunk/include/linux/igmp.h @@ -167,10 +167,10 @@ struct ip_sf_socklist { */ struct ip_mc_socklist { - struct ip_mc_socklist __rcu *next_rcu; + struct ip_mc_socklist *next; struct ip_mreqn multi; unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ - struct ip_sf_socklist __rcu *sflist; + struct ip_sf_socklist *sflist; struct rcu_head rcu; }; @@ -186,14 +186,11 @@ struct ip_sf_list { struct ip_mc_list { struct in_device *interface; __be32 multiaddr; - unsigned int sfmode; struct ip_sf_list *sources; struct ip_sf_list *tomb; + unsigned int sfmode; unsigned long sfcount[2]; - union { - struct ip_mc_list *next; - struct ip_mc_list __rcu *next_rcu; - }; + struct ip_mc_list *next; struct timer_list timer; int users; atomic_t refcnt; @@ -204,7 +201,6 @@ struct ip_mc_list { char loaded; unsigned char gsquery; /* check source marks? */ unsigned char crcount; - struct rcu_head rcu; }; /* V3 exponential field decoding */ @@ -238,7 +234,7 @@ extern void ip_mc_unmap(struct in_device *); extern void ip_mc_remap(struct in_device *); extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr); extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr); -extern void ip_mc_rejoin_groups(struct in_device *in_dev); +extern void ip_mc_rejoin_group(struct ip_mc_list *im); #endif #endif diff --git a/trunk/include/linux/inetdevice.h b/trunk/include/linux/inetdevice.h index 2b86eaf11773..ccd5b07d678d 100644 --- a/trunk/include/linux/inetdevice.h +++ b/trunk/include/linux/inetdevice.h @@ -41,12 +41,10 @@ enum __IPV4_DEVCONF_MAX }; -#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1) - struct ipv4_devconf { void *sysctl; - int data[IPV4_DEVCONF_MAX]; - DECLARE_BITMAP(state, IPV4_DEVCONF_MAX); + int data[__IPV4_DEVCONF_MAX - 1]; + DECLARE_BITMAP(state, __IPV4_DEVCONF_MAX - 1); }; struct in_device { @@ -54,8 +52,9 @@ struct in_device { atomic_t refcnt; int dead; struct in_ifaddr *ifa_list; /* IP ifaddr chain */ - struct ip_mc_list __rcu *mc_list; /* IP multicast filter chain */ - int mc_count; /* Number of installed mcasts */ + rwlock_t mc_list_lock; + struct ip_mc_list *mc_list; /* IP multicast filter chain */ + int mc_count; /* Number of installed mcasts */ spinlock_t mc_tomb_lock; struct ip_mc_list *mc_tomb; unsigned long mr_v1_seen; @@ -92,7 +91,7 @@ static inline void ipv4_devconf_set(struct in_device *in_dev, int index, static inline void ipv4_devconf_setall(struct in_device *in_dev) { - bitmap_fill(in_dev->cnf.state, IPV4_DEVCONF_MAX); + bitmap_fill(in_dev->cnf.state, __IPV4_DEVCONF_MAX - 1); } #define IN_DEV_CONF_GET(in_dev, attr) \ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index 6ef44465db8d..51af441f3a21 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -1406,8 +1406,6 @@ static inline void input_set_drvdata(struct input_dev *dev, void *data) int __must_check input_register_device(struct input_dev *); void input_unregister_device(struct input_dev *); -void input_reset_device(struct input_dev *); - int __must_check input_register_handler(struct input_handler *); void input_unregister_handler(struct input_handler *); @@ -1423,7 +1421,7 @@ void input_release_device(struct input_handle *); int input_open_device(struct input_handle *); void input_close_device(struct input_handle *); -int input_flush_device(struct input_handle *handle, struct file *file); +int input_flush_device(struct input_handle* handle, struct file* file); void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value); diff --git a/trunk/include/linux/iocontext.h b/trunk/include/linux/iocontext.h index b2eee896dcbc..3e70b21884a9 100644 --- a/trunk/include/linux/iocontext.h +++ b/trunk/include/linux/iocontext.h @@ -76,6 +76,7 @@ int put_io_context(struct io_context *ioc); void exit_io_context(struct task_struct *task); struct io_context *get_io_context(gfp_t gfp_flags, int node); struct io_context *alloc_io_context(gfp_t gfp_flags, int node); +void copy_io_context(struct io_context **pdst, struct io_context **psrc); #else static inline void exit_io_context(struct task_struct *task) { diff --git a/trunk/include/linux/ipv6.h b/trunk/include/linux/ipv6.h index 0c997767429a..8e429d0e0405 100644 --- a/trunk/include/linux/ipv6.h +++ b/trunk/include/linux/ipv6.h @@ -364,7 +364,7 @@ struct ipv6_pinfo { __u32 dst_cookie; - struct ipv6_mc_socklist __rcu *ipv6_mc_list; + struct ipv6_mc_socklist *ipv6_mc_list; struct ipv6_ac_socklist *ipv6_ac_list; struct ipv6_fl_socklist *ipv6_fl_list; diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index fc3da9e4da19..450092c1e35f 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -60,7 +60,7 @@ extern const char linux_proc_banner[]; #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define roundup(x, y) ( \ { \ - const typeof(y) __y = y; \ + typeof(y) __y = y; \ (((x) + (__y - 1)) / __y) * __y; \ } \ ) @@ -293,7 +293,6 @@ extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, unsigned int interval_msec); extern int printk_delay_msec; -extern int dmesg_restrict; /* * Print a one-time message (analogous to WARN_ONCE() et al): diff --git a/trunk/include/linux/leds-lp5521.h b/trunk/include/linux/leds-lp5521.h deleted file mode 100644 index 38368d785f08..000000000000 --- a/trunk/include/linux/leds-lp5521.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * LP5521 LED chip driver. - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Samu Onkalo - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef __LINUX_LP5521_H -#define __LINUX_LP5521_H - -/* See Documentation/leds/leds-lp5521.txt */ - -struct lp5521_led_config { - u8 chan_nr; - u8 led_current; /* mA x10, 0 if led is not connected */ - u8 max_current; -}; - -#define LP5521_CLOCK_AUTO 0 -#define LP5521_CLOCK_INT 1 -#define LP5521_CLOCK_EXT 2 - -struct lp5521_platform_data { - struct lp5521_led_config *led_config; - u8 num_channels; - u8 clock_mode; - int (*setup_resources)(void); - void (*release_resources)(void); - void (*enable)(bool state); -}; - -#endif /* __LINUX_LP5521_H */ diff --git a/trunk/include/linux/leds-lp5523.h b/trunk/include/linux/leds-lp5523.h deleted file mode 100644 index 796747637b80..000000000000 --- a/trunk/include/linux/leds-lp5523.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * LP5523 LED Driver - * - * Copyright (C) 2010 Nokia Corporation - * - * Contact: Samu Onkalo - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef __LINUX_LP5523_H -#define __LINUX_LP5523_H - -/* See Documentation/leds/leds-lp5523.txt */ - -struct lp5523_led_config { - u8 chan_nr; - u8 led_current; /* mA x10, 0 if led is not connected */ - u8 max_current; -}; - -#define LP5523_CLOCK_AUTO 0 -#define LP5523_CLOCK_INT 1 -#define LP5523_CLOCK_EXT 2 - -struct lp5523_platform_data { - struct lp5523_led_config *led_config; - u8 num_channels; - u8 clock_mode; - int (*setup_resources)(void); - void (*release_resources)(void); - void (*enable)(bool state); -}; - -#endif /* __LINUX_LP5523_H */ diff --git a/trunk/include/linux/leds.h b/trunk/include/linux/leds.h index 0f19df9e37b0..ba6986a11663 100644 --- a/trunk/include/linux/leds.h +++ b/trunk/include/linux/leds.h @@ -15,7 +15,6 @@ #include #include #include -#include struct device; /* @@ -46,14 +45,10 @@ struct led_classdev { /* Get LED brightness level */ enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); - /* - * Activate hardware accelerated blink, delays are in milliseconds - * and if both are zero then a sensible default should be chosen. - * The call should adjust the timings in that case and if it can't - * match the values specified exactly. - * Deactivate blinking again when the brightness is set to a fixed - * value via the brightness_set() callback. - */ + /* Activate hardware accelerated blink, delays are in + * miliseconds and if none is provided then a sensible default + * should be chosen. The call can adjust the timings if it can't + * match the values specified exactly. */ int (*blink_set)(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off); @@ -62,10 +57,6 @@ struct led_classdev { struct list_head node; /* LED Device list */ const char *default_trigger; /* Trigger to use */ - unsigned long blink_delay_on, blink_delay_off; - struct timer_list blink_timer; - int blink_brightness; - #ifdef CONFIG_LEDS_TRIGGERS /* Protects the trigger data below */ struct rw_semaphore trigger_lock; @@ -82,36 +73,6 @@ extern void led_classdev_unregister(struct led_classdev *led_cdev); extern void led_classdev_suspend(struct led_classdev *led_cdev); extern void led_classdev_resume(struct led_classdev *led_cdev); -/** - * led_blink_set - set blinking with software fallback - * @led_cdev: the LED to start blinking - * @delay_on: the time it should be on (in ms) - * @delay_off: the time it should ble off (in ms) - * - * This function makes the LED blink, attempting to use the - * hardware acceleration if possible, but falling back to - * software blinking if there is no hardware blinking or if - * the LED refuses the passed values. - * - * Note that if software blinking is active, simply calling - * led_cdev->brightness_set() will not stop the blinking, - * use led_classdev_brightness_set() instead. - */ -extern void led_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off); -/** - * led_brightness_set - set LED brightness - * @led_cdev: the LED to set - * @brightness: the brightness to set it to - * - * Set an LED's brightness, and, if necessary, cancel the - * software blink timer that implements blinking when the - * hardware doesn't. - */ -extern void led_brightness_set(struct led_classdev *led_cdev, - enum led_brightness brightness); - /* * LED Triggers */ diff --git a/trunk/include/linux/mmc/sh_mmcif.h b/trunk/include/linux/mmc/sh_mmcif.h index 5c99da1078aa..d19e2114fd86 100644 --- a/trunk/include/linux/mmc/sh_mmcif.h +++ b/trunk/include/linux/mmc/sh_mmcif.h @@ -59,19 +59,19 @@ struct sh_mmcif_plat_data { #define MMCIF_CE_HOST_STS2 0x0000004C #define MMCIF_CE_VERSION 0x0000007C -static inline u32 sh_mmcif_readl(void __iomem *addr, int reg) +extern inline u32 sh_mmcif_readl(void __iomem *addr, int reg) { return readl(addr + reg); } -static inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val) +extern inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val) { writel(val, addr + reg); } #define SH_MMCIF_BBS 512 /* boot block size */ -static inline void sh_mmcif_boot_cmd_send(void __iomem *base, +extern inline void sh_mmcif_boot_cmd_send(void __iomem *base, unsigned long cmd, unsigned long arg) { sh_mmcif_writel(base, MMCIF_CE_INT, 0); @@ -79,7 +79,7 @@ static inline void sh_mmcif_boot_cmd_send(void __iomem *base, sh_mmcif_writel(base, MMCIF_CE_CMD_SET, cmd); } -static inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask) +extern inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask) { unsigned long tmp; int cnt; @@ -95,14 +95,14 @@ static inline int sh_mmcif_boot_cmd_poll(void __iomem *base, unsigned long mask) return -1; } -static inline int sh_mmcif_boot_cmd(void __iomem *base, +extern inline int sh_mmcif_boot_cmd(void __iomem *base, unsigned long cmd, unsigned long arg) { sh_mmcif_boot_cmd_send(base, cmd, arg); return sh_mmcif_boot_cmd_poll(base, 0x00010000); } -static inline int sh_mmcif_boot_do_read_single(void __iomem *base, +extern inline int sh_mmcif_boot_do_read_single(void __iomem *base, unsigned int block_nr, unsigned long *buf) { @@ -125,7 +125,7 @@ static inline int sh_mmcif_boot_do_read_single(void __iomem *base, return 0; } -static inline int sh_mmcif_boot_do_read(void __iomem *base, +extern inline int sh_mmcif_boot_do_read(void __iomem *base, unsigned long first_block, unsigned long nr_blocks, void *buf) @@ -143,7 +143,7 @@ static inline int sh_mmcif_boot_do_read(void __iomem *base, return ret; } -static inline void sh_mmcif_boot_init(void __iomem *base) +extern inline void sh_mmcif_boot_init(void __iomem *base) { unsigned long tmp; @@ -177,7 +177,7 @@ static inline void sh_mmcif_boot_init(void __iomem *base) sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000); } -static inline void sh_mmcif_boot_slurp(void __iomem *base, +extern inline void sh_mmcif_boot_slurp(void __iomem *base, unsigned char *buf, unsigned long no_bytes) { diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 4b0c7f3aa32b..072652d94d9f 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -493,8 +493,6 @@ static inline void napi_synchronize(const struct napi_struct *n) enum netdev_queue_state_t { __QUEUE_STATE_XOFF, __QUEUE_STATE_FROZEN, -#define QUEUE_STATE_XOFF_OR_FROZEN ((1 << __QUEUE_STATE_XOFF) | \ - (1 << __QUEUE_STATE_FROZEN)) }; struct netdev_queue { @@ -505,10 +503,6 @@ struct netdev_queue { struct Qdisc *qdisc; unsigned long state; struct Qdisc *qdisc_sleeping; -#ifdef CONFIG_RPS - struct kobject kobj; -#endif - /* * write mostly part */ @@ -598,36 +592,11 @@ struct netdev_rx_queue { struct rps_map __rcu *rps_map; struct rps_dev_flow_table __rcu *rps_flow_table; struct kobject kobj; - struct net_device *dev; + struct netdev_rx_queue *first; + atomic_t count; } ____cacheline_aligned_in_smp; #endif /* CONFIG_RPS */ -#ifdef CONFIG_XPS -/* - * This structure holds an XPS map which can be of variable length. The - * map is an array of queues. - */ -struct xps_map { - unsigned int len; - unsigned int alloc_len; - struct rcu_head rcu; - u16 queues[0]; -}; -#define XPS_MAP_SIZE(_num) (sizeof(struct xps_map) + (_num * sizeof(u16))) -#define XPS_MIN_MAP_ALLOC ((L1_CACHE_BYTES - sizeof(struct xps_map)) \ - / sizeof(u16)) - -/* - * This structure holds all XPS maps for device. Maps are indexed by CPU. - */ -struct xps_dev_maps { - struct rcu_head rcu; - struct xps_map __rcu *cpu_map[0]; -}; -#define XPS_DEV_MAPS_SIZE (sizeof(struct xps_dev_maps) + \ - (nr_cpu_ids * sizeof(struct xps_map *))) -#endif /* CONFIG_XPS */ - /* * This structure defines the management hooks for network devices. * The following hooks can be defined; unless noted otherwise, they are @@ -982,7 +951,7 @@ struct net_device { #endif void *atalk_ptr; /* AppleTalk link */ struct in_device __rcu *ip_ptr; /* IPv4 specific data */ - struct dn_dev __rcu *dn_ptr; /* DECnet specific data */ + void *dn_ptr; /* DECnet specific data */ struct inet6_dev __rcu *ip6_ptr; /* IPv6 specific data */ void *ec_ptr; /* Econet specific data */ void *ax25_ptr; /* AX.25 specific data */ @@ -1026,8 +995,8 @@ struct net_device { unsigned int real_num_rx_queues; #endif - rx_handler_func_t __rcu *rx_handler; - void __rcu *rx_handler_data; + rx_handler_func_t *rx_handler; + void *rx_handler_data; struct netdev_queue __rcu *ingress_queue; @@ -1048,10 +1017,6 @@ struct net_device { unsigned long tx_queue_len; /* Max frames per queue allowed */ spinlock_t tx_global_lock; -#ifdef CONFIG_XPS - struct xps_dev_maps __rcu *xps_maps; -#endif - /* These may be needed for future network-power-down code. */ /* @@ -1589,11 +1554,6 @@ static inline void netif_tx_wake_all_queues(struct net_device *dev) static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue) { - if (WARN_ON(!dev_queue)) { - printk(KERN_INFO "netif_stop_queue() cannot be called before " - "register_netdev()"); - return; - } set_bit(__QUEUE_STATE_XOFF, &dev_queue->state); } @@ -1635,9 +1595,9 @@ static inline int netif_queue_stopped(const struct net_device *dev) return netif_tx_queue_stopped(netdev_get_tx_queue(dev, 0)); } -static inline int netif_tx_queue_frozen_or_stopped(const struct netdev_queue *dev_queue) +static inline int netif_tx_queue_frozen(const struct netdev_queue *dev_queue) { - return dev_queue->state & QUEUE_STATE_XOFF_OR_FROZEN; + return test_bit(__QUEUE_STATE_FROZEN, &dev_queue->state); } /** @@ -2274,8 +2234,6 @@ unsigned long netdev_fix_features(unsigned long features, const char *name); void netif_stacked_transfer_operstate(const struct net_device *rootdev, struct net_device *dev); -int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev); - static inline int net_gso_ok(int features, int gso_type) { int feature = gso_type << NETIF_F_GSO_SHIFT; @@ -2291,7 +2249,10 @@ static inline int skb_gso_ok(struct sk_buff *skb, int features) static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) { if (skb_is_gso(skb)) { - int features = netif_get_vlan_features(skb, dev); + int features = dev->features; + + if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci) + features &= dev->vlan_features; return (!skb_gso_ok(skb, features) || unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); diff --git a/trunk/include/linux/netfilter.h b/trunk/include/linux/netfilter.h index 1893837b3966..89341c32631a 100644 --- a/trunk/include/linux/netfilter.h +++ b/trunk/include/linux/netfilter.h @@ -33,8 +33,6 @@ #define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE) -#define NF_DROP_ERR(x) (((-x) << NF_VERDICT_BITS) | NF_DROP) - /* only for userspace compatibility */ #ifndef __KERNEL__ /* Generic cache responses from hook functions. @@ -217,7 +215,7 @@ NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb, int ret; if (!cond || - ((ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN)) == 1)) + (ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN) == 1)) ret = okfn(skb); return ret; } diff --git a/trunk/include/linux/perf_event.h b/trunk/include/linux/perf_event.h index 40150f345982..057bf22a8323 100644 --- a/trunk/include/linux/perf_event.h +++ b/trunk/include/linux/perf_event.h @@ -747,16 +747,6 @@ struct perf_event { u64 tstamp_running; u64 tstamp_stopped; - /* - * timestamp shadows the actual context timing but it can - * be safely used in NMI interrupt context. It reflects the - * context time as it was when the event was last scheduled in. - * - * ctx_time already accounts for ctx->timestamp. Therefore to - * compute ctx_time for a sample, simply add perf_clock(). - */ - u64 shadow_ctx_time; - struct perf_event_attr attr; struct hw_perf_event hw; diff --git a/trunk/include/linux/pwm_backlight.h b/trunk/include/linux/pwm_backlight.h index e031e1a486d9..01b3d759f1fc 100644 --- a/trunk/include/linux/pwm_backlight.h +++ b/trunk/include/linux/pwm_backlight.h @@ -8,7 +8,6 @@ struct platform_pwm_backlight_data { int pwm_id; unsigned int max_brightness; unsigned int dft_brightness; - unsigned int lth_brightness; unsigned int pwm_period_ns; int (*init)(struct device *dev); int (*notify)(struct device *dev, int brightness); diff --git a/trunk/include/linux/radix-tree.h b/trunk/include/linux/radix-tree.h index ab2baa5c4884..a39cbed9ee17 100644 --- a/trunk/include/linux/radix-tree.h +++ b/trunk/include/linux/radix-tree.h @@ -34,13 +34,19 @@ * needed for RCU lookups (because root->height is unreliable). The only * time callers need worry about this is when doing a lookup_slot under * RCU. - * - * Indirect pointer in fact is also used to tag the last pointer of a node - * when it is shrunk, before we rcu free the node. See shrink code for - * details. */ #define RADIX_TREE_INDIRECT_PTR 1 +#define RADIX_TREE_RETRY ((void *)-1UL) + +static inline void *radix_tree_ptr_to_indirect(void *ptr) +{ + return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR); +} +static inline void *radix_tree_indirect_to_ptr(void *ptr) +{ + return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR); +} #define radix_tree_indirect_to_ptr(ptr) \ radix_tree_indirect_to_ptr((void __force *)(ptr)) @@ -134,29 +140,16 @@ do { \ * removed. * * For use with radix_tree_lookup_slot(). Caller must hold tree at least read - * locked across slot lookup and dereference. Not required if write lock is - * held (ie. items cannot be concurrently inserted). - * - * radix_tree_deref_retry must be used to confirm validity of the pointer if - * only the read lock is held. + * locked across slot lookup and dereference. More likely, will be used with + * radix_tree_replace_slot(), as well, so caller will hold tree write locked. */ static inline void *radix_tree_deref_slot(void **pslot) { - return rcu_dereference(*pslot); + void *ret = rcu_dereference(*pslot); + if (unlikely(radix_tree_is_indirect_ptr(ret))) + ret = RADIX_TREE_RETRY; + return ret; } - -/** - * radix_tree_deref_retry - check radix_tree_deref_slot - * @arg: pointer returned by radix_tree_deref_slot - * Returns: 0 if retry is not required, otherwise retry is required - * - * radix_tree_deref_retry must be used with radix_tree_deref_slot. - */ -static inline int radix_tree_deref_retry(void *arg) -{ - return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR); -} - /** * radix_tree_replace_slot - replace item in a slot * @pslot: pointer to slot, returned by radix_tree_lookup_slot diff --git a/trunk/include/linux/resource.h b/trunk/include/linux/resource.h index d01c96c1966e..88d36f9145ba 100644 --- a/trunk/include/linux/resource.h +++ b/trunk/include/linux/resource.h @@ -2,7 +2,6 @@ #define _LINUX_RESOURCE_H #include -#include /* * Resource control/accounting header file for linux diff --git a/trunk/include/linux/rtnetlink.h b/trunk/include/linux/rtnetlink.h index bbad657a3725..d42f274418b8 100644 --- a/trunk/include/linux/rtnetlink.h +++ b/trunk/include/linux/rtnetlink.h @@ -6,6 +6,7 @@ #include #include #include +#include /* rtnetlink families. Values up to 127 are reserved for real address * families, values above 128 may be used arbitrarily. @@ -605,7 +606,6 @@ struct tcamsg { #ifdef __KERNEL__ #include -#include static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str) { diff --git a/trunk/include/linux/sh_clk.h b/trunk/include/linux/sh_clk.h index cea0c38e7a63..4dca992f3093 100644 --- a/trunk/include/linux/sh_clk.h +++ b/trunk/include/linux/sh_clk.h @@ -122,10 +122,6 @@ int clk_rate_table_find(struct clk *clk, long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, unsigned int div_max, unsigned long rate); -long clk_round_parent(struct clk *clk, unsigned long target, - unsigned long *best_freq, unsigned long *parent_freq, - unsigned int div_min, unsigned int div_max); - #define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ { \ .parent = _parent, \ diff --git a/trunk/include/linux/sh_timer.h b/trunk/include/linux/sh_timer.h index 4d9dcd138315..864bd56bd3b0 100644 --- a/trunk/include/linux/sh_timer.h +++ b/trunk/include/linux/sh_timer.h @@ -5,6 +5,7 @@ struct sh_timer_config { char *name; long channel_offset; int timer_bit; + char *clk; unsigned long clockevent_rating; unsigned long clocksource_rating; }; diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 19f37a6ee6c4..e6ba898de61c 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -386,10 +386,9 @@ struct sk_buff { #else __u8 deliver_no_wcard:1; #endif - __u8 ooo_okay:1; kmemcheck_bitfield_end(flags2); - /* 0/13 bit hole */ + /* 0/14 bit hole */ #ifdef CONFIG_NET_DMA dma_cookie_t dma_cookie; diff --git a/trunk/include/linux/stmmac.h b/trunk/include/linux/stmmac.h index e10352915698..d66c61774d95 100644 --- a/trunk/include/linux/stmmac.h +++ b/trunk/include/linux/stmmac.h @@ -40,9 +40,9 @@ struct plat_stmmacenet_data { int pmt; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(void __iomem *ioaddr); - int (*init)(struct platform_device *pdev); - void (*exit)(struct platform_device *pdev); - void *custom_cfg; +#ifdef CONFIG_STM_DRIVERS + struct stm_pad_config *pad_config; +#endif void *bsp_priv; }; diff --git a/trunk/include/linux/sunrpc/svc_xprt.h b/trunk/include/linux/sunrpc/svc_xprt.h index aea0d438e3c7..bbdb680ffbe9 100644 --- a/trunk/include/linux/sunrpc/svc_xprt.h +++ b/trunk/include/linux/sunrpc/svc_xprt.h @@ -82,28 +82,18 @@ struct svc_xprt { struct net *xpt_net; }; -static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) +static inline void register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) { spin_lock(&xpt->xpt_lock); - list_del_init(&u->list); + list_add(&u->list, &xpt->xpt_users); spin_unlock(&xpt->xpt_lock); } -static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) +static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u) { spin_lock(&xpt->xpt_lock); - if (test_bit(XPT_CLOSE, &xpt->xpt_flags)) { - /* - * The connection is about to be deleted soon (or, - * worse, may already be deleted--in which case we've - * already notified the xpt_users). - */ - spin_unlock(&xpt->xpt_lock); - return -ENOTCONN; - } - list_add(&u->list, &xpt->xpt_users); + list_del_init(&u->list); spin_unlock(&xpt->xpt_lock); - return 0; } int svc_reg_xprt_class(struct svc_xprt_class *); diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h index c7ea9bc8897c..2a754748dd5f 100644 --- a/trunk/include/linux/tty.h +++ b/trunk/include/linux/tty.h @@ -50,7 +50,7 @@ #define N_V253 19 /* Codec control over voice modem */ #define N_CAIF 20 /* CAIF protocol for talking to modems */ #define N_GSM0710 21 /* GSM 0710 Mux */ -#define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */ +#define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */ /* * This character is the same as _POSIX_VDISABLE: it cannot be used as diff --git a/trunk/include/linux/usb.h b/trunk/include/linux/usb.h index 24300d8a1bc1..35fe6ab222bb 100644 --- a/trunk/include/linux/usb.h +++ b/trunk/include/linux/usb.h @@ -797,7 +797,7 @@ struct usbdrv_wrap { * @disconnect: Called when the interface is no longer accessible, usually * because its device has been (or is being) disconnected or the * driver module is being unloaded. - * @unlocked_ioctl: Used for drivers that want to talk to userspace through + * @ioctl: Used for drivers that want to talk to userspace through * the "usbfs" filesystem. This lets devices provide ways to * expose information to user space regardless of where they * do (or don't) show up otherwise in the filesystem. diff --git a/trunk/include/linux/usb/musb.h b/trunk/include/linux/usb/musb.h index 2387f9fc8138..ee2dd1d506ed 100644 --- a/trunk/include/linux/usb/musb.h +++ b/trunk/include/linux/usb/musb.h @@ -89,8 +89,6 @@ struct musb_hdrc_config { /* A GPIO controlling VRSEL in Blackfin */ unsigned int gpio_vrsel; unsigned int gpio_vrsel_active; - /* musb CLKIN in Blackfin in MHZ */ - unsigned char clkin; #endif }; diff --git a/trunk/include/net/caif/caif_dev.h b/trunk/include/net/caif/caif_dev.h index 8eff83b95366..6da573c75d54 100644 --- a/trunk/include/net/caif/caif_dev.h +++ b/trunk/include/net/caif/caif_dev.h @@ -28,7 +28,7 @@ struct caif_param { * @sockaddr: Socket address to connect. * @priority: Priority of the connection. * @link_selector: Link selector (high bandwidth or low latency) - * @ifindex: kernel index of the interface. + * @link_name: Name of the CAIF Link Layer to use. * @param: Connect Request parameters (CAIF_SO_REQ_PARAM). * * This struct is used when connecting a CAIF channel. @@ -39,7 +39,7 @@ struct caif_connect_request { struct sockaddr_caif sockaddr; enum caif_channel_priority priority; enum caif_link_selector link_selector; - int ifindex; + char link_name[16]; struct caif_param param; }; diff --git a/trunk/include/net/caif/caif_spi.h b/trunk/include/net/caif/caif_spi.h index 87c3d11b8e55..ce4570dff020 100644 --- a/trunk/include/net/caif/caif_spi.h +++ b/trunk/include/net/caif/caif_spi.h @@ -121,8 +121,6 @@ struct cfspi { wait_queue_head_t wait; spinlock_t lock; bool flow_stop; - bool slave; - bool slave_talked; #ifdef CONFIG_DEBUG_FS enum cfspi_state dbg_state; u16 pcmd; diff --git a/trunk/include/net/caif/cfcnfg.h b/trunk/include/net/caif/cfcnfg.h index f688478bfb84..bd646faffa47 100644 --- a/trunk/include/net/caif/cfcnfg.h +++ b/trunk/include/net/caif/cfcnfg.h @@ -139,10 +139,10 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, enum cfcnfg_phy_preference phy_pref); /** - * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex, - * it matches caif physical id with the kernel interface id. + * cfcnfg_get_named() - Get the Physical Identifier of CAIF Link Layer * @cnfg: Configuration object - * @ifi: ifindex obtained from socket.c bindtodevice. + * @name: Name of the Physical Layer (Caif Link Layer) */ -int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi); +int cfcnfg_get_named(struct cfcnfg *cnfg, char *name); + #endif /* CFCNFG_H_ */ diff --git a/trunk/include/net/caif/cfctrl.h b/trunk/include/net/caif/cfctrl.h index e54f6396fa4c..9402543fc20d 100644 --- a/trunk/include/net/caif/cfctrl.h +++ b/trunk/include/net/caif/cfctrl.h @@ -51,7 +51,7 @@ struct cfctrl_rsp { void (*restart_rsp)(void); void (*radioset_rsp)(void); void (*reject_rsp)(struct cflayer *layer, u8 linkid, - struct cflayer *client_layer); + struct cflayer *client_layer);; }; /* Link Setup Parameters for CAIF-Links. */ diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 772dea243e5d..e5702f5ac57c 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -1356,7 +1356,7 @@ enum wiphy_flags { WIPHY_FLAG_4ADDR_AP = BIT(5), WIPHY_FLAG_4ADDR_STATION = BIT(6), WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), - WIPHY_FLAG_IBSS_RSN = BIT(8), + WIPHY_FLAG_IBSS_RSN = BIT(7), }; struct mac_address { diff --git a/trunk/include/net/dn.h b/trunk/include/net/dn.h index a514a3cf4573..e5469f7b67a3 100644 --- a/trunk/include/net/dn.h +++ b/trunk/include/net/dn.h @@ -225,7 +225,7 @@ extern int decnet_di_count; extern int decnet_dr_count; extern int decnet_no_fc_max_cwnd; -extern long sysctl_decnet_mem[3]; +extern int sysctl_decnet_mem[3]; extern int sysctl_decnet_wmem[3]; extern int sysctl_decnet_rmem[3]; diff --git a/trunk/include/net/dn_dev.h b/trunk/include/net/dn_dev.h index b9e32db03f20..0916bbf3bdff 100644 --- a/trunk/include/net/dn_dev.h +++ b/trunk/include/net/dn_dev.h @@ -5,14 +5,13 @@ struct dn_dev; struct dn_ifaddr { - struct dn_ifaddr __rcu *ifa_next; + struct dn_ifaddr *ifa_next; struct dn_dev *ifa_dev; __le16 ifa_local; __le16 ifa_address; __u8 ifa_flags; __u8 ifa_scope; char ifa_label[IFNAMSIZ]; - struct rcu_head rcu; }; #define DN_DEV_S_RU 0 /* Run - working normally */ @@ -84,7 +83,7 @@ struct dn_dev_parms { struct dn_dev { - struct dn_ifaddr __rcu *ifa_list; + struct dn_ifaddr *ifa_list; struct net_device *dev; struct dn_dev_parms parms; char use_long; @@ -172,27 +171,19 @@ extern int unregister_dnaddr_notifier(struct notifier_block *nb); static inline int dn_dev_islocal(struct net_device *dev, __le16 addr) { - struct dn_dev *dn_db; + struct dn_dev *dn_db = dev->dn_ptr; struct dn_ifaddr *ifa; - int res = 0; - rcu_read_lock(); - dn_db = rcu_dereference(dev->dn_ptr); if (dn_db == NULL) { printk(KERN_DEBUG "dn_dev_islocal: Called for non DECnet device\n"); - goto out; + return 0; } - for (ifa = rcu_dereference(dn_db->ifa_list); - ifa != NULL; - ifa = rcu_dereference(ifa->ifa_next)) - if ((addr ^ ifa->ifa_local) == 0) { - res = 1; - break; - } -out: - rcu_read_unlock(); - return res; + for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) + if ((addr ^ ifa->ifa_local) == 0) + return 1; + + return 0; } #endif /* _NET_DN_DEV_H */ diff --git a/trunk/include/net/dn_route.h b/trunk/include/net/dn_route.h index 9b185df265fb..ccadab3aa3f6 100644 --- a/trunk/include/net/dn_route.h +++ b/trunk/include/net/dn_route.h @@ -80,16 +80,6 @@ struct dn_route { unsigned rt_type; }; -static inline bool dn_is_input_route(struct dn_route *rt) -{ - return rt->fl.iif != 0; -} - -static inline bool dn_is_output_route(struct dn_route *rt) -{ - return rt->fl.iif == 0; -} - extern void dn_route_init(void); extern void dn_route_cleanup(void); diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index a5bd72646d65..ffe9cb719c0e 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -94,10 +94,10 @@ struct dst_entry { int __use; unsigned long lastuse; union { - struct dst_entry *next; - struct rtable __rcu *rt_next; - struct rt6_info *rt6_next; - struct dn_route __rcu *dn_next; + struct dst_entry *next; + struct rtable __rcu *rt_next; + struct rt6_info *rt6_next; + struct dn_route *dn_next; }; }; diff --git a/trunk/include/net/dst_ops.h b/trunk/include/net/dst_ops.h index 51665b3461b8..1fa5306e3e23 100644 --- a/trunk/include/net/dst_ops.h +++ b/trunk/include/net/dst_ops.h @@ -2,7 +2,6 @@ #define _NET_DST_OPS_H #include #include -#include struct dst_entry; struct kmem_cachep; diff --git a/trunk/include/net/flow.h b/trunk/include/net/flow.h index 7196e6864b8d..0ac3fb5e0973 100644 --- a/trunk/include/net/flow.h +++ b/trunk/include/net/flow.h @@ -67,7 +67,6 @@ struct flowi { } dnports; __be32 spi; - __be32 gre_key; struct { __u8 type; @@ -79,7 +78,6 @@ struct flowi { #define fl_icmp_code uli_u.icmpt.code #define fl_ipsec_spi uli_u.spi #define fl_mh_type uli_u.mht.type -#define fl_gre_key uli_u.gre_key __u32 secid; /* used by xfrm; see secid.txt */ } __attribute__((__aligned__(BITS_PER_LONG/8))); diff --git a/trunk/include/net/if_inet6.h b/trunk/include/net/if_inet6.h index 04977eefb0ee..f95ff8d9aa47 100644 --- a/trunk/include/net/if_inet6.h +++ b/trunk/include/net/if_inet6.h @@ -89,11 +89,10 @@ struct ip6_sf_socklist { struct ipv6_mc_socklist { struct in6_addr addr; int ifindex; - struct ipv6_mc_socklist __rcu *next; + struct ipv6_mc_socklist *next; rwlock_t sflock; unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */ struct ip6_sf_socklist *sflist; - struct rcu_head rcu; }; struct ip6_sf_list { diff --git a/trunk/include/net/inet_sock.h b/trunk/include/net/inet_sock.h index 8945f9fb192a..1989cfd7405f 100644 --- a/trunk/include/net/inet_sock.h +++ b/trunk/include/net/inet_sock.h @@ -141,7 +141,7 @@ struct inet_sock { nodefrag:1; int mc_index; __be32 mc_addr; - struct ip_mc_socklist __rcu *mc_list; + struct ip_mc_socklist *mc_list; struct { unsigned int flags; unsigned int fragsize; diff --git a/trunk/include/net/neighbour.h b/trunk/include/net/neighbour.h index 4014b623880c..55590ab16b3e 100644 --- a/trunk/include/net/neighbour.h +++ b/trunk/include/net/neighbour.h @@ -96,16 +96,16 @@ struct neighbour { struct neigh_parms *parms; unsigned long confirmed; unsigned long updated; - rwlock_t lock; + __u8 flags; + __u8 nud_state; + __u8 type; + __u8 dead; atomic_t refcnt; struct sk_buff_head arp_queue; struct timer_list timer; unsigned long used; atomic_t probes; - __u8 flags; - __u8 nud_state; - __u8 type; - __u8 dead; + rwlock_t lock; seqlock_t ha_lock; unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; struct hh_cache *hh; @@ -303,7 +303,7 @@ static inline void neigh_confirm(struct neighbour *neigh) static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) { - unsigned long now = jiffies; + unsigned long now = ACCESS_ONCE(jiffies); if (neigh->used != now) neigh->used = now; diff --git a/trunk/include/net/netlink.h b/trunk/include/net/netlink.h index 373f1a900cf4..f3b201d335b3 100644 --- a/trunk/include/net/netlink.h +++ b/trunk/include/net/netlink.h @@ -225,15 +225,13 @@ extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid, unsigned int group, int report, gfp_t flags); -extern int nla_validate(const struct nlattr *head, - int len, int maxtype, +extern int nla_validate(struct nlattr *head, int len, int maxtype, const struct nla_policy *policy); -extern int nla_parse(struct nlattr **tb, int maxtype, - const struct nlattr *head, int len, +extern int nla_parse(struct nlattr *tb[], int maxtype, + struct nlattr *head, int len, const struct nla_policy *policy); extern int nla_policy_len(const struct nla_policy *, int); -extern struct nlattr * nla_find(const struct nlattr *head, - int len, int attrtype); +extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype); extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize); extern int nla_memcpy(void *dest, const struct nlattr *src, int count); @@ -348,8 +346,7 @@ static inline int nlmsg_ok(const struct nlmsghdr *nlh, int remaining) * Returns the next netlink message in the message stream and * decrements remaining by the size of the current message. */ -static inline struct nlmsghdr * -nlmsg_next(const struct nlmsghdr *nlh, int *remaining) +static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining) { int totlen = NLMSG_ALIGN(nlh->nlmsg_len); @@ -387,7 +384,7 @@ static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, * * Returns the first attribute which matches the specified type. */ -static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, +static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, int hdrlen, int attrtype) { return nla_find(nlmsg_attrdata(nlh, hdrlen), @@ -401,8 +398,7 @@ static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, * @maxtype: maximum attribute type to be expected * @policy: validation policy */ -static inline int nlmsg_validate(const struct nlmsghdr *nlh, - int hdrlen, int maxtype, +static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, const struct nla_policy *policy) { if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) @@ -731,8 +727,7 @@ static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining) * * Returns the first attribute which matches the specified type. */ -static inline struct nlattr * -nla_find_nested(const struct nlattr *nla, int attrtype) +static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype) { return nla_find(nla_data(nla), nla_len(nla), attrtype); } @@ -1037,7 +1032,7 @@ static inline void nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) * * Returns 0 on success or a negative error code. */ -static inline int nla_validate_nested(const struct nlattr *start, int maxtype, +static inline int nla_validate_nested(struct nlattr *start, int maxtype, const struct nla_policy *policy) { return nla_validate(nla_data(start), nla_len(start), maxtype, policy); diff --git a/trunk/include/net/netns/generic.h b/trunk/include/net/netns/generic.h index 3419bf5cd154..81a31c0db3e7 100644 --- a/trunk/include/net/netns/generic.h +++ b/trunk/include/net/netns/generic.h @@ -30,7 +30,7 @@ struct net_generic { void *ptr[0]; }; -static inline void *net_generic(const struct net *net, int id) +static inline void *net_generic(struct net *net, int id) { struct net_generic *ng; void *ptr; diff --git a/trunk/include/net/route.h b/trunk/include/net/route.h index b8c1f7703fc6..7e5e73bfa4de 100644 --- a/trunk/include/net/route.h +++ b/trunk/include/net/route.h @@ -55,6 +55,8 @@ struct rtable { /* Cache lookup keys */ struct flowi fl; + struct in_device *idev; + int rt_genid; unsigned rt_flags; __u16 rt_type; @@ -71,16 +73,6 @@ struct rtable { struct inet_peer *peer; /* long-living peer info */ }; -static inline bool rt_is_input_route(struct rtable *rt) -{ - return rt->fl.iif != 0; -} - -static inline bool rt_is_output_route(struct rtable *rt) -{ - return rt->fl.iif == 0; -} - struct ip_rt_acct { __u32 o_bytes; __u32 o_packets; @@ -169,12 +161,14 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, { struct flowi fl = { .oif = oif, .mark = sk->sk_mark, - .fl4_dst = dst, - .fl4_src = src, - .fl4_tos = tos, + .nl_u = { .ip4_u = { .daddr = dst, + .saddr = src, + .tos = tos } }, .proto = protocol, - .fl_ip_sport = sport, - .fl_ip_dport = dport }; + .uli_u = { .ports = + { .sport = sport, + .dport = dport } } }; + int err; struct net *net = sock_net(sk); diff --git a/trunk/include/net/rtnetlink.h b/trunk/include/net/rtnetlink.h index 4093ca78cf60..e013c68bfb00 100644 --- a/trunk/include/net/rtnetlink.h +++ b/trunk/include/net/rtnetlink.h @@ -83,41 +83,6 @@ extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); extern int rtnl_link_register(struct rtnl_link_ops *ops); extern void rtnl_link_unregister(struct rtnl_link_ops *ops); -/** - * struct rtnl_af_ops - rtnetlink address family operations - * - * @list: Used internally - * @family: Address family - * @fill_link_af: Function to fill IFLA_AF_SPEC with address family - * specific netlink attributes. - * @get_link_af_size: Function to calculate size of address family specific - * netlink attributes exlusive the container attribute. - * @validate_link_af: Validate a IFLA_AF_SPEC attribute, must check attr - * for invalid configuration settings. - * @set_link_af: Function to parse a IFLA_AF_SPEC attribute and modify - * net_device accordingly. - */ -struct rtnl_af_ops { - struct list_head list; - int family; - - int (*fill_link_af)(struct sk_buff *skb, - const struct net_device *dev); - size_t (*get_link_af_size)(const struct net_device *dev); - - int (*validate_link_af)(const struct net_device *dev, - const struct nlattr *attr); - int (*set_link_af)(struct net_device *dev, - const struct nlattr *attr); -}; - -extern int __rtnl_af_register(struct rtnl_af_ops *ops); -extern void __rtnl_af_unregister(struct rtnl_af_ops *ops); - -extern int rtnl_af_register(struct rtnl_af_ops *ops); -extern void rtnl_af_unregister(struct rtnl_af_ops *ops); - - extern struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]); extern struct net_device *rtnl_create_link(struct net *src_net, struct net *net, char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]); diff --git a/trunk/include/net/scm.h b/trunk/include/net/scm.h index 745460fa2f02..31656506d967 100644 --- a/trunk/include/net/scm.h +++ b/trunk/include/net/scm.h @@ -10,12 +10,11 @@ /* Well, we should have at least one descriptor open * to accept passed FDs 8) */ -#define SCM_MAX_FD 253 +#define SCM_MAX_FD 255 struct scm_fp_list { struct list_head list; - short count; - short max; + int count; struct file *fp[SCM_MAX_FD]; }; diff --git a/trunk/include/net/sctp/command.h b/trunk/include/net/sctp/command.h index c01dc99def07..2c55a7ea20af 100644 --- a/trunk/include/net/sctp/command.h +++ b/trunk/include/net/sctp/command.h @@ -111,6 +111,9 @@ typedef enum { SCTP_CMD_LAST } sctp_verb_t; +#define SCTP_CMD_MAX (SCTP_CMD_LAST - 1) +#define SCTP_CMD_NUM_VERBS (SCTP_CMD_MAX + 1) + /* How many commands can you put in an sctp_cmd_seq_t? * This is a rather arbitrary number, ideally derived from a careful * analysis of the state functions, but in reality just taken from diff --git a/trunk/include/net/sctp/constants.h b/trunk/include/net/sctp/constants.h index c70d8ccc55cb..63908840eef0 100644 --- a/trunk/include/net/sctp/constants.h +++ b/trunk/include/net/sctp/constants.h @@ -61,6 +61,7 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM }; * symbols. CIDs are dense through SCTP_CID_BASE_MAX. */ #define SCTP_CID_BASE_MAX SCTP_CID_SHUTDOWN_COMPLETE +#define SCTP_CID_MAX SCTP_CID_ASCONF_ACK #define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1) @@ -85,6 +86,9 @@ typedef enum { } sctp_event_t; +#define SCTP_EVENT_T_MAX SCTP_EVENT_T_PRIMITIVE +#define SCTP_EVENT_T_NUM (SCTP_EVENT_T_MAX + 1) + /* As a convenience for the state machine, we append SCTP_EVENT_* and * SCTP_ULP_* to the list of possible chunks. */ @@ -158,6 +162,9 @@ SCTP_SUBTYPE_CONSTRUCTOR(PRIMITIVE, sctp_event_primitive_t, primitive) - (unsigned long)(c->chunk_hdr)\ - sizeof(sctp_data_chunk_t))) +#define SCTP_MAX_ERROR_CAUSE SCTP_ERROR_NONEXIST_IP +#define SCTP_NUM_ERROR_CAUSE 10 + /* Internal error codes */ typedef enum { @@ -259,6 +266,7 @@ enum { SCTP_ARBITRARY_COOKIE_ECHO_LEN = 200 }; #define SCTP_TSN_MAP_INITIAL BITS_PER_LONG #define SCTP_TSN_MAP_INCREMENT SCTP_TSN_MAP_INITIAL #define SCTP_TSN_MAP_SIZE 4096 +#define SCTP_TSN_MAX_GAP 65535 /* We will not record more than this many duplicate TSNs between two * SACKs. The minimum PMTU is 576. Remove all the headers and there @@ -293,6 +301,9 @@ enum { SCTP_MAX_GABS = 16 }; #define SCTP_CLOCK_GRANULARITY 1 /* 1 jiffy */ +#define SCTP_DEF_MAX_INIT 6 +#define SCTP_DEF_MAX_SEND 10 + #define SCTP_DEFAULT_COOKIE_LIFE (60 * 1000) /* 60 seconds */ #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ @@ -306,6 +317,9 @@ enum { SCTP_MAX_GABS = 16 }; */ #define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */ #define SCTP_HOW_MANY_SECRETS 2 /* How many secrets I keep */ +#define SCTP_HOW_LONG_COOKIE_LIVE 3600 /* How many seconds the current + * secret will live? + */ #define SCTP_SECRET_SIZE 32 /* Number of octets in a 256 bits. */ #define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */ diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index cc9185ca8fd1..69fef4fb79c0 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -261,6 +261,8 @@ extern struct sctp_globals { #define sctp_assoc_hashsize (sctp_globals.assoc_hashsize) #define sctp_assoc_hashtable (sctp_globals.assoc_hashtable) #define sctp_port_hashsize (sctp_globals.port_hashsize) +#define sctp_port_rover (sctp_globals.port_rover) +#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock) #define sctp_port_hashtable (sctp_globals.port_hashtable) #define sctp_local_addr_list (sctp_globals.local_addr_list) #define sctp_local_addr_lock (sctp_globals.addr_list_lock) diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 5557dfb3dd68..c7a736228ca2 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -57,7 +57,7 @@ #include #include -#include +#include #include #include @@ -241,67 +241,59 @@ struct sock { #define sk_bind_node __sk_common.skc_bind_node #define sk_prot __sk_common.skc_prot #define sk_net __sk_common.skc_net + kmemcheck_bitfield_begin(flags); + unsigned int sk_shutdown : 2, + sk_no_check : 2, + sk_userlocks : 4, + sk_protocol : 8, + sk_type : 16; + kmemcheck_bitfield_end(flags); + int sk_rcvbuf; socket_lock_t sk_lock; - struct sk_buff_head sk_receive_queue; /* * The backlog queue is special, it is always used with * the per-socket spinlock held and requires low latency * access. Therefore we special case it's implementation. - * Note : rmem_alloc is in this structure to fill a hole - * on 64bit arches, not because its logically part of - * backlog. */ struct { - atomic_t rmem_alloc; - int len; - struct sk_buff *head; - struct sk_buff *tail; + struct sk_buff *head; + struct sk_buff *tail; + int len; } sk_backlog; -#define sk_rmem_alloc sk_backlog.rmem_alloc - int sk_forward_alloc; -#ifdef CONFIG_RPS - __u32 sk_rxhash; -#endif - atomic_t sk_drops; - int sk_rcvbuf; - - struct sk_filter __rcu *sk_filter; struct socket_wq *sk_wq; - -#ifdef CONFIG_NET_DMA - struct sk_buff_head sk_async_wait_queue; -#endif - + struct dst_entry *sk_dst_cache; #ifdef CONFIG_XFRM struct xfrm_policy *sk_policy[2]; #endif - unsigned long sk_flags; - struct dst_entry *sk_dst_cache; spinlock_t sk_dst_lock; + atomic_t sk_rmem_alloc; atomic_t sk_wmem_alloc; atomic_t sk_omem_alloc; int sk_sndbuf; + struct sk_buff_head sk_receive_queue; struct sk_buff_head sk_write_queue; - kmemcheck_bitfield_begin(flags); - unsigned int sk_shutdown : 2, - sk_no_check : 2, - sk_userlocks : 4, - sk_protocol : 8, - sk_type : 16; - kmemcheck_bitfield_end(flags); +#ifdef CONFIG_NET_DMA + struct sk_buff_head sk_async_wait_queue; +#endif int sk_wmem_queued; + int sk_forward_alloc; gfp_t sk_allocation; int sk_route_caps; int sk_route_nocaps; int sk_gso_type; unsigned int sk_gso_max_size; int sk_rcvlowat; +#ifdef CONFIG_RPS + __u32 sk_rxhash; +#endif + unsigned long sk_flags; unsigned long sk_lingertime; struct sk_buff_head sk_error_queue; struct proto *sk_prot_creator; rwlock_t sk_callback_lock; int sk_err, sk_err_soft; + atomic_t sk_drops; unsigned short sk_ack_backlog; unsigned short sk_max_ack_backlog; __u32 sk_priority; @@ -309,6 +301,7 @@ struct sock { const struct cred *sk_peer_cred; long sk_rcvtimeo; long sk_sndtimeo; + struct sk_filter __rcu *sk_filter; void *sk_protinfo; struct timer_list sk_timer; ktime_t sk_stamp; @@ -769,7 +762,7 @@ struct proto { /* Memory pressure */ void (*enter_memory_pressure)(struct sock *sk); - atomic_long_t *memory_allocated; /* Current allocated memory. */ + atomic_t *memory_allocated; /* Current allocated memory. */ struct percpu_counter *sockets_allocated; /* Current number of sockets. */ /* * Pressure flag: try to collapse. @@ -778,7 +771,7 @@ struct proto { * is strict, actions are advisory and have some latency. */ int *memory_pressure; - long *sysctl_mem; + int *sysctl_mem; int *sysctl_wmem; int *sysctl_rmem; int max_header; diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index e36c874c7fb1..4fee0424af7e 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -224,7 +224,7 @@ extern int sysctl_tcp_fack; extern int sysctl_tcp_reordering; extern int sysctl_tcp_ecn; extern int sysctl_tcp_dsack; -extern long sysctl_tcp_mem[3]; +extern int sysctl_tcp_mem[3]; extern int sysctl_tcp_wmem[3]; extern int sysctl_tcp_rmem[3]; extern int sysctl_tcp_app_win; @@ -247,7 +247,7 @@ extern int sysctl_tcp_cookie_size; extern int sysctl_tcp_thin_linear_timeouts; extern int sysctl_tcp_thin_dupack; -extern atomic_long_t tcp_memory_allocated; +extern atomic_t tcp_memory_allocated; extern struct percpu_counter tcp_sockets_allocated; extern int tcp_memory_pressure; @@ -280,7 +280,7 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift) } if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && - atomic_long_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) + atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) return true; return false; } diff --git a/trunk/include/net/udp.h b/trunk/include/net/udp.h index bb967dd59bf7..200b82848c9a 100644 --- a/trunk/include/net/udp.h +++ b/trunk/include/net/udp.h @@ -105,10 +105,10 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table, extern struct proto udp_prot; -extern atomic_long_t udp_memory_allocated; +extern atomic_t udp_memory_allocated; /* sysctl variables for udp */ -extern long sysctl_udp_mem[3]; +extern int sysctl_udp_mem[3]; extern int sysctl_udp_rmem_min; extern int sysctl_udp_wmem_min; diff --git a/trunk/include/net/x25.h b/trunk/include/net/x25.h index a06119a05129..1479cb4a41fc 100644 --- a/trunk/include/net/x25.h +++ b/trunk/include/net/x25.h @@ -315,8 +315,6 @@ extern struct list_head x25_route_list; extern rwlock_t x25_route_list_lock; extern struct list_head x25_forward_list; extern rwlock_t x25_forward_list_lock; -extern struct list_head x25_neigh_list; -extern rwlock_t x25_neigh_list_lock; extern int x25_proc_init(void); extern void x25_proc_exit(void); diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 7fa5b005893e..bcfb6b24b019 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -805,9 +805,6 @@ __be16 xfrm_flowi_sport(struct flowi *fl) case IPPROTO_MH: port = htons(fl->fl_mh_type); break; - case IPPROTO_GRE: - port = htons(ntohl(fl->fl_gre_key) >> 16); - break; default: port = 0; /*XXX*/ } @@ -829,9 +826,6 @@ __be16 xfrm_flowi_dport(struct flowi *fl) case IPPROTO_ICMPV6: port = htons(fl->fl_icmp_code); break; - case IPPROTO_GRE: - port = htons(ntohl(fl->fl_gre_key) & 0xffff); - break; default: port = 0; /*XXX*/ } diff --git a/trunk/include/trace/events/ext4.h b/trunk/include/trace/events/ext4.h index e5e345fb2a5c..289010d3270b 100644 --- a/trunk/include/trace/events/ext4.h +++ b/trunk/include/trace/events/ext4.h @@ -98,103 +98,6 @@ TRACE_EVENT(ext4_allocate_inode, (unsigned long) __entry->dir, __entry->mode) ); -TRACE_EVENT(ext4_evict_inode, - TP_PROTO(struct inode *inode), - - TP_ARGS(inode), - - TP_STRUCT__entry( - __field( int, dev_major ) - __field( int, dev_minor ) - __field( ino_t, ino ) - __field( int, nlink ) - ), - - TP_fast_assign( - __entry->dev_major = MAJOR(inode->i_sb->s_dev); - __entry->dev_minor = MINOR(inode->i_sb->s_dev); - __entry->ino = inode->i_ino; - __entry->nlink = inode->i_nlink; - ), - - TP_printk("dev %d,%d ino %lu nlink %d", - __entry->dev_major, __entry->dev_minor, - (unsigned long) __entry->ino, __entry->nlink) -); - -TRACE_EVENT(ext4_drop_inode, - TP_PROTO(struct inode *inode, int drop), - - TP_ARGS(inode, drop), - - TP_STRUCT__entry( - __field( int, dev_major ) - __field( int, dev_minor ) - __field( ino_t, ino ) - __field( int, drop ) - ), - - TP_fast_assign( - __entry->dev_major = MAJOR(inode->i_sb->s_dev); - __entry->dev_minor = MINOR(inode->i_sb->s_dev); - __entry->ino = inode->i_ino; - __entry->drop = drop; - ), - - TP_printk("dev %d,%d ino %lu drop %d", - __entry->dev_major, __entry->dev_minor, - (unsigned long) __entry->ino, __entry->drop) -); - -TRACE_EVENT(ext4_mark_inode_dirty, - TP_PROTO(struct inode *inode, unsigned long IP), - - TP_ARGS(inode, IP), - - TP_STRUCT__entry( - __field( int, dev_major ) - __field( int, dev_minor ) - __field( ino_t, ino ) - __field(unsigned long, ip ) - ), - - TP_fast_assign( - __entry->dev_major = MAJOR(inode->i_sb->s_dev); - __entry->dev_minor = MINOR(inode->i_sb->s_dev); - __entry->ino = inode->i_ino; - __entry->ip = IP; - ), - - TP_printk("dev %d,%d ino %lu caller %pF", - __entry->dev_major, __entry->dev_minor, - (unsigned long) __entry->ino, (void *)__entry->ip) -); - -TRACE_EVENT(ext4_begin_ordered_truncate, - TP_PROTO(struct inode *inode, loff_t new_size), - - TP_ARGS(inode, new_size), - - TP_STRUCT__entry( - __field( int, dev_major ) - __field( int, dev_minor ) - __field( ino_t, ino ) - __field( loff_t, new_size ) - ), - - TP_fast_assign( - __entry->dev_major = MAJOR(inode->i_sb->s_dev); - __entry->dev_minor = MINOR(inode->i_sb->s_dev); - __entry->ino = inode->i_ino; - __entry->new_size = new_size; - ), - - TP_printk("dev %d,%d ino %lu new_size %lld", - __entry->dev_major, __entry->dev_minor, - (unsigned long) __entry->ino, - (long long) __entry->new_size) -); - DECLARE_EVENT_CLASS(ext4__write_begin, TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 21aa7b3001fb..b194febf5799 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -95,14 +95,6 @@ static void __exit_signal(struct task_struct *tsk) tty = sig->tty; sig->tty = NULL; } else { - /* - * This can only happen if the caller is de_thread(). - * FIXME: this is the temporary hack, we should teach - * posix-cpu-timers to handle this case correctly. - */ - if (unlikely(has_group_leader_pid(tsk))) - posix_cpu_timers_exit_group(tsk); - /* * If there is any task waiting for the group exit * then notify it: diff --git a/trunk/kernel/latencytop.c b/trunk/kernel/latencytop.c index 17110a4a4fc2..877fb306d415 100644 --- a/trunk/kernel/latencytop.c +++ b/trunk/kernel/latencytop.c @@ -194,7 +194,14 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter) account_global_scheduler_latency(tsk, &lat); - for (i = 0; i < tsk->latency_record_count; i++) { + /* + * short term hack; if we're > 32 we stop; future we recycle: + */ + tsk->latency_record_count++; + if (tsk->latency_record_count >= LT_SAVECOUNT) + goto out_unlock; + + for (i = 0; i < LT_SAVECOUNT; i++) { struct latency_record *mylat; int same = 1; @@ -220,14 +227,8 @@ __account_scheduler_latency(struct task_struct *tsk, int usecs, int inter) } } - /* - * short term hack; if we're > 32 we stop; future we recycle: - */ - if (tsk->latency_record_count >= LT_SAVECOUNT) - goto out_unlock; - /* Allocated a new one: */ - i = tsk->latency_record_count++; + i = tsk->latency_record_count; memcpy(&tsk->latency_record[i], &lat, sizeof(struct latency_record)); out_unlock: diff --git a/trunk/kernel/perf_event.c b/trunk/kernel/perf_event.c index cb6c0d2af68f..517d827f4982 100644 --- a/trunk/kernel/perf_event.c +++ b/trunk/kernel/perf_event.c @@ -674,8 +674,6 @@ event_sched_in(struct perf_event *event, event->tstamp_running += ctx->time - event->tstamp_stopped; - event->shadow_ctx_time = ctx->time - ctx->timestamp; - if (!is_software_event(event)) cpuctx->active_oncpu++; ctx->nr_active++; @@ -3398,8 +3396,7 @@ static u32 perf_event_tid(struct perf_event *event, struct task_struct *p) } static void perf_output_read_one(struct perf_output_handle *handle, - struct perf_event *event, - u64 enabled, u64 running) + struct perf_event *event) { u64 read_format = event->attr.read_format; u64 values[4]; @@ -3407,11 +3404,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, values[n++] = perf_event_count(event); if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { - values[n++] = enabled + + values[n++] = event->total_time_enabled + atomic64_read(&event->child_total_time_enabled); } if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { - values[n++] = running + + values[n++] = event->total_time_running + atomic64_read(&event->child_total_time_running); } if (read_format & PERF_FORMAT_ID) @@ -3424,8 +3421,7 @@ static void perf_output_read_one(struct perf_output_handle *handle, * XXX PERF_FORMAT_GROUP vs inherited events seems difficult. */ static void perf_output_read_group(struct perf_output_handle *handle, - struct perf_event *event, - u64 enabled, u64 running) + struct perf_event *event) { struct perf_event *leader = event->group_leader, *sub; u64 read_format = event->attr.read_format; @@ -3435,10 +3431,10 @@ static void perf_output_read_group(struct perf_output_handle *handle, values[n++] = 1 + leader->nr_siblings; if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) - values[n++] = enabled; + values[n++] = leader->total_time_enabled; if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) - values[n++] = running; + values[n++] = leader->total_time_running; if (leader != event) leader->pmu->read(leader); @@ -3463,35 +3459,13 @@ static void perf_output_read_group(struct perf_output_handle *handle, } } -#define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\ - PERF_FORMAT_TOTAL_TIME_RUNNING) - static void perf_output_read(struct perf_output_handle *handle, struct perf_event *event) { - u64 enabled = 0, running = 0, now, ctx_time; - u64 read_format = event->attr.read_format; - - /* - * compute total_time_enabled, total_time_running - * based on snapshot values taken when the event - * was last scheduled in. - * - * we cannot simply called update_context_time() - * because of locking issue as we are called in - * NMI context - */ - if (read_format & PERF_FORMAT_TOTAL_TIMES) { - now = perf_clock(); - ctx_time = event->shadow_ctx_time + now; - enabled = ctx_time - event->tstamp_enabled; - running = ctx_time - event->tstamp_running; - } - if (event->attr.read_format & PERF_FORMAT_GROUP) - perf_output_read_group(handle, event, enabled, running); + perf_output_read_group(handle, event); else - perf_output_read_one(handle, event, enabled, running); + perf_output_read_one(handle, event); } void perf_output_sample(struct perf_output_handle *handle, diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 38e7d5868d60..b2ebaee8c377 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -261,12 +261,6 @@ static inline void boot_delay_msec(void) } #endif -#ifdef CONFIG_SECURITY_DMESG_RESTRICT -int dmesg_restrict = 1; -#else -int dmesg_restrict; -#endif - int do_syslog(int type, char __user *buf, int len, bool from_file) { unsigned i, j, limit, count; diff --git a/trunk/kernel/range.c b/trunk/kernel/range.c index 37fa9b99ad58..471b66acabb5 100644 --- a/trunk/kernel/range.c +++ b/trunk/kernel/range.c @@ -119,7 +119,7 @@ static int cmp_range(const void *x1, const void *x2) int clean_sort_range(struct range *range, int az) { - int i, j, k = az - 1, nr_range = az; + int i, j, k = az - 1, nr_range = 0; for (i = 0; i < k; i++) { if (range[i].end) diff --git a/trunk/kernel/relay.c b/trunk/kernel/relay.c index 859ea5a9605f..c7cf397fb929 100644 --- a/trunk/kernel/relay.c +++ b/trunk/kernel/relay.c @@ -70,10 +70,17 @@ static const struct vm_operations_struct relay_file_mmap_ops = { */ static struct page **relay_alloc_page_array(unsigned int n_pages) { - const size_t pa_size = n_pages * sizeof(struct page *); - if (pa_size > PAGE_SIZE) - return vzalloc(pa_size); - return kzalloc(pa_size, GFP_KERNEL); + struct page **array; + size_t pa_size = n_pages * sizeof(struct page *); + + if (pa_size > PAGE_SIZE) { + array = vmalloc(pa_size); + if (array) + memset(array, 0, pa_size); + } else { + array = kzalloc(pa_size, GFP_KERNEL); + } + return array; } /* diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index b65bf634035e..c33a1edb799f 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -703,15 +703,6 @@ static struct ctl_table kern_table[] = { .extra2 = &ten_thousand, }, #endif - { - .procname = "dmesg_restrict", - .data = &dmesg_restrict, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = &zero, - .extra2 = &one, - }, { .procname = "ngroups_max", .data = &ngroups_max, diff --git a/trunk/kernel/trace/blktrace.c b/trunk/kernel/trace/blktrace.c index 7b8ec0281548..bc251ed66724 100644 --- a/trunk/kernel/trace/blktrace.c +++ b/trunk/kernel/trace/blktrace.c @@ -168,6 +168,7 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK_TC_WRITE) }; +#define BLK_TC_HARDBARRIER BLK_TC_BARRIER #define BLK_TC_RAHEAD BLK_TC_AHEAD /* The ilog2() calls fall out because they're constant */ @@ -195,6 +196,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, return; what |= ddir_act[rw & WRITE]; + what |= MASK_TC_BIT(rw, HARDBARRIER); what |= MASK_TC_BIT(rw, SYNC); what |= MASK_TC_BIT(rw, RAHEAD); what |= MASK_TC_BIT(rw, META); @@ -1805,6 +1807,8 @@ void blk_fill_rwbs(char *rwbs, u32 rw, int bytes) if (rw & REQ_RAHEAD) rwbs[i++] = 'A'; + if (rw & REQ_HARDBARRIER) + rwbs[i++] = 'B'; if (rw & REQ_SYNC) rwbs[i++] = 'S'; if (rw & REQ_META) diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index 6e3c41a4024c..bafba687a6d8 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -43,7 +43,7 @@ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); #endif -static int no_watchdog; +static int __initdata no_watchdog; /* boot commands */ diff --git a/trunk/lib/nlattr.c b/trunk/lib/nlattr.c index 00e8a02681a6..c4706eb98d3d 100644 --- a/trunk/lib/nlattr.c +++ b/trunk/lib/nlattr.c @@ -15,7 +15,7 @@ #include #include -static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = { +static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = { [NLA_U8] = sizeof(u8), [NLA_U16] = sizeof(u16), [NLA_U32] = sizeof(u32), @@ -23,7 +23,7 @@ static const u16 nla_attr_minlen[NLA_TYPE_MAX+1] = { [NLA_NESTED] = NLA_HDRLEN, }; -static int validate_nla(const struct nlattr *nla, int maxtype, +static int validate_nla(struct nlattr *nla, int maxtype, const struct nla_policy *policy) { const struct nla_policy *pt; @@ -115,10 +115,10 @@ static int validate_nla(const struct nlattr *nla, int maxtype, * * Returns 0 on success or a negative error code. */ -int nla_validate(const struct nlattr *head, int len, int maxtype, +int nla_validate(struct nlattr *head, int len, int maxtype, const struct nla_policy *policy) { - const struct nlattr *nla; + struct nlattr *nla; int rem, err; nla_for_each_attr(nla, head, len, rem) { @@ -173,10 +173,10 @@ nla_policy_len(const struct nla_policy *p, int n) * * Returns 0 on success or a negative error code. */ -int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, - int len, const struct nla_policy *policy) +int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, + const struct nla_policy *policy) { - const struct nlattr *nla; + struct nlattr *nla; int rem, err; memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1)); @@ -191,7 +191,7 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, goto errout; } - tb[type] = (struct nlattr *)nla; + tb[type] = nla; } } @@ -212,14 +212,14 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, * * Returns the first attribute in the stream matching the specified type. */ -struct nlattr *nla_find(const struct nlattr *head, int len, int attrtype) +struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) { - const struct nlattr *nla; + struct nlattr *nla; int rem; nla_for_each_attr(nla, head, len, rem) if (nla_type(nla) == attrtype) - return (struct nlattr *)nla; + return nla; return NULL; } diff --git a/trunk/lib/radix-tree.c b/trunk/lib/radix-tree.c index 5086bb962b4d..6f412ab4c24f 100644 --- a/trunk/lib/radix-tree.c +++ b/trunk/lib/radix-tree.c @@ -82,16 +82,6 @@ struct radix_tree_preload { }; static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; -static inline void *ptr_to_indirect(void *ptr) -{ - return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR); -} - -static inline void *indirect_to_ptr(void *ptr) -{ - return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR); -} - static inline gfp_t root_gfp_mask(struct radix_tree_root *root) { return root->gfp_mask & __GFP_BITS_MASK; @@ -275,7 +265,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) return -ENOMEM; /* Increase the height. */ - node->slots[0] = indirect_to_ptr(root->rnode); + node->slots[0] = radix_tree_indirect_to_ptr(root->rnode); /* Propagate the aggregated tag info into the new root */ for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { @@ -286,7 +276,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index) newheight = root->height+1; node->height = newheight; node->count = 1; - node = ptr_to_indirect(node); + node = radix_tree_ptr_to_indirect(node); rcu_assign_pointer(root->rnode, node); root->height = newheight; } while (height > root->height); @@ -319,7 +309,7 @@ int radix_tree_insert(struct radix_tree_root *root, return error; } - slot = indirect_to_ptr(root->rnode); + slot = radix_tree_indirect_to_ptr(root->rnode); height = root->height; shift = (height-1) * RADIX_TREE_MAP_SHIFT; @@ -335,7 +325,8 @@ int radix_tree_insert(struct radix_tree_root *root, rcu_assign_pointer(node->slots[offset], slot); node->count++; } else - rcu_assign_pointer(root->rnode, ptr_to_indirect(slot)); + rcu_assign_pointer(root->rnode, + radix_tree_ptr_to_indirect(slot)); } /* Go a level down */ @@ -383,7 +374,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root, return NULL; return is_slot ? (void *)&root->rnode : node; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); height = node->height; if (index > radix_tree_maxindex(height)) @@ -402,7 +393,7 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root, height--; } while (height > 0); - return is_slot ? (void *)slot : indirect_to_ptr(node); + return is_slot ? (void *)slot:node; } /** @@ -464,7 +455,7 @@ void *radix_tree_tag_set(struct radix_tree_root *root, height = root->height; BUG_ON(index > radix_tree_maxindex(height)); - slot = indirect_to_ptr(root->rnode); + slot = radix_tree_indirect_to_ptr(root->rnode); shift = (height - 1) * RADIX_TREE_MAP_SHIFT; while (height > 0) { @@ -518,7 +509,7 @@ void *radix_tree_tag_clear(struct radix_tree_root *root, shift = (height - 1) * RADIX_TREE_MAP_SHIFT; pathp->node = NULL; - slot = indirect_to_ptr(root->rnode); + slot = radix_tree_indirect_to_ptr(root->rnode); while (height > 0) { int offset; @@ -588,7 +579,7 @@ int radix_tree_tag_get(struct radix_tree_root *root, if (!radix_tree_is_indirect_ptr(node)) return (index == 0); - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); height = node->height; if (index > radix_tree_maxindex(height)) @@ -675,7 +666,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, } shift = (height - 1) * RADIX_TREE_MAP_SHIFT; - slot = indirect_to_ptr(root->rnode); + slot = radix_tree_indirect_to_ptr(root->rnode); /* * we fill the path from (root->height - 2) to 0, leaving the index at @@ -906,7 +897,7 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, results[0] = node; return 1; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); max_index = radix_tree_maxindex(node->height); @@ -925,8 +916,7 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, slot = *(((void ***)results)[ret + i]); if (!slot) continue; - results[ret + nr_found] = - indirect_to_ptr(rcu_dereference_raw(slot)); + results[ret + nr_found] = rcu_dereference_raw(slot); nr_found++; } ret += nr_found; @@ -975,7 +965,7 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, results[0] = (void **)&root->rnode; return 1; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); max_index = radix_tree_maxindex(node->height); @@ -1100,7 +1090,7 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, results[0] = node; return 1; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); max_index = radix_tree_maxindex(node->height); @@ -1119,8 +1109,7 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results, slot = *(((void ***)results)[ret + i]); if (!slot) continue; - results[ret + nr_found] = - indirect_to_ptr(rcu_dereference_raw(slot)); + results[ret + nr_found] = rcu_dereference_raw(slot); nr_found++; } ret += nr_found; @@ -1170,7 +1159,7 @@ radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, results[0] = (void **)&root->rnode; return 1; } - node = indirect_to_ptr(node); + node = radix_tree_indirect_to_ptr(node); max_index = radix_tree_maxindex(node->height); @@ -1206,7 +1195,7 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) void *newptr; BUG_ON(!radix_tree_is_indirect_ptr(to_free)); - to_free = indirect_to_ptr(to_free); + to_free = radix_tree_indirect_to_ptr(to_free); /* * The candidate node has more than one child, or its child @@ -1219,39 +1208,16 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) /* * We don't need rcu_assign_pointer(), since we are simply - * moving the node from one part of the tree to another: if it - * was safe to dereference the old pointer to it + * moving the node from one part of the tree to another. If + * it was safe to dereference the old pointer to it * (to_free->slots[0]), it will be safe to dereference the new - * one (root->rnode) as far as dependent read barriers go. + * one (root->rnode). */ newptr = to_free->slots[0]; if (root->height > 1) - newptr = ptr_to_indirect(newptr); + newptr = radix_tree_ptr_to_indirect(newptr); root->rnode = newptr; root->height--; - - /* - * We have a dilemma here. The node's slot[0] must not be - * NULLed in case there are concurrent lookups expecting to - * find the item. However if this was a bottom-level node, - * then it may be subject to the slot pointer being visible - * to callers dereferencing it. If item corresponding to - * slot[0] is subsequently deleted, these callers would expect - * their slot to become empty sooner or later. - * - * For example, lockless pagecache will look up a slot, deref - * the page pointer, and if the page is 0 refcount it means it - * was concurrently deleted from pagecache so try the deref - * again. Fortunately there is already a requirement for logic - * to retry the entire slot lookup -- the indirect pointer - * problem (replacing direct root node with an indirect pointer - * also results in a stale slot). So tag the slot as indirect - * to force callers to retry. - */ - if (root->height == 0) - *((unsigned long *)&to_free->slots[0]) |= - RADIX_TREE_INDIRECT_PTR; - radix_tree_node_free(to_free); } } @@ -1288,7 +1254,7 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) root->rnode = NULL; goto out; } - slot = indirect_to_ptr(slot); + slot = radix_tree_indirect_to_ptr(slot); shift = (height - 1) * RADIX_TREE_MAP_SHIFT; pathp->node = NULL; @@ -1330,7 +1296,8 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) radix_tree_node_free(to_free); if (pathp->node->count) { - if (pathp->node == indirect_to_ptr(root->rnode)) + if (pathp->node == + radix_tree_indirect_to_ptr(root->rnode)) radix_tree_shrink(root); goto out; } diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index ea89840fc65f..75572b5f2374 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -644,9 +644,7 @@ struct page *find_get_page(struct address_space *mapping, pgoff_t offset) pagep = radix_tree_lookup_slot(&mapping->page_tree, offset); if (pagep) { page = radix_tree_deref_slot(pagep); - if (unlikely(!page)) - goto out; - if (radix_tree_deref_retry(page)) + if (unlikely(!page || page == RADIX_TREE_RETRY)) goto repeat; if (!page_cache_get_speculative(page)) @@ -662,7 +660,6 @@ struct page *find_get_page(struct address_space *mapping, pgoff_t offset) goto repeat; } } -out: rcu_read_unlock(); return page; @@ -780,11 +777,12 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, page = radix_tree_deref_slot((void **)pages[i]); if (unlikely(!page)) continue; - if (radix_tree_deref_retry(page)) { - if (ret) - start = pages[ret-1]->index; + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) goto restart; - } if (!page_cache_get_speculative(page)) goto repeat; @@ -832,7 +830,11 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index, page = radix_tree_deref_slot((void **)pages[i]); if (unlikely(!page)) continue; - if (radix_tree_deref_retry(page)) + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) goto restart; if (page->mapping == NULL || page->index != index) @@ -885,7 +887,11 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, page = radix_tree_deref_slot((void **)pages[i]); if (unlikely(!page)) continue; - if (radix_tree_deref_retry(page)) + /* + * this can only trigger if nr_found == 1, making livelock + * a non issue. + */ + if (unlikely(page == RADIX_TREE_RETRY)) goto restart; if (!page_cache_get_speculative(page)) @@ -1023,9 +1029,6 @@ static void do_generic_file_read(struct file *filp, loff_t *ppos, goto page_not_up_to_date; if (!trylock_page(page)) goto page_not_up_to_date; - /* Did it get truncated before we got the lock? */ - if (!page->mapping) - goto page_not_up_to_date_locked; if (!mapping->a_ops->is_partially_uptodate(page, desc, offset)) goto page_not_up_to_date_locked; @@ -1560,10 +1563,8 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) goto no_cached_page; } - if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) { - page_cache_release(page); + if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) return ret | VM_FAULT_RETRY; - } /* Did it get truncated? */ if (unlikely(page->mapping != mapping)) { diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 2efa8ea07ff7..9a99cfaf0a19 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -4208,17 +4208,15 @@ static struct mem_cgroup *mem_cgroup_alloc(void) memset(mem, 0, size); mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu); - if (!mem->stat) - goto out_free; + if (!mem->stat) { + if (size < PAGE_SIZE) + kfree(mem); + else + vfree(mem); + mem = NULL; + } spin_lock_init(&mem->pcp_counter_lock); return mem; - -out_free: - if (size < PAGE_SIZE) - kfree(mem); - else - vfree(mem); - return NULL; } /* diff --git a/trunk/mm/mprotect.c b/trunk/mm/mprotect.c index 4c5133873097..2d1bf7cf8851 100644 --- a/trunk/mm/mprotect.c +++ b/trunk/mm/mprotect.c @@ -211,7 +211,6 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, mmu_notifier_invalidate_range_end(mm, start, end); vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); vm_stat_account(mm, newflags, vma->vm_file, nrpages); - perf_event_mmap(vma); return 0; fail: @@ -300,6 +299,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); if (error) goto out; + perf_event_mmap(vma); nstart = tmp; if (nstart < prev->vm_end) diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index d31d7ce52c0e..b8a6fdc21312 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -913,7 +913,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, * back off and wait for congestion to clear because further reclaim * will encounter the same problem */ - if (nr_dirty == nr_congested && nr_dirty != 0) + if (nr_dirty == nr_congested) zone_set_flag(zone, ZONE_CONGESTED); free_page_list(&free_pages); diff --git a/trunk/mm/vmstat.c b/trunk/mm/vmstat.c index 42eac4d33216..cd2e42be7b68 100644 --- a/trunk/mm/vmstat.c +++ b/trunk/mm/vmstat.c @@ -949,7 +949,7 @@ static void *vmstat_start(struct seq_file *m, loff_t *pos) v[PGPGIN] /= 2; /* sectors -> kbytes */ v[PGPGOUT] /= 2; #endif - return (unsigned long *)m->private + *pos; + return m->private + *pos; } static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos) diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index 6e64f7c6a2e9..52077ca22072 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -272,11 +272,13 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); } - new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, vlan_setup); + new_dev = alloc_netdev_mq(sizeof(struct vlan_dev_info), name, + vlan_setup, real_dev->num_tx_queues); if (new_dev == NULL) return -ENOBUFS; + netif_copy_real_num_queues(new_dev, real_dev); dev_net_set(new_dev, net); /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. @@ -332,15 +334,12 @@ static void vlan_transfer_features(struct net_device *dev, vlandev->features &= ~dev->vlan_features; vlandev->features |= dev->features & dev->vlan_features; vlandev->gso_max_size = dev->gso_max_size; - - if (dev->features & NETIF_F_HW_VLAN_TX) - vlandev->hard_header_len = dev->hard_header_len; - else - vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; - #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; #endif + vlandev->real_num_tx_queues = dev->real_num_tx_queues; + BUG_ON(vlandev->real_num_tx_queues > vlandev->num_tx_queues); + if (old_features != vlandev->features) netdev_features_change(vlandev); } diff --git a/trunk/net/8021q/vlan.h b/trunk/net/8021q/vlan.h index 5687c9b95f33..db01b3181fdc 100644 --- a/trunk/net/8021q/vlan.h +++ b/trunk/net/8021q/vlan.h @@ -19,25 +19,19 @@ struct vlan_priority_tci_mapping { /** - * struct vlan_pcpu_stats - VLAN percpu rx/tx stats + * struct vlan_rx_stats - VLAN percpu rx stats * @rx_packets: number of received packets * @rx_bytes: number of received bytes * @rx_multicast: number of received multicast packets - * @tx_packets: number of transmitted packets - * @tx_bytes: number of transmitted bytes * @syncp: synchronization point for 64bit counters - * @rx_errors: number of rx errors - * @tx_dropped: number of tx drops + * @rx_errors: number of errors */ -struct vlan_pcpu_stats { +struct vlan_rx_stats { u64 rx_packets; u64 rx_bytes; u64 rx_multicast; - u64 tx_packets; - u64 tx_bytes; struct u64_stats_sync syncp; - u32 rx_errors; - u32 tx_dropped; + unsigned long rx_errors; }; /** @@ -51,7 +45,9 @@ struct vlan_pcpu_stats { * @real_dev: underlying netdevice * @real_dev_addr: address of underlying netdevice * @dent: proc dir entry - * @vlan_pcpu_stats: ptr to percpu rx stats + * @cnt_inc_headroom_on_tx: statistic - number of skb expansions on TX + * @cnt_encap_on_xmit: statistic - number of skb encapsulations on TX + * @vlan_rx_stats: ptr to percpu rx stats */ struct vlan_dev_info { unsigned int nr_ingress_mappings; @@ -66,7 +62,9 @@ struct vlan_dev_info { unsigned char real_dev_addr[ETH_ALEN]; struct proc_dir_entry *dent; - struct vlan_pcpu_stats __percpu *vlan_pcpu_stats; + unsigned long cnt_inc_headroom_on_tx; + unsigned long cnt_encap_on_xmit; + struct vlan_rx_stats __percpu *vlan_rx_stats; }; static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) diff --git a/trunk/net/8021q/vlan_core.c b/trunk/net/8021q/vlan_core.c index ce8e3ab3e7a5..69b2f79800a5 100644 --- a/trunk/net/8021q/vlan_core.c +++ b/trunk/net/8021q/vlan_core.c @@ -9,7 +9,7 @@ bool vlan_hwaccel_do_receive(struct sk_buff **skbp) struct sk_buff *skb = *skbp; u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; struct net_device *vlan_dev; - struct vlan_pcpu_stats *rx_stats; + struct vlan_rx_stats *rx_stats; vlan_dev = vlan_find_dev(skb->dev, vlan_id); if (!vlan_dev) { @@ -26,7 +26,7 @@ bool vlan_hwaccel_do_receive(struct sk_buff **skbp) skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); skb->vlan_tci = 0; - rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_pcpu_stats); + rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_rx_stats); u64_stats_update_begin(&rx_stats->syncp); rx_stats->rx_packets++; diff --git a/trunk/net/8021q/vlan_dev.c b/trunk/net/8021q/vlan_dev.c index be737539f34d..14e3d1fa07a0 100644 --- a/trunk/net/8021q/vlan_dev.c +++ b/trunk/net/8021q/vlan_dev.c @@ -141,7 +141,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev) { struct vlan_hdr *vhdr; - struct vlan_pcpu_stats *rx_stats; + struct vlan_rx_stats *rx_stats; struct net_device *vlan_dev; u16 vlan_id; u16 vlan_tci; @@ -177,7 +177,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, } else { skb->dev = vlan_dev; - rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_pcpu_stats); + rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats); u64_stats_update_begin(&rx_stats->syncp); rx_stats->rx_packets++; @@ -274,6 +274,9 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, u16 vlan_tci = 0; int rc; + if (WARN_ON(skb_headroom(skb) < dev->hard_header_len)) + return -ENOSPC; + if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) { vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); @@ -310,6 +313,8 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { + int i = skb_get_queue_mapping(skb); + struct netdev_queue *txq = netdev_get_tx_queue(dev, i); struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); unsigned int len; int ret; @@ -321,31 +326,71 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, */ if (veth->h_vlan_proto != htons(ETH_P_8021Q) || vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { + unsigned int orig_headroom = skb_headroom(skb); u16 vlan_tci; + + vlan_dev_info(dev)->cnt_encap_on_xmit++; + vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); - skb = __vlan_hwaccel_put_tag(skb, vlan_tci); + skb = __vlan_put_tag(skb, vlan_tci); + if (!skb) { + txq->tx_dropped++; + return NETDEV_TX_OK; + } + + if (orig_headroom < VLAN_HLEN) + vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; } + skb_set_dev(skb, vlan_dev_info(dev)->real_dev); len = skb->len; ret = dev_queue_xmit(skb); if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { - struct vlan_pcpu_stats *stats; + txq->tx_packets++; + txq->tx_bytes += len; + } else + txq->tx_dropped++; - stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats); - u64_stats_update_begin(&stats->syncp); - stats->tx_packets++; - stats->tx_bytes += len; - u64_stats_update_begin(&stats->syncp); - } else { - this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); - } + return ret; +} + +static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + int i = skb_get_queue_mapping(skb); + struct netdev_queue *txq = netdev_get_tx_queue(dev, i); + u16 vlan_tci; + unsigned int len; + int ret; + + vlan_tci = vlan_dev_info(dev)->vlan_id; + vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); + skb = __vlan_hwaccel_put_tag(skb, vlan_tci); + + skb->dev = vlan_dev_info(dev)->real_dev; + len = skb->len; + ret = dev_queue_xmit(skb); + + if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { + txq->tx_packets++; + txq->tx_bytes += len; + } else + txq->tx_dropped++; return ret; } +static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + struct net_device *rdev = vlan_dev_info(dev)->real_dev; + const struct net_device_ops *ops = rdev->netdev_ops; + + return ops->ndo_select_queue(rdev, skb); +} + static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) { /* TODO: gotta make sure the underlying layer can handle it, @@ -674,7 +719,8 @@ static const struct header_ops vlan_header_ops = { .parse = eth_header_parse, }; -static const struct net_device_ops vlan_netdev_ops; +static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops, + vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq; static int vlan_dev_init(struct net_device *dev) { @@ -692,7 +738,6 @@ static int vlan_dev_init(struct net_device *dev) (1<<__LINK_STATE_PRESENT); dev->features |= real_dev->features & real_dev->vlan_features; - dev->features |= NETIF_F_LLTX; dev->gso_max_size = real_dev->gso_max_size; /* ipv6 shared card related stuff */ @@ -710,20 +755,26 @@ static int vlan_dev_init(struct net_device *dev) if (real_dev->features & NETIF_F_HW_VLAN_TX) { dev->header_ops = real_dev->header_ops; dev->hard_header_len = real_dev->hard_header_len; + if (real_dev->netdev_ops->ndo_select_queue) + dev->netdev_ops = &vlan_netdev_accel_ops_sq; + else + dev->netdev_ops = &vlan_netdev_accel_ops; } else { dev->header_ops = &vlan_header_ops; dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; + if (real_dev->netdev_ops->ndo_select_queue) + dev->netdev_ops = &vlan_netdev_ops_sq; + else + dev->netdev_ops = &vlan_netdev_ops; } - dev->netdev_ops = &vlan_netdev_ops; - if (is_vlan_dev(real_dev)) subclass = 1; vlan_dev_set_lockdep_class(dev, subclass); - vlan_dev_info(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats); - if (!vlan_dev_info(dev)->vlan_pcpu_stats) + vlan_dev_info(dev)->vlan_rx_stats = alloc_percpu(struct vlan_rx_stats); + if (!vlan_dev_info(dev)->vlan_rx_stats) return -ENOMEM; return 0; @@ -735,8 +786,8 @@ static void vlan_dev_uninit(struct net_device *dev) struct vlan_dev_info *vlan = vlan_dev_info(dev); int i; - free_percpu(vlan->vlan_pcpu_stats); - vlan->vlan_pcpu_stats = NULL; + free_percpu(vlan->vlan_rx_stats); + vlan->vlan_rx_stats = NULL; for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) { while ((pm = vlan->egress_priority_map[i]) != NULL) { vlan->egress_priority_map[i] = pm->next; @@ -774,37 +825,33 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev) static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { + dev_txq_stats_fold(dev, stats); - if (vlan_dev_info(dev)->vlan_pcpu_stats) { - struct vlan_pcpu_stats *p; - u32 rx_errors = 0, tx_dropped = 0; + if (vlan_dev_info(dev)->vlan_rx_stats) { + struct vlan_rx_stats *p, accum = {0}; int i; for_each_possible_cpu(i) { - u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes; + u64 rxpackets, rxbytes, rxmulticast; unsigned int start; - p = per_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats, i); + p = per_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats, i); do { start = u64_stats_fetch_begin_bh(&p->syncp); rxpackets = p->rx_packets; rxbytes = p->rx_bytes; rxmulticast = p->rx_multicast; - txpackets = p->tx_packets; - txbytes = p->tx_bytes; } while (u64_stats_fetch_retry_bh(&p->syncp, start)); - - stats->rx_packets += rxpackets; - stats->rx_bytes += rxbytes; - stats->multicast += rxmulticast; - stats->tx_packets += txpackets; - stats->tx_bytes += txbytes; - /* rx_errors & tx_dropped are u32 */ - rx_errors += p->rx_errors; - tx_dropped += p->tx_dropped; + accum.rx_packets += rxpackets; + accum.rx_bytes += rxbytes; + accum.rx_multicast += rxmulticast; + /* rx_errors is ulong, not protected by syncp */ + accum.rx_errors += p->rx_errors; } - stats->rx_errors = rx_errors; - stats->tx_dropped = tx_dropped; + stats->rx_packets = accum.rx_packets; + stats->rx_bytes = accum.rx_bytes; + stats->rx_errors = accum.rx_errors; + stats->multicast = accum.rx_multicast; } return stats; } @@ -861,6 +908,80 @@ static const struct net_device_ops vlan_netdev_ops = { #endif }; +static const struct net_device_ops vlan_netdev_accel_ops = { + .ndo_change_mtu = vlan_dev_change_mtu, + .ndo_init = vlan_dev_init, + .ndo_uninit = vlan_dev_uninit, + .ndo_open = vlan_dev_open, + .ndo_stop = vlan_dev_stop, + .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = vlan_dev_set_mac_address, + .ndo_set_rx_mode = vlan_dev_set_rx_mode, + .ndo_set_multicast_list = vlan_dev_set_rx_mode, + .ndo_change_rx_flags = vlan_dev_change_rx_flags, + .ndo_do_ioctl = vlan_dev_ioctl, + .ndo_neigh_setup = vlan_dev_neigh_setup, + .ndo_get_stats64 = vlan_dev_get_stats64, +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) + .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, + .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, + .ndo_fcoe_enable = vlan_dev_fcoe_enable, + .ndo_fcoe_disable = vlan_dev_fcoe_disable, + .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, +#endif +}; + +static const struct net_device_ops vlan_netdev_ops_sq = { + .ndo_select_queue = vlan_dev_select_queue, + .ndo_change_mtu = vlan_dev_change_mtu, + .ndo_init = vlan_dev_init, + .ndo_uninit = vlan_dev_uninit, + .ndo_open = vlan_dev_open, + .ndo_stop = vlan_dev_stop, + .ndo_start_xmit = vlan_dev_hard_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = vlan_dev_set_mac_address, + .ndo_set_rx_mode = vlan_dev_set_rx_mode, + .ndo_set_multicast_list = vlan_dev_set_rx_mode, + .ndo_change_rx_flags = vlan_dev_change_rx_flags, + .ndo_do_ioctl = vlan_dev_ioctl, + .ndo_neigh_setup = vlan_dev_neigh_setup, + .ndo_get_stats64 = vlan_dev_get_stats64, +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) + .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, + .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, + .ndo_fcoe_enable = vlan_dev_fcoe_enable, + .ndo_fcoe_disable = vlan_dev_fcoe_disable, + .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, +#endif +}; + +static const struct net_device_ops vlan_netdev_accel_ops_sq = { + .ndo_select_queue = vlan_dev_select_queue, + .ndo_change_mtu = vlan_dev_change_mtu, + .ndo_init = vlan_dev_init, + .ndo_uninit = vlan_dev_uninit, + .ndo_open = vlan_dev_open, + .ndo_stop = vlan_dev_stop, + .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = vlan_dev_set_mac_address, + .ndo_set_rx_mode = vlan_dev_set_rx_mode, + .ndo_set_multicast_list = vlan_dev_set_rx_mode, + .ndo_change_rx_flags = vlan_dev_change_rx_flags, + .ndo_do_ioctl = vlan_dev_ioctl, + .ndo_neigh_setup = vlan_dev_neigh_setup, + .ndo_get_stats64 = vlan_dev_get_stats64, +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) + .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, + .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, + .ndo_fcoe_enable = vlan_dev_fcoe_enable, + .ndo_fcoe_disable = vlan_dev_fcoe_disable, + .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, +#endif +}; + void vlan_setup(struct net_device *dev) { ether_setup(dev); diff --git a/trunk/net/8021q/vlan_netlink.c b/trunk/net/8021q/vlan_netlink.c index be9a5c19a775..ddc105734af7 100644 --- a/trunk/net/8021q/vlan_netlink.c +++ b/trunk/net/8021q/vlan_netlink.c @@ -101,6 +101,25 @@ static int vlan_changelink(struct net_device *dev, return 0; } +static int vlan_get_tx_queues(struct net *net, + struct nlattr *tb[], + unsigned int *num_tx_queues, + unsigned int *real_num_tx_queues) +{ + struct net_device *real_dev; + + if (!tb[IFLA_LINK]) + return -EINVAL; + + real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); + if (!real_dev) + return -ENODEV; + + *num_tx_queues = real_dev->num_tx_queues; + *real_num_tx_queues = real_dev->real_num_tx_queues; + return 0; +} + static int vlan_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { @@ -218,6 +237,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = { .maxtype = IFLA_VLAN_MAX, .policy = vlan_policy, .priv_size = sizeof(struct vlan_dev_info), + .get_tx_queues = vlan_get_tx_queues, .setup = vlan_setup, .validate = vlan_validate, .newlink = vlan_newlink, diff --git a/trunk/net/8021q/vlanproc.c b/trunk/net/8021q/vlanproc.c index d1314cf18adf..80e280f56686 100644 --- a/trunk/net/8021q/vlanproc.c +++ b/trunk/net/8021q/vlanproc.c @@ -280,6 +280,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *stats; + static const char fmt[] = "%30s %12lu\n"; static const char fmt64[] = "%30s %12llu\n"; int i; @@ -298,6 +299,10 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) seq_puts(seq, "\n"); seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets); seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes); + seq_printf(seq, fmt, "total headroom inc", + dev_info->cnt_inc_headroom_on_tx); + seq_printf(seq, fmt, "total encap on xmit", + dev_info->cnt_encap_on_xmit); seq_printf(seq, "Device: %s", dev_info->real_dev->name); /* now show all PRIORITY mappings relating to this VLAN */ seq_printf(seq, "\nINGRESS priority mappings: " diff --git a/trunk/net/Kconfig b/trunk/net/Kconfig index 126c2af0fc1f..55fd82e9ffd9 100644 --- a/trunk/net/Kconfig +++ b/trunk/net/Kconfig @@ -220,11 +220,6 @@ config RPS depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS default y -config XPS - boolean - depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS - default y - menu "Network testing" config NET_PKTGEN diff --git a/trunk/net/atm/br2684.c b/trunk/net/atm/br2684.c index fce2eae8d476..ad2b232a2055 100644 --- a/trunk/net/atm/br2684.c +++ b/trunk/net/atm/br2684.c @@ -97,7 +97,7 @@ static LIST_HEAD(br2684_devs); static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev) { - return netdev_priv(net_dev); + return (struct br2684_dev *)netdev_priv(net_dev); } static inline struct net_device *list_entry_brdev(const struct list_head *le) diff --git a/trunk/net/atm/clip.c b/trunk/net/atm/clip.c index d257da50fcfb..ff956d1115bc 100644 --- a/trunk/net/atm/clip.c +++ b/trunk/net/atm/clip.c @@ -502,8 +502,7 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip) struct atmarp_entry *entry; int error; struct clip_vcc *clip_vcc; - struct flowi fl = { .fl4_dst = ip, - .fl4_tos = 1 }; + struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}} }; struct rtable *rt; if (vcc->push != clip_push) { diff --git a/trunk/net/atm/lec.c b/trunk/net/atm/lec.c index 179e04bc99dd..181d70c73d70 100644 --- a/trunk/net/atm/lec.c +++ b/trunk/net/atm/lec.c @@ -816,7 +816,8 @@ static int lec_mcast_attach(struct atm_vcc *vcc, int arg) if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg]) return -EINVAL; vcc->proto_data = dev_lec[arg]; - return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc); + return lec_mcast_make((struct lec_priv *)netdev_priv(dev_lec[arg]), + vcc); } /* Initialize device. */ diff --git a/trunk/net/ax25/af_ax25.c b/trunk/net/ax25/af_ax25.c index bb86d2932394..26eaebf4aaa9 100644 --- a/trunk/net/ax25/af_ax25.c +++ b/trunk/net/ax25/af_ax25.c @@ -1392,7 +1392,6 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, ax25_cb *ax25; int err = 0; - memset(fsa, 0, sizeof(fsa)); lock_sock(sk); ax25 = ax25_sk(sk); @@ -1404,6 +1403,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, fsa->fsa_ax25.sax25_family = AF_AX25; fsa->fsa_ax25.sax25_call = ax25->dest_addr; + fsa->fsa_ax25.sax25_ndigis = 0; if (ax25->digipeat != NULL) { ndigi = ax25->digipeat->ndigi; diff --git a/trunk/net/bluetooth/Makefile b/trunk/net/bluetooth/Makefile index 7ca1f46a471a..d1e433f7d673 100644 --- a/trunk/net/bluetooth/Makefile +++ b/trunk/net/bluetooth/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_BT_BNEP) += bnep/ obj-$(CONFIG_BT_CMTP) += cmtp/ obj-$(CONFIG_BT_HIDP) += hidp/ -bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o +bluetooth-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o hci_sysfs.o lib.o diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index 84093b0000b9..bfef5bae0b3a 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -1175,12 +1175,6 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, sizeof(cp), &cp); - } else if (!ev->status && conn->out && - conn->sec_level == BT_SECURITY_HIGH) { - struct hci_cp_auth_requested cp; - cp.handle = ev->handle; - hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, - sizeof(cp), &cp); } else { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); diff --git a/trunk/net/bluetooth/hidp/Kconfig b/trunk/net/bluetooth/hidp/Kconfig index 86a91543172a..98fdfa1fbddd 100644 --- a/trunk/net/bluetooth/hidp/Kconfig +++ b/trunk/net/bluetooth/hidp/Kconfig @@ -1,6 +1,6 @@ config BT_HIDP tristate "HIDP protocol support" - depends on BT && BT_L2CAP && INPUT && HID_SUPPORT + depends on BT && BT_L2CAP && INPUT select HID help HIDP (Human Interface Device Protocol) is a transport layer diff --git a/trunk/net/bluetooth/l2cap.c b/trunk/net/bluetooth/l2cap.c index cd8f6ea03841..daa7a988d9a6 100644 --- a/trunk/net/bluetooth/l2cap.c +++ b/trunk/net/bluetooth/l2cap.c @@ -2421,11 +2421,11 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned break; case 2: - *val = get_unaligned_le16(opt->val); + *val = __le16_to_cpu(*((__le16 *) opt->val)); break; case 4: - *val = get_unaligned_le32(opt->val); + *val = __le32_to_cpu(*((__le32 *) opt->val)); break; default: @@ -2452,11 +2452,11 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) break; case 2: - put_unaligned_le16(val, opt->val); + *((__le16 *) opt->val) = cpu_to_le16(val); break; case 4: - put_unaligned_le32(val, opt->val); + *((__le32 *) opt->val) = cpu_to_le32(val); break; default: diff --git a/trunk/net/bluetooth/rfcomm/core.c b/trunk/net/bluetooth/rfcomm/core.c index fa642aa652bd..39a5d87e33b4 100644 --- a/trunk/net/bluetooth/rfcomm/core.c +++ b/trunk/net/bluetooth/rfcomm/core.c @@ -79,10 +79,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr); static void rfcomm_process_connect(struct rfcomm_session *s); -static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, - bdaddr_t *dst, - u8 sec_level, - int *err); +static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err); static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst); static void rfcomm_session_del(struct rfcomm_session *s); @@ -404,7 +401,7 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, s = rfcomm_session_get(src, dst); if (!s) { - s = rfcomm_session_create(src, dst, d->sec_level, &err); + s = rfcomm_session_create(src, dst, &err); if (!s) return err; } @@ -682,10 +679,7 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err) rfcomm_session_put(s); } -static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, - bdaddr_t *dst, - u8 sec_level, - int *err) +static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err) { struct rfcomm_session *s = NULL; struct sockaddr_l2 addr; @@ -710,7 +704,6 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, sk = sock->sk; lock_sock(sk); l2cap_pi(sk)->imtu = l2cap_mtu; - l2cap_pi(sk)->sec_level = sec_level; if (l2cap_ertm) l2cap_pi(sk)->mode = L2CAP_MODE_ERTM; release_sock(sk); diff --git a/trunk/net/bridge/br.c b/trunk/net/bridge/br.c index 84bbb82599b2..c8436fa31344 100644 --- a/trunk/net/bridge/br.c +++ b/trunk/net/bridge/br.c @@ -22,6 +22,8 @@ #include "br_private.h" +int (*br_should_route_hook)(struct sk_buff *skb); + static const struct stp_proto br_stp_proto = { .rcv = br_stp_rcv, }; @@ -100,6 +102,8 @@ static void __exit br_deinit(void) br_fdb_fini(); } +EXPORT_SYMBOL(br_should_route_hook); + module_init(br_init) module_exit(br_deinit) MODULE_LICENSE("GPL"); diff --git a/trunk/net/bridge/br_fdb.c b/trunk/net/bridge/br_fdb.c index 2872393b2939..90512ccfd3e9 100644 --- a/trunk/net/bridge/br_fdb.c +++ b/trunk/net/bridge/br_fdb.c @@ -238,18 +238,15 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br, int br_fdb_test_addr(struct net_device *dev, unsigned char *addr) { struct net_bridge_fdb_entry *fdb; - struct net_bridge_port *port; int ret; + if (!br_port_exists(dev)) + return 0; + rcu_read_lock(); - port = br_port_get_rcu(dev); - if (!port) - ret = 0; - else { - fdb = __br_fdb_get(port->br, addr); - ret = fdb && fdb->dst->dev != dev && - fdb->dst->state == BR_STATE_FORWARDING; - } + fdb = __br_fdb_get(br_port_get_rcu(dev)->br, addr); + ret = fdb && fdb->dst->dev != dev && + fdb->dst->state == BR_STATE_FORWARDING; rcu_read_unlock(); return ret; diff --git a/trunk/net/bridge/br_forward.c b/trunk/net/bridge/br_forward.c index 2bd11ec6d166..cbfe87f0f34a 100644 --- a/trunk/net/bridge/br_forward.c +++ b/trunk/net/bridge/br_forward.c @@ -223,7 +223,7 @@ static void br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct net_bridge_port_group *p; struct hlist_node *rp; - rp = rcu_dereference(hlist_first_rcu(&br->router_list)); + rp = rcu_dereference(br->router_list.first); p = mdst ? rcu_dereference(mdst->ports) : NULL; while (p || rp) { struct net_bridge_port *port, *lport, *rport; @@ -242,7 +242,7 @@ static void br_multicast_flood(struct net_bridge_mdb_entry *mdst, if ((unsigned long)lport >= (unsigned long)port) p = rcu_dereference(p->next); if ((unsigned long)rport >= (unsigned long)port) - rp = rcu_dereference(hlist_next_rcu(rp)); + rp = rcu_dereference(rp->next); } if (!prev) diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index d9d1e2bac1d6..89ad25a76202 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -475,8 +475,11 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; - p = br_port_get_rtnl(dev); - if (!p || p->br != br) + if (!br_port_exists(dev)) + return -EINVAL; + + p = br_port_get(dev); + if (p->br != br) return -EINVAL; del_nbp(p); diff --git a/trunk/net/bridge/br_input.c b/trunk/net/bridge/br_input.c index 6f6d8e1b776f..25207a1f182b 100644 --- a/trunk/net/bridge/br_input.c +++ b/trunk/net/bridge/br_input.c @@ -21,10 +21,6 @@ /* Bridge group multicast address 802.1d (pg 51). */ const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; -/* Hook for brouter */ -br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; -EXPORT_SYMBOL(br_should_route_hook); - static int br_pass_frame_up(struct sk_buff *skb) { struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; @@ -143,7 +139,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) { struct net_bridge_port *p; const unsigned char *dest = eth_hdr(skb)->h_dest; - br_should_route_hook_t *rhook; + int (*rhook)(struct sk_buff *skb); if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) return skb; @@ -177,8 +173,8 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) switch (p->state) { case BR_STATE_FORWARDING: rhook = rcu_dereference(br_should_route_hook); - if (rhook) { - if ((*rhook)(skb)) + if (rhook != NULL) { + if (rhook(skb)) return skb; dest = eth_hdr(skb)->h_dest; } diff --git a/trunk/net/bridge/br_multicast.c b/trunk/net/bridge/br_multicast.c index 326e599f83fb..eb5b256ffc88 100644 --- a/trunk/net/bridge/br_multicast.c +++ b/trunk/net/bridge/br_multicast.c @@ -33,9 +33,6 @@ #include "br_private.h" -#define mlock_dereference(X, br) \ - rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static inline int ipv6_is_local_multicast(const struct in6_addr *addr) { @@ -138,7 +135,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get( struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, struct sk_buff *skb) { - struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb); + struct net_bridge_mdb_htable *mdb = br->mdb; struct br_ip ip; if (br->multicast_disabled) @@ -238,8 +235,7 @@ static void br_multicast_group_expired(unsigned long data) if (mp->ports) goto out; - mdb = mlock_dereference(br->mdb, br); - + mdb = br->mdb; hlist_del_rcu(&mp->hlist[mdb->ver]); mdb->size--; @@ -253,20 +249,16 @@ static void br_multicast_group_expired(unsigned long data) static void br_multicast_del_pg(struct net_bridge *br, struct net_bridge_port_group *pg) { - struct net_bridge_mdb_htable *mdb; + struct net_bridge_mdb_htable *mdb = br->mdb; struct net_bridge_mdb_entry *mp; struct net_bridge_port_group *p; - struct net_bridge_port_group __rcu **pp; - - mdb = mlock_dereference(br->mdb, br); + struct net_bridge_port_group **pp; mp = br_mdb_ip_get(mdb, &pg->addr); if (WARN_ON(!mp)) return; - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { + for (pp = &mp->ports; (p = *pp); pp = &p->next) { if (p != pg) continue; @@ -302,10 +294,10 @@ static void br_multicast_port_group_expired(unsigned long data) spin_unlock(&br->multicast_lock); } -static int br_mdb_rehash(struct net_bridge_mdb_htable __rcu **mdbp, int max, +static int br_mdb_rehash(struct net_bridge_mdb_htable **mdbp, int max, int elasticity) { - struct net_bridge_mdb_htable *old = rcu_dereference_protected(*mdbp, 1); + struct net_bridge_mdb_htable *old = *mdbp; struct net_bridge_mdb_htable *mdb; int err; @@ -577,7 +569,7 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( struct net_bridge *br, struct net_bridge_port *port, struct br_ip *group, int hash) { - struct net_bridge_mdb_htable *mdb; + struct net_bridge_mdb_htable *mdb = br->mdb; struct net_bridge_mdb_entry *mp; struct hlist_node *p; unsigned count = 0; @@ -585,7 +577,6 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( int elasticity; int err; - mdb = rcu_dereference_protected(br->mdb, 1); hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { count++; if (unlikely(br_ip_equal(group, &mp->addr))) @@ -651,11 +642,10 @@ static struct net_bridge_mdb_entry *br_multicast_new_group( struct net_bridge *br, struct net_bridge_port *port, struct br_ip *group) { - struct net_bridge_mdb_htable *mdb; + struct net_bridge_mdb_htable *mdb = br->mdb; struct net_bridge_mdb_entry *mp; int hash; - mdb = rcu_dereference_protected(br->mdb, 1); if (!mdb) { if (br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0)) return NULL; @@ -670,7 +660,7 @@ static struct net_bridge_mdb_entry *br_multicast_new_group( case -EAGAIN: rehash: - mdb = rcu_dereference_protected(br->mdb, 1); + mdb = br->mdb; hash = br_ip_hash(mdb, group); break; @@ -702,7 +692,7 @@ static int br_multicast_add_group(struct net_bridge *br, { struct net_bridge_mdb_entry *mp; struct net_bridge_port_group *p; - struct net_bridge_port_group __rcu **pp; + struct net_bridge_port_group **pp; unsigned long now = jiffies; int err; @@ -722,9 +712,7 @@ static int br_multicast_add_group(struct net_bridge *br, goto out; } - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { + for (pp = &mp->ports; (p = *pp); pp = &p->next) { if (p->port == port) goto found; if ((unsigned long)p->port < (unsigned long)port) @@ -1118,7 +1106,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, struct net_bridge_mdb_entry *mp; struct igmpv3_query *ih3; struct net_bridge_port_group *p; - struct net_bridge_port_group __rcu **pp; + struct net_bridge_port_group **pp; unsigned long max_delay; unsigned long now = jiffies; __be32 group; @@ -1157,7 +1145,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, if (!group) goto out; - mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group); + mp = br_mdb_ip4_get(br->mdb, group); if (!mp) goto out; @@ -1169,9 +1157,7 @@ static int br_ip4_multicast_query(struct net_bridge *br, try_to_del_timer_sync(&mp->timer) >= 0)) mod_timer(&mp->timer, now + max_delay); - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { + for (pp = &mp->ports; (p = *pp); pp = &p->next) { if (timer_pending(&p->timer) ? time_after(p->timer.expires, now + max_delay) : try_to_del_timer_sync(&p->timer) >= 0) @@ -1192,8 +1178,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb); struct net_bridge_mdb_entry *mp; struct mld2_query *mld2q; - struct net_bridge_port_group *p; - struct net_bridge_port_group __rcu **pp; + struct net_bridge_port_group *p, **pp; unsigned long max_delay; unsigned long now = jiffies; struct in6_addr *group = NULL; @@ -1229,7 +1214,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, if (!group) goto out; - mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group); + mp = br_mdb_ip6_get(br->mdb, group); if (!mp) goto out; @@ -1240,9 +1225,7 @@ static int br_ip6_multicast_query(struct net_bridge *br, try_to_del_timer_sync(&mp->timer) >= 0)) mod_timer(&mp->timer, now + max_delay); - for (pp = &mp->ports; - (p = mlock_dereference(*pp, br)) != NULL; - pp = &p->next) { + for (pp = &mp->ports; (p = *pp); pp = &p->next) { if (timer_pending(&p->timer) ? time_after(p->timer.expires, now + max_delay) : try_to_del_timer_sync(&p->timer) >= 0) @@ -1271,7 +1254,7 @@ static void br_multicast_leave_group(struct net_bridge *br, timer_pending(&br->multicast_querier_timer)) goto out; - mdb = mlock_dereference(br->mdb, br); + mdb = br->mdb; mp = br_mdb_ip_get(mdb, group); if (!mp) goto out; @@ -1294,9 +1277,7 @@ static void br_multicast_leave_group(struct net_bridge *br, goto out; } - for (p = mlock_dereference(mp->ports, br); - p != NULL; - p = mlock_dereference(p->next, br)) { + for (p = mp->ports; p; p = p->next) { if (p->port != port) continue; @@ -1644,7 +1625,7 @@ void br_multicast_stop(struct net_bridge *br) del_timer_sync(&br->multicast_query_timer); spin_lock_bh(&br->multicast_lock); - mdb = mlock_dereference(br->mdb, br); + mdb = br->mdb; if (!mdb) goto out; @@ -1748,7 +1729,6 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val) { struct net_bridge_port *port; int err = 0; - struct net_bridge_mdb_htable *mdb; spin_lock(&br->multicast_lock); if (br->multicast_disabled == !val) @@ -1761,16 +1741,15 @@ int br_multicast_toggle(struct net_bridge *br, unsigned long val) if (!netif_running(br->dev)) goto unlock; - mdb = mlock_dereference(br->mdb, br); - if (mdb) { - if (mdb->old) { + if (br->mdb) { + if (br->mdb->old) { err = -EEXIST; rollback: br->multicast_disabled = !!val; goto unlock; } - err = br_mdb_rehash(&br->mdb, mdb->max, + err = br_mdb_rehash(&br->mdb, br->mdb->max, br->hash_elasticity); if (err) goto rollback; @@ -1795,7 +1774,6 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) { int err = -ENOENT; u32 old; - struct net_bridge_mdb_htable *mdb; spin_lock(&br->multicast_lock); if (!netif_running(br->dev)) @@ -1804,9 +1782,7 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) err = -EINVAL; if (!is_power_of_2(val)) goto unlock; - - mdb = mlock_dereference(br->mdb, br); - if (mdb && val < mdb->size) + if (br->mdb && val < br->mdb->size) goto unlock; err = 0; @@ -1814,8 +1790,8 @@ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val) old = br->hash_max; br->hash_max = val; - if (mdb) { - if (mdb->old) { + if (br->mdb) { + if (br->mdb->old) { err = -EEXIST; rollback: br->hash_max = old; diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index 6e1392093911..865fd7634b67 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -131,18 +131,17 @@ void br_netfilter_rtable_init(struct net_bridge *br) static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) { - struct net_bridge_port *port; - - port = br_port_get_rcu(dev); - return port ? &port->br->fake_rtable : NULL; + if (!br_port_exists(dev)) + return NULL; + return &br_port_get_rcu(dev)->br->fake_rtable; } static inline struct net_device *bridge_parent(const struct net_device *dev) { - struct net_bridge_port *port; + if (!br_port_exists(dev)) + return NULL; - port = br_port_get_rcu(dev); - return port ? port->br->dev : NULL; + return br_port_get_rcu(dev)->br->dev; } static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) @@ -413,8 +412,13 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) if (dnat_took_place(skb)) { if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { struct flowi fl = { - .fl4_dst = iph->daddr, - .fl4_tos = RT_TOS(iph->tos), + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = 0, + .tos = RT_TOS(iph->tos) }, + }, + .proto = 0, }; struct in_device *in_dev = __in_dev_get_rcu(dev); diff --git a/trunk/net/bridge/br_netlink.c b/trunk/net/bridge/br_netlink.c index f8bf4c7f842c..4a6a378c84e3 100644 --- a/trunk/net/bridge/br_netlink.c +++ b/trunk/net/bridge/br_netlink.c @@ -119,13 +119,11 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) idx = 0; for_each_netdev(net, dev) { - struct net_bridge_port *port = br_port_get_rtnl(dev); - /* not a bridge port */ - if (!port || idx < cb->args[0]) + if (!br_port_exists(dev) || idx < cb->args[0]) goto skip; - if (br_fill_ifinfo(skb, port, + if (br_fill_ifinfo(skb, br_port_get(dev), NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI) < 0) @@ -171,9 +169,9 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if (!dev) return -ENODEV; - p = br_port_get_rtnl(dev); - if (!p) + if (!br_port_exists(dev)) return -EINVAL; + p = br_port_get(dev); /* if kernel STP is running, don't allow changes */ if (p->br->stp_enabled == BR_KERNEL_STP) diff --git a/trunk/net/bridge/br_notify.c b/trunk/net/bridge/br_notify.c index 7d337c9b6082..404d4e14c6a7 100644 --- a/trunk/net/bridge/br_notify.c +++ b/trunk/net/bridge/br_notify.c @@ -32,15 +32,15 @@ struct notifier_block br_device_notifier = { static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *dev = ptr; - struct net_bridge_port *p; + struct net_bridge_port *p = br_port_get(dev); struct net_bridge *br; int err; /* not a port of a bridge */ - p = br_port_get_rtnl(dev); - if (!p) + if (!br_port_exists(dev)) return NOTIFY_DONE; + p = br_port_get(dev); br = p->br; switch (event) { diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index 84aac7734bfc..75c90edaf7db 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -72,7 +72,7 @@ struct net_bridge_fdb_entry struct net_bridge_port_group { struct net_bridge_port *port; - struct net_bridge_port_group __rcu *next; + struct net_bridge_port_group *next; struct hlist_node mglist; struct rcu_head rcu; struct timer_list timer; @@ -86,7 +86,7 @@ struct net_bridge_mdb_entry struct hlist_node hlist[2]; struct hlist_node mglist; struct net_bridge *br; - struct net_bridge_port_group __rcu *ports; + struct net_bridge_port_group *ports; struct rcu_head rcu; struct timer_list timer; struct timer_list query_timer; @@ -151,20 +151,11 @@ struct net_bridge_port #endif }; +#define br_port_get_rcu(dev) \ + ((struct net_bridge_port *) rcu_dereference(dev->rx_handler_data)) +#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data) #define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT) -static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) -{ - struct net_bridge_port *port = rcu_dereference(dev->rx_handler_data); - return br_port_exists(dev) ? port : NULL; -} - -static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev) -{ - return br_port_exists(dev) ? - rtnl_dereference(dev->rx_handler_data) : NULL; -} - struct br_cpu_netstats { u64 rx_packets; u64 rx_bytes; @@ -236,7 +227,7 @@ struct net_bridge unsigned long multicast_startup_query_interval; spinlock_t multicast_lock; - struct net_bridge_mdb_htable __rcu *mdb; + struct net_bridge_mdb_htable *mdb; struct hlist_head router_list; struct hlist_head mglist; diff --git a/trunk/net/bridge/br_stp_bpdu.c b/trunk/net/bridge/br_stp_bpdu.c index 3d9a55d3822f..35cf27087b56 100644 --- a/trunk/net/bridge/br_stp_bpdu.c +++ b/trunk/net/bridge/br_stp_bpdu.c @@ -141,6 +141,10 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, struct net_bridge *br; const unsigned char *buf; + if (!br_port_exists(dev)) + goto err; + p = br_port_get_rcu(dev); + if (!pskb_may_pull(skb, 4)) goto err; @@ -149,10 +153,6 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) goto err; - p = br_port_get_rcu(dev); - if (!p) - goto err; - br = p->br; spin_lock(&br->lock); diff --git a/trunk/net/bridge/netfilter/ebtable_broute.c b/trunk/net/bridge/netfilter/ebtable_broute.c index 1bcaf36ad612..ae3f106c3908 100644 --- a/trunk/net/bridge/netfilter/ebtable_broute.c +++ b/trunk/net/bridge/netfilter/ebtable_broute.c @@ -87,8 +87,7 @@ static int __init ebtable_broute_init(void) if (ret < 0) return ret; /* see br_input.c */ - rcu_assign_pointer(br_should_route_hook, - (br_should_route_hook_t *)ebt_broute); + rcu_assign_pointer(br_should_route_hook, ebt_broute); return 0; } diff --git a/trunk/net/bridge/netfilter/ebtables.c b/trunk/net/bridge/netfilter/ebtables.c index cbc9f395ab1e..a1dcf83f0d58 100644 --- a/trunk/net/bridge/netfilter/ebtables.c +++ b/trunk/net/bridge/netfilter/ebtables.c @@ -128,7 +128,6 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out) { const struct ethhdr *h = eth_hdr(skb); - const struct net_bridge_port *p; __be16 ethproto; int verdict, i; @@ -149,11 +148,13 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb, if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT)) return 1; /* rcu_read_lock()ed by nf_hook_slow */ - if (in && (p = br_port_get_rcu(in)) != NULL && - FWINV2(ebt_dev_check(e->logical_in, p->br->dev), EBT_ILOGICALIN)) + if (in && br_port_exists(in) && + FWINV2(ebt_dev_check(e->logical_in, br_port_get_rcu(in)->br->dev), + EBT_ILOGICALIN)) return 1; - if (out && (p = br_port_get_rcu(out)) != NULL && - FWINV2(ebt_dev_check(e->logical_out, p->br->dev), EBT_ILOGICALOUT)) + if (out && br_port_exists(out) && + FWINV2(ebt_dev_check(e->logical_out, br_port_get_rcu(out)->br->dev), + EBT_ILOGICALOUT)) return 1; if (e->bitmask & EBT_SOURCEMAC) { diff --git a/trunk/net/caif/Makefile b/trunk/net/caif/Makefile index 9d38e406e4a4..f87481fb0e65 100644 --- a/trunk/net/caif/Makefile +++ b/trunk/net/caif/Makefile @@ -1,6 +1,8 @@ -ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG +ifeq ($(CONFIG_CAIF_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif -caif-y := caif_dev.o \ +caif-objs := caif_dev.o \ cfcnfg.o cfmuxl.o cfctrl.o \ cffrml.o cfveil.o cfdbgl.o\ cfserl.o cfdgml.o \ @@ -11,4 +13,4 @@ obj-$(CONFIG_CAIF) += caif.o obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o obj-$(CONFIG_CAIF) += caif_socket.o -export-y := caif.o +export-objs := caif.o diff --git a/trunk/net/caif/caif_config_util.c b/trunk/net/caif/caif_config_util.c index d522d8c1703e..76ae68303d3a 100644 --- a/trunk/net/caif/caif_config_util.c +++ b/trunk/net/caif/caif_config_util.c @@ -16,18 +16,11 @@ int connect_req_to_link_param(struct cfcnfg *cnfg, { struct dev_info *dev_info; enum cfcnfg_phy_preference pref; - int res; - memset(l, 0, sizeof(*l)); - /* In caif protocol low value is high priority */ - l->priority = CAIF_PRIO_MAX - s->priority + 1; + l->priority = s->priority; - if (s->ifindex != 0){ - res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex); - if (res < 0) - return res; - l->phyid = res; - } + if (s->link_name[0] != '\0') + l->phyid = cfcnfg_get_named(cnfg, s->link_name); else { switch (s->link_selector) { case CAIF_LINK_HIGH_BANDW: diff --git a/trunk/net/caif/caif_dev.c b/trunk/net/caif/caif_dev.c index a42a408306e4..b99369a055d1 100644 --- a/trunk/net/caif/caif_dev.c +++ b/trunk/net/caif/caif_dev.c @@ -307,8 +307,6 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, case NETDEV_UNREGISTER: caifd = caif_get(dev); - if (caifd == NULL) - break; netdev_info(dev, "unregister\n"); atomic_set(&caifd->state, what); caif_device_destroy(dev); diff --git a/trunk/net/caif/caif_socket.c b/trunk/net/caif/caif_socket.c index 1bf0cf503796..2eca2dd0000f 100644 --- a/trunk/net/caif/caif_socket.c +++ b/trunk/net/caif/caif_socket.c @@ -716,7 +716,8 @@ static int setsockopt(struct socket *sock, { struct sock *sk = sock->sk; struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); - int linksel; + int prio, linksel; + struct ifreq ifreq; if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) return -ENOPROTOOPT; @@ -734,6 +735,33 @@ static int setsockopt(struct socket *sock, release_sock(&cf_sk->sk); return 0; + case SO_PRIORITY: + if (lvl != SOL_SOCKET) + goto bad_sol; + if (ol < sizeof(int)) + return -EINVAL; + if (copy_from_user(&prio, ov, sizeof(int))) + return -EINVAL; + lock_sock(&(cf_sk->sk)); + cf_sk->conn_req.priority = prio; + release_sock(&cf_sk->sk); + return 0; + + case SO_BINDTODEVICE: + if (lvl != SOL_SOCKET) + goto bad_sol; + if (ol < sizeof(struct ifreq)) + return -EINVAL; + if (copy_from_user(&ifreq, ov, sizeof(ifreq))) + return -EFAULT; + lock_sock(&(cf_sk->sk)); + strncpy(cf_sk->conn_req.link_name, ifreq.ifr_name, + sizeof(cf_sk->conn_req.link_name)); + cf_sk->conn_req.link_name + [sizeof(cf_sk->conn_req.link_name)-1] = 0; + release_sock(&cf_sk->sk); + return 0; + case CAIFSO_REQ_PARAM: if (lvl != SOL_CAIF) goto bad_sol; @@ -852,18 +880,6 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, sock->state = SS_CONNECTING; sk->sk_state = CAIF_CONNECTING; - /* Check priority value comming from socket */ - /* if priority value is out of range it will be ajusted */ - if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX) - cf_sk->conn_req.priority = CAIF_PRIO_MAX; - else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN) - cf_sk->conn_req.priority = CAIF_PRIO_MIN; - else - cf_sk->conn_req.priority = cf_sk->sk.sk_priority; - - /*ifindex = id of the interface.*/ - cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if; - dbfs_atomic_inc(&cnt.num_connect_req); cf_sk->layer.receive = caif_sktrecv_cb; err = caif_connect_client(&cf_sk->conn_req, @@ -889,7 +905,6 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, cf_sk->maxframe = mtu - (headroom + tailroom); if (cf_sk->maxframe < 1) { pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); - err = -ENODEV; goto out; } @@ -1127,7 +1142,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, set_rx_flow_on(cf_sk); /* Set default options on configuration */ - cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL; + cf_sk->conn_req.priority = CAIF_PRIO_NORMAL; cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; cf_sk->conn_req.protocol = protocol; /* Increase the number of sockets created. */ diff --git a/trunk/net/caif/cfcnfg.c b/trunk/net/caif/cfcnfg.c index 21ede141018a..41adafd18914 100644 --- a/trunk/net/caif/cfcnfg.c +++ b/trunk/net/caif/cfcnfg.c @@ -173,15 +173,18 @@ static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg, return NULL; } - -int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi) +int cfcnfg_get_named(struct cfcnfg *cnfg, char *name) { int i; - for (i = 0; i < MAX_PHY_LAYERS; i++) - if (cnfg->phy_layers[i].frm_layer != NULL && - cnfg->phy_layers[i].ifindex == ifi) - return i; - return -ENODEV; + + /* Try to match with specified name */ + for (i = 0; i < MAX_PHY_LAYERS; i++) { + if (cnfg->phy_layers[i].frm_layer != NULL + && strcmp(cnfg->phy_layers[i].phy_layer->name, + name) == 0) + return cnfg->phy_layers[i].frm_layer->id; + } + return 0; } int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) diff --git a/trunk/net/caif/cfctrl.c b/trunk/net/caif/cfctrl.c index 3cd8f978e309..08f267a109aa 100644 --- a/trunk/net/caif/cfctrl.c +++ b/trunk/net/caif/cfctrl.c @@ -361,10 +361,11 @@ void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) struct cfctrl_request_info *p, *tmp; struct cfctrl *ctrl = container_obj(layr); spin_lock(&ctrl->info_list_lock); + pr_warn("enter\n"); list_for_each_entry_safe(p, tmp, &ctrl->list, list) { if (p->client_layer == adap_layer) { - pr_debug("cancel req :%d\n", p->sequence_no); + pr_warn("cancel req :%d\n", p->sequence_no); list_del(&p->list); kfree(p); } diff --git a/trunk/net/caif/cfdbgl.c b/trunk/net/caif/cfdbgl.c index 11a2af4c162a..496fda9ac66f 100644 --- a/trunk/net/caif/cfdbgl.c +++ b/trunk/net/caif/cfdbgl.c @@ -12,8 +12,6 @@ #include #include -#define container_obj(layr) ((struct cfsrvl *) layr) - static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt); static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); @@ -40,17 +38,5 @@ static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt) static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt) { - struct cfsrvl *service = container_obj(layr); - struct caif_payload_info *info; - int ret; - - if (!cfsrvl_ready(service, &ret)) - return ret; - - /* Add info for MUX-layer to route the packet out */ - info = cfpkt_info(pkt); - info->channel_id = service->layer.id; - info->dev_info = &service->dev_info; - return layr->dn->transmit(layr->dn, pkt); } diff --git a/trunk/net/caif/cfrfml.c b/trunk/net/caif/cfrfml.c index e2fb5fa75795..bde8481e8d25 100644 --- a/trunk/net/caif/cfrfml.c +++ b/trunk/net/caif/cfrfml.c @@ -193,7 +193,7 @@ static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt) static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) { - caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size); + caif_assert(cfpkt_getlen(pkt) >= rfml->fragment_size); /* Add info for MUX-layer to route the packet out. */ cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; diff --git a/trunk/net/can/Makefile b/trunk/net/can/Makefile index 2d3894b32742..9cd3c4b3abda 100644 --- a/trunk/net/can/Makefile +++ b/trunk/net/can/Makefile @@ -3,10 +3,10 @@ # obj-$(CONFIG_CAN) += can.o -can-y := af_can.o proc.o +can-objs := af_can.o proc.o obj-$(CONFIG_CAN_RAW) += can-raw.o -can-raw-y := raw.o +can-raw-objs := raw.o obj-$(CONFIG_CAN_BCM) += can-bcm.o -can-bcm-y := bcm.o +can-bcm-objs := bcm.o diff --git a/trunk/net/can/bcm.c b/trunk/net/can/bcm.c index 6faa8256e10c..08ffe9e4be20 100644 --- a/trunk/net/can/bcm.c +++ b/trunk/net/can/bcm.c @@ -125,7 +125,7 @@ struct bcm_sock { struct list_head tx_ops; unsigned long dropped_usr_msgs; struct proc_dir_entry *bcm_proc_read; - char procname [20]; /* pointer printed in ASCII with \0 */ + char procname [9]; /* pointer printed in ASCII with \0 */ }; static inline struct bcm_sock *bcm_sk(const struct sock *sk) diff --git a/trunk/net/ceph/Makefile b/trunk/net/ceph/Makefile index 153bdec40835..aab1cabb8035 100644 --- a/trunk/net/ceph/Makefile +++ b/trunk/net/ceph/Makefile @@ -6,7 +6,7 @@ ifneq ($(KERNELRELEASE),) obj-$(CONFIG_CEPH_LIB) += libceph.o -libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ +libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ mon_client.o \ osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \ debugfs.o \ diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 3259d2c323a6..35dfb8318483 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1557,19 +1557,12 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) */ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) { - int rc; - if (txq < 1 || txq > dev->num_tx_queues) return -EINVAL; if (dev->reg_state == NETREG_REGISTERED) { ASSERT_RTNL(); - rc = netdev_queue_update_kobjects(dev, dev->real_num_tx_queues, - txq); - if (rc) - return rc; - if (txq < dev->real_num_tx_queues) qdisc_reset_all_tx_gt(dev, txq); } @@ -1801,18 +1794,16 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); struct packet_type *ptype; __be16 type = skb->protocol; - int vlan_depth = ETH_HLEN; int err; - while (type == htons(ETH_P_8021Q)) { - struct vlan_hdr *vh; + if (type == htons(ETH_P_8021Q)) { + struct vlan_ethhdr *veh; - if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN))) + if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) return ERR_PTR(-EINVAL); - vh = (struct vlan_hdr *)(skb->data + vlan_depth); - type = vh->h_vlan_encapsulated_proto; - vlan_depth += VLAN_HLEN; + veh = (struct vlan_ethhdr *)skb->data; + type = veh->h_vlan_encapsulated_proto; } skb_reset_mac_header(skb); @@ -1826,7 +1817,8 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) if (dev && dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) dev->ethtool_ops->get_drvinfo(dev, &info); - WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d ip_summed=%d\n", + WARN(1, "%s: caps=(0x%lx, 0x%lx) len=%d data_len=%d " + "ip_summed=%d", info.driver, dev ? dev->features : 0L, skb->sk ? skb->sk->sk_route_caps : 0L, skb->len, skb->data_len, skb->ip_summed); @@ -1975,23 +1967,6 @@ static inline void skb_orphan_try(struct sk_buff *skb) } } -int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev) -{ - __be16 protocol = skb->protocol; - - if (protocol == htons(ETH_P_8021Q)) { - struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; - protocol = veh->h_vlan_encapsulated_proto; - } else if (!skb->vlan_tci) - return dev->features; - - if (protocol != htons(ETH_P_8021Q)) - return dev->features & dev->vlan_features; - else - return 0; -} -EXPORT_SYMBOL(netif_get_vlan_features); - /* * Returns true if either: * 1. skb has frag_list and the device doesn't support FRAGLIST, or @@ -2002,20 +1977,15 @@ EXPORT_SYMBOL(netif_get_vlan_features); static inline int skb_needs_linearize(struct sk_buff *skb, struct net_device *dev) { - if (skb_is_nonlinear(skb)) { - int features = dev->features; - - if (vlan_tx_tag_present(skb)) - features &= dev->vlan_features; + int features = dev->features; - return (skb_has_frag_list(skb) && - !(features & NETIF_F_FRAGLIST)) || - (skb_shinfo(skb)->nr_frags && - (!(features & NETIF_F_SG) || - illegal_highdma(dev, skb))); - } + if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb)) + features &= dev->vlan_features; - return 0; + return skb_is_nonlinear(skb) && + ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) || + (skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) || + illegal_highdma(dev, skb)))); } int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, @@ -2149,70 +2119,26 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) return queue_index; } -static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb) -{ -#ifdef CONFIG_XPS - struct xps_dev_maps *dev_maps; - struct xps_map *map; - int queue_index = -1; - - rcu_read_lock(); - dev_maps = rcu_dereference(dev->xps_maps); - if (dev_maps) { - map = rcu_dereference( - dev_maps->cpu_map[raw_smp_processor_id()]); - if (map) { - if (map->len == 1) - queue_index = map->queues[0]; - else { - u32 hash; - if (skb->sk && skb->sk->sk_hash) - hash = skb->sk->sk_hash; - else - hash = (__force u16) skb->protocol ^ - skb->rxhash; - hash = jhash_1word(hash, hashrnd); - queue_index = map->queues[ - ((u64)hash * map->len) >> 32]; - } - if (unlikely(queue_index >= dev->real_num_tx_queues)) - queue_index = -1; - } - } - rcu_read_unlock(); - - return queue_index; -#else - return -1; -#endif -} - static struct netdev_queue *dev_pick_tx(struct net_device *dev, struct sk_buff *skb) { int queue_index; const struct net_device_ops *ops = dev->netdev_ops; - if (dev->real_num_tx_queues == 1) - queue_index = 0; - else if (ops->ndo_select_queue) { + if (ops->ndo_select_queue) { queue_index = ops->ndo_select_queue(dev, skb); queue_index = dev_cap_txqueue(dev, queue_index); } else { struct sock *sk = skb->sk; queue_index = sk_tx_queue_get(sk); + if (queue_index < 0) { - if (queue_index < 0 || skb->ooo_okay || - queue_index >= dev->real_num_tx_queues) { - int old_index = queue_index; - - queue_index = get_xps_queue(dev, skb); - if (queue_index < 0) + queue_index = 0; + if (dev->real_num_tx_queues > 1) queue_index = skb_tx_hash(dev, skb); - if (queue_index != old_index && sk) { - struct dst_entry *dst = - rcu_dereference_check(sk->sk_dst_cache, 1); + if (sk) { + struct dst_entry *dst = rcu_dereference_check(sk->sk_dst_cache, 1); if (dst && skb_dst(skb) == dst) sk_tx_queue_set(sk, queue_index); @@ -5088,9 +5014,9 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev, } EXPORT_SYMBOL(netif_stacked_transfer_operstate); -#ifdef CONFIG_RPS static int netif_alloc_rx_queues(struct net_device *dev) { +#ifdef CONFIG_RPS unsigned int i, count = dev->num_rx_queues; struct netdev_rx_queue *rx; @@ -5103,17 +5029,20 @@ static int netif_alloc_rx_queues(struct net_device *dev) } dev->_rx = rx; + /* + * Set a pointer to first element in the array which holds the + * reference count. + */ for (i = 0; i < count; i++) - rx[i].dev = dev; + rx[i].first = rx; +#endif return 0; } -#endif static int netif_alloc_netdev_queues(struct net_device *dev) { unsigned int count = dev->num_tx_queues; struct netdev_queue *tx; - int i; BUG_ON(count < 1); @@ -5124,10 +5053,6 @@ static int netif_alloc_netdev_queues(struct net_device *dev) return -ENOMEM; } dev->_tx = tx; - - for (i = 0; i < count; i++) - tx[i].dev = dev; - return 0; } @@ -5135,6 +5060,8 @@ static void netdev_init_one_queue(struct net_device *dev, struct netdev_queue *queue, void *_unused) { + queue->dev = dev; + /* Initialize queue lock */ spin_lock_init(&queue->_xmit_lock); netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); @@ -5183,6 +5110,14 @@ int register_netdevice(struct net_device *dev) dev->iflink = -1; + ret = netif_alloc_rx_queues(dev); + if (ret) + goto out; + + ret = netif_alloc_netdev_queues(dev); + if (ret) + goto out; + netdev_init_queues(dev); /* Init, if this function is available */ @@ -5642,14 +5577,10 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, dev->num_tx_queues = queue_count; dev->real_num_tx_queues = queue_count; - if (netif_alloc_netdev_queues(dev)) - goto free_pcpu; #ifdef CONFIG_RPS dev->num_rx_queues = queue_count; dev->real_num_rx_queues = queue_count; - if (netif_alloc_rx_queues(dev)) - goto free_pcpu; #endif dev->gso_max_size = GSO_MAX_SIZE; @@ -5666,11 +5597,6 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, free_pcpu: free_percpu(dev->pcpu_refcnt); - kfree(dev->_tx); -#ifdef CONFIG_RPS - kfree(dev->_rx); -#endif - free_p: kfree(p); return NULL; @@ -5692,9 +5618,6 @@ void free_netdev(struct net_device *dev) release_net(dev_net(dev)); kfree(dev->_tx); -#ifdef CONFIG_RPS - kfree(dev->_rx); -#endif kfree(rcu_dereference_raw(dev->ingress_queue)); diff --git a/trunk/net/core/dst.c b/trunk/net/core/dst.c index b99c7c7ffce2..8abe628b79f1 100644 --- a/trunk/net/core/dst.c +++ b/trunk/net/core/dst.c @@ -370,7 +370,6 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, static struct notifier_block dst_dev_notifier = { .notifier_call = dst_dev_event, - .priority = -10, /* must be called after other network notifiers */ }; void __init dst_init(void) diff --git a/trunk/net/core/filter.c b/trunk/net/core/filter.c index a44d27f9f0f0..7beaec36b541 100644 --- a/trunk/net/core/filter.c +++ b/trunk/net/core/filter.c @@ -37,55 +37,6 @@ #include #include #include -#include - -enum { - BPF_S_RET_K = 1, - BPF_S_RET_A, - BPF_S_ALU_ADD_K, - BPF_S_ALU_ADD_X, - BPF_S_ALU_SUB_K, - BPF_S_ALU_SUB_X, - BPF_S_ALU_MUL_K, - BPF_S_ALU_MUL_X, - BPF_S_ALU_DIV_X, - BPF_S_ALU_AND_K, - BPF_S_ALU_AND_X, - BPF_S_ALU_OR_K, - BPF_S_ALU_OR_X, - BPF_S_ALU_LSH_K, - BPF_S_ALU_LSH_X, - BPF_S_ALU_RSH_K, - BPF_S_ALU_RSH_X, - BPF_S_ALU_NEG, - BPF_S_LD_W_ABS, - BPF_S_LD_H_ABS, - BPF_S_LD_B_ABS, - BPF_S_LD_W_LEN, - BPF_S_LD_W_IND, - BPF_S_LD_H_IND, - BPF_S_LD_B_IND, - BPF_S_LD_IMM, - BPF_S_LDX_W_LEN, - BPF_S_LDX_B_MSH, - BPF_S_LDX_IMM, - BPF_S_MISC_TAX, - BPF_S_MISC_TXA, - BPF_S_ALU_DIV_K, - BPF_S_LD_MEM, - BPF_S_LDX_MEM, - BPF_S_ST, - BPF_S_STX, - BPF_S_JMP_JA, - BPF_S_JMP_JEQ_K, - BPF_S_JMP_JEQ_X, - BPF_S_JMP_JGE_K, - BPF_S_JMP_JGE_X, - BPF_S_JMP_JGT_K, - BPF_S_JMP_JGT_X, - BPF_S_JMP_JSET_K, - BPF_S_JMP_JSET_X, -}; /* No hurry in this branch */ static void *__load_pointer(struct sk_buff *skb, int k) @@ -138,7 +89,7 @@ int sk_filter(struct sock *sk, struct sk_buff *skb) rcu_read_lock_bh(); filter = rcu_dereference_bh(sk->sk_filter); if (filter) { - unsigned int pkt_len = sk_run_filter(skb, filter->insns); + unsigned int pkt_len = sk_run_filter(skb, filter->insns, filter->len); err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM; } @@ -152,53 +103,48 @@ EXPORT_SYMBOL(sk_filter); * sk_run_filter - run a filter on a socket * @skb: buffer to run the filter on * @filter: filter to apply + * @flen: length of filter * * Decode and apply filter instructions to the skb->data. - * Return length to keep, 0 for none. @skb is the data we are - * filtering, @filter is the array of filter instructions. - * Because all jumps are guaranteed to be before last instruction, - * and last instruction guaranteed to be a RET, we dont need to check - * flen. (We used to pass to this function the length of filter) + * Return length to keep, 0 for none. skb is the data we are + * filtering, filter is the array of filter instructions, and + * len is the number of filter blocks in the array. */ -unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry) +unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) { + struct sock_filter *fentry; /* We walk down these */ void *ptr; u32 A = 0; /* Accumulator */ u32 X = 0; /* Index Register */ u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ - unsigned long memvalid = 0; u32 tmp; int k; + int pc; - BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG); /* * Process array of filter instructions. */ - for (;; fentry++) { -#if defined(CONFIG_X86_32) -#define K (fentry->k) -#else - const u32 K = fentry->k; -#endif + for (pc = 0; pc < flen; pc++) { + fentry = &filter[pc]; switch (fentry->code) { case BPF_S_ALU_ADD_X: A += X; continue; case BPF_S_ALU_ADD_K: - A += K; + A += fentry->k; continue; case BPF_S_ALU_SUB_X: A -= X; continue; case BPF_S_ALU_SUB_K: - A -= K; + A -= fentry->k; continue; case BPF_S_ALU_MUL_X: A *= X; continue; case BPF_S_ALU_MUL_K: - A *= K; + A *= fentry->k; continue; case BPF_S_ALU_DIV_X: if (X == 0) @@ -206,64 +152,64 @@ unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry A /= X; continue; case BPF_S_ALU_DIV_K: - A = reciprocal_divide(A, K); + A /= fentry->k; continue; case BPF_S_ALU_AND_X: A &= X; continue; case BPF_S_ALU_AND_K: - A &= K; + A &= fentry->k; continue; case BPF_S_ALU_OR_X: A |= X; continue; case BPF_S_ALU_OR_K: - A |= K; + A |= fentry->k; continue; case BPF_S_ALU_LSH_X: A <<= X; continue; case BPF_S_ALU_LSH_K: - A <<= K; + A <<= fentry->k; continue; case BPF_S_ALU_RSH_X: A >>= X; continue; case BPF_S_ALU_RSH_K: - A >>= K; + A >>= fentry->k; continue; case BPF_S_ALU_NEG: A = -A; continue; case BPF_S_JMP_JA: - fentry += K; + pc += fentry->k; continue; case BPF_S_JMP_JGT_K: - fentry += (A > K) ? fentry->jt : fentry->jf; + pc += (A > fentry->k) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JGE_K: - fentry += (A >= K) ? fentry->jt : fentry->jf; + pc += (A >= fentry->k) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JEQ_K: - fentry += (A == K) ? fentry->jt : fentry->jf; + pc += (A == fentry->k) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JSET_K: - fentry += (A & K) ? fentry->jt : fentry->jf; + pc += (A & fentry->k) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JGT_X: - fentry += (A > X) ? fentry->jt : fentry->jf; + pc += (A > X) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JGE_X: - fentry += (A >= X) ? fentry->jt : fentry->jf; + pc += (A >= X) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JEQ_X: - fentry += (A == X) ? fentry->jt : fentry->jf; + pc += (A == X) ? fentry->jt : fentry->jf; continue; case BPF_S_JMP_JSET_X: - fentry += (A & X) ? fentry->jt : fentry->jf; + pc += (A & X) ? fentry->jt : fentry->jf; continue; case BPF_S_LD_W_ABS: - k = K; + k = fentry->k; load_w: ptr = load_pointer(skb, k, 4, &tmp); if (ptr != NULL) { @@ -272,7 +218,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry } break; case BPF_S_LD_H_ABS: - k = K; + k = fentry->k; load_h: ptr = load_pointer(skb, k, 2, &tmp); if (ptr != NULL) { @@ -281,7 +227,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry } break; case BPF_S_LD_B_ABS: - k = K; + k = fentry->k; load_b: ptr = load_pointer(skb, k, 1, &tmp); if (ptr != NULL) { @@ -296,34 +242,32 @@ unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry X = skb->len; continue; case BPF_S_LD_W_IND: - k = X + K; + k = X + fentry->k; goto load_w; case BPF_S_LD_H_IND: - k = X + K; + k = X + fentry->k; goto load_h; case BPF_S_LD_B_IND: - k = X + K; + k = X + fentry->k; goto load_b; case BPF_S_LDX_B_MSH: - ptr = load_pointer(skb, K, 1, &tmp); + ptr = load_pointer(skb, fentry->k, 1, &tmp); if (ptr != NULL) { X = (*(u8 *)ptr & 0xf) << 2; continue; } return 0; case BPF_S_LD_IMM: - A = K; + A = fentry->k; continue; case BPF_S_LDX_IMM: - X = K; + X = fentry->k; continue; case BPF_S_LD_MEM: - A = (memvalid & (1UL << K)) ? - mem[K] : 0; + A = mem[fentry->k]; continue; case BPF_S_LDX_MEM: - X = (memvalid & (1UL << K)) ? - mem[K] : 0; + X = mem[fentry->k]; continue; case BPF_S_MISC_TAX: X = A; @@ -332,16 +276,14 @@ unsigned int sk_run_filter(struct sk_buff *skb, const struct sock_filter *fentry A = X; continue; case BPF_S_RET_K: - return K; + return fentry->k; case BPF_S_RET_A: return A; case BPF_S_ST: - memvalid |= 1UL << K; - mem[K] = A; + mem[fentry->k] = A; continue; case BPF_S_STX: - memvalid |= 1UL << K; - mem[K] = X; + mem[fentry->k] = X; continue; default: WARN_ON(1); @@ -435,57 +377,7 @@ EXPORT_SYMBOL(sk_run_filter); */ int sk_chk_filter(struct sock_filter *filter, int flen) { - /* - * Valid instructions are initialized to non-0. - * Invalid instructions are initialized to 0. - */ - static const u8 codes[] = { - [BPF_ALU|BPF_ADD|BPF_K] = BPF_S_ALU_ADD_K, - [BPF_ALU|BPF_ADD|BPF_X] = BPF_S_ALU_ADD_X, - [BPF_ALU|BPF_SUB|BPF_K] = BPF_S_ALU_SUB_K, - [BPF_ALU|BPF_SUB|BPF_X] = BPF_S_ALU_SUB_X, - [BPF_ALU|BPF_MUL|BPF_K] = BPF_S_ALU_MUL_K, - [BPF_ALU|BPF_MUL|BPF_X] = BPF_S_ALU_MUL_X, - [BPF_ALU|BPF_DIV|BPF_X] = BPF_S_ALU_DIV_X, - [BPF_ALU|BPF_AND|BPF_K] = BPF_S_ALU_AND_K, - [BPF_ALU|BPF_AND|BPF_X] = BPF_S_ALU_AND_X, - [BPF_ALU|BPF_OR|BPF_K] = BPF_S_ALU_OR_K, - [BPF_ALU|BPF_OR|BPF_X] = BPF_S_ALU_OR_X, - [BPF_ALU|BPF_LSH|BPF_K] = BPF_S_ALU_LSH_K, - [BPF_ALU|BPF_LSH|BPF_X] = BPF_S_ALU_LSH_X, - [BPF_ALU|BPF_RSH|BPF_K] = BPF_S_ALU_RSH_K, - [BPF_ALU|BPF_RSH|BPF_X] = BPF_S_ALU_RSH_X, - [BPF_ALU|BPF_NEG] = BPF_S_ALU_NEG, - [BPF_LD|BPF_W|BPF_ABS] = BPF_S_LD_W_ABS, - [BPF_LD|BPF_H|BPF_ABS] = BPF_S_LD_H_ABS, - [BPF_LD|BPF_B|BPF_ABS] = BPF_S_LD_B_ABS, - [BPF_LD|BPF_W|BPF_LEN] = BPF_S_LD_W_LEN, - [BPF_LD|BPF_W|BPF_IND] = BPF_S_LD_W_IND, - [BPF_LD|BPF_H|BPF_IND] = BPF_S_LD_H_IND, - [BPF_LD|BPF_B|BPF_IND] = BPF_S_LD_B_IND, - [BPF_LD|BPF_IMM] = BPF_S_LD_IMM, - [BPF_LDX|BPF_W|BPF_LEN] = BPF_S_LDX_W_LEN, - [BPF_LDX|BPF_B|BPF_MSH] = BPF_S_LDX_B_MSH, - [BPF_LDX|BPF_IMM] = BPF_S_LDX_IMM, - [BPF_MISC|BPF_TAX] = BPF_S_MISC_TAX, - [BPF_MISC|BPF_TXA] = BPF_S_MISC_TXA, - [BPF_RET|BPF_K] = BPF_S_RET_K, - [BPF_RET|BPF_A] = BPF_S_RET_A, - [BPF_ALU|BPF_DIV|BPF_K] = BPF_S_ALU_DIV_K, - [BPF_LD|BPF_MEM] = BPF_S_LD_MEM, - [BPF_LDX|BPF_MEM] = BPF_S_LDX_MEM, - [BPF_ST] = BPF_S_ST, - [BPF_STX] = BPF_S_STX, - [BPF_JMP|BPF_JA] = BPF_S_JMP_JA, - [BPF_JMP|BPF_JEQ|BPF_K] = BPF_S_JMP_JEQ_K, - [BPF_JMP|BPF_JEQ|BPF_X] = BPF_S_JMP_JEQ_X, - [BPF_JMP|BPF_JGE|BPF_K] = BPF_S_JMP_JGE_K, - [BPF_JMP|BPF_JGE|BPF_X] = BPF_S_JMP_JGE_X, - [BPF_JMP|BPF_JGT|BPF_K] = BPF_S_JMP_JGT_K, - [BPF_JMP|BPF_JGT|BPF_X] = BPF_S_JMP_JGT_X, - [BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K, - [BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X, - }; + struct sock_filter *ftest; int pc; if (flen == 0 || flen > BPF_MAXINSNS) @@ -493,31 +385,136 @@ int sk_chk_filter(struct sock_filter *filter, int flen) /* check the filter code now */ for (pc = 0; pc < flen; pc++) { - struct sock_filter *ftest = &filter[pc]; - u16 code = ftest->code; + ftest = &filter[pc]; + + /* Only allow valid instructions */ + switch (ftest->code) { + case BPF_ALU|BPF_ADD|BPF_K: + ftest->code = BPF_S_ALU_ADD_K; + break; + case BPF_ALU|BPF_ADD|BPF_X: + ftest->code = BPF_S_ALU_ADD_X; + break; + case BPF_ALU|BPF_SUB|BPF_K: + ftest->code = BPF_S_ALU_SUB_K; + break; + case BPF_ALU|BPF_SUB|BPF_X: + ftest->code = BPF_S_ALU_SUB_X; + break; + case BPF_ALU|BPF_MUL|BPF_K: + ftest->code = BPF_S_ALU_MUL_K; + break; + case BPF_ALU|BPF_MUL|BPF_X: + ftest->code = BPF_S_ALU_MUL_X; + break; + case BPF_ALU|BPF_DIV|BPF_X: + ftest->code = BPF_S_ALU_DIV_X; + break; + case BPF_ALU|BPF_AND|BPF_K: + ftest->code = BPF_S_ALU_AND_K; + break; + case BPF_ALU|BPF_AND|BPF_X: + ftest->code = BPF_S_ALU_AND_X; + break; + case BPF_ALU|BPF_OR|BPF_K: + ftest->code = BPF_S_ALU_OR_K; + break; + case BPF_ALU|BPF_OR|BPF_X: + ftest->code = BPF_S_ALU_OR_X; + break; + case BPF_ALU|BPF_LSH|BPF_K: + ftest->code = BPF_S_ALU_LSH_K; + break; + case BPF_ALU|BPF_LSH|BPF_X: + ftest->code = BPF_S_ALU_LSH_X; + break; + case BPF_ALU|BPF_RSH|BPF_K: + ftest->code = BPF_S_ALU_RSH_K; + break; + case BPF_ALU|BPF_RSH|BPF_X: + ftest->code = BPF_S_ALU_RSH_X; + break; + case BPF_ALU|BPF_NEG: + ftest->code = BPF_S_ALU_NEG; + break; + case BPF_LD|BPF_W|BPF_ABS: + ftest->code = BPF_S_LD_W_ABS; + break; + case BPF_LD|BPF_H|BPF_ABS: + ftest->code = BPF_S_LD_H_ABS; + break; + case BPF_LD|BPF_B|BPF_ABS: + ftest->code = BPF_S_LD_B_ABS; + break; + case BPF_LD|BPF_W|BPF_LEN: + ftest->code = BPF_S_LD_W_LEN; + break; + case BPF_LD|BPF_W|BPF_IND: + ftest->code = BPF_S_LD_W_IND; + break; + case BPF_LD|BPF_H|BPF_IND: + ftest->code = BPF_S_LD_H_IND; + break; + case BPF_LD|BPF_B|BPF_IND: + ftest->code = BPF_S_LD_B_IND; + break; + case BPF_LD|BPF_IMM: + ftest->code = BPF_S_LD_IMM; + break; + case BPF_LDX|BPF_W|BPF_LEN: + ftest->code = BPF_S_LDX_W_LEN; + break; + case BPF_LDX|BPF_B|BPF_MSH: + ftest->code = BPF_S_LDX_B_MSH; + break; + case BPF_LDX|BPF_IMM: + ftest->code = BPF_S_LDX_IMM; + break; + case BPF_MISC|BPF_TAX: + ftest->code = BPF_S_MISC_TAX; + break; + case BPF_MISC|BPF_TXA: + ftest->code = BPF_S_MISC_TXA; + break; + case BPF_RET|BPF_K: + ftest->code = BPF_S_RET_K; + break; + case BPF_RET|BPF_A: + ftest->code = BPF_S_RET_A; + break; - if (code >= ARRAY_SIZE(codes)) - return -EINVAL; - code = codes[code]; - if (!code) - return -EINVAL; /* Some instructions need special checks */ - switch (code) { - case BPF_S_ALU_DIV_K: + /* check for division by zero */ + case BPF_ALU|BPF_DIV|BPF_K: if (ftest->k == 0) return -EINVAL; - ftest->k = reciprocal_value(ftest->k); + ftest->code = BPF_S_ALU_DIV_K; break; - case BPF_S_LD_MEM: - case BPF_S_LDX_MEM: - case BPF_S_ST: - case BPF_S_STX: - /* check for invalid memory addresses */ + + /* check for invalid memory addresses */ + case BPF_LD|BPF_MEM: if (ftest->k >= BPF_MEMWORDS) return -EINVAL; + ftest->code = BPF_S_LD_MEM; break; - case BPF_S_JMP_JA: + case BPF_LDX|BPF_MEM: + if (ftest->k >= BPF_MEMWORDS) + return -EINVAL; + ftest->code = BPF_S_LDX_MEM; + break; + case BPF_ST: + if (ftest->k >= BPF_MEMWORDS) + return -EINVAL; + ftest->code = BPF_S_ST; + break; + case BPF_STX: + if (ftest->k >= BPF_MEMWORDS) + return -EINVAL; + ftest->code = BPF_S_STX; + break; + + case BPF_JMP|BPF_JA: /* * Note, the large ftest->k might cause loops. * Compare this with conditional jumps below, @@ -525,7 +522,40 @@ int sk_chk_filter(struct sock_filter *filter, int flen) */ if (ftest->k >= (unsigned)(flen-pc-1)) return -EINVAL; + ftest->code = BPF_S_JMP_JA; + break; + + case BPF_JMP|BPF_JEQ|BPF_K: + ftest->code = BPF_S_JMP_JEQ_K; break; + case BPF_JMP|BPF_JEQ|BPF_X: + ftest->code = BPF_S_JMP_JEQ_X; + break; + case BPF_JMP|BPF_JGE|BPF_K: + ftest->code = BPF_S_JMP_JGE_K; + break; + case BPF_JMP|BPF_JGE|BPF_X: + ftest->code = BPF_S_JMP_JGE_X; + break; + case BPF_JMP|BPF_JGT|BPF_K: + ftest->code = BPF_S_JMP_JGT_K; + break; + case BPF_JMP|BPF_JGT|BPF_X: + ftest->code = BPF_S_JMP_JGT_X; + break; + case BPF_JMP|BPF_JSET|BPF_K: + ftest->code = BPF_S_JMP_JSET_K; + break; + case BPF_JMP|BPF_JSET|BPF_X: + ftest->code = BPF_S_JMP_JSET_X; + break; + + default: + return -EINVAL; + } + + /* for conditionals both must be safe */ + switch (ftest->code) { case BPF_S_JMP_JEQ_K: case BPF_S_JMP_JEQ_X: case BPF_S_JMP_JGE_K: @@ -534,13 +564,10 @@ int sk_chk_filter(struct sock_filter *filter, int flen) case BPF_S_JMP_JGT_X: case BPF_S_JMP_JSET_X: case BPF_S_JMP_JSET_K: - /* for conditionals both must be safe */ if (pc + ftest->jt + 1 >= flen || pc + ftest->jf + 1 >= flen) return -EINVAL; - break; } - ftest->code = code; } /* last instruction must be a RET code */ @@ -548,13 +575,15 @@ int sk_chk_filter(struct sock_filter *filter, int flen) case BPF_S_RET_K: case BPF_S_RET_A: return 0; - } - return -EINVAL; + break; + default: + return -EINVAL; + } } EXPORT_SYMBOL(sk_chk_filter); /** - * sk_filter_rcu_release - Release a socket filter by rcu_head + * sk_filter_rcu_release: Release a socket filter by rcu_head * @rcu: rcu_head that contains the sk_filter to free */ static void sk_filter_rcu_release(struct rcu_head *rcu) diff --git a/trunk/net/core/net-sysfs.c b/trunk/net/core/net-sysfs.c index f85cee3d869e..a5ff5a89f376 100644 --- a/trunk/net/core/net-sysfs.c +++ b/trunk/net/core/net-sysfs.c @@ -706,24 +706,21 @@ static struct attribute *rx_queue_default_attrs[] = { static void rx_queue_release(struct kobject *kobj) { struct netdev_rx_queue *queue = to_rx_queue(kobj); + struct netdev_rx_queue *first = queue->first; struct rps_map *map; struct rps_dev_flow_table *flow_table; map = rcu_dereference_raw(queue->rps_map); - if (map) { - RCU_INIT_POINTER(queue->rps_map, NULL); + if (map) call_rcu(&map->rcu, rps_map_release); - } flow_table = rcu_dereference_raw(queue->rps_flow_table); - if (flow_table) { - RCU_INIT_POINTER(queue->rps_flow_table, NULL); + if (flow_table) call_rcu(&flow_table->rcu, rps_dev_flow_table_release); - } - memset(kobj, 0, sizeof(*kobj)); - dev_put(queue->dev); + if (atomic_dec_and_test(&first->count)) + kfree(first); } static struct kobj_type rx_queue_ktype = { @@ -735,6 +732,7 @@ static struct kobj_type rx_queue_ktype = { static int rx_queue_add_kobject(struct net_device *net, int index) { struct netdev_rx_queue *queue = net->_rx + index; + struct netdev_rx_queue *first = queue->first; struct kobject *kobj = &queue->kobj; int error = 0; @@ -747,16 +745,14 @@ static int rx_queue_add_kobject(struct net_device *net, int index) } kobject_uevent(kobj, KOBJ_ADD); - dev_hold(queue->dev); + atomic_inc(&first->count); return error; } -#endif /* CONFIG_RPS */ int net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) { -#ifdef CONFIG_RPS int i; int error = 0; @@ -772,412 +768,23 @@ net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) kobject_put(&net->_rx[i].kobj); return error; -#else - return 0; -#endif -} - -#ifdef CONFIG_XPS -/* - * netdev_queue sysfs structures and functions. - */ -struct netdev_queue_attribute { - struct attribute attr; - ssize_t (*show)(struct netdev_queue *queue, - struct netdev_queue_attribute *attr, char *buf); - ssize_t (*store)(struct netdev_queue *queue, - struct netdev_queue_attribute *attr, const char *buf, size_t len); -}; -#define to_netdev_queue_attr(_attr) container_of(_attr, \ - struct netdev_queue_attribute, attr) - -#define to_netdev_queue(obj) container_of(obj, struct netdev_queue, kobj) - -static ssize_t netdev_queue_attr_show(struct kobject *kobj, - struct attribute *attr, char *buf) -{ - struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr); - struct netdev_queue *queue = to_netdev_queue(kobj); - - if (!attribute->show) - return -EIO; - - return attribute->show(queue, attribute, buf); -} - -static ssize_t netdev_queue_attr_store(struct kobject *kobj, - struct attribute *attr, - const char *buf, size_t count) -{ - struct netdev_queue_attribute *attribute = to_netdev_queue_attr(attr); - struct netdev_queue *queue = to_netdev_queue(kobj); - - if (!attribute->store) - return -EIO; - - return attribute->store(queue, attribute, buf, count); -} - -static const struct sysfs_ops netdev_queue_sysfs_ops = { - .show = netdev_queue_attr_show, - .store = netdev_queue_attr_store, -}; - -static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue) -{ - struct net_device *dev = queue->dev; - int i; - - for (i = 0; i < dev->num_tx_queues; i++) - if (queue == &dev->_tx[i]) - break; - - BUG_ON(i >= dev->num_tx_queues); - - return i; -} - - -static ssize_t show_xps_map(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, char *buf) -{ - struct net_device *dev = queue->dev; - struct xps_dev_maps *dev_maps; - cpumask_var_t mask; - unsigned long index; - size_t len = 0; - int i; - - if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) - return -ENOMEM; - - index = get_netdev_queue_index(queue); - - rcu_read_lock(); - dev_maps = rcu_dereference(dev->xps_maps); - if (dev_maps) { - for_each_possible_cpu(i) { - struct xps_map *map = - rcu_dereference(dev_maps->cpu_map[i]); - if (map) { - int j; - for (j = 0; j < map->len; j++) { - if (map->queues[j] == index) { - cpumask_set_cpu(i, mask); - break; - } - } - } - } - } - rcu_read_unlock(); - - len += cpumask_scnprintf(buf + len, PAGE_SIZE, mask); - if (PAGE_SIZE - len < 3) { - free_cpumask_var(mask); - return -EINVAL; - } - - free_cpumask_var(mask); - len += sprintf(buf + len, "\n"); - return len; -} - -static void xps_map_release(struct rcu_head *rcu) -{ - struct xps_map *map = container_of(rcu, struct xps_map, rcu); - - kfree(map); -} - -static void xps_dev_maps_release(struct rcu_head *rcu) -{ - struct xps_dev_maps *dev_maps = - container_of(rcu, struct xps_dev_maps, rcu); - - kfree(dev_maps); -} - -static DEFINE_MUTEX(xps_map_mutex); -#define xmap_dereference(P) \ - rcu_dereference_protected((P), lockdep_is_held(&xps_map_mutex)) - -static ssize_t store_xps_map(struct netdev_queue *queue, - struct netdev_queue_attribute *attribute, - const char *buf, size_t len) -{ - struct net_device *dev = queue->dev; - cpumask_var_t mask; - int err, i, cpu, pos, map_len, alloc_len, need_set; - unsigned long index; - struct xps_map *map, *new_map; - struct xps_dev_maps *dev_maps, *new_dev_maps; - int nonempty = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (!alloc_cpumask_var(&mask, GFP_KERNEL)) - return -ENOMEM; - - index = get_netdev_queue_index(queue); - - err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits); - if (err) { - free_cpumask_var(mask); - return err; - } - - new_dev_maps = kzalloc(max_t(unsigned, - XPS_DEV_MAPS_SIZE, L1_CACHE_BYTES), GFP_KERNEL); - if (!new_dev_maps) { - free_cpumask_var(mask); - return -ENOMEM; - } - - mutex_lock(&xps_map_mutex); - - dev_maps = xmap_dereference(dev->xps_maps); - - for_each_possible_cpu(cpu) { - map = dev_maps ? - xmap_dereference(dev_maps->cpu_map[cpu]) : NULL; - new_map = map; - if (map) { - for (pos = 0; pos < map->len; pos++) - if (map->queues[pos] == index) - break; - map_len = map->len; - alloc_len = map->alloc_len; - } else - pos = map_len = alloc_len = 0; - - need_set = cpu_isset(cpu, *mask) && cpu_online(cpu); - - if (need_set && pos >= map_len) { - /* Need to add queue to this CPU's map */ - if (map_len >= alloc_len) { - alloc_len = alloc_len ? - 2 * alloc_len : XPS_MIN_MAP_ALLOC; - new_map = kzalloc_node(XPS_MAP_SIZE(alloc_len), - GFP_KERNEL, - cpu_to_node(cpu)); - if (!new_map) - goto error; - new_map->alloc_len = alloc_len; - for (i = 0; i < map_len; i++) - new_map->queues[i] = map->queues[i]; - new_map->len = map_len; - } - new_map->queues[new_map->len++] = index; - } else if (!need_set && pos < map_len) { - /* Need to remove queue from this CPU's map */ - if (map_len > 1) - new_map->queues[pos] = - new_map->queues[--new_map->len]; - else - new_map = NULL; - } - RCU_INIT_POINTER(new_dev_maps->cpu_map[cpu], new_map); - } - - /* Cleanup old maps */ - for_each_possible_cpu(cpu) { - map = dev_maps ? - xmap_dereference(dev_maps->cpu_map[cpu]) : NULL; - if (map && xmap_dereference(new_dev_maps->cpu_map[cpu]) != map) - call_rcu(&map->rcu, xps_map_release); - if (new_dev_maps->cpu_map[cpu]) - nonempty = 1; - } - - if (nonempty) - rcu_assign_pointer(dev->xps_maps, new_dev_maps); - else { - kfree(new_dev_maps); - rcu_assign_pointer(dev->xps_maps, NULL); - } - - if (dev_maps) - call_rcu(&dev_maps->rcu, xps_dev_maps_release); - - mutex_unlock(&xps_map_mutex); - - free_cpumask_var(mask); - return len; - -error: - mutex_unlock(&xps_map_mutex); - - if (new_dev_maps) - for_each_possible_cpu(i) - kfree(rcu_dereference_protected( - new_dev_maps->cpu_map[i], - 1)); - kfree(new_dev_maps); - free_cpumask_var(mask); - return -ENOMEM; -} - -static struct netdev_queue_attribute xps_cpus_attribute = - __ATTR(xps_cpus, S_IRUGO | S_IWUSR, show_xps_map, store_xps_map); - -static struct attribute *netdev_queue_default_attrs[] = { - &xps_cpus_attribute.attr, - NULL -}; - -static void netdev_queue_release(struct kobject *kobj) -{ - struct netdev_queue *queue = to_netdev_queue(kobj); - struct net_device *dev = queue->dev; - struct xps_dev_maps *dev_maps; - struct xps_map *map; - unsigned long index; - int i, pos, nonempty = 0; - - index = get_netdev_queue_index(queue); - - mutex_lock(&xps_map_mutex); - dev_maps = xmap_dereference(dev->xps_maps); - - if (dev_maps) { - for_each_possible_cpu(i) { - map = xmap_dereference(dev_maps->cpu_map[i]); - if (!map) - continue; - - for (pos = 0; pos < map->len; pos++) - if (map->queues[pos] == index) - break; - - if (pos < map->len) { - if (map->len > 1) - map->queues[pos] = - map->queues[--map->len]; - else { - RCU_INIT_POINTER(dev_maps->cpu_map[i], - NULL); - call_rcu(&map->rcu, xps_map_release); - map = NULL; - } - } - if (map) - nonempty = 1; - } - - if (!nonempty) { - RCU_INIT_POINTER(dev->xps_maps, NULL); - call_rcu(&dev_maps->rcu, xps_dev_maps_release); - } - } - - mutex_unlock(&xps_map_mutex); - - memset(kobj, 0, sizeof(*kobj)); - dev_put(queue->dev); -} - -static struct kobj_type netdev_queue_ktype = { - .sysfs_ops = &netdev_queue_sysfs_ops, - .release = netdev_queue_release, - .default_attrs = netdev_queue_default_attrs, -}; - -static int netdev_queue_add_kobject(struct net_device *net, int index) -{ - struct netdev_queue *queue = net->_tx + index; - struct kobject *kobj = &queue->kobj; - int error = 0; - - kobj->kset = net->queues_kset; - error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL, - "tx-%u", index); - if (error) { - kobject_put(kobj); - return error; - } - - kobject_uevent(kobj, KOBJ_ADD); - dev_hold(queue->dev); - - return error; -} -#endif /* CONFIG_XPS */ - -int -netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num) -{ -#ifdef CONFIG_XPS - int i; - int error = 0; - - for (i = old_num; i < new_num; i++) { - error = netdev_queue_add_kobject(net, i); - if (error) { - new_num = old_num; - break; - } - } - - while (--i >= new_num) - kobject_put(&net->_tx[i].kobj); - - return error; -#else - return 0; -#endif } -static int register_queue_kobjects(struct net_device *net) +static int rx_queue_register_kobjects(struct net_device *net) { - int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0; - -#if defined(CONFIG_RPS) || defined(CONFIG_XPS) net->queues_kset = kset_create_and_add("queues", NULL, &net->dev.kobj); if (!net->queues_kset) return -ENOMEM; -#endif - -#ifdef CONFIG_RPS - real_rx = net->real_num_rx_queues; -#endif - real_tx = net->real_num_tx_queues; - - error = net_rx_queue_update_kobjects(net, 0, real_rx); - if (error) - goto error; - rxq = real_rx; - - error = netdev_queue_update_kobjects(net, 0, real_tx); - if (error) - goto error; - txq = real_tx; - - return 0; - -error: - netdev_queue_update_kobjects(net, txq, 0); - net_rx_queue_update_kobjects(net, rxq, 0); - return error; + return net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues); } -static void remove_queue_kobjects(struct net_device *net) +static void rx_queue_remove_kobjects(struct net_device *net) { - int real_rx = 0, real_tx = 0; - -#ifdef CONFIG_RPS - real_rx = net->real_num_rx_queues; -#endif - real_tx = net->real_num_tx_queues; - - net_rx_queue_update_kobjects(net, real_rx, 0); - netdev_queue_update_kobjects(net, real_tx, 0); -#if defined(CONFIG_RPS) || defined(CONFIG_XPS) + net_rx_queue_update_kobjects(net, net->real_num_rx_queues, 0); kset_unregister(net->queues_kset); -#endif } +#endif /* CONFIG_RPS */ static const void *net_current_ns(void) { @@ -1276,7 +883,9 @@ void netdev_unregister_kobject(struct net_device * net) kobject_get(&dev->kobj); - remove_queue_kobjects(net); +#ifdef CONFIG_RPS + rx_queue_remove_kobjects(net); +#endif device_del(dev); } @@ -1315,11 +924,13 @@ int netdev_register_kobject(struct net_device *net) if (error) return error; - error = register_queue_kobjects(net); +#ifdef CONFIG_RPS + error = rx_queue_register_kobjects(net); if (error) { device_del(dev); return error; } +#endif return error; } diff --git a/trunk/net/core/net-sysfs.h b/trunk/net/core/net-sysfs.h index bd7751ec1c4d..778e1571548d 100644 --- a/trunk/net/core/net-sysfs.h +++ b/trunk/net/core/net-sysfs.h @@ -4,8 +4,8 @@ int netdev_kobject_init(void); int netdev_register_kobject(struct net_device *); void netdev_unregister_kobject(struct net_device *); +#ifdef CONFIG_RPS int net_rx_queue_update_kobjects(struct net_device *, int old_num, int new_num); -int netdev_queue_update_kobjects(struct net_device *net, - int old_num, int new_num); +#endif #endif diff --git a/trunk/net/core/netpoll.c b/trunk/net/core/netpoll.c index ee38acb6d463..4e98ffac3af0 100644 --- a/trunk/net/core/netpoll.c +++ b/trunk/net/core/netpoll.c @@ -76,7 +76,8 @@ static void queue_process(struct work_struct *work) local_irq_save(flags); __netif_tx_lock(txq, smp_processor_id()); - if (netif_tx_queue_frozen_or_stopped(txq) || + if (netif_tx_queue_stopped(txq) || + netif_tx_queue_frozen(txq) || ops->ndo_start_xmit(skb, dev) != NETDEV_TX_OK) { skb_queue_head(&npinfo->txq, skb); __netif_tx_unlock(txq); diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index 2953b2abc971..fbce4b05a53e 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -378,7 +378,6 @@ struct pktgen_dev { u16 queue_map_min; u16 queue_map_max; - __u32 skb_priority; /* skb priority field */ int node; /* Memory node */ #ifdef CONFIG_XFRM @@ -395,8 +394,6 @@ struct pktgen_hdr { __be32 tv_usec; }; -static bool pktgen_exiting __read_mostly; - struct pktgen_thread { spinlock_t if_lock; /* for list of devices */ struct list_head if_list; /* All device here */ @@ -550,10 +547,6 @@ static int pktgen_if_show(struct seq_file *seq, void *v) pkt_dev->queue_map_min, pkt_dev->queue_map_max); - if (pkt_dev->skb_priority) - seq_printf(seq, " skb_priority: %u\n", - pkt_dev->skb_priority); - if (pkt_dev->flags & F_IPV6) { char b1[128], b2[128], b3[128]; fmt_ip6(b1, pkt_dev->in6_saddr.s6_addr); @@ -894,7 +887,7 @@ static ssize_t pktgen_if_write(struct file *file, i += len; if (debug) { - size_t copy = min_t(size_t, count, 1023); + size_t copy = min(count, 1023); char tb[copy + 1]; if (copy_from_user(tb, user_buffer, copy)) return -EFAULT; @@ -1718,18 +1711,6 @@ static ssize_t pktgen_if_write(struct file *file, return count; } - if (!strcmp(name, "skb_priority")) { - len = num_arg(&user_buffer[i], 9, &value); - if (len < 0) - return len; - - i += len; - pkt_dev->skb_priority = value; - sprintf(pg_result, "OK: skb_priority=%i", - pkt_dev->skb_priority); - return count; - } - sprintf(pkt_dev->result, "No such parameter \"%s\"", name); return -EINVAL; } @@ -2631,8 +2612,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, /* Update any of the values, used when we're incrementing various * fields. */ - mod_cur_headers(pkt_dev); queue_map = pkt_dev->cur_queue_map; + mod_cur_headers(pkt_dev); datalen = (odev->hard_header_len + 16) & ~0xf; @@ -2690,8 +2671,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, skb->transport_header = skb->network_header + sizeof(struct iphdr); skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr)); skb_set_queue_mapping(skb, queue_map); - skb->priority = pkt_dev->skb_priority; - iph = ip_hdr(skb); udph = udp_hdr(skb); @@ -2997,8 +2976,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, /* Update any of the values, used when we're incrementing various * fields. */ - mod_cur_headers(pkt_dev); queue_map = pkt_dev->cur_queue_map; + mod_cur_headers(pkt_dev); skb = __netdev_alloc_skb(odev, pkt_dev->cur_pkt_size + 64 @@ -3037,7 +3016,6 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, skb->transport_header = skb->network_header + sizeof(struct ipv6hdr); skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr)); skb_set_queue_mapping(skb, queue_map); - skb->priority = pkt_dev->skb_priority; iph = ipv6_hdr(skb); udph = udp_hdr(skb); @@ -3453,6 +3431,11 @@ static void pktgen_rem_thread(struct pktgen_thread *t) remove_proc_entry(t->tsk->comm, pg_proc_dir); + mutex_lock(&pktgen_thread_lock); + + list_del(&t->th_list); + + mutex_unlock(&pktgen_thread_lock); } static void pktgen_resched(struct pktgen_dev *pkt_dev) @@ -3527,7 +3510,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) __netif_tx_lock_bh(txq); - if (unlikely(netif_tx_queue_frozen_or_stopped(txq))) { + if (unlikely(netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq))) { ret = NETDEV_TX_BUSY; pkt_dev->last_ok = 0; goto unlock; @@ -3599,8 +3582,6 @@ static int pktgen_thread_worker(void *arg) pkt_dev = next_to_run(t); if (unlikely(!pkt_dev && t->control == 0)) { - if (pktgen_exiting) - break; wait_event_interruptible_timeout(t->queue, t->control != 0, HZ/10); @@ -3653,13 +3634,6 @@ static int pktgen_thread_worker(void *arg) pr_debug("%s removing thread\n", t->tsk->comm); pktgen_rem_thread(t); - /* Wait for kthread_stop */ - while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - } - __set_current_state(TASK_RUNNING); - return 0; } @@ -3934,7 +3908,6 @@ static void __exit pg_cleanup(void) struct list_head *q, *n; /* Stop all interfaces & threads */ - pktgen_exiting = true; list_for_each_safe(q, n, &pktgen_threads) { t = list_entry(q, struct pktgen_thread, th_list); diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 750db57f3bb3..8121268ddbdd 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -347,106 +347,16 @@ static size_t rtnl_link_get_size(const struct net_device *dev) if (!ops) return 0; - size = nla_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */ - nla_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */ + size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */ + nlmsg_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */ if (ops->get_size) /* IFLA_INFO_DATA + nested data */ - size += nla_total_size(sizeof(struct nlattr)) + + size += nlmsg_total_size(sizeof(struct nlattr)) + ops->get_size(dev); if (ops->get_xstats_size) - /* IFLA_INFO_XSTATS */ - size += nla_total_size(ops->get_xstats_size(dev)); - - return size; -} - -static LIST_HEAD(rtnl_af_ops); - -static const struct rtnl_af_ops *rtnl_af_lookup(const int family) -{ - const struct rtnl_af_ops *ops; - - list_for_each_entry(ops, &rtnl_af_ops, list) { - if (ops->family == family) - return ops; - } - - return NULL; -} - -/** - * __rtnl_af_register - Register rtnl_af_ops with rtnetlink. - * @ops: struct rtnl_af_ops * to register - * - * The caller must hold the rtnl_mutex. - * - * Returns 0 on success or a negative error code. - */ -int __rtnl_af_register(struct rtnl_af_ops *ops) -{ - list_add_tail(&ops->list, &rtnl_af_ops); - return 0; -} -EXPORT_SYMBOL_GPL(__rtnl_af_register); - -/** - * rtnl_af_register - Register rtnl_af_ops with rtnetlink. - * @ops: struct rtnl_af_ops * to register - * - * Returns 0 on success or a negative error code. - */ -int rtnl_af_register(struct rtnl_af_ops *ops) -{ - int err; - - rtnl_lock(); - err = __rtnl_af_register(ops); - rtnl_unlock(); - return err; -} -EXPORT_SYMBOL_GPL(rtnl_af_register); - -/** - * __rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink. - * @ops: struct rtnl_af_ops * to unregister - * - * The caller must hold the rtnl_mutex. - */ -void __rtnl_af_unregister(struct rtnl_af_ops *ops) -{ - list_del(&ops->list); -} -EXPORT_SYMBOL_GPL(__rtnl_af_unregister); - -/** - * rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink. - * @ops: struct rtnl_af_ops * to unregister - */ -void rtnl_af_unregister(struct rtnl_af_ops *ops) -{ - rtnl_lock(); - __rtnl_af_unregister(ops); - rtnl_unlock(); -} -EXPORT_SYMBOL_GPL(rtnl_af_unregister); - -static size_t rtnl_link_get_af_size(const struct net_device *dev) -{ - struct rtnl_af_ops *af_ops; - size_t size; - - /* IFLA_AF_SPEC */ - size = nla_total_size(sizeof(struct nlattr)); - - list_for_each_entry(af_ops, &rtnl_af_ops, list) { - if (af_ops->get_link_af_size) { - /* AF_* + nested data */ - size += nla_total_size(sizeof(struct nlattr)) + - af_ops->get_link_af_size(dev); - } - } + size += ops->get_xstats_size(dev); /* IFLA_INFO_XSTATS */ return size; } @@ -760,8 +670,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev) + nla_total_size(4) /* IFLA_NUM_VF */ + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */ + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ - + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ - + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */ + + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ } static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev) @@ -847,8 +756,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, struct nlmsghdr *nlh; struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *stats; - struct nlattr *attr, *af_spec; - struct rtnl_af_ops *af_ops; + struct nlattr *attr; nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); if (nlh == NULL) @@ -957,36 +865,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, goto nla_put_failure; } - if (!(af_spec = nla_nest_start(skb, IFLA_AF_SPEC))) - goto nla_put_failure; - - list_for_each_entry(af_ops, &rtnl_af_ops, list) { - if (af_ops->fill_link_af) { - struct nlattr *af; - int err; - - if (!(af = nla_nest_start(skb, af_ops->family))) - goto nla_put_failure; - - err = af_ops->fill_link_af(skb, dev); - - /* - * Caller may return ENODATA to indicate that there - * was no data to be dumped. This is not an error, it - * means we should trim the attribute header and - * continue. - */ - if (err == -ENODATA) - nla_nest_cancel(skb, af); - else if (err < 0) - goto nla_put_failure; - - nla_nest_end(skb, af); - } - } - - nla_nest_end(skb, af_spec); - return nlmsg_end(skb, nlh); nla_put_failure: @@ -1045,7 +923,6 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, [IFLA_VF_PORTS] = { .type = NLA_NESTED }, [IFLA_PORT_SELF] = { .type = NLA_NESTED }, - [IFLA_AF_SPEC] = { .type = NLA_NESTED }, }; EXPORT_SYMBOL(ifla_policy); @@ -1107,28 +984,6 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) return -EINVAL; } - if (tb[IFLA_AF_SPEC]) { - struct nlattr *af; - int rem, err; - - nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) { - const struct rtnl_af_ops *af_ops; - - if (!(af_ops = rtnl_af_lookup(nla_type(af)))) - return -EAFNOSUPPORT; - - if (!af_ops->set_link_af) - return -EOPNOTSUPP; - - if (af_ops->validate_link_af) { - err = af_ops->validate_link_af(dev, - tb[IFLA_AF_SPEC]); - if (err < 0) - return err; - } - } - } - return 0; } @@ -1369,24 +1224,6 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, goto errout; modified = 1; } - - if (tb[IFLA_AF_SPEC]) { - struct nlattr *af; - int rem; - - nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) { - const struct rtnl_af_ops *af_ops; - - if (!(af_ops = rtnl_af_lookup(nla_type(af)))) - BUG(); - - err = af_ops->set_link_af(dev, af); - if (err < 0) - goto errout; - - modified = 1; - } - } err = 0; errout: diff --git a/trunk/net/core/scm.c b/trunk/net/core/scm.c index bbe454450801..413cab89017d 100644 --- a/trunk/net/core/scm.c +++ b/trunk/net/core/scm.c @@ -79,11 +79,10 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) return -ENOMEM; *fplp = fpl; fpl->count = 0; - fpl->max = SCM_MAX_FD; } fpp = &fpl->fp[fpl->count]; - if (fpl->count + num > fpl->max) + if (fpl->count + num > SCM_MAX_FD) return -EINVAL; /* @@ -332,12 +331,11 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) if (!fpl) return NULL; - new_fpl = kmemdup(fpl, offsetof(struct scm_fp_list, fp[fpl->count]), - GFP_KERNEL); + new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL); if (new_fpl) { - for (i = 0; i < fpl->count; i++) + for (i=fpl->count-1; i>=0; i--) get_file(fpl->fp[i]); - new_fpl->max = new_fpl->count; + memcpy(new_fpl, fpl, sizeof(*fpl)); } return new_fpl; } diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index fb6080111461..3eed5424e659 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -1653,10 +1653,10 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) { struct proto *prot = sk->sk_prot; int amt = sk_mem_pages(size); - long allocated; + int allocated; sk->sk_forward_alloc += amt * SK_MEM_QUANTUM; - allocated = atomic_long_add_return(amt, prot->memory_allocated); + allocated = atomic_add_return(amt, prot->memory_allocated); /* Under limit. */ if (allocated <= prot->sysctl_mem[0]) { @@ -1714,7 +1714,7 @@ int __sk_mem_schedule(struct sock *sk, int size, int kind) /* Alas. Undo changes. */ sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; - atomic_long_sub(amt, prot->memory_allocated); + atomic_sub(amt, prot->memory_allocated); return 0; } EXPORT_SYMBOL(__sk_mem_schedule); @@ -1727,12 +1727,12 @@ void __sk_mem_reclaim(struct sock *sk) { struct proto *prot = sk->sk_prot; - atomic_long_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, + atomic_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, prot->memory_allocated); sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1; if (prot->memory_pressure && *prot->memory_pressure && - (atomic_long_read(prot->memory_allocated) < prot->sysctl_mem[0])) + (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0])) *prot->memory_pressure = 0; } EXPORT_SYMBOL(__sk_mem_reclaim); @@ -2452,12 +2452,12 @@ static char proto_method_implemented(const void *method) static void proto_seq_printf(struct seq_file *seq, struct proto *proto) { - seq_printf(seq, "%-9s %4u %6d %6ld %-3s %6u %-3s %-10s " + seq_printf(seq, "%-9s %4u %6d %6d %-3s %6u %-3s %-10s " "%2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c %2c\n", proto->name, proto->obj_size, sock_prot_inuse_get(seq_file_net(seq), proto), - proto->memory_allocated != NULL ? atomic_long_read(proto->memory_allocated) : -1L, + proto->memory_allocated != NULL ? atomic_read(proto->memory_allocated) : -1, proto->memory_pressure != NULL ? *proto->memory_pressure ? "yes" : "no" : "NI", proto->max_header, proto->slab == NULL ? "no" : "yes", diff --git a/trunk/net/core/timestamping.c b/trunk/net/core/timestamping.c index dac7ed687f60..0ae6c22da85b 100644 --- a/trunk/net/core/timestamping.c +++ b/trunk/net/core/timestamping.c @@ -31,7 +31,7 @@ static unsigned int classify(struct sk_buff *skb) if (likely(skb->dev && skb->dev->phydev && skb->dev->phydev->drv)) - return sk_run_filter(skb, ptp_filter); + return sk_run_filter(skb, ptp_filter, ARRAY_SIZE(ptp_filter)); else return PTP_CLASS_NONE; } diff --git a/trunk/net/dccp/ackvec.c b/trunk/net/dccp/ackvec.c index 25b7a8d1ad58..92a6fcb40d7d 100644 --- a/trunk/net/dccp/ackvec.c +++ b/trunk/net/dccp/ackvec.c @@ -1,375 +1,444 @@ /* * net/dccp/ackvec.c * - * An implementation of Ack Vectors for the DCCP protocol - * Copyright (c) 2007 University of Aberdeen, Scotland, UK + * An implementation of the DCCP protocol * Copyright (c) 2005 Arnaldo Carvalho de Melo * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; version 2 of the License; */ + +#include "ackvec.h" #include "dccp.h" + +#include +#include #include +#include #include +#include + static struct kmem_cache *dccp_ackvec_slab; static struct kmem_cache *dccp_ackvec_record_slab; -struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority) +static struct dccp_ackvec_record *dccp_ackvec_record_new(void) { - struct dccp_ackvec *av = kmem_cache_zalloc(dccp_ackvec_slab, priority); + struct dccp_ackvec_record *avr = + kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC); - if (av != NULL) { - av->av_buf_head = av->av_buf_tail = DCCPAV_MAX_ACKVEC_LEN - 1; - INIT_LIST_HEAD(&av->av_records); - } - return av; + if (avr != NULL) + INIT_LIST_HEAD(&avr->avr_node); + + return avr; } -static void dccp_ackvec_purge_records(struct dccp_ackvec *av) +static void dccp_ackvec_record_delete(struct dccp_ackvec_record *avr) { - struct dccp_ackvec_record *cur, *next; - - list_for_each_entry_safe(cur, next, &av->av_records, avr_node) - kmem_cache_free(dccp_ackvec_record_slab, cur); - INIT_LIST_HEAD(&av->av_records); + if (unlikely(avr == NULL)) + return; + /* Check if deleting a linked record */ + WARN_ON(!list_empty(&avr->avr_node)); + kmem_cache_free(dccp_ackvec_record_slab, avr); } -void dccp_ackvec_free(struct dccp_ackvec *av) +static void dccp_ackvec_insert_avr(struct dccp_ackvec *av, + struct dccp_ackvec_record *avr) { - if (likely(av != NULL)) { - dccp_ackvec_purge_records(av); - kmem_cache_free(dccp_ackvec_slab, av); + /* + * AVRs are sorted by seqno. Since we are sending them in order, we + * just add the AVR at the head of the list. + * -sorbo. + */ + if (!list_empty(&av->av_records)) { + const struct dccp_ackvec_record *head = + list_entry(av->av_records.next, + struct dccp_ackvec_record, + avr_node); + BUG_ON(before48(avr->avr_ack_seqno, head->avr_ack_seqno)); } + + list_add(&avr->avr_node, &av->av_records); } -/** - * dccp_ackvec_update_records - Record information about sent Ack Vectors - * @av: Ack Vector records to update - * @seqno: Sequence number of the packet carrying the Ack Vector just sent - * @nonce_sum: The sum of all buffer nonces contained in the Ack Vector - */ -int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seqno, u8 nonce_sum) +int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) { + struct dccp_sock *dp = dccp_sk(sk); + struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; + /* Figure out how many options do we need to represent the ackvec */ + const u8 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_SINGLE_OPT_MAXLEN); + u16 len = av->av_vec_len + 2 * nr_opts, i; + u32 elapsed_time; + const unsigned char *tail, *from; + unsigned char *to; struct dccp_ackvec_record *avr; + suseconds_t delta; + + if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) + return -1; + + delta = ktime_us_delta(ktime_get_real(), av->av_time); + elapsed_time = delta / 10; - avr = kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC); + if (elapsed_time != 0 && + dccp_insert_option_elapsed_time(skb, elapsed_time)) + return -1; + + avr = dccp_ackvec_record_new(); if (avr == NULL) - return -ENOBUFS; + return -1; + + DCCP_SKB_CB(skb)->dccpd_opt_len += len; + + to = skb_push(skb, len); + len = av->av_vec_len; + from = av->av_buf + av->av_buf_head; + tail = av->av_buf + DCCP_MAX_ACKVEC_LEN; + + for (i = 0; i < nr_opts; ++i) { + int copylen = len; + + if (len > DCCP_SINGLE_OPT_MAXLEN) + copylen = DCCP_SINGLE_OPT_MAXLEN; + + *to++ = DCCPO_ACK_VECTOR_0; + *to++ = copylen + 2; + + /* Check if buf_head wraps */ + if (from + copylen > tail) { + const u16 tailsize = tail - from; + + memcpy(to, from, tailsize); + to += tailsize; + len -= tailsize; + copylen -= tailsize; + from = av->av_buf; + } + + memcpy(to, from, copylen); + from += copylen; + to += copylen; + len -= copylen; + } - avr->avr_ack_seqno = seqno; - avr->avr_ack_ptr = av->av_buf_head; - avr->avr_ack_ackno = av->av_buf_ackno; - avr->avr_ack_nonce = nonce_sum; - avr->avr_ack_runlen = dccp_ackvec_runlen(av->av_buf + av->av_buf_head); - /* - * When the buffer overflows, we keep no more than one record. This is - * the simplest way of disambiguating sender-Acks dating from before the - * overflow from sender-Acks which refer to after the overflow; a simple - * solution is preferable here since we are handling an exception. - */ - if (av->av_overflow) - dccp_ackvec_purge_records(av); /* - * Since GSS is incremented for each packet, the list is automatically - * arranged in descending order of @ack_seqno. + * From RFC 4340, A.2: + * + * For each acknowledgement it sends, the HC-Receiver will add an + * acknowledgement record. ack_seqno will equal the HC-Receiver + * sequence number it used for the ack packet; ack_ptr will equal + * buf_head; ack_ackno will equal buf_ackno; and ack_nonce will + * equal buf_nonce. */ - list_add(&avr->avr_node, &av->av_records); + avr->avr_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq; + avr->avr_ack_ptr = av->av_buf_head; + avr->avr_ack_ackno = av->av_buf_ackno; + avr->avr_ack_nonce = av->av_buf_nonce; + avr->avr_sent_len = av->av_vec_len; - dccp_pr_debug("Added Vector, ack_seqno=%llu, ack_ackno=%llu (rl=%u)\n", + dccp_ackvec_insert_avr(av, avr); + + dccp_pr_debug("%s ACK Vector 0, len=%d, ack_seqno=%llu, " + "ack_ackno=%llu\n", + dccp_role(sk), avr->avr_sent_len, (unsigned long long)avr->avr_ack_seqno, - (unsigned long long)avr->avr_ack_ackno, - avr->avr_ack_runlen); + (unsigned long long)avr->avr_ack_ackno); return 0; } -static struct dccp_ackvec_record *dccp_ackvec_lookup(struct list_head *av_list, - const u64 ackno) +struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority) { - struct dccp_ackvec_record *avr; - /* - * Exploit that records are inserted in descending order of sequence - * number, start with the oldest record first. If @ackno is `before' - * the earliest ack_ackno, the packet is too old to be considered. - */ - list_for_each_entry_reverse(avr, av_list, avr_node) { - if (avr->avr_ack_seqno == ackno) - return avr; - if (before48(ackno, avr->avr_ack_seqno)) - break; + struct dccp_ackvec *av = kmem_cache_alloc(dccp_ackvec_slab, priority); + + if (av != NULL) { + av->av_buf_head = DCCP_MAX_ACKVEC_LEN - 1; + av->av_buf_ackno = UINT48_MAX + 1; + av->av_buf_nonce = 0; + av->av_time = ktime_set(0, 0); + av->av_vec_len = 0; + INIT_LIST_HEAD(&av->av_records); } - return NULL; + + return av; } -/* - * Buffer index and length computation using modulo-buffersize arithmetic. - * Note that, as pointers move from right to left, head is `before' tail. - */ -static inline u16 __ackvec_idx_add(const u16 a, const u16 b) +void dccp_ackvec_free(struct dccp_ackvec *av) { - return (a + b) % DCCPAV_MAX_ACKVEC_LEN; + if (unlikely(av == NULL)) + return; + + if (!list_empty(&av->av_records)) { + struct dccp_ackvec_record *avr, *next; + + list_for_each_entry_safe(avr, next, &av->av_records, avr_node) { + list_del_init(&avr->avr_node); + dccp_ackvec_record_delete(avr); + } + } + + kmem_cache_free(dccp_ackvec_slab, av); } -static inline u16 __ackvec_idx_sub(const u16 a, const u16 b) +static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av, + const u32 index) { - return __ackvec_idx_add(a, DCCPAV_MAX_ACKVEC_LEN - b); + return av->av_buf[index] & DCCP_ACKVEC_STATE_MASK; } -u16 dccp_ackvec_buflen(const struct dccp_ackvec *av) +static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av, + const u32 index) { - if (unlikely(av->av_overflow)) - return DCCPAV_MAX_ACKVEC_LEN; - return __ackvec_idx_sub(av->av_buf_tail, av->av_buf_head); + return av->av_buf[index] & DCCP_ACKVEC_LEN_MASK; } -/** - * dccp_ackvec_update_old - Update previous state as per RFC 4340, 11.4.1 - * @av: non-empty buffer to update - * @distance: negative or zero distance of @seqno from buf_ackno downward - * @seqno: the (old) sequence number whose record is to be updated - * @state: state in which packet carrying @seqno was received +/* + * If several packets are missing, the HC-Receiver may prefer to enter multiple + * bytes with run length 0, rather than a single byte with a larger run length; + * this simplifies table updates if one of the missing packets arrives. */ -static void dccp_ackvec_update_old(struct dccp_ackvec *av, s64 distance, - u64 seqno, enum dccp_ackvec_states state) +static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, + const unsigned int packets, + const unsigned char state) { - u16 ptr = av->av_buf_head; + long gap; + long new_head; - BUG_ON(distance > 0); - if (unlikely(dccp_ackvec_is_empty(av))) - return; + if (av->av_vec_len + packets > DCCP_MAX_ACKVEC_LEN) + return -ENOBUFS; - do { - u8 runlen = dccp_ackvec_runlen(av->av_buf + ptr); + gap = packets - 1; + new_head = av->av_buf_head - packets; - if (distance + runlen >= 0) { - /* - * Only update the state if packet has not been received - * yet. This is OK as per the second table in RFC 4340, - * 11.4.1; i.e. here we are using the following table: - * RECEIVED - * 0 1 3 - * S +---+---+---+ - * T 0 | 0 | 0 | 0 | - * O +---+---+---+ - * R 1 | 1 | 1 | 1 | - * E +---+---+---+ - * D 3 | 0 | 1 | 3 | - * +---+---+---+ - * The "Not Received" state was set by reserve_seats(). - */ - if (av->av_buf[ptr] == DCCPAV_NOT_RECEIVED) - av->av_buf[ptr] = state; - else - dccp_pr_debug("Not changing %llu state to %u\n", - (unsigned long long)seqno, state); - break; + if (new_head < 0) { + if (gap > 0) { + memset(av->av_buf, DCCP_ACKVEC_STATE_NOT_RECEIVED, + gap + new_head + 1); + gap = -new_head; } + new_head += DCCP_MAX_ACKVEC_LEN; + } - distance += runlen + 1; - ptr = __ackvec_idx_add(ptr, 1); + av->av_buf_head = new_head; - } while (ptr != av->av_buf_tail); -} + if (gap > 0) + memset(av->av_buf + av->av_buf_head + 1, + DCCP_ACKVEC_STATE_NOT_RECEIVED, gap); -/* Mark @num entries after buf_head as "Not yet received". */ -static void dccp_ackvec_reserve_seats(struct dccp_ackvec *av, u16 num) -{ - u16 start = __ackvec_idx_add(av->av_buf_head, 1), - len = DCCPAV_MAX_ACKVEC_LEN - start; - - /* check for buffer wrap-around */ - if (num > len) { - memset(av->av_buf + start, DCCPAV_NOT_RECEIVED, len); - start = 0; - num -= len; - } - if (num) - memset(av->av_buf + start, DCCPAV_NOT_RECEIVED, num); + av->av_buf[av->av_buf_head] = state; + av->av_vec_len += packets; + return 0; } -/** - * dccp_ackvec_add_new - Record one or more new entries in Ack Vector buffer - * @av: container of buffer to update (can be empty or non-empty) - * @num_packets: number of packets to register (must be >= 1) - * @seqno: sequence number of the first packet in @num_packets - * @state: state in which packet carrying @seqno was received +/* + * Implements the RFC 4340, Appendix A */ -static void dccp_ackvec_add_new(struct dccp_ackvec *av, u32 num_packets, - u64 seqno, enum dccp_ackvec_states state) +int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, + const u64 ackno, const u8 state) { - u32 num_cells = num_packets; + /* + * Check at the right places if the buffer is full, if it is, tell the + * caller to start dropping packets till the HC-Sender acks our ACK + * vectors, when we will free up space in av_buf. + * + * We may well decide to do buffer compression, etc, but for now lets + * just drop. + * + * From Appendix A.1.1 (`New Packets'): + * + * Of course, the circular buffer may overflow, either when the + * HC-Sender is sending data at a very high rate, when the + * HC-Receiver's acknowledgements are not reaching the HC-Sender, + * or when the HC-Sender is forgetting to acknowledge those acks + * (so the HC-Receiver is unable to clean up old state). In this + * case, the HC-Receiver should either compress the buffer (by + * increasing run lengths when possible), transfer its state to + * a larger buffer, or, as a last resort, drop all received + * packets, without processing them whatsoever, until its buffer + * shrinks again. + */ - if (num_packets > DCCPAV_BURST_THRESH) { - u32 lost_packets = num_packets - 1; + /* See if this is the first ackno being inserted */ + if (av->av_vec_len == 0) { + av->av_buf[av->av_buf_head] = state; + av->av_vec_len = 1; + } else if (after48(ackno, av->av_buf_ackno)) { + const u64 delta = dccp_delta_seqno(av->av_buf_ackno, ackno); - DCCP_WARN("Warning: large burst loss (%u)\n", lost_packets); /* - * We received 1 packet and have a loss of size "num_packets-1" - * which we squeeze into num_cells-1 rather than reserving an - * entire byte for each lost packet. - * The reason is that the vector grows in O(burst_length); when - * it grows too large there will no room left for the payload. - * This is a trade-off: if a few packets out of the burst show - * up later, their state will not be changed; it is simply too - * costly to reshuffle/reallocate/copy the buffer each time. - * Should such problems persist, we will need to switch to a - * different underlying data structure. + * Look if the state of this packet is the same as the + * previous ackno and if so if we can bump the head len. */ - for (num_packets = num_cells = 1; lost_packets; ++num_cells) { - u8 len = min(lost_packets, (u32)DCCPAV_MAX_RUNLEN); - - av->av_buf_head = __ackvec_idx_sub(av->av_buf_head, 1); - av->av_buf[av->av_buf_head] = DCCPAV_NOT_RECEIVED | len; + if (delta == 1 && + dccp_ackvec_state(av, av->av_buf_head) == state && + dccp_ackvec_len(av, av->av_buf_head) < DCCP_ACKVEC_LEN_MASK) + av->av_buf[av->av_buf_head]++; + else if (dccp_ackvec_set_buf_head_state(av, delta, state)) + return -ENOBUFS; + } else { + /* + * A.1.2. Old Packets + * + * When a packet with Sequence Number S <= buf_ackno + * arrives, the HC-Receiver will scan the table for + * the byte corresponding to S. (Indexing structures + * could reduce the complexity of this scan.) + */ + u64 delta = dccp_delta_seqno(ackno, av->av_buf_ackno); + u32 index = av->av_buf_head; - lost_packets -= len; + while (1) { + const u8 len = dccp_ackvec_len(av, index); + const u8 av_state = dccp_ackvec_state(av, index); + /* + * valid packets not yet in av_buf have a reserved + * entry, with a len equal to 0. + */ + if (av_state == DCCP_ACKVEC_STATE_NOT_RECEIVED && + len == 0 && delta == 0) { /* Found our + reserved seat! */ + dccp_pr_debug("Found %llu reserved seat!\n", + (unsigned long long)ackno); + av->av_buf[index] = state; + goto out; + } + /* len == 0 means one packet */ + if (delta < len + 1) + goto out_duplicate; + + delta -= len + 1; + if (++index == DCCP_MAX_ACKVEC_LEN) + index = 0; } } - if (num_cells + dccp_ackvec_buflen(av) >= DCCPAV_MAX_ACKVEC_LEN) { - DCCP_CRIT("Ack Vector buffer overflow: dropping old entries\n"); - av->av_overflow = true; - } - - av->av_buf_head = __ackvec_idx_sub(av->av_buf_head, num_packets); - if (av->av_overflow) - av->av_buf_tail = av->av_buf_head; - - av->av_buf[av->av_buf_head] = state; - av->av_buf_ackno = seqno; + av->av_buf_ackno = ackno; + av->av_time = ktime_get_real(); +out: + return 0; - if (num_packets > 1) - dccp_ackvec_reserve_seats(av, num_packets - 1); +out_duplicate: + /* Duplicate packet */ + dccp_pr_debug("Received a dup or already considered lost " + "packet: %llu\n", (unsigned long long)ackno); + return -EILSEQ; } -/** - * dccp_ackvec_input - Register incoming packet in the buffer - */ -void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb) +static void dccp_ackvec_throw_record(struct dccp_ackvec *av, + struct dccp_ackvec_record *avr) { - u64 seqno = DCCP_SKB_CB(skb)->dccpd_seq; - enum dccp_ackvec_states state = DCCPAV_RECEIVED; + struct dccp_ackvec_record *next; - if (dccp_ackvec_is_empty(av)) { - dccp_ackvec_add_new(av, 1, seqno, state); - av->av_tail_ackno = seqno; + /* sort out vector length */ + if (av->av_buf_head <= avr->avr_ack_ptr) + av->av_vec_len = avr->avr_ack_ptr - av->av_buf_head; + else + av->av_vec_len = DCCP_MAX_ACKVEC_LEN - 1 - + av->av_buf_head + avr->avr_ack_ptr; - } else { - s64 num_packets = dccp_delta_seqno(av->av_buf_ackno, seqno); - u8 *current_head = av->av_buf + av->av_buf_head; - - if (num_packets == 1 && - dccp_ackvec_state(current_head) == state && - dccp_ackvec_runlen(current_head) < DCCPAV_MAX_RUNLEN) { + /* free records */ + list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) { + list_del_init(&avr->avr_node); + dccp_ackvec_record_delete(avr); + } +} - *current_head += 1; - av->av_buf_ackno = seqno; +void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk, + const u64 ackno) +{ + struct dccp_ackvec_record *avr; - } else if (num_packets > 0) { - dccp_ackvec_add_new(av, num_packets, seqno, state); - } else { - dccp_ackvec_update_old(av, num_packets, seqno, state); - } + /* + * If we traverse backwards, it should be faster when we have large + * windows. We will be receiving ACKs for stuff we sent a while back + * -sorbo. + */ + list_for_each_entry_reverse(avr, &av->av_records, avr_node) { + if (ackno == avr->avr_ack_seqno) { + dccp_pr_debug("%s ACK packet 0, len=%d, ack_seqno=%llu, " + "ack_ackno=%llu, ACKED!\n", + dccp_role(sk), 1, + (unsigned long long)avr->avr_ack_seqno, + (unsigned long long)avr->avr_ack_ackno); + dccp_ackvec_throw_record(av, avr); + break; + } else if (avr->avr_ack_seqno > ackno) + break; /* old news */ } } -/** - * dccp_ackvec_clear_state - Perform house-keeping / garbage-collection - * This routine is called when the peer acknowledges the receipt of Ack Vectors - * up to and including @ackno. While based on on section A.3 of RFC 4340, here - * are additional precautions to prevent corrupted buffer state. In particular, - * we use tail_ackno to identify outdated records; it always marks the earliest - * packet of group (2) in 11.4.2. - */ -void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno) +static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, + struct sock *sk, u64 *ackno, + const unsigned char len, + const unsigned char *vector) { - struct dccp_ackvec_record *avr, *next; - u8 runlen_now, eff_runlen; - s64 delta; + unsigned char i; + struct dccp_ackvec_record *avr; - avr = dccp_ackvec_lookup(&av->av_records, ackno); - if (avr == NULL) + /* Check if we actually sent an ACK vector */ + if (list_empty(&av->av_records)) return; - /* - * Deal with outdated acknowledgments: this arises when e.g. there are - * several old records and the acks from the peer come in slowly. In - * that case we may still have records that pre-date tail_ackno. - */ - delta = dccp_delta_seqno(av->av_tail_ackno, avr->avr_ack_ackno); - if (delta < 0) - goto free_records; - /* - * Deal with overlapping Ack Vectors: don't subtract more than the - * number of packets between tail_ackno and ack_ackno. - */ - eff_runlen = delta < avr->avr_ack_runlen ? delta : avr->avr_ack_runlen; - runlen_now = dccp_ackvec_runlen(av->av_buf + avr->avr_ack_ptr); + i = len; /* - * The run length of Ack Vector cells does not decrease over time. If - * the run length is the same as at the time the Ack Vector was sent, we - * free the ack_ptr cell. That cell can however not be freed if the run - * length has increased: in this case we need to move the tail pointer - * backwards (towards higher indices), to its next-oldest neighbour. + * XXX + * I think it might be more efficient to work backwards. See comment on + * rcv_ackno. -sorbo. */ - if (runlen_now > eff_runlen) { + avr = list_entry(av->av_records.next, struct dccp_ackvec_record, avr_node); + while (i--) { + const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; + u64 ackno_end_rl; - av->av_buf[avr->avr_ack_ptr] -= eff_runlen + 1; - av->av_buf_tail = __ackvec_idx_add(avr->avr_ack_ptr, 1); + dccp_set_seqno(&ackno_end_rl, *ackno - rl); - /* This move may not have cleared the overflow flag. */ - if (av->av_overflow) - av->av_overflow = (av->av_buf_head == av->av_buf_tail); - } else { - av->av_buf_tail = avr->avr_ack_ptr; /* - * We have made sure that avr points to a valid cell within the - * buffer. This cell is either older than head, or equals head - * (empty buffer): in both cases we no longer have any overflow. + * If our AVR sequence number is greater than the ack, go + * forward in the AVR list until it is not so. */ - av->av_overflow = 0; - } - - /* - * The peer has acknowledged up to and including ack_ackno. Hence the - * first packet in group (2) of 11.4.2 is the successor of ack_ackno. - */ - av->av_tail_ackno = ADD48(avr->avr_ack_ackno, 1); + list_for_each_entry_from(avr, &av->av_records, avr_node) { + if (!after48(avr->avr_ack_seqno, *ackno)) + goto found; + } + /* End of the av_records list, not found, exit */ + break; +found: + if (between48(avr->avr_ack_seqno, ackno_end_rl, *ackno)) { + const u8 state = *vector & DCCP_ACKVEC_STATE_MASK; + if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { + dccp_pr_debug("%s ACK vector 0, len=%d, " + "ack_seqno=%llu, ack_ackno=%llu, " + "ACKED!\n", + dccp_role(sk), len, + (unsigned long long) + avr->avr_ack_seqno, + (unsigned long long) + avr->avr_ack_ackno); + dccp_ackvec_throw_record(av, avr); + break; + } + /* + * If it wasn't received, continue scanning... we might + * find another one. + */ + } -free_records: - list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) { - list_del(&avr->avr_node); - kmem_cache_free(dccp_ackvec_record_slab, avr); + dccp_set_seqno(ackno, ackno_end_rl - 1); + ++vector; } } -/* - * Routines to keep track of Ack Vectors received in an skb - */ -int dccp_ackvec_parsed_add(struct list_head *head, u8 *vec, u8 len, u8 nonce) +int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, + u64 *ackno, const u8 opt, const u8 *value, const u8 len) { - struct dccp_ackvec_parsed *new = kmalloc(sizeof(*new), GFP_ATOMIC); - - if (new == NULL) - return -ENOBUFS; - new->vec = vec; - new->len = len; - new->nonce = nonce; + if (len > DCCP_SINGLE_OPT_MAXLEN) + return -1; - list_add_tail(&new->node, head); + /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */ + dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk, + ackno, len, value); return 0; } -EXPORT_SYMBOL_GPL(dccp_ackvec_parsed_add); - -void dccp_ackvec_parsed_cleanup(struct list_head *parsed_chunks) -{ - struct dccp_ackvec_parsed *cur, *next; - - list_for_each_entry_safe(cur, next, parsed_chunks, node) - kfree(cur); - INIT_LIST_HEAD(parsed_chunks); -} -EXPORT_SYMBOL_GPL(dccp_ackvec_parsed_cleanup); int __init dccp_ackvec_init(void) { @@ -379,9 +448,10 @@ int __init dccp_ackvec_init(void) if (dccp_ackvec_slab == NULL) goto out_err; - dccp_ackvec_record_slab = kmem_cache_create("dccp_ackvec_record", - sizeof(struct dccp_ackvec_record), - 0, SLAB_HWCACHE_ALIGN, NULL); + dccp_ackvec_record_slab = + kmem_cache_create("dccp_ackvec_record", + sizeof(struct dccp_ackvec_record), + 0, SLAB_HWCACHE_ALIGN, NULL); if (dccp_ackvec_record_slab == NULL) goto out_destroy_slab; diff --git a/trunk/net/dccp/ackvec.h b/trunk/net/dccp/ackvec.h index e2ab0627a5ff..7ea557b7c6b1 100644 --- a/trunk/net/dccp/ackvec.h +++ b/trunk/net/dccp/ackvec.h @@ -3,9 +3,9 @@ /* * net/dccp/ackvec.h * - * An implementation of Ack Vectors for the DCCP protocol - * Copyright (c) 2007 University of Aberdeen, Scotland, UK + * An implementation of the DCCP protocol * Copyright (c) 2005 Arnaldo Carvalho de Melo + * * 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. @@ -13,124 +13,99 @@ #include #include +#include #include #include -/* - * Ack Vector buffer space is static, in multiples of %DCCP_SINGLE_OPT_MAXLEN, - * the maximum size of a single Ack Vector. Setting %DCCPAV_NUM_ACKVECS to 1 - * will be sufficient for most cases of low Ack Ratios, using a value of 2 gives - * more headroom if Ack Ratio is higher or when the sender acknowledges slowly. - * The maximum value is bounded by the u16 types for indices and functions. - */ -#define DCCPAV_NUM_ACKVECS 2 -#define DCCPAV_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * DCCPAV_NUM_ACKVECS) +/* We can spread an ack vector across multiple options */ +#define DCCP_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * 2) /* Estimated minimum average Ack Vector length - used for updating MPS */ #define DCCPAV_MIN_OPTLEN 16 -/* Threshold for coping with large bursts of losses */ -#define DCCPAV_BURST_THRESH (DCCPAV_MAX_ACKVEC_LEN / 8) +#define DCCP_ACKVEC_STATE_RECEIVED 0 +#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6) +#define DCCP_ACKVEC_STATE_NOT_RECEIVED (3 << 6) -enum dccp_ackvec_states { - DCCPAV_RECEIVED = 0x00, - DCCPAV_ECN_MARKED = 0x40, - DCCPAV_RESERVED = 0x80, - DCCPAV_NOT_RECEIVED = 0xC0 -}; -#define DCCPAV_MAX_RUNLEN 0x3F +#define DCCP_ACKVEC_STATE_MASK 0xC0 /* 11000000 */ +#define DCCP_ACKVEC_LEN_MASK 0x3F /* 00111111 */ -static inline u8 dccp_ackvec_runlen(const u8 *cell) -{ - return *cell & DCCPAV_MAX_RUNLEN; -} - -static inline u8 dccp_ackvec_state(const u8 *cell) -{ - return *cell & ~DCCPAV_MAX_RUNLEN; -} - -/** struct dccp_ackvec - Ack Vector main data structure +/** struct dccp_ackvec - ack vector + * + * This data structure is the one defined in RFC 4340, Appendix A. * - * This implements a fixed-size circular buffer within an array and is largely - * based on Appendix A of RFC 4340. + * @av_buf_head - circular buffer head + * @av_buf_tail - circular buffer tail + * @av_buf_ackno - ack # of the most recent packet acknowledgeable in the + * buffer (i.e. %av_buf_head) + * @av_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked + * by the buffer with State 0 * - * @av_buf: circular buffer storage area - * @av_buf_head: head index; begin of live portion in @av_buf - * @av_buf_tail: tail index; first index _after_ the live portion in @av_buf - * @av_buf_ackno: highest seqno of acknowledgeable packet recorded in @av_buf - * @av_tail_ackno: lowest seqno of acknowledgeable packet recorded in @av_buf - * @av_buf_nonce: ECN nonce sums, each covering subsequent segments of up to - * %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf - * @av_overflow: if 1 then buf_head == buf_tail indicates buffer wraparound - * @av_records: list of %dccp_ackvec_record (Ack Vectors sent previously) + * Additionally, the HC-Receiver must keep some information about the + * Ack Vectors it has recently sent. For each packet sent carrying an + * Ack Vector, it remembers four variables: + * + * @av_records - list of dccp_ackvec_record + * @av_ack_nonce - the one-bit sum of the ECN Nonces for all State 0. + * + * @av_time - the time in usecs + * @av_buf - circular buffer of acknowledgeable packets */ struct dccp_ackvec { - u8 av_buf[DCCPAV_MAX_ACKVEC_LEN]; - u16 av_buf_head; - u16 av_buf_tail; - u64 av_buf_ackno:48; - u64 av_tail_ackno:48; - bool av_buf_nonce[DCCPAV_NUM_ACKVECS]; - u8 av_overflow:1; + u64 av_buf_ackno; struct list_head av_records; + ktime_t av_time; + u16 av_buf_head; + u16 av_vec_len; + u8 av_buf_nonce; + u8 av_ack_nonce; + u8 av_buf[DCCP_MAX_ACKVEC_LEN]; }; -/** struct dccp_ackvec_record - Records information about sent Ack Vectors +/** struct dccp_ackvec_record - ack vector record * - * These list entries define the additional information which the HC-Receiver - * keeps about recently-sent Ack Vectors; again refer to RFC 4340, Appendix A. + * ACK vector record as defined in Appendix A of spec. * - * @avr_node: the list node in @av_records - * @avr_ack_seqno: sequence number of the packet the Ack Vector was sent on - * @avr_ack_ackno: the Ack number that this record/Ack Vector refers to - * @avr_ack_ptr: pointer into @av_buf where this record starts - * @avr_ack_runlen: run length of @avr_ack_ptr at the time of sending - * @avr_ack_nonce: the sum of @av_buf_nonce's at the time this record was sent + * The list is sorted by avr_ack_seqno * - * The list as a whole is sorted in descending order by @avr_ack_seqno. + * @avr_node - node in av_records + * @avr_ack_seqno - sequence number of the packet this record was sent on + * @avr_ack_ackno - sequence number being acknowledged + * @avr_ack_ptr - pointer into av_buf where this record starts + * @avr_ack_nonce - av_ack_nonce at the time this record was sent + * @avr_sent_len - lenght of the record in av_buf */ struct dccp_ackvec_record { struct list_head avr_node; - u64 avr_ack_seqno:48; - u64 avr_ack_ackno:48; + u64 avr_ack_seqno; + u64 avr_ack_ackno; u16 avr_ack_ptr; - u8 avr_ack_runlen; - u8 avr_ack_nonce:1; + u16 avr_sent_len; + u8 avr_ack_nonce; }; +struct sock; +struct sk_buff; + extern int dccp_ackvec_init(void); extern void dccp_ackvec_exit(void); extern struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority); extern void dccp_ackvec_free(struct dccp_ackvec *av); -extern void dccp_ackvec_input(struct dccp_ackvec *av, struct sk_buff *skb); -extern int dccp_ackvec_update_records(struct dccp_ackvec *av, u64 seq, u8 sum); -extern void dccp_ackvec_clear_state(struct dccp_ackvec *av, const u64 ackno); -extern u16 dccp_ackvec_buflen(const struct dccp_ackvec *av); +extern int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, + const u64 ackno, const u8 state); -static inline bool dccp_ackvec_is_empty(const struct dccp_ackvec *av) -{ - return av->av_overflow == 0 && av->av_buf_head == av->av_buf_tail; -} +extern void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, + struct sock *sk, const u64 ackno); +extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, + u64 *ackno, const u8 opt, + const u8 *value, const u8 len); -/** - * struct dccp_ackvec_parsed - Record offsets of Ack Vectors in skb - * @vec: start of vector (offset into skb) - * @len: length of @vec - * @nonce: whether @vec had an ECN nonce of 0 or 1 - * @node: FIFO - arranged in descending order of ack_ackno - * This structure is used by CCIDs to access Ack Vectors in a received skb. - */ -struct dccp_ackvec_parsed { - u8 *vec, - len, - nonce:1; - struct list_head node; -}; +extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb); -extern int dccp_ackvec_parsed_add(struct list_head *head, - u8 *vec, u8 len, u8 nonce); -extern void dccp_ackvec_parsed_cleanup(struct list_head *parsed_chunks); +static inline int dccp_ackvec_pending(const struct dccp_ackvec *av) +{ + return av->av_vec_len; +} #endif /* _ACKVEC_H */ diff --git a/trunk/net/dccp/ccids/ccid2.c b/trunk/net/dccp/ccids/ccid2.c index e96d5e810039..6576eae9e779 100644 --- a/trunk/net/dccp/ccids/ccid2.c +++ b/trunk/net/dccp/ccids/ccid2.c @@ -246,6 +246,68 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len) #endif } +/* XXX Lame code duplication! + * returns -1 if none was found. + * else returns the next offset to use in the function call. + */ +static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset, + unsigned char **vec, unsigned char *veclen) +{ + const struct dccp_hdr *dh = dccp_hdr(skb); + unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); + unsigned char *opt_ptr; + const unsigned char *opt_end = (unsigned char *)dh + + (dh->dccph_doff * 4); + unsigned char opt, len; + unsigned char *value; + + BUG_ON(offset < 0); + options += offset; + opt_ptr = options; + if (opt_ptr >= opt_end) + return -1; + + while (opt_ptr != opt_end) { + opt = *opt_ptr++; + len = 0; + value = NULL; + + /* Check if this isn't a single byte option */ + if (opt > DCCPO_MAX_RESERVED) { + if (opt_ptr == opt_end) + goto out_invalid_option; + + len = *opt_ptr++; + if (len < 3) + goto out_invalid_option; + /* + * Remove the type and len fields, leaving + * just the value size + */ + len -= 2; + value = opt_ptr; + opt_ptr += len; + + if (opt_ptr > opt_end) + goto out_invalid_option; + } + + switch (opt) { + case DCCPO_ACK_VECTOR_0: + case DCCPO_ACK_VECTOR_1: + *vec = value; + *veclen = len; + return offset + (opt_ptr - options); + } + } + + return -1; + +out_invalid_option: + DCCP_BUG("Invalid option - this should not happen (previous parsing)!"); + return -1; +} + /** * ccid2_rtt_estimator - Sample RTT and compute RTO using RFC2988 algorithm * This code is almost identical with TCP's tcp_rtt_estimator(), since @@ -370,28 +432,16 @@ static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp) ccid2_change_l_ack_ratio(sk, hc->tx_cwnd); } -static int ccid2_hc_tx_parse_options(struct sock *sk, u8 packet_type, - u8 option, u8 *optval, u8 optlen) -{ - struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - - switch (option) { - case DCCPO_ACK_VECTOR_0: - case DCCPO_ACK_VECTOR_1: - return dccp_ackvec_parsed_add(&hc->tx_av_chunks, optval, optlen, - option - DCCPO_ACK_VECTOR_0); - } - return 0; -} - static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); const bool sender_was_blocked = ccid2_cwnd_network_limited(hc); - struct dccp_ackvec_parsed *avp; u64 ackno, seqno; struct ccid2_seq *seqp; + unsigned char *vector; + unsigned char veclen; + int offset = 0; int done = 0; unsigned int maxincr = 0; @@ -425,12 +475,17 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) } /* check forward path congestion */ - if (dccp_packet_without_ack(skb)) - return; - /* still didn't send out new data packets */ if (hc->tx_seqh == hc->tx_seqt) - goto done; + return; + + switch (DCCP_SKB_CB(skb)->dccpd_type) { + case DCCP_PKT_ACK: + case DCCP_PKT_DATAACK: + break; + default: + return; + } ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; if (after48(ackno, hc->tx_high_ack)) @@ -454,16 +509,16 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) maxincr = DIV_ROUND_UP(dp->dccps_l_ack_ratio, 2); /* go through all ack vectors */ - list_for_each_entry(avp, &hc->tx_av_chunks, node) { + while ((offset = ccid2_ackvector(sk, skb, offset, + &vector, &veclen)) != -1) { /* go through this ack vector */ - for (; avp->len--; avp->vec++) { - u64 ackno_end_rl = SUB48(ackno, - dccp_ackvec_runlen(avp->vec)); + while (veclen--) { + const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; + u64 ackno_end_rl = SUB48(ackno, rl); - ccid2_pr_debug("ackvec %llu |%u,%u|\n", + ccid2_pr_debug("ackvec start:%llu end:%llu\n", (unsigned long long)ackno, - dccp_ackvec_state(avp->vec) >> 6, - dccp_ackvec_runlen(avp->vec)); + (unsigned long long)ackno_end_rl); /* if the seqno we are analyzing is larger than the * current ackno, then move towards the tail of our * seqnos. @@ -482,15 +537,17 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) * run length */ while (between48(seqp->ccid2s_seq,ackno_end_rl,ackno)) { - const u8 state = dccp_ackvec_state(avp->vec); + const u8 state = *vector & + DCCP_ACKVEC_STATE_MASK; /* new packet received or marked */ - if (state != DCCPAV_NOT_RECEIVED && + if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED && !seqp->ccid2s_acked) { - if (state == DCCPAV_ECN_MARKED) + if (state == + DCCP_ACKVEC_STATE_ECN_MARKED) { ccid2_congestion_event(sk, seqp); - else + } else ccid2_new_ack(sk, seqp, &maxincr); @@ -509,6 +566,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) break; ackno = SUB48(ackno_end_rl, 1); + vector++; } if (done) break; @@ -576,11 +634,10 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) sk_stop_timer(sk, &hc->tx_rtotimer); else sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); -done: + /* check if incoming Acks allow pending packets to be sent */ if (sender_was_blocked && !ccid2_cwnd_network_limited(hc)) tasklet_schedule(&dccp_sk(sk)->dccps_xmitlet); - dccp_ackvec_parsed_cleanup(&hc->tx_av_chunks); } static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) @@ -609,7 +666,6 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) hc->tx_last_cong = ccid2_time_stamp; setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, (unsigned long)sk); - INIT_LIST_HEAD(&hc->tx_av_chunks); return 0; } @@ -643,17 +699,16 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) } struct ccid_operations ccid2_ops = { - .ccid_id = DCCPC_CCID2, - .ccid_name = "TCP-like", - .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock), - .ccid_hc_tx_init = ccid2_hc_tx_init, - .ccid_hc_tx_exit = ccid2_hc_tx_exit, - .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet, - .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent, - .ccid_hc_tx_parse_options = ccid2_hc_tx_parse_options, - .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv, - .ccid_hc_rx_obj_size = sizeof(struct ccid2_hc_rx_sock), - .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv, + .ccid_id = DCCPC_CCID2, + .ccid_name = "TCP-like", + .ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock), + .ccid_hc_tx_init = ccid2_hc_tx_init, + .ccid_hc_tx_exit = ccid2_hc_tx_exit, + .ccid_hc_tx_send_packet = ccid2_hc_tx_send_packet, + .ccid_hc_tx_packet_sent = ccid2_hc_tx_packet_sent, + .ccid_hc_tx_packet_recv = ccid2_hc_tx_packet_recv, + .ccid_hc_rx_obj_size = sizeof(struct ccid2_hc_rx_sock), + .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv, }; #ifdef CONFIG_IP_DCCP_CCID2_DEBUG diff --git a/trunk/net/dccp/ccids/ccid2.h b/trunk/net/dccp/ccids/ccid2.h index e9985dafc2c7..25cb6b216eda 100644 --- a/trunk/net/dccp/ccids/ccid2.h +++ b/trunk/net/dccp/ccids/ccid2.h @@ -55,7 +55,6 @@ struct ccid2_seq { * @tx_rtt_seq: to decay RTTVAR at most once per flight * @tx_rpseq: last consecutive seqno * @tx_rpdupack: dupacks since rpseq - * @tx_av_chunks: list of Ack Vectors received on current skb */ struct ccid2_hc_tx_sock { u32 tx_cwnd; @@ -80,7 +79,6 @@ struct ccid2_hc_tx_sock { int tx_rpdupack; u32 tx_last_cong; u64 tx_high_ack; - struct list_head tx_av_chunks; }; static inline bool ccid2_cwnd_network_limited(struct ccid2_hc_tx_sock *hc) diff --git a/trunk/net/dccp/dccp.h b/trunk/net/dccp/dccp.h index 19fafd597465..a8ed459508b2 100644 --- a/trunk/net/dccp/dccp.h +++ b/trunk/net/dccp/dccp.h @@ -457,15 +457,12 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq) dp->dccps_awh = dp->dccps_gss; } -static inline int dccp_ackvec_pending(const struct sock *sk) -{ - return dccp_sk(sk)->dccps_hc_rx_ackvec != NULL && - !dccp_ackvec_is_empty(dccp_sk(sk)->dccps_hc_rx_ackvec); -} - static inline int dccp_ack_pending(const struct sock *sk) { - return dccp_ackvec_pending(sk) || inet_csk_ack_scheduled(sk); + const struct dccp_sock *dp = dccp_sk(sk); + return (dp->dccps_hc_rx_ackvec != NULL && + dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) || + inet_csk_ack_scheduled(sk); } extern int dccp_feat_finalise_settings(struct dccp_sock *dp); diff --git a/trunk/net/dccp/input.c b/trunk/net/dccp/input.c index 7d230d14ce22..265985370fa1 100644 --- a/trunk/net/dccp/input.c +++ b/trunk/net/dccp/input.c @@ -160,15 +160,13 @@ static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) dccp_time_wait(sk, DCCP_TIME_WAIT, 0); } -static void dccp_handle_ackvec_processing(struct sock *sk, struct sk_buff *skb) +static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) { - struct dccp_ackvec *av = dccp_sk(sk)->dccps_hc_rx_ackvec; + struct dccp_sock *dp = dccp_sk(sk); - if (av == NULL) - return; - if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) - dccp_ackvec_clear_state(av, DCCP_SKB_CB(skb)->dccpd_ack_seq); - dccp_ackvec_input(av, skb); + if (dp->dccps_hc_rx_ackvec != NULL) + dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk, + DCCP_SKB_CB(skb)->dccpd_ack_seq); } static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb) @@ -367,13 +365,22 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct dccp_hdr *dh, const unsigned len) { + struct dccp_sock *dp = dccp_sk(sk); + if (dccp_check_seqno(sk, skb)) goto discard; if (dccp_parse_options(sk, NULL, skb)) return 1; - dccp_handle_ackvec_processing(sk, skb); + if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) + dccp_event_ack_recv(sk, skb); + + if (dp->dccps_hc_rx_ackvec != NULL && + dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, + DCCP_SKB_CB(skb)->dccpd_seq, + DCCP_ACKVEC_STATE_RECEIVED)) + goto discard; dccp_deliver_input_to_ccids(sk, skb); return __dccp_rcv_established(sk, skb, dh, len); @@ -625,7 +632,15 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, if (dccp_parse_options(sk, NULL, skb)) return 1; - dccp_handle_ackvec_processing(sk, skb); + if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) + dccp_event_ack_recv(sk, skb); + + if (dp->dccps_hc_rx_ackvec != NULL && + dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, + DCCP_SKB_CB(skb)->dccpd_seq, + DCCP_ACKVEC_STATE_RECEIVED)) + goto discard; + dccp_deliver_input_to_ccids(sk, skb); } diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index 45a434f94169..3f69ea114829 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -462,12 +462,15 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, { struct rtable *rt; struct flowi fl = { .oif = skb_rtable(skb)->rt_iif, - .fl4_dst = ip_hdr(skb)->saddr, - .fl4_src = ip_hdr(skb)->daddr, - .fl4_tos = RT_CONN_FLAGS(sk), + .nl_u = { .ip4_u = + { .daddr = ip_hdr(skb)->saddr, + .saddr = ip_hdr(skb)->daddr, + .tos = RT_CONN_FLAGS(sk) } }, .proto = sk->sk_protocol, - .fl_ip_sport = dccp_hdr(skb)->dccph_dport, - .fl_ip_dport = dccp_hdr(skb)->dccph_sport + .uli_u = { .ports = + { .sport = dccp_hdr(skb)->dccph_dport, + .dport = dccp_hdr(skb)->dccph_sport } + } }; security_skb_classify_flow(skb, &fl); diff --git a/trunk/net/dccp/options.c b/trunk/net/dccp/options.c index f06ffcfc8d71..cd3061813009 100644 --- a/trunk/net/dccp/options.c +++ b/trunk/net/dccp/options.c @@ -54,6 +54,7 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, struct dccp_sock *dp = dccp_sk(sk); const struct dccp_hdr *dh = dccp_hdr(skb); const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type; + u64 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); unsigned char *opt_ptr = options; const unsigned char *opt_end = (unsigned char *)dh + @@ -128,6 +129,14 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, if (rc) goto out_featneg_failed; break; + case DCCPO_ACK_VECTOR_0: + case DCCPO_ACK_VECTOR_1: + if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */ + break; + if (dp->dccps_hc_rx_ackvec != NULL && + dccp_ackvec_parse(sk, skb, &ackno, opt, value, len)) + goto out_invalid_option; + break; case DCCPO_TIMESTAMP: if (len != 4) goto out_invalid_option; @@ -217,16 +226,6 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, pkt_type, opt, value, len)) goto out_invalid_option; break; - case DCCPO_ACK_VECTOR_0: - case DCCPO_ACK_VECTOR_1: - if (dccp_packet_without_ack(skb)) /* RFC 4340, 11.4 */ - break; - /* - * Ack vectors are processed by the TX CCID if it is - * interested. The RX CCID need not parse Ack Vectors, - * since it is only interested in clearing old state. - * Fall through. - */ case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC: if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, pkt_type, opt, value, len)) @@ -341,7 +340,6 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time) return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4; } -/* FIXME: This function is currently not used anywhere */ int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed_time) { const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time); @@ -426,83 +424,6 @@ static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp, return 0; } -static int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) -{ - struct dccp_sock *dp = dccp_sk(sk); - struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; - struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); - const u16 buflen = dccp_ackvec_buflen(av); - /* Figure out how many options do we need to represent the ackvec */ - const u8 nr_opts = DIV_ROUND_UP(buflen, DCCP_SINGLE_OPT_MAXLEN); - u16 len = buflen + 2 * nr_opts; - u8 i, nonce = 0; - const unsigned char *tail, *from; - unsigned char *to; - - if (dcb->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) { - DCCP_WARN("Lacking space for %u bytes on %s packet\n", len, - dccp_packet_name(dcb->dccpd_type)); - return -1; - } - /* - * Since Ack Vectors are variable-length, we can not always predict - * their size. To catch exception cases where the space is running out - * on the skb, a separate Sync is scheduled to carry the Ack Vector. - */ - if (len > DCCPAV_MIN_OPTLEN && - len + dcb->dccpd_opt_len + skb->len > dp->dccps_mss_cache) { - DCCP_WARN("No space left for Ack Vector (%u) on skb (%u+%u), " - "MPS=%u ==> reduce payload size?\n", len, skb->len, - dcb->dccpd_opt_len, dp->dccps_mss_cache); - dp->dccps_sync_scheduled = 1; - return 0; - } - dcb->dccpd_opt_len += len; - - to = skb_push(skb, len); - len = buflen; - from = av->av_buf + av->av_buf_head; - tail = av->av_buf + DCCPAV_MAX_ACKVEC_LEN; - - for (i = 0; i < nr_opts; ++i) { - int copylen = len; - - if (len > DCCP_SINGLE_OPT_MAXLEN) - copylen = DCCP_SINGLE_OPT_MAXLEN; - - /* - * RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via - * its type; ack_nonce is the sum of all individual buf_nonce's. - */ - nonce ^= av->av_buf_nonce[i]; - - *to++ = DCCPO_ACK_VECTOR_0 + av->av_buf_nonce[i]; - *to++ = copylen + 2; - - /* Check if buf_head wraps */ - if (from + copylen > tail) { - const u16 tailsize = tail - from; - - memcpy(to, from, tailsize); - to += tailsize; - len -= tailsize; - copylen -= tailsize; - from = av->av_buf; - } - - memcpy(to, from, copylen); - from += copylen; - to += copylen; - len -= copylen; - } - /* - * Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340. - */ - if (dccp_ackvec_update_records(av, dcb->dccpd_seq, nonce)) - return -ENOBUFS; - return 0; -} - /** * dccp_insert_option_mandatory - Mandatory option (5.8.2) * Note that since we are using skb_push, this function needs to be called @@ -598,7 +519,8 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb) if (dccp_insert_option_timestamp(skb)) return -1; - } else if (dccp_ackvec_pending(sk) && + } else if (dp->dccps_hc_rx_ackvec != NULL && + dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) && dccp_insert_option_ackvec(sk, skb)) { return -1; } diff --git a/trunk/net/dccp/output.c b/trunk/net/dccp/output.c index d96dd9d362ae..45b91853f5ae 100644 --- a/trunk/net/dccp/output.c +++ b/trunk/net/dccp/output.c @@ -283,15 +283,6 @@ static void dccp_xmit_packet(struct sock *sk) * any local drop will eventually be reported via receiver feedback. */ ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); - - /* - * If the CCID needs to transfer additional header options out-of-band - * (e.g. Ack Vectors or feature-negotiation options), it activates this - * flag to schedule a Sync. The Sync will automatically incorporate all - * currently pending header options, thus clearing the backlog. - */ - if (dp->dccps_sync_scheduled) - dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC); } /** @@ -645,12 +636,6 @@ void dccp_send_sync(struct sock *sk, const u64 ackno, DCCP_SKB_CB(skb)->dccpd_type = pkt_type; DCCP_SKB_CB(skb)->dccpd_ack_seq = ackno; - /* - * Clear the flag in case the Sync was scheduled for out-of-band data, - * such as carrying a long Ack Vector. - */ - dccp_sk(sk)->dccps_sync_scheduled = 0; - dccp_transmit_skb(sk, skb); } diff --git a/trunk/net/decnet/af_decnet.c b/trunk/net/decnet/af_decnet.c index 9ecef9968c39..d6b93d19790f 100644 --- a/trunk/net/decnet/af_decnet.c +++ b/trunk/net/decnet/af_decnet.c @@ -155,7 +155,7 @@ static const struct proto_ops dn_proto_ops; static DEFINE_RWLOCK(dn_hash_lock); static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE]; static struct hlist_head dn_wild_sk; -static atomic_long_t decnet_memory_allocated; +static atomic_t decnet_memory_allocated; static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags); static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags); @@ -1848,7 +1848,7 @@ unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu) { unsigned mss = 230 - DN_MAX_NSP_DATA_HEADER; if (dev) { - struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; mtu -= LL_RESERVED_SPACE(dev); if (dn_db->use_long) mtu -= 21; diff --git a/trunk/net/decnet/dn_dev.c b/trunk/net/decnet/dn_dev.c index 0ba15633c418..4c409b46aa35 100644 --- a/trunk/net/decnet/dn_dev.c +++ b/trunk/net/decnet/dn_dev.c @@ -267,7 +267,7 @@ static int dn_forwarding_proc(ctl_table *table, int write, if (table->extra1 == NULL) return -EINVAL; - dn_db = rcu_dereference_raw(dev->dn_ptr); + dn_db = dev->dn_ptr; old = dn_db->parms.forwarding; err = proc_dointvec(table, write, buffer, lenp, ppos); @@ -332,19 +332,14 @@ static struct dn_ifaddr *dn_dev_alloc_ifa(void) return ifa; } -static void dn_dev_free_ifa_rcu(struct rcu_head *head) +static __inline__ void dn_dev_free_ifa(struct dn_ifaddr *ifa) { - kfree(container_of(head, struct dn_ifaddr, rcu)); + kfree(ifa); } -static void dn_dev_free_ifa(struct dn_ifaddr *ifa) +static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int destroy) { - call_rcu(&ifa->rcu, dn_dev_free_ifa_rcu); -} - -static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr __rcu **ifap, int destroy) -{ - struct dn_ifaddr *ifa1 = rtnl_dereference(*ifap); + struct dn_ifaddr *ifa1 = *ifap; unsigned char mac_addr[6]; struct net_device *dev = dn_db->dev; @@ -378,9 +373,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) ASSERT_RTNL(); /* Check for duplicates */ - for (ifa1 = rtnl_dereference(dn_db->ifa_list); - ifa1 != NULL; - ifa1 = rtnl_dereference(ifa1->ifa_next)) { + for(ifa1 = dn_db->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { if (ifa1->ifa_local == ifa->ifa_local) return -EEXIST; } @@ -393,7 +386,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) } ifa->ifa_next = dn_db->ifa_list; - rcu_assign_pointer(dn_db->ifa_list, ifa); + dn_db->ifa_list = ifa; dn_ifaddr_notify(RTM_NEWADDR, ifa); blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); @@ -403,7 +396,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) static int dn_dev_set_ifa(struct net_device *dev, struct dn_ifaddr *ifa) { - struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; int rv; if (dn_db == NULL) { @@ -432,8 +425,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr; struct dn_dev *dn_db; struct net_device *dev; - struct dn_ifaddr *ifa = NULL; - struct dn_ifaddr __rcu **ifap = NULL; + struct dn_ifaddr *ifa = NULL, **ifap = NULL; int ret = 0; if (copy_from_user(ifr, arg, DN_IFREQ_SIZE)) @@ -462,10 +454,8 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg) goto done; } - if ((dn_db = rtnl_dereference(dev->dn_ptr)) != NULL) { - for (ifap = &dn_db->ifa_list; - (ifa = rtnl_dereference(*ifap)) != NULL; - ifap = &ifa->ifa_next) + if ((dn_db = dev->dn_ptr) != NULL) { + for (ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) if (strcmp(ifr->ifr_name, ifa->ifa_label) == 0) break; } @@ -568,7 +558,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex) dev = __dev_get_by_index(&init_net, ifindex); if (dev) - dn_dev = rtnl_dereference(dev->dn_ptr); + dn_dev = dev->dn_ptr; return dn_dev; } @@ -586,8 +576,7 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct nlattr *tb[IFA_MAX+1]; struct dn_dev *dn_db; struct ifaddrmsg *ifm; - struct dn_ifaddr *ifa; - struct dn_ifaddr __rcu **ifap; + struct dn_ifaddr *ifa, **ifap; int err = -EINVAL; if (!net_eq(net, &init_net)) @@ -603,9 +592,7 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) goto errout; err = -EADDRNOTAVAIL; - for (ifap = &dn_db->ifa_list; - (ifa = rtnl_dereference(*ifap)) != NULL; - ifap = &ifa->ifa_next) { + for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) { if (tb[IFA_LOCAL] && nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2)) continue; @@ -645,7 +632,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if ((dev = __dev_get_by_index(&init_net, ifm->ifa_index)) == NULL) return -ENODEV; - if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) { + if ((dn_db = dev->dn_ptr) == NULL) { dn_db = dn_dev_create(dev, &err); if (!dn_db) return err; @@ -761,11 +748,11 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) skip_naddr = 0; } - if ((dn_db = rtnl_dereference(dev->dn_ptr)) == NULL) + if ((dn_db = dev->dn_ptr) == NULL) goto cont; - for (ifa = rtnl_dereference(dn_db->ifa_list), dn_idx = 0; ifa; - ifa = rtnl_dereference(ifa->ifa_next), dn_idx++) { + for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; + ifa = ifa->ifa_next, dn_idx++) { if (dn_idx < skip_naddr) continue; @@ -786,22 +773,21 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) static int dn_dev_get_first(struct net_device *dev, __le16 *addr) { - struct dn_dev *dn_db; + struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; struct dn_ifaddr *ifa; int rv = -ENODEV; - rcu_read_lock(); - dn_db = rcu_dereference(dev->dn_ptr); if (dn_db == NULL) goto out; - ifa = rcu_dereference(dn_db->ifa_list); + rtnl_lock(); + ifa = dn_db->ifa_list; if (ifa != NULL) { *addr = ifa->ifa_local; rv = 0; } + rtnl_unlock(); out: - rcu_read_unlock(); return rv; } @@ -837,7 +823,7 @@ static void dn_send_endnode_hello(struct net_device *dev, struct dn_ifaddr *ifa) struct endnode_hello_message *msg; struct sk_buff *skb = NULL; __le16 *pktlen; - struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); + struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; if ((skb = dn_alloc_skb(NULL, sizeof(*msg), GFP_ATOMIC)) == NULL) return; @@ -903,7 +889,7 @@ static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db, struct dn static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) { int n; - struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; struct dn_neigh *dn = (struct dn_neigh *)dn_db->router; struct sk_buff *skb; size_t size; @@ -974,7 +960,7 @@ static void dn_send_router_hello(struct net_device *dev, struct dn_ifaddr *ifa) static void dn_send_brd_hello(struct net_device *dev, struct dn_ifaddr *ifa) { - struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); + struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; if (dn_db->parms.forwarding == 0) dn_send_endnode_hello(dev, ifa); @@ -1012,7 +998,7 @@ static void dn_send_ptp_hello(struct net_device *dev, struct dn_ifaddr *ifa) static int dn_eth_up(struct net_device *dev) { - struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; if (dn_db->parms.forwarding == 0) dev_mc_add(dev, dn_rt_all_end_mcast); @@ -1026,7 +1012,7 @@ static int dn_eth_up(struct net_device *dev) static void dn_eth_down(struct net_device *dev) { - struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; if (dn_db->parms.forwarding == 0) dev_mc_del(dev, dn_rt_all_end_mcast); @@ -1039,16 +1025,12 @@ static void dn_dev_set_timer(struct net_device *dev); static void dn_dev_timer_func(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; - struct dn_dev *dn_db; + struct dn_dev *dn_db = dev->dn_ptr; struct dn_ifaddr *ifa; - rcu_read_lock(); - dn_db = rcu_dereference(dev->dn_ptr); if (dn_db->t3 <= dn_db->parms.t2) { if (dn_db->parms.timer3) { - for (ifa = rcu_dereference(dn_db->ifa_list); - ifa; - ifa = rcu_dereference(ifa->ifa_next)) { + for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { if (!(ifa->ifa_flags & IFA_F_SECONDARY)) dn_db->parms.timer3(dev, ifa); } @@ -1057,13 +1039,13 @@ static void dn_dev_timer_func(unsigned long arg) } else { dn_db->t3 -= dn_db->parms.t2; } - rcu_read_unlock(); + dn_dev_set_timer(dev); } static void dn_dev_set_timer(struct net_device *dev) { - struct dn_dev *dn_db = rcu_dereference_raw(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; if (dn_db->parms.t2 > dn_db->parms.t3) dn_db->parms.t2 = dn_db->parms.t3; @@ -1095,8 +1077,8 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err) return NULL; memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); - - rcu_assign_pointer(dev->dn_ptr, dn_db); + smp_wmb(); + dev->dn_ptr = dn_db; dn_db->dev = dev; init_timer(&dn_db->timer); @@ -1104,7 +1086,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err) dn_db->neigh_parms = neigh_parms_alloc(dev, &dn_neigh_table); if (!dn_db->neigh_parms) { - rcu_assign_pointer(dev->dn_ptr, NULL); + dev->dn_ptr = NULL; kfree(dn_db); return NULL; } @@ -1143,7 +1125,7 @@ void dn_dev_up(struct net_device *dev) struct dn_ifaddr *ifa; __le16 addr = decnet_address; int maybe_default = 0; - struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); + struct dn_dev *dn_db = (struct dn_dev *)dev->dn_ptr; if ((dev->type != ARPHRD_ETHER) && (dev->type != ARPHRD_LOOPBACK)) return; @@ -1194,7 +1176,7 @@ void dn_dev_up(struct net_device *dev) static void dn_dev_delete(struct net_device *dev) { - struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; if (dn_db == NULL) return; @@ -1222,13 +1204,13 @@ static void dn_dev_delete(struct net_device *dev) void dn_dev_down(struct net_device *dev) { - struct dn_dev *dn_db = rtnl_dereference(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; struct dn_ifaddr *ifa; if (dn_db == NULL) return; - while ((ifa = rtnl_dereference(dn_db->ifa_list)) != NULL) { + while((ifa = dn_db->ifa_list) != NULL) { dn_dev_del_ifa(dn_db, &dn_db->ifa_list, 0); dn_dev_free_ifa(ifa); } @@ -1288,7 +1270,7 @@ static inline int is_dn_dev(struct net_device *dev) } static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(RCU) + __acquires(rcu) { int i; struct net_device *dev; @@ -1331,7 +1313,7 @@ static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) } static void dn_dev_seq_stop(struct seq_file *seq, void *v) - __releases(RCU) + __releases(rcu) { rcu_read_unlock(); } @@ -1358,7 +1340,7 @@ static int dn_dev_seq_show(struct seq_file *seq, void *v) struct net_device *dev = v; char peer_buf[DN_ASCBUF_LEN]; char router_buf[DN_ASCBUF_LEN]; - struct dn_dev *dn_db = rcu_dereference(dev->dn_ptr); + struct dn_dev *dn_db = dev->dn_ptr; seq_printf(seq, "%-8s %1s %04u %04u %04lu %04lu" " %04hu %03d %02x %-10s %-7s %-7s\n", diff --git a/trunk/net/decnet/dn_fib.c b/trunk/net/decnet/dn_fib.c index 0ef0a81bcd72..4ab96c15166d 100644 --- a/trunk/net/decnet/dn_fib.c +++ b/trunk/net/decnet/dn_fib.c @@ -610,12 +610,10 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa) /* Scan device list */ rcu_read_lock(); for_each_netdev_rcu(&init_net, dev) { - dn_db = rcu_dereference(dev->dn_ptr); + dn_db = dev->dn_ptr; if (dn_db == NULL) continue; - for (ifa2 = rcu_dereference(dn_db->ifa_list); - ifa2 != NULL; - ifa2 = rcu_dereference(ifa2->ifa_next)) { + for(ifa2 = dn_db->ifa_list; ifa2; ifa2 = ifa2->ifa_next) { if (ifa2->ifa_local == ifa->ifa_local) { found_it = 1; break; diff --git a/trunk/net/decnet/dn_neigh.c b/trunk/net/decnet/dn_neigh.c index 602dade7e9a3..a085dbcf5c7f 100644 --- a/trunk/net/decnet/dn_neigh.c +++ b/trunk/net/decnet/dn_neigh.c @@ -391,7 +391,7 @@ int dn_neigh_router_hello(struct sk_buff *skb) write_lock(&neigh->lock); neigh->used = jiffies; - dn_db = rcu_dereference(neigh->dev->dn_ptr); + dn_db = (struct dn_dev *)neigh->dev->dn_ptr; if (!(neigh->nud_state & NUD_PERMANENT)) { neigh->updated = jiffies; diff --git a/trunk/net/decnet/dn_route.c b/trunk/net/decnet/dn_route.c index 8280e43c8861..df0f3e54ff8a 100644 --- a/trunk/net/decnet/dn_route.c +++ b/trunk/net/decnet/dn_route.c @@ -93,7 +93,7 @@ struct dn_rt_hash_bucket { - struct dn_route __rcu *chain; + struct dn_route *chain; spinlock_t lock; }; @@ -157,17 +157,15 @@ static inline void dnrt_drop(struct dn_route *rt) static void dn_dst_check_expire(unsigned long dummy) { int i; - struct dn_route *rt; - struct dn_route __rcu **rtp; + struct dn_route *rt, **rtp; unsigned long now = jiffies; unsigned long expire = 120 * HZ; - for (i = 0; i <= dn_rt_hash_mask; i++) { + for(i = 0; i <= dn_rt_hash_mask; i++) { rtp = &dn_rt_hash_table[i].chain; spin_lock(&dn_rt_hash_table[i].lock); - while ((rt = rcu_dereference_protected(*rtp, - lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) { + while((rt=*rtp) != NULL) { if (atomic_read(&rt->dst.__refcnt) || (now - rt->dst.lastuse) < expire) { rtp = &rt->dst.dn_next; @@ -188,19 +186,17 @@ static void dn_dst_check_expire(unsigned long dummy) static int dn_dst_gc(struct dst_ops *ops) { - struct dn_route *rt; - struct dn_route __rcu **rtp; + struct dn_route *rt, **rtp; int i; unsigned long now = jiffies; unsigned long expire = 10 * HZ; - for (i = 0; i <= dn_rt_hash_mask; i++) { + for(i = 0; i <= dn_rt_hash_mask; i++) { spin_lock_bh(&dn_rt_hash_table[i].lock); rtp = &dn_rt_hash_table[i].chain; - while ((rt = rcu_dereference_protected(*rtp, - lockdep_is_held(&dn_rt_hash_table[i].lock))) != NULL) { + while((rt=*rtp) != NULL) { if (atomic_read(&rt->dst.__refcnt) || (now - rt->dst.lastuse) < expire) { rtp = &rt->dst.dn_next; @@ -231,7 +227,7 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) { u32 min_mtu = 230; struct dn_dev *dn = dst->neighbour ? - rcu_dereference_raw(dst->neighbour->dev->dn_ptr) : NULL; + (struct dn_dev *)dst->neighbour->dev->dn_ptr : NULL; if (dn && dn->use_long == 0) min_mtu -= 6; @@ -271,25 +267,23 @@ static void dn_dst_link_failure(struct sk_buff *skb) static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) { - return ((fl1->fld_dst ^ fl2->fld_dst) | - (fl1->fld_src ^ fl2->fld_src) | + return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | + (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | (fl1->mark ^ fl2->mark) | - (fl1->fld_scope ^ fl2->fld_scope) | + (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | (fl1->oif ^ fl2->oif) | (fl1->iif ^ fl2->iif)) == 0; } static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) { - struct dn_route *rth; - struct dn_route __rcu **rthp; + struct dn_route *rth, **rthp; unsigned long now = jiffies; rthp = &dn_rt_hash_table[hash].chain; spin_lock_bh(&dn_rt_hash_table[hash].lock); - while ((rth = rcu_dereference_protected(*rthp, - lockdep_is_held(&dn_rt_hash_table[hash].lock))) != NULL) { + while((rth = *rthp) != NULL) { if (compare_keys(&rth->fl, &rt->fl)) { /* Put it first */ *rthp = rth->dst.dn_next; @@ -321,15 +315,15 @@ static void dn_run_flush(unsigned long dummy) int i; struct dn_route *rt, *next; - for (i = 0; i < dn_rt_hash_mask; i++) { + for(i = 0; i < dn_rt_hash_mask; i++) { spin_lock_bh(&dn_rt_hash_table[i].lock); - if ((rt = xchg((struct dn_route **)&dn_rt_hash_table[i].chain, NULL)) == NULL) + if ((rt = xchg(&dn_rt_hash_table[i].chain, NULL)) == NULL) goto nothing_to_declare; - for(; rt; rt = next) { - next = rcu_dereference_raw(rt->dst.dn_next); - RCU_INIT_POINTER(rt->dst.dn_next, NULL); + for(; rt; rt=next) { + next = rt->dst.dn_next; + rt->dst.dn_next = NULL; dst_free((struct dst_entry *)rt); } @@ -464,16 +458,15 @@ static int dn_return_long(struct sk_buff *skb) */ static int dn_route_rx_packet(struct sk_buff *skb) { - struct dn_skb_cb *cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); int err; if ((err = dn_route_input(skb)) == 0) return dst_input(skb); - cb = DN_SKB_CB(skb); if (decnet_debug_level & 4) { char *devname = skb->dev ? skb->dev->name : "???"; - + struct dn_skb_cb *cb = DN_SKB_CB(skb); printk(KERN_DEBUG "DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n", (int)cb->rt_flags, devname, skb->len, @@ -580,7 +573,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type struct dn_skb_cb *cb; unsigned char flags = 0; __u16 len = le16_to_cpu(*(__le16 *)skb->data); - struct dn_dev *dn = rcu_dereference(dev->dn_ptr); + struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr; unsigned char padlen = 0; if (!net_eq(dev_net(dev), &init_net)) @@ -735,7 +728,7 @@ static int dn_forward(struct sk_buff *skb) { struct dn_skb_cb *cb = DN_SKB_CB(skb); struct dst_entry *dst = skb_dst(skb); - struct dn_dev *dn_db = rcu_dereference(dst->dev->dn_ptr); + struct dn_dev *dn_db = dst->dev->dn_ptr; struct dn_route *rt; struct neighbour *neigh = dst->neighbour; int header_len; @@ -842,16 +835,13 @@ static inline int dn_match_addr(__le16 addr1, __le16 addr2) static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int scope) { __le16 saddr = 0; - struct dn_dev *dn_db; + struct dn_dev *dn_db = dev->dn_ptr; struct dn_ifaddr *ifa; int best_match = 0; int ret; - rcu_read_lock(); - dn_db = rcu_dereference(dev->dn_ptr); - for (ifa = rcu_dereference(dn_db->ifa_list); - ifa != NULL; - ifa = rcu_dereference(ifa->ifa_next)) { + read_lock(&dev_base_lock); + for(ifa = dn_db->ifa_list; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_scope > scope) continue; if (!daddr) { @@ -864,7 +854,7 @@ static __le16 dnet_select_source(const struct net_device *dev, __le16 daddr, int if (best_match == 0) saddr = ifa->ifa_local; } - rcu_read_unlock(); + read_unlock(&dev_base_lock); return saddr; } @@ -882,9 +872,11 @@ static inline __le16 dn_fib_rules_map_destination(__le16 daddr, struct dn_fib_re static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *oldflp, int try_hard) { - struct flowi fl = { .fld_dst = oldflp->fld_dst, - .fld_src = oldflp->fld_src, - .fld_scope = RT_SCOPE_UNIVERSE, + struct flowi fl = { .nl_u = { .dn_u = + { .daddr = oldflp->fld_dst, + .saddr = oldflp->fld_src, + .scope = RT_SCOPE_UNIVERSE, + } }, .mark = oldflp->mark, .iif = init_net.loopback_dev->ifindex, .oif = oldflp->oif }; @@ -1028,7 +1020,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old err = -ENODEV; if (dev_out == NULL) goto out; - dn_db = rcu_dereference_raw(dev_out->dn_ptr); + dn_db = dev_out->dn_ptr; /* Possible improvement - check all devices for local addr */ if (dn_dev_islocal(dev_out, fl.fld_dst)) { dev_put(dev_out); @@ -1179,7 +1171,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl if ((flp->fld_dst == rt->fl.fld_dst) && (flp->fld_src == rt->fl.fld_src) && (flp->mark == rt->fl.mark) && - dn_is_output_route(rt) && + (rt->fl.iif == 0) && (rt->fl.oif == flp->oif)) { dst_use(&rt->dst, jiffies); rcu_read_unlock_bh(); @@ -1228,9 +1220,11 @@ static int dn_route_input_slow(struct sk_buff *skb) int flags = 0; __le16 gateway = 0; __le16 local_src = 0; - struct flowi fl = { .fld_dst = cb->dst, - .fld_src = cb->src, - .fld_scope = RT_SCOPE_UNIVERSE, + struct flowi fl = { .nl_u = { .dn_u = + { .daddr = cb->dst, + .saddr = cb->src, + .scope = RT_SCOPE_UNIVERSE, + } }, .mark = skb->mark, .iif = skb->dev->ifindex }; struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE }; @@ -1239,7 +1233,7 @@ static int dn_route_input_slow(struct sk_buff *skb) dev_hold(in_dev); - if ((dn_db = rcu_dereference(in_dev->dn_ptr)) == NULL) + if ((dn_db = in_dev->dn_ptr) == NULL) goto out; /* Zero source addresses are not allowed */ @@ -1508,7 +1502,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires, rt->dst.error) < 0) goto rtattr_failure; - if (dn_is_input_route(rt)) + if (rt->fl.iif) RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); nlh->nlmsg_len = skb_tail_pointer(skb) - b; @@ -1683,15 +1677,15 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou { struct dn_rt_cache_iter_state *s = seq->private; - rt = rcu_dereference_bh(rt->dst.dn_next); - while (!rt) { + rt = rt->dst.dn_next; + while(!rt) { rcu_read_unlock_bh(); if (--s->bucket < 0) break; rcu_read_lock_bh(); - rt = rcu_dereference_bh(dn_rt_hash_table[s->bucket].chain); + rt = dn_rt_hash_table[s->bucket].chain; } - return rt; + return rcu_dereference_bh(rt); } static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos) diff --git a/trunk/net/decnet/dn_rules.c b/trunk/net/decnet/dn_rules.c index 6eb91df3c550..48fdf10be7a1 100644 --- a/trunk/net/decnet/dn_rules.c +++ b/trunk/net/decnet/dn_rules.c @@ -175,7 +175,7 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, unsigned dnet_addr_type(__le16 addr) { - struct flowi fl = { .fld_dst = addr }; + struct flowi fl = { .nl_u = { .dn_u = { .daddr = addr } } }; struct dn_fib_res res; unsigned ret = RTN_UNICAST; struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0); diff --git a/trunk/net/decnet/sysctl_net_decnet.c b/trunk/net/decnet/sysctl_net_decnet.c index 28f8b5e5f73b..be3eb8e23288 100644 --- a/trunk/net/decnet/sysctl_net_decnet.c +++ b/trunk/net/decnet/sysctl_net_decnet.c @@ -38,7 +38,7 @@ int decnet_log_martians = 1; int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW; /* Reasonable defaults, I hope, based on tcp's defaults */ -long sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 }; +int sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 }; int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; @@ -324,7 +324,7 @@ static ctl_table dn_table[] = { .data = &sysctl_decnet_mem, .maxlen = sizeof(sysctl_decnet_mem), .mode = 0644, - .proc_handler = proc_doulongvec_minmax + .proc_handler = proc_dointvec, }, { .procname = "decnet_rmem", diff --git a/trunk/net/dns_resolver/Makefile b/trunk/net/dns_resolver/Makefile index d5c13c2eb36d..c0ef4e71dc49 100644 --- a/trunk/net/dns_resolver/Makefile +++ b/trunk/net/dns_resolver/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_DNS_RESOLVER) += dns_resolver.o -dns_resolver-y := dns_key.o dns_query.o +dns_resolver-objs := dns_key.o dns_query.o diff --git a/trunk/net/econet/Makefile b/trunk/net/econet/Makefile index 05fae8be2fed..39f0a77abdbd 100644 --- a/trunk/net/econet/Makefile +++ b/trunk/net/econet/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_ECONET) += econet.o -econet-y := af_econet.o +econet-objs := af_econet.o diff --git a/trunk/net/ipv4/af_inet.c b/trunk/net/ipv4/af_inet.c index f2b61107df6c..f581f77d1097 100644 --- a/trunk/net/ipv4/af_inet.c +++ b/trunk/net/ipv4/af_inet.c @@ -1148,13 +1148,21 @@ int inet_sk_rebuild_header(struct sock *sk) struct flowi fl = { .oif = sk->sk_bound_dev_if, .mark = sk->sk_mark, - .fl4_dst = daddr, - .fl4_src = inet->inet_saddr, - .fl4_tos = RT_CONN_FLAGS(sk), + .nl_u = { + .ip4_u = { + .daddr = daddr, + .saddr = inet->inet_saddr, + .tos = RT_CONN_FLAGS(sk), + }, + }, .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet->inet_sport, - .fl_ip_dport = inet->inet_dport, + .uli_u = { + .ports = { + .sport = inet->inet_sport, + .dport = inet->inet_dport, + }, + }, }; security_sk_classify_flow(sk, &fl); diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index 7833f17b648a..d8e540c5b071 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -433,8 +433,8 @@ static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) { - struct flowi fl = { .fl4_dst = sip, - .fl4_src = tip }; + struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip, + .saddr = tip } } }; struct rtable *rt; int flag = 0; /*unsigned long now; */ @@ -1061,8 +1061,8 @@ static int arp_req_set(struct net *net, struct arpreq *r, if (r->arp_flags & ATF_PERM) r->arp_flags |= ATF_COM; if (dev == NULL) { - struct flowi fl = { .fl4_dst = ip, - .fl4_tos = RTO_ONLINK }; + struct flowi fl = { .nl_u.ip4_u = { .daddr = ip, + .tos = RTO_ONLINK } }; struct rtable *rt; err = ip_route_output_key(net, &rt, &fl); if (err != 0) @@ -1169,8 +1169,8 @@ static int arp_req_delete(struct net *net, struct arpreq *r, ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; if (dev == NULL) { - struct flowi fl = { .fl4_dst = ip, - .fl4_tos = RTO_ONLINK }; + struct flowi fl = { .nl_u.ip4_u = { .daddr = ip, + .tos = RTO_ONLINK } }; struct rtable *rt; err = ip_route_output_key(net, &rt, &fl); if (err != 0) diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index d9f71bae45c4..dc94b0316b78 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -1256,87 +1256,6 @@ static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh, rtnl_set_sk_err(net, RTNLGRP_IPV4_IFADDR, err); } -static size_t inet_get_link_af_size(const struct net_device *dev) -{ - struct in_device *in_dev = __in_dev_get_rcu(dev); - - if (!in_dev) - return 0; - - return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */ -} - -static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev) -{ - struct in_device *in_dev = __in_dev_get_rcu(dev); - struct nlattr *nla; - int i; - - if (!in_dev) - return -ENODATA; - - nla = nla_reserve(skb, IFLA_INET_CONF, IPV4_DEVCONF_MAX * 4); - if (nla == NULL) - return -EMSGSIZE; - - for (i = 0; i < IPV4_DEVCONF_MAX; i++) - ((u32 *) nla_data(nla))[i] = in_dev->cnf.data[i]; - - return 0; -} - -static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] = { - [IFLA_INET_CONF] = { .type = NLA_NESTED }, -}; - -static int inet_validate_link_af(const struct net_device *dev, - const struct nlattr *nla) -{ - struct nlattr *a, *tb[IFLA_INET_MAX+1]; - int err, rem; - - if (dev && !__in_dev_get_rcu(dev)) - return -EAFNOSUPPORT; - - err = nla_parse_nested(tb, IFLA_INET_MAX, nla, inet_af_policy); - if (err < 0) - return err; - - if (tb[IFLA_INET_CONF]) { - nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) { - int cfgid = nla_type(a); - - if (nla_len(a) < 4) - return -EINVAL; - - if (cfgid <= 0 || cfgid > IPV4_DEVCONF_MAX) - return -EINVAL; - } - } - - return 0; -} - -static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla) -{ - struct in_device *in_dev = __in_dev_get_rcu(dev); - struct nlattr *a, *tb[IFLA_INET_MAX+1]; - int rem; - - if (!in_dev) - return -EAFNOSUPPORT; - - if (nla_parse_nested(tb, IFLA_INET_MAX, nla, NULL) < 0) - BUG(); - - if (tb[IFLA_INET_CONF]) { - nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) - ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a)); - } - - return 0; -} - #ifdef CONFIG_SYSCTL static void devinet_copy_dflt_conf(struct net *net, int i) @@ -1700,14 +1619,6 @@ static __net_initdata struct pernet_operations devinet_ops = { .exit = devinet_exit_net, }; -static struct rtnl_af_ops inet_af_ops = { - .family = AF_INET, - .fill_link_af = inet_fill_link_af, - .get_link_af_size = inet_get_link_af_size, - .validate_link_af = inet_validate_link_af, - .set_link_af = inet_set_link_af, -}; - void __init devinet_init(void) { register_pernet_subsys(&devinet_ops); @@ -1715,8 +1626,6 @@ void __init devinet_init(void) register_gifconf(PF_INET, inet_gifconf); register_netdevice_notifier(&ip_netdev_notifier); - rtnl_af_register(&inet_af_ops); - rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL); rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL); rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr); diff --git a/trunk/net/ipv4/fib_frontend.c b/trunk/net/ipv4/fib_frontend.c index d3a1112b9d9c..eb6f69a8f27a 100644 --- a/trunk/net/ipv4/fib_frontend.c +++ b/trunk/net/ipv4/fib_frontend.c @@ -158,7 +158,11 @@ static void fib_flush(struct net *net) struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { struct flowi fl = { - .fl4_dst = addr, + .nl_u = { + .ip4_u = { + .daddr = addr + } + }, .flags = FLOWI_FLAG_MATCH_ANY_IIF }; struct fib_result res = { 0 }; @@ -189,7 +193,7 @@ static inline unsigned __inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr) { - struct flowi fl = { .fl4_dst = addr }; + struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; struct fib_result res; unsigned ret = RTN_BROADCAST; struct fib_table *local_table; @@ -243,9 +247,13 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, { struct in_device *in_dev; struct flowi fl = { - .fl4_dst = src, - .fl4_src = dst, - .fl4_tos = tos, + .nl_u = { + .ip4_u = { + .daddr = src, + .saddr = dst, + .tos = tos + } + }, .mark = mark, .iif = oif }; @@ -845,9 +853,13 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb) struct fib_result res; struct flowi fl = { .mark = frn->fl_mark, - .fl4_dst = frn->fl_addr, - .fl4_tos = frn->fl_tos, - .fl4_scope = frn->fl_scope, + .nl_u = { + .ip4_u = { + .daddr = frn->fl_addr, + .tos = frn->fl_tos, + .scope = frn->fl_scope + } + } }; #ifdef CONFIG_IP_MULTIPLE_TABLES diff --git a/trunk/net/ipv4/fib_lookup.h b/trunk/net/ipv4/fib_lookup.h index c079cc0ec651..a29edf2219c8 100644 --- a/trunk/net/ipv4/fib_lookup.h +++ b/trunk/net/ipv4/fib_lookup.h @@ -47,8 +47,11 @@ extern int fib_detect_death(struct fib_info *fi, int order, static inline void fib_result_assign(struct fib_result *res, struct fib_info *fi) { - /* we used to play games with refcounts, but we now use RCU */ + if (res->fi != NULL) + fib_info_put(res->fi); res->fi = fi; + if (fi != NULL) + atomic_inc(&fi->fib_clntref); } #endif /* _FIB_LOOKUP_H */ diff --git a/trunk/net/ipv4/fib_semantics.c b/trunk/net/ipv4/fib_semantics.c index 12d3dc3df1b7..3e0da3ef6116 100644 --- a/trunk/net/ipv4/fib_semantics.c +++ b/trunk/net/ipv4/fib_semantics.c @@ -563,8 +563,12 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, rcu_read_lock(); { struct flowi fl = { - .fl4_dst = nh->nh_gw, - .fl4_scope = cfg->fc_scope + 1, + .nl_u = { + .ip4_u = { + .daddr = nh->nh_gw, + .scope = cfg->fc_scope + 1, + }, + }, .oif = nh->nh_oif, }; diff --git a/trunk/net/ipv4/icmp.c b/trunk/net/ipv4/icmp.c index 4aa1b7f01ea0..96bc7f9475a3 100644 --- a/trunk/net/ipv4/icmp.c +++ b/trunk/net/ipv4/icmp.c @@ -386,9 +386,10 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) daddr = icmp_param->replyopts.faddr; } { - struct flowi fl = { .fl4_dst= daddr, - .fl4_src = rt->rt_spec_dst, - .fl4_tos = RT_TOS(ip_hdr(skb)->tos), + struct flowi fl = { .nl_u = { .ip4_u = + { .daddr = daddr, + .saddr = rt->rt_spec_dst, + .tos = RT_TOS(ip_hdr(skb)->tos) } }, .proto = IPPROTO_ICMP }; security_skb_classify_flow(skb, &fl); if (ip_route_output_key(net, &rt, &fl)) @@ -505,8 +506,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) struct net_device *dev = NULL; rcu_read_lock(); - if (rt_is_input_route(rt) && - net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr) + if (rt->fl.iif && + net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr) dev = dev_get_by_index_rcu(net, rt->fl.iif); if (dev) @@ -541,13 +542,22 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) { struct flowi fl = { - .fl4_dst = icmp_param.replyopts.srr ? - icmp_param.replyopts.faddr : iph->saddr, - .fl4_src = saddr, - .fl4_tos = RT_TOS(tos), + .nl_u = { + .ip4_u = { + .daddr = icmp_param.replyopts.srr ? + icmp_param.replyopts.faddr : + iph->saddr, + .saddr = saddr, + .tos = RT_TOS(tos) + } + }, .proto = IPPROTO_ICMP, - .fl_icmp_type = type, - .fl_icmp_code = code, + .uli_u = { + .icmpt = { + .type = type, + .code = code + } + } }; int err; struct rtable *rt2; @@ -559,9 +569,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) /* No need to clone since we're just using its address. */ rt2 = rt; - if (!fl.nl_u.ip4_u.saddr) - fl.nl_u.ip4_u.saddr = rt->rt_src; - err = xfrm_lookup(net, (struct dst_entry **)&rt, &fl, NULL, 0); switch (err) { case 0: diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index e0e77e297de3..c8877c6c7216 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -149,37 +149,21 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc); static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, int sfcount, __be32 *psfsrc, int delta); - -static void ip_mc_list_reclaim(struct rcu_head *head) -{ - kfree(container_of(head, struct ip_mc_list, rcu)); -} - static void ip_ma_put(struct ip_mc_list *im) { if (atomic_dec_and_test(&im->refcnt)) { in_dev_put(im->interface); - call_rcu(&im->rcu, ip_mc_list_reclaim); + kfree(im); } } -#define for_each_pmc_rcu(in_dev, pmc) \ - for (pmc = rcu_dereference(in_dev->mc_list); \ - pmc != NULL; \ - pmc = rcu_dereference(pmc->next_rcu)) - -#define for_each_pmc_rtnl(in_dev, pmc) \ - for (pmc = rtnl_dereference(in_dev->mc_list); \ - pmc != NULL; \ - pmc = rtnl_dereference(pmc->next_rcu)) - #ifdef CONFIG_IP_MULTICAST /* * Timer management */ -static void igmp_stop_timer(struct ip_mc_list *im) +static __inline__ void igmp_stop_timer(struct ip_mc_list *im) { spin_lock_bh(&im->lock); if (del_timer(&im->timer)) @@ -300,8 +284,6 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted) return scount; } -#define igmp_skb_size(skb) (*(unsigned int *)((skb)->cb)) - static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) { struct sk_buff *skb; @@ -310,20 +292,14 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) struct igmpv3_report *pig; struct net *net = dev_net(dev); - while (1) { - skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), - GFP_ATOMIC | __GFP_NOWARN); - if (skb) - break; - size >>= 1; - if (size < 256) - return NULL; - } - igmp_skb_size(skb) = size; + skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC); + if (skb == NULL) + return NULL; { struct flowi fl = { .oif = dev->ifindex, - .fl4_dst = IGMPV3_ALL_MCR, + .nl_u = { .ip4_u = { + .daddr = IGMPV3_ALL_MCR } }, .proto = IPPROTO_IGMP }; if (ip_route_output_key(net, &rt, &fl)) { kfree_skb(skb); @@ -408,7 +384,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, return skb; } -#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? igmp_skb_size(skb) - (skb)->len : \ +#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? (skb)->dev->mtu - (skb)->len : \ skb_tailroom(skb)) : 0) static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, @@ -526,8 +502,8 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) int type; if (!pmc) { - rcu_read_lock(); - for_each_pmc_rcu(in_dev, pmc) { + read_lock(&in_dev->mc_list_lock); + for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { if (pmc->multiaddr == IGMP_ALL_HOSTS) continue; spin_lock_bh(&pmc->lock); @@ -538,7 +514,7 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc) skb = add_grec(skb, pmc, type, 0, 0); spin_unlock_bh(&pmc->lock); } - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); } else { spin_lock_bh(&pmc->lock); if (pmc->sfcount[MCAST_EXCLUDE]) @@ -580,7 +556,7 @@ static void igmpv3_send_cr(struct in_device *in_dev) struct sk_buff *skb = NULL; int type, dtype; - rcu_read_lock(); + read_lock(&in_dev->mc_list_lock); spin_lock_bh(&in_dev->mc_tomb_lock); /* deleted MCA's */ @@ -617,7 +593,7 @@ static void igmpv3_send_cr(struct in_device *in_dev) spin_unlock_bh(&in_dev->mc_tomb_lock); /* change recs */ - for_each_pmc_rcu(in_dev, pmc) { + for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { spin_lock_bh(&pmc->lock); if (pmc->sfcount[MCAST_EXCLUDE]) { type = IGMPV3_BLOCK_OLD_SOURCES; @@ -640,7 +616,7 @@ static void igmpv3_send_cr(struct in_device *in_dev) } spin_unlock_bh(&pmc->lock); } - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); if (!skb) return; @@ -668,7 +644,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc, { struct flowi fl = { .oif = dev->ifindex, - .fl4_dst = dst, + .nl_u = { .ip4_u = { .daddr = dst } }, .proto = IPPROTO_IGMP }; if (ip_route_output_key(net, &rt, &fl)) return -1; @@ -837,14 +813,14 @@ static void igmp_heard_report(struct in_device *in_dev, __be32 group) if (group == IGMP_ALL_HOSTS) return; - rcu_read_lock(); - for_each_pmc_rcu(in_dev, im) { + read_lock(&in_dev->mc_list_lock); + for (im=in_dev->mc_list; im!=NULL; im=im->next) { if (im->multiaddr == group) { igmp_stop_timer(im); break; } } - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); } static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, @@ -930,8 +906,8 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, * - Use the igmp->igmp_code field as the maximum * delay possible */ - rcu_read_lock(); - for_each_pmc_rcu(in_dev, im) { + read_lock(&in_dev->mc_list_lock); + for (im=in_dev->mc_list; im!=NULL; im=im->next) { int changed; if (group && group != im->multiaddr) @@ -949,7 +925,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, if (changed) igmp_mod_timer(im, max_delay); } - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); } /* called in rcu_read_lock() section */ @@ -985,7 +961,7 @@ int igmp_rcv(struct sk_buff *skb) case IGMP_HOST_MEMBERSHIP_REPORT: case IGMPV2_HOST_MEMBERSHIP_REPORT: /* Is it our report looped back? */ - if (rt_is_output_route(skb_rtable(skb))) + if (skb_rtable(skb)->fl.iif == 0) break; /* don't rely on MC router hearing unicast reports */ if (skb->pkt_type == PACKET_MULTICAST || @@ -1134,8 +1110,8 @@ static void igmpv3_clear_delrec(struct in_device *in_dev) kfree(pmc); } /* clear dead sources, too */ - rcu_read_lock(); - for_each_pmc_rcu(in_dev, pmc) { + read_lock(&in_dev->mc_list_lock); + for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { struct ip_sf_list *psf, *psf_next; spin_lock_bh(&pmc->lock); @@ -1147,7 +1123,7 @@ static void igmpv3_clear_delrec(struct in_device *in_dev) kfree(psf); } } - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); } #endif @@ -1233,7 +1209,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) ASSERT_RTNL(); - for_each_pmc_rtnl(in_dev, im) { + for (im=in_dev->mc_list; im; im=im->next) { if (im->multiaddr == addr) { im->users++; ip_mc_add_src(in_dev, &addr, MCAST_EXCLUDE, 0, NULL, 0); @@ -1241,7 +1217,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) } } - im = kzalloc(sizeof(*im), GFP_KERNEL); + im = kmalloc(sizeof(*im), GFP_KERNEL); if (!im) goto out; @@ -1251,18 +1227,26 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) im->multiaddr = addr; /* initial mode is (EX, empty) */ im->sfmode = MCAST_EXCLUDE; + im->sfcount[MCAST_INCLUDE] = 0; im->sfcount[MCAST_EXCLUDE] = 1; + im->sources = NULL; + im->tomb = NULL; + im->crcount = 0; atomic_set(&im->refcnt, 1); spin_lock_init(&im->lock); #ifdef CONFIG_IP_MULTICAST + im->tm_running = 0; setup_timer(&im->timer, &igmp_timer_expire, (unsigned long)im); im->unsolicit_count = IGMP_Unsolicited_Report_Count; + im->reporter = 0; + im->gsquery = 0; #endif - - im->next_rcu = in_dev->mc_list; + im->loaded = 0; + write_lock_bh(&in_dev->mc_list_lock); + im->next = in_dev->mc_list; + in_dev->mc_list = im; in_dev->mc_count++; - rcu_assign_pointer(in_dev->mc_list, im); - + write_unlock_bh(&in_dev->mc_list_lock); #ifdef CONFIG_IP_MULTICAST igmpv3_del_delrec(in_dev, im->multiaddr); #endif @@ -1276,32 +1260,26 @@ EXPORT_SYMBOL(ip_mc_inc_group); /* * Resend IGMP JOIN report; used for bonding. - * Called with rcu_read_lock() */ -void ip_mc_rejoin_groups(struct in_device *in_dev) +void ip_mc_rejoin_group(struct ip_mc_list *im) { #ifdef CONFIG_IP_MULTICAST - struct ip_mc_list *im; - int type; + struct in_device *in_dev = im->interface; - for_each_pmc_rcu(in_dev, im) { - if (im->multiaddr == IGMP_ALL_HOSTS) - continue; + if (im->multiaddr == IGMP_ALL_HOSTS) + return; - /* a failover is happening and switches - * must be notified immediately - */ - if (IGMP_V1_SEEN(in_dev)) - type = IGMP_HOST_MEMBERSHIP_REPORT; - else if (IGMP_V2_SEEN(in_dev)) - type = IGMPV2_HOST_MEMBERSHIP_REPORT; - else - type = IGMPV3_HOST_MEMBERSHIP_REPORT; - igmp_send_report(in_dev, im, type); - } + /* a failover is happening and switches + * must be notified immediately */ + if (IGMP_V1_SEEN(in_dev)) + igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT); + else if (IGMP_V2_SEEN(in_dev)) + igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT); + else + igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT); #endif } -EXPORT_SYMBOL(ip_mc_rejoin_groups); +EXPORT_SYMBOL(ip_mc_rejoin_group); /* * A socket has left a multicast group on device dev @@ -1309,18 +1287,17 @@ EXPORT_SYMBOL(ip_mc_rejoin_groups); void ip_mc_dec_group(struct in_device *in_dev, __be32 addr) { - struct ip_mc_list *i; - struct ip_mc_list __rcu **ip; + struct ip_mc_list *i, **ip; ASSERT_RTNL(); - for (ip = &in_dev->mc_list; - (i = rtnl_dereference(*ip)) != NULL; - ip = &i->next_rcu) { + for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { if (i->multiaddr == addr) { if (--i->users == 0) { - *ip = i->next_rcu; + write_lock_bh(&in_dev->mc_list_lock); + *ip = i->next; in_dev->mc_count--; + write_unlock_bh(&in_dev->mc_list_lock); igmp_group_dropped(i); if (!in_dev->dead) @@ -1339,34 +1316,34 @@ EXPORT_SYMBOL(ip_mc_dec_group); void ip_mc_unmap(struct in_device *in_dev) { - struct ip_mc_list *pmc; + struct ip_mc_list *i; ASSERT_RTNL(); - for_each_pmc_rtnl(in_dev, pmc) - igmp_group_dropped(pmc); + for (i = in_dev->mc_list; i; i = i->next) + igmp_group_dropped(i); } void ip_mc_remap(struct in_device *in_dev) { - struct ip_mc_list *pmc; + struct ip_mc_list *i; ASSERT_RTNL(); - for_each_pmc_rtnl(in_dev, pmc) - igmp_group_added(pmc); + for (i = in_dev->mc_list; i; i = i->next) + igmp_group_added(i); } /* Device going down */ void ip_mc_down(struct in_device *in_dev) { - struct ip_mc_list *pmc; + struct ip_mc_list *i; ASSERT_RTNL(); - for_each_pmc_rtnl(in_dev, pmc) - igmp_group_dropped(pmc); + for (i=in_dev->mc_list; i; i=i->next) + igmp_group_dropped(i); #ifdef CONFIG_IP_MULTICAST in_dev->mr_ifc_count = 0; @@ -1397,6 +1374,7 @@ void ip_mc_init_dev(struct in_device *in_dev) in_dev->mr_qrv = IGMP_Unsolicited_Report_Count; #endif + rwlock_init(&in_dev->mc_list_lock); spin_lock_init(&in_dev->mc_tomb_lock); } @@ -1404,14 +1382,14 @@ void ip_mc_init_dev(struct in_device *in_dev) void ip_mc_up(struct in_device *in_dev) { - struct ip_mc_list *pmc; + struct ip_mc_list *i; ASSERT_RTNL(); ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS); - for_each_pmc_rtnl(in_dev, pmc) - igmp_group_added(pmc); + for (i=in_dev->mc_list; i; i=i->next) + igmp_group_added(i); } /* @@ -1427,19 +1405,24 @@ void ip_mc_destroy_dev(struct in_device *in_dev) /* Deactivate timers */ ip_mc_down(in_dev); - while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) { - in_dev->mc_list = i->next_rcu; + write_lock_bh(&in_dev->mc_list_lock); + while ((i = in_dev->mc_list) != NULL) { + in_dev->mc_list = i->next; in_dev->mc_count--; - + write_unlock_bh(&in_dev->mc_list_lock); igmp_group_dropped(i); ip_ma_put(i); + + write_lock_bh(&in_dev->mc_list_lock); } + write_unlock_bh(&in_dev->mc_list_lock); } /* RTNL is locked */ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) { - struct flowi fl = { .fl4_dst = imr->imr_multiaddr.s_addr }; + struct flowi fl = { .nl_u = { .ip4_u = + { .daddr = imr->imr_multiaddr.s_addr } } }; struct rtable *rt; struct net_device *dev = NULL; struct in_device *idev = NULL; @@ -1530,18 +1513,18 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode, if (!in_dev) return -ENODEV; - rcu_read_lock(); - for_each_pmc_rcu(in_dev, pmc) { + read_lock(&in_dev->mc_list_lock); + for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { if (*pmca == pmc->multiaddr) break; } if (!pmc) { /* MCA not found?? bug */ - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); return -ESRCH; } spin_lock_bh(&pmc->lock); - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); #ifdef CONFIG_IP_MULTICAST sf_markstate(pmc); #endif @@ -1702,18 +1685,18 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, if (!in_dev) return -ENODEV; - rcu_read_lock(); - for_each_pmc_rcu(in_dev, pmc) { + read_lock(&in_dev->mc_list_lock); + for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) { if (*pmca == pmc->multiaddr) break; } if (!pmc) { /* MCA not found?? bug */ - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); return -ESRCH; } spin_lock_bh(&pmc->lock); - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); #ifdef CONFIG_IP_MULTICAST sf_markstate(pmc); @@ -1810,7 +1793,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) err = -EADDRINUSE; ifindex = imr->imr_ifindex; - for_each_pmc_rtnl(inet, i) { + for (i = inet->mc_list; i; i = i->next) { if (i->multi.imr_multiaddr.s_addr == addr && i->multi.imr_ifindex == ifindex) goto done; @@ -1824,7 +1807,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr) goto done; memcpy(&iml->multi, imr, sizeof(*imr)); - iml->next_rcu = inet->mc_list; + iml->next = inet->mc_list; iml->sflist = NULL; iml->sfmode = MCAST_EXCLUDE; rcu_assign_pointer(inet->mc_list, iml); @@ -1838,14 +1821,17 @@ EXPORT_SYMBOL(ip_mc_join_group); static void ip_sf_socklist_reclaim(struct rcu_head *rp) { - kfree(container_of(rp, struct ip_sf_socklist, rcu)); + struct ip_sf_socklist *psf; + + psf = container_of(rp, struct ip_sf_socklist, rcu); /* sk_omem_alloc should have been decreased by the caller*/ + kfree(psf); } static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, struct in_device *in_dev) { - struct ip_sf_socklist *psf = rtnl_dereference(iml->sflist); + struct ip_sf_socklist *psf = iml->sflist; int err; if (psf == NULL) { @@ -1865,8 +1851,11 @@ static int ip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml, static void ip_mc_socklist_reclaim(struct rcu_head *rp) { - kfree(container_of(rp, struct ip_mc_socklist, rcu)); + struct ip_mc_socklist *iml; + + iml = container_of(rp, struct ip_mc_socklist, rcu); /* sk_omem_alloc should have been decreased by the caller*/ + kfree(iml); } @@ -1877,8 +1866,7 @@ static void ip_mc_socklist_reclaim(struct rcu_head *rp) int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) { struct inet_sock *inet = inet_sk(sk); - struct ip_mc_socklist *iml; - struct ip_mc_socklist __rcu **imlp; + struct ip_mc_socklist *iml, **imlp; struct in_device *in_dev; struct net *net = sock_net(sk); __be32 group = imr->imr_multiaddr.s_addr; @@ -1888,9 +1876,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) rtnl_lock(); in_dev = ip_mc_find_dev(net, imr); ifindex = imr->imr_ifindex; - for (imlp = &inet->mc_list; - (iml = rtnl_dereference(*imlp)) != NULL; - imlp = &iml->next_rcu) { + for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) { if (iml->multi.imr_multiaddr.s_addr != group) continue; if (ifindex) { @@ -1902,7 +1888,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) (void) ip_mc_leave_src(sk, iml, in_dev); - *imlp = iml->next_rcu; + rcu_assign_pointer(*imlp, iml->next); if (in_dev) ip_mc_dec_group(in_dev, group); @@ -1948,7 +1934,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct } err = -EADDRNOTAVAIL; - for_each_pmc_rtnl(inet, pmc) { + for (pmc=inet->mc_list; pmc; pmc=pmc->next) { if ((pmc->multi.imr_multiaddr.s_addr == imr.imr_multiaddr.s_addr) && (pmc->multi.imr_ifindex == imr.imr_ifindex)) @@ -1972,7 +1958,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct pmc->sfmode = omode; } - psl = rtnl_dereference(pmc->sflist); + psl = pmc->sflist; if (!add) { if (!psl) goto done; /* err = -EADDRNOTAVAIL */ @@ -2091,7 +2077,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) goto done; } - for_each_pmc_rtnl(inet, pmc) { + for (pmc=inet->mc_list; pmc; pmc=pmc->next) { if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && pmc->multi.imr_ifindex == imr.imr_ifindex) break; @@ -2121,7 +2107,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex) (void) ip_mc_add_src(in_dev, &msf->imsf_multiaddr, msf->imsf_fmode, 0, NULL, 0); } - psl = rtnl_dereference(pmc->sflist); + psl = pmc->sflist; if (psl) { (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode, psl->sl_count, psl->sl_addr, 0); @@ -2169,7 +2155,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf, } err = -EADDRNOTAVAIL; - for_each_pmc_rtnl(inet, pmc) { + for (pmc=inet->mc_list; pmc; pmc=pmc->next) { if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr && pmc->multi.imr_ifindex == imr.imr_ifindex) break; @@ -2177,7 +2163,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf, if (!pmc) /* must have a prior join */ goto done; msf->imsf_fmode = pmc->sfmode; - psl = rtnl_dereference(pmc->sflist); + psl = pmc->sflist; rtnl_unlock(); if (!psl) { len = 0; @@ -2222,7 +2208,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf, err = -EADDRNOTAVAIL; - for_each_pmc_rtnl(inet, pmc) { + for (pmc=inet->mc_list; pmc; pmc=pmc->next) { if (pmc->multi.imr_multiaddr.s_addr == addr && pmc->multi.imr_ifindex == gsf->gf_interface) break; @@ -2230,7 +2216,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf, if (!pmc) /* must have a prior join */ goto done; gsf->gf_fmode = pmc->sfmode; - psl = rtnl_dereference(pmc->sflist); + psl = pmc->sflist; rtnl_unlock(); count = psl ? psl->sl_count : 0; copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc; @@ -2271,7 +2257,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif) goto out; rcu_read_lock(); - for_each_pmc_rcu(inet, pmc) { + for (pmc=rcu_dereference(inet->mc_list); pmc; pmc=rcu_dereference(pmc->next)) { if (pmc->multi.imr_multiaddr.s_addr == loc_addr && pmc->multi.imr_ifindex == dif) break; @@ -2279,7 +2265,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif) ret = inet->mc_all; if (!pmc) goto unlock; - psl = rcu_dereference(pmc->sflist); + psl = pmc->sflist; ret = (pmc->sfmode == MCAST_EXCLUDE); if (!psl) goto unlock; @@ -2314,14 +2300,16 @@ void ip_mc_drop_socket(struct sock *sk) return; rtnl_lock(); - while ((iml = rtnl_dereference(inet->mc_list)) != NULL) { + while ((iml = inet->mc_list) != NULL) { struct in_device *in_dev; + rcu_assign_pointer(inet->mc_list, iml->next); - inet->mc_list = iml->next_rcu; in_dev = inetdev_by_index(net, iml->multi.imr_ifindex); (void) ip_mc_leave_src(sk, iml, in_dev); - if (in_dev != NULL) + if (in_dev != NULL) { ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr); + in_dev_put(in_dev); + } /* decrease mem now to avoid the memleak warning */ atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); call_rcu(&iml->rcu, ip_mc_socklist_reclaim); @@ -2335,8 +2323,8 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p struct ip_sf_list *psf; int rv = 0; - rcu_read_lock(); - for_each_pmc_rcu(in_dev, im) { + read_lock(&in_dev->mc_list_lock); + for (im=in_dev->mc_list; im; im=im->next) { if (im->multiaddr == mc_addr) break; } @@ -2357,7 +2345,7 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p } else rv = 1; /* unspecified source; tentatively allow */ } - rcu_read_unlock(); + read_unlock(&in_dev->mc_list_lock); return rv; } @@ -2383,11 +2371,13 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) in_dev = __in_dev_get_rcu(state->dev); if (!in_dev) continue; - im = rcu_dereference(in_dev->mc_list); + read_lock(&in_dev->mc_list_lock); + im = in_dev->mc_list; if (im) { state->in_dev = in_dev; break; } + read_unlock(&in_dev->mc_list_lock); } return im; } @@ -2395,9 +2385,11 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_list *im) { struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); - - im = rcu_dereference(im->next_rcu); + im = im->next; while (!im) { + if (likely(state->in_dev != NULL)) + read_unlock(&state->in_dev->mc_list_lock); + state->dev = next_net_device_rcu(state->dev); if (!state->dev) { state->in_dev = NULL; @@ -2406,7 +2398,8 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li state->in_dev = __in_dev_get_rcu(state->dev); if (!state->in_dev) continue; - im = rcu_dereference(state->in_dev->mc_list); + read_lock(&state->in_dev->mc_list_lock); + im = state->in_dev->mc_list; } return im; } @@ -2442,8 +2435,10 @@ static void igmp_mc_seq_stop(struct seq_file *seq, void *v) __releases(rcu) { struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); - - state->in_dev = NULL; + if (likely(state->in_dev != NULL)) { + read_unlock(&state->in_dev->mc_list_lock); + state->in_dev = NULL; + } state->dev = NULL; rcu_read_unlock(); } @@ -2465,7 +2460,7 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v) querier = "NONE"; #endif - if (rcu_dereference(state->in_dev->mc_list) == im) { + if (state->in_dev->mc_list == im) { seq_printf(seq, "%d\t%-10s: %5d %7s\n", state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier); } @@ -2524,7 +2519,8 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) idev = __in_dev_get_rcu(state->dev); if (unlikely(idev == NULL)) continue; - im = rcu_dereference(idev->mc_list); + read_lock(&idev->mc_list_lock); + im = idev->mc_list; if (likely(im != NULL)) { spin_lock_bh(&im->lock); psf = im->sources; @@ -2535,6 +2531,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) } spin_unlock_bh(&im->lock); } + read_unlock(&idev->mc_list_lock); } return psf; } @@ -2548,6 +2545,9 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l spin_unlock_bh(&state->im->lock); state->im = state->im->next; while (!state->im) { + if (likely(state->idev != NULL)) + read_unlock(&state->idev->mc_list_lock); + state->dev = next_net_device_rcu(state->dev); if (!state->dev) { state->idev = NULL; @@ -2556,7 +2556,8 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l state->idev = __in_dev_get_rcu(state->dev); if (!state->idev) continue; - state->im = rcu_dereference(state->idev->mc_list); + read_lock(&state->idev->mc_list_lock); + state->im = state->idev->mc_list; } if (!state->im) break; @@ -2602,7 +2603,10 @@ static void igmp_mcf_seq_stop(struct seq_file *seq, void *v) spin_unlock_bh(&state->im->lock); state->im = NULL; } - state->idev = NULL; + if (likely(state->idev != NULL)) { + read_unlock(&state->idev->mc_list_lock); + state->idev = NULL; + } state->dev = NULL; rcu_read_unlock(); } diff --git a/trunk/net/ipv4/inet_connection_sock.c b/trunk/net/ipv4/inet_connection_sock.c index 06f5f8f482f0..7174370b1195 100644 --- a/trunk/net/ipv4/inet_connection_sock.c +++ b/trunk/net/ipv4/inet_connection_sock.c @@ -358,14 +358,17 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, struct ip_options *opt = inet_rsk(req)->opt; struct flowi fl = { .oif = sk->sk_bound_dev_if, .mark = sk->sk_mark, - .fl4_dst = ((opt && opt->srr) ? - opt->faddr : ireq->rmt_addr), - .fl4_src = ireq->loc_addr, - .fl4_tos = RT_CONN_FLAGS(sk), + .nl_u = { .ip4_u = + { .daddr = ((opt && opt->srr) ? + opt->faddr : + ireq->rmt_addr), + .saddr = ireq->loc_addr, + .tos = RT_CONN_FLAGS(sk) } }, .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet_sk(sk)->inet_sport, - .fl_ip_dport = ireq->rmt_port }; + .uli_u = { .ports = + { .sport = inet_sk(sk)->inet_sport, + .dport = ireq->rmt_port } } }; struct net *net = sock_net(sk); security_req_classify_flow(req, &fl); diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 2ada17129fce..ba8042665849 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -490,11 +490,9 @@ static int inet_csk_diag_dump(struct sock *sk, { struct inet_diag_req *r = NLMSG_DATA(cb->nlh); - if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { + if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { struct inet_diag_entry entry; - const struct nlattr *bc = nlmsg_find_attr(cb->nlh, - sizeof(*r), - INET_DIAG_REQ_BYTECODE); + struct rtattr *bc = (struct rtattr *)(r + 1); struct inet_sock *inet = inet_sk(sk); entry.family = sk->sk_family; @@ -514,7 +512,7 @@ static int inet_csk_diag_dump(struct sock *sk, entry.dport = ntohs(inet->inet_dport); entry.userlocks = sk->sk_userlocks; - if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) + if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) return 0; } @@ -529,11 +527,9 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, { struct inet_diag_req *r = NLMSG_DATA(cb->nlh); - if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { + if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { struct inet_diag_entry entry; - const struct nlattr *bc = nlmsg_find_attr(cb->nlh, - sizeof(*r), - INET_DIAG_REQ_BYTECODE); + struct rtattr *bc = (struct rtattr *)(r + 1); entry.family = tw->tw_family; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) @@ -552,7 +548,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, entry.dport = ntohs(tw->tw_dport); entry.userlocks = 0; - if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) + if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) return 0; } @@ -622,7 +618,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, struct inet_diag_req *r = NLMSG_DATA(cb->nlh); struct inet_connection_sock *icsk = inet_csk(sk); struct listen_sock *lopt; - const struct nlattr *bc = NULL; + struct rtattr *bc = NULL; struct inet_sock *inet = inet_sk(sk); int j, s_j; int reqnum, s_reqnum; @@ -642,9 +638,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, if (!lopt || !lopt->qlen) goto out; - if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { - bc = nlmsg_find_attr(cb->nlh, sizeof(*r), - INET_DIAG_REQ_BYTECODE); + if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { + bc = (struct rtattr *)(r + 1); entry.sport = inet->inet_num; entry.userlocks = sk->sk_userlocks; } @@ -677,8 +672,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, &ireq->rmt_addr; entry.dport = ntohs(ireq->rmt_port); - if (!inet_diag_bc_run(nla_data(bc), - nla_len(bc), &entry)) + if (!inet_diag_bc_run(RTA_DATA(bc), + RTA_PAYLOAD(bc), &entry)) continue; } diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 897210adaa77..70ff77f02eee 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -634,7 +634,7 @@ static int ipgre_rcv(struct sk_buff *skb) #ifdef CONFIG_NET_IPGRE_BROADCAST if (ipv4_is_multicast(iph->daddr)) { /* Looped back packet, drop it! */ - if (rt_is_output_route(skb_rtable(skb))) + if (skb_rtable(skb)->fl.iif == 0) goto drop; tunnel->dev->stats.multicast++; skb->pkt_type = PACKET_BROADCAST; @@ -772,11 +772,16 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev { struct flowi fl = { .oif = tunnel->parms.link, - .fl4_dst = dst, - .fl4_src = tiph->saddr, - .fl4_tos = RT_TOS(tos), - .fl_gre_key = tunnel->parms.o_key - }; + .nl_u = { + .ip4_u = { + .daddr = dst, + .saddr = tiph->saddr, + .tos = RT_TOS(tos) + } + }, + .proto = IPPROTO_GRE + } +; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { dev->stats.tx_carrier_errors++; goto tx_error; @@ -946,11 +951,14 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) if (iph->daddr) { struct flowi fl = { .oif = tunnel->parms.link, - .fl4_dst = iph->daddr, - .fl4_src = iph->saddr, - .fl4_tos = RT_TOS(iph->tos), - .proto = IPPROTO_GRE, - .fl_gre_key = tunnel->parms.o_key + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_GRE }; struct rtable *rt; @@ -1208,11 +1216,14 @@ static int ipgre_open(struct net_device *dev) if (ipv4_is_multicast(t->parms.iph.daddr)) { struct flowi fl = { .oif = t->parms.link, - .fl4_dst = t->parms.iph.daddr, - .fl4_src = t->parms.iph.saddr, - .fl4_tos = RT_TOS(t->parms.iph.tos), - .proto = IPPROTO_GRE, - .fl_gre_key = t->parms.o_key + .nl_u = { + .ip4_u = { + .daddr = t->parms.iph.daddr, + .saddr = t->parms.iph.saddr, + .tos = RT_TOS(t->parms.iph.tos) + } + }, + .proto = IPPROTO_GRE }; struct rtable *rt; diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 5090c7ff525e..439d2a34ee44 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -341,13 +341,15 @@ int ip_queue_xmit(struct sk_buff *skb) { struct flowi fl = { .oif = sk->sk_bound_dev_if, .mark = sk->sk_mark, - .fl4_dst = daddr, - .fl4_src = inet->inet_saddr, - .fl4_tos = RT_CONN_FLAGS(sk), + .nl_u = { .ip4_u = + { .daddr = daddr, + .saddr = inet->inet_saddr, + .tos = RT_CONN_FLAGS(sk) } }, .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet->inet_sport, - .fl_ip_dport = inet->inet_dport }; + .uli_u = { .ports = + { .sport = inet->inet_sport, + .dport = inet->inet_dport } } }; /* If this fails, retransmit mechanism of transport layer will * keep trying until route appears or the connection times @@ -1402,11 +1404,14 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar { struct flowi fl = { .oif = arg->bound_dev_if, - .fl4_dst = daddr, - .fl4_src = rt->rt_spec_dst, - .fl4_tos = RT_TOS(ip_hdr(skb)->tos), - .fl_ip_sport = tcp_hdr(skb)->dest, - .fl_ip_dport = tcp_hdr(skb)->source, + .nl_u = { .ip4_u = + { .daddr = daddr, + .saddr = rt->rt_spec_dst, + .tos = RT_TOS(ip_hdr(skb)->tos) } }, + /* Not quite clean, but right. */ + .uli_u = { .ports = + { .sport = tcp_hdr(skb)->dest, + .dport = tcp_hdr(skb)->source } }, .proto = sk->sk_protocol, .flags = ip_reply_arg_flowi_flags(arg) }; security_skb_classify_flow(skb, &fl); diff --git a/trunk/net/ipv4/ipconfig.c b/trunk/net/ipv4/ipconfig.c index 2b097752426b..3a6e1ec5e9ae 100644 --- a/trunk/net/ipv4/ipconfig.c +++ b/trunk/net/ipv4/ipconfig.c @@ -1191,13 +1191,13 @@ static int __init ic_dynamic(void) (ic_proto_enabled & IC_USE_DHCP) && ic_dhcp_msgtype != DHCPACK) { ic_got_reply = 0; - printk(KERN_CONT ","); + printk(","); continue; } #endif /* IPCONFIG_DHCP */ if (ic_got_reply) { - printk(KERN_CONT " OK\n"); + printk(" OK\n"); break; } @@ -1205,7 +1205,7 @@ static int __init ic_dynamic(void) continue; if (! --retries) { - printk(KERN_CONT " timed out!\n"); + printk(" timed out!\n"); break; } @@ -1215,7 +1215,7 @@ static int __init ic_dynamic(void) if (timeout > CONF_TIMEOUT_MAX) timeout = CONF_TIMEOUT_MAX; - printk(KERN_CONT "."); + printk("."); } #ifdef IPCONFIG_BOOTP @@ -1236,7 +1236,7 @@ static int __init ic_dynamic(void) ((ic_got_reply & IC_RARP) ? "RARP" : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"), &ic_servaddr); - printk(KERN_CONT "my address is %pI4\n", &ic_myaddr); + printk("my address is %pI4\n", &ic_myaddr); return 0; } @@ -1468,19 +1468,19 @@ static int __init ip_auto_config(void) /* * Clue in the operator. */ - printk("IP-Config: Complete:\n"); - printk(" device=%s", ic_dev->name); - printk(KERN_CONT ", addr=%pI4", &ic_myaddr); - printk(KERN_CONT ", mask=%pI4", &ic_netmask); - printk(KERN_CONT ", gw=%pI4", &ic_gateway); - printk(KERN_CONT ",\n host=%s, domain=%s, nis-domain=%s", + printk("IP-Config: Complete:"); + printk("\n device=%s", ic_dev->name); + printk(", addr=%pI4", &ic_myaddr); + printk(", mask=%pI4", &ic_netmask); + printk(", gw=%pI4", &ic_gateway); + printk(",\n host=%s, domain=%s, nis-domain=%s", utsname()->nodename, ic_domain, utsname()->domainname); - printk(KERN_CONT ",\n bootserver=%pI4", &ic_servaddr); - printk(KERN_CONT ", rootserver=%pI4", &root_server_addr); - printk(KERN_CONT ", rootpath=%s", root_server_path); + printk(",\n bootserver=%pI4", &ic_servaddr); + printk(", rootserver=%pI4", &root_server_addr); + printk(", rootpath=%s", root_server_path); if (ic_dev_mtu) - printk(KERN_CONT ", mtu=%d", ic_dev_mtu); - printk(KERN_CONT "\n"); + printk(", mtu=%d", ic_dev_mtu); + printk("\n"); #endif /* !SILENT */ return 0; diff --git a/trunk/net/ipv4/ipip.c b/trunk/net/ipv4/ipip.c index e70ad581398e..cd300aaee78f 100644 --- a/trunk/net/ipv4/ipip.c +++ b/trunk/net/ipv4/ipip.c @@ -463,9 +463,13 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { struct flowi fl = { .oif = tunnel->parms.link, - .fl4_dst = dst, - .fl4_src= tiph->saddr, - .fl4_tos = RT_TOS(tos), + .nl_u = { + .ip4_u = { + .daddr = dst, + .saddr = tiph->saddr, + .tos = RT_TOS(tos) + } + }, .proto = IPPROTO_IPIP }; @@ -585,9 +589,13 @@ static void ipip_tunnel_bind_dev(struct net_device *dev) if (iph->daddr) { struct flowi fl = { .oif = tunnel->parms.link, - .fl4_dst = iph->daddr, - .fl4_src = iph->saddr, - .fl4_tos = RT_TOS(iph->tos), + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos) + } + }, .proto = IPPROTO_IPIP }; struct rtable *rt; diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c index 3f3a9afd73e0..86dd5691af46 100644 --- a/trunk/net/ipv4/ipmr.c +++ b/trunk/net/ipv4/ipmr.c @@ -1537,9 +1537,13 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, if (vif->flags & VIFF_TUNNEL) { struct flowi fl = { .oif = vif->link, - .fl4_dst = vif->remote, - .fl4_src = vif->local, - .fl4_tos = RT_TOS(iph->tos), + .nl_u = { + .ip4_u = { + .daddr = vif->remote, + .saddr = vif->local, + .tos = RT_TOS(iph->tos) + } + }, .proto = IPPROTO_IPIP }; @@ -1549,8 +1553,12 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, } else { struct flowi fl = { .oif = vif->link, - .fl4_dst = iph->daddr, - .fl4_tos = RT_TOS(iph->tos), + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .tos = RT_TOS(iph->tos) + } + }, .proto = IPPROTO_IPIP }; @@ -1646,7 +1654,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, if (mrt->vif_table[vif].dev != skb->dev) { int true_vifi; - if (rt_is_output_route(skb_rtable(skb))) { + if (skb_rtable(skb)->fl.iif == 0) { /* It is our own packet, looped back. * Very complicated situation... * diff --git a/trunk/net/ipv4/netfilter.c b/trunk/net/ipv4/netfilter.c index 994a1f29ebbc..d88a46c54fd1 100644 --- a/trunk/net/ipv4/netfilter.c +++ b/trunk/net/ipv4/netfilter.c @@ -31,10 +31,10 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. */ if (addr_type == RTN_LOCAL) { - fl.fl4_dst = iph->daddr; + fl.nl_u.ip4_u.daddr = iph->daddr; if (type == RTN_LOCAL) - fl.fl4_src = iph->saddr; - fl.fl4_tos = RT_TOS(iph->tos); + fl.nl_u.ip4_u.saddr = iph->saddr; + fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; fl.mark = skb->mark; fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; @@ -47,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) } else { /* non-local src, find valid iif to satisfy * rp-filter when calling ip_route_input. */ - fl.fl4_dst = iph->saddr; + fl.nl_u.ip4_u.daddr = iph->saddr; if (ip_route_output_key(net, &rt, &fl) != 0) return -1; diff --git a/trunk/net/ipv4/netfilter/Makefile b/trunk/net/ipv4/netfilter/Makefile index 19eb59d01037..48111594ee9b 100644 --- a/trunk/net/ipv4/netfilter/Makefile +++ b/trunk/net/ipv4/netfilter/Makefile @@ -3,15 +3,15 @@ # # objects for l3 independent conntrack -nf_conntrack_ipv4-y := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o +nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y) ifeq ($(CONFIG_PROC_FS),y) nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o endif endif -nf_nat-y := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o -iptable_nat-y := nf_nat_rule.o nf_nat_standalone.o +nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o +iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o # connection tracking obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o diff --git a/trunk/net/ipv4/netfilter/arp_tables.c b/trunk/net/ipv4/netfilter/arp_tables.c index 3fac340a28d5..3cad2591ace0 100644 --- a/trunk/net/ipv4/netfilter/arp_tables.c +++ b/trunk/net/ipv4/netfilter/arp_tables.c @@ -927,7 +927,6 @@ static int get_info(struct net *net, void __user *user, private = &tmp; } #endif - memset(&info, 0, sizeof(info)); info.valid_hooks = t->valid_hooks; memcpy(info.hook_entry, private->hook_entry, sizeof(info.hook_entry)); diff --git a/trunk/net/ipv4/netfilter/ip_tables.c b/trunk/net/ipv4/netfilter/ip_tables.c index a846d633b3b6..d31b007a6d80 100644 --- a/trunk/net/ipv4/netfilter/ip_tables.c +++ b/trunk/net/ipv4/netfilter/ip_tables.c @@ -1124,7 +1124,6 @@ static int get_info(struct net *net, void __user *user, private = &tmp; } #endif - memset(&info, 0, sizeof(info)); info.valid_hooks = t->valid_hooks; memcpy(info.hook_entry, private->hook_entry, sizeof(info.hook_entry)); diff --git a/trunk/net/ipv4/netfilter/nf_nat_core.c b/trunk/net/ipv4/netfilter/nf_nat_core.c index c04787ce1a71..295c97431e43 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_core.c +++ b/trunk/net/ipv4/netfilter/nf_nat_core.c @@ -47,6 +47,26 @@ __nf_nat_proto_find(u_int8_t protonum) return rcu_dereference(nf_nat_protos[protonum]); } +static const struct nf_nat_protocol * +nf_nat_proto_find_get(u_int8_t protonum) +{ + const struct nf_nat_protocol *p; + + rcu_read_lock(); + p = __nf_nat_proto_find(protonum); + if (!try_module_get(p->me)) + p = &nf_nat_unknown_protocol; + rcu_read_unlock(); + + return p; +} + +static void +nf_nat_proto_put(const struct nf_nat_protocol *p) +{ + module_put(p->me); +} + /* We keep an extra hash for each conntrack, for fast searching. */ static inline unsigned int hash_by_src(const struct net *net, u16 zone, @@ -568,26 +588,6 @@ static struct nf_ct_ext_type nat_extend __read_mostly = { #include #include -static const struct nf_nat_protocol * -nf_nat_proto_find_get(u_int8_t protonum) -{ - const struct nf_nat_protocol *p; - - rcu_read_lock(); - p = __nf_nat_proto_find(protonum); - if (!try_module_get(p->me)) - p = &nf_nat_unknown_protocol; - rcu_read_unlock(); - - return p; -} - -static void -nf_nat_proto_put(const struct nf_nat_protocol *p) -{ - module_put(p->me); -} - static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = { [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 }, [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 }, diff --git a/trunk/net/ipv4/proc.c b/trunk/net/ipv4/proc.c index 1b48eb1ed453..4ae1f203f7cb 100644 --- a/trunk/net/ipv4/proc.c +++ b/trunk/net/ipv4/proc.c @@ -59,13 +59,13 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) local_bh_enable(); socket_seq_show(seq); - seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n", + seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", sock_prot_inuse_get(net, &tcp_prot), orphans, tcp_death_row.tw_count, sockets, - atomic_long_read(&tcp_memory_allocated)); - seq_printf(seq, "UDP: inuse %d mem %ld\n", + atomic_read(&tcp_memory_allocated)); + seq_printf(seq, "UDP: inuse %d mem %d\n", sock_prot_inuse_get(net, &udp_prot), - atomic_long_read(&udp_memory_allocated)); + atomic_read(&udp_memory_allocated)); seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(net, &udplite_prot)); seq_printf(seq, "RAW: inuse %d\n", diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index a3d5ab786e81..1f85ef289895 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -549,9 +549,10 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, { struct flowi fl = { .oif = ipc.oif, .mark = sk->sk_mark, - .fl4_dst = daddr, - .fl4_src = saddr, - .fl4_tos = tos, + .nl_u = { .ip4_u = + { .daddr = daddr, + .saddr = saddr, + .tos = tos } }, .proto = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, }; diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index ec2333fb637e..987bf9adb318 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -140,15 +140,13 @@ static unsigned long expires_ljiffies; static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); static void ipv4_dst_destroy(struct dst_entry *dst); +static void ipv4_dst_ifdown(struct dst_entry *dst, + struct net_device *dev, int how); static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); static void ipv4_link_failure(struct sk_buff *skb); static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu); static int rt_garbage_collect(struct dst_ops *ops); -static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, - int how) -{ -} static struct dst_ops ipv4_dst_ops = { .family = AF_INET, @@ -623,7 +621,7 @@ static inline int rt_fast_clean(struct rtable *rth) /* Kill broadcast/multicast entries very aggresively, if they collide in hash table with more useful entries */ return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) && - rt_is_input_route(rth) && rth->dst.rt_next; + rth->fl.iif && rth->dst.rt_next; } static inline int rt_valuable(struct rtable *rth) @@ -668,7 +666,7 @@ static inline u32 rt_score(struct rtable *rt) if (rt_valuable(rt)) score |= (1<<31); - if (rt_is_output_route(rt) || + if (!rt->fl.iif || !(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL))) score |= (1<<30); @@ -684,17 +682,17 @@ static inline bool rt_caching(const struct net *net) static inline bool compare_hash_inputs(const struct flowi *fl1, const struct flowi *fl2) { - return ((((__force u32)fl1->fl4_dst ^ (__force u32)fl2->fl4_dst) | - ((__force u32)fl1->fl4_src ^ (__force u32)fl2->fl4_src) | + return ((((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) | + ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) | (fl1->iif ^ fl2->iif)) == 0); } static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) { - return (((__force u32)fl1->fl4_dst ^ (__force u32)fl2->fl4_dst) | - ((__force u32)fl1->fl4_src ^ (__force u32)fl2->fl4_src) | + return (((__force u32)fl1->nl_u.ip4_u.daddr ^ (__force u32)fl2->nl_u.ip4_u.daddr) | + ((__force u32)fl1->nl_u.ip4_u.saddr ^ (__force u32)fl2->nl_u.ip4_u.saddr) | (fl1->mark ^ fl2->mark) | - (*(u16 *)&fl1->fl4_tos ^ *(u16 *)&fl2->fl4_tos) | + (*(u16 *)&fl1->nl_u.ip4_u.tos ^ *(u16 *)&fl2->nl_u.ip4_u.tos) | (fl1->oif ^ fl2->oif) | (fl1->iif ^ fl2->iif)) == 0; } @@ -1126,7 +1124,7 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, */ rt->dst.flags |= DST_NOCACHE; - if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) { + if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { int err = arp_bind_neighbour(&rt->dst); if (err) { if (net_ratelimit()) @@ -1224,7 +1222,7 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, /* Try to bind route to arp only if it is output route or unicast forwarding path. */ - if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) { + if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { int err = arp_bind_neighbour(&rt->dst); if (err) { spin_unlock_bh(rt_hash_lock_addr(hash)); @@ -1406,7 +1404,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, if (rth->fl.fl4_dst != daddr || rth->fl.fl4_src != skeys[i] || rth->fl.oif != ikeys[k] || - rt_is_input_route(rth) || + rth->fl.iif != 0 || rt_is_expired(rth) || !net_eq(dev_net(rth->dst.dev), net)) { rthp = &rth->dst.rt_next; @@ -1435,6 +1433,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, rt->dst.child = NULL; if (rt->dst.dev) dev_hold(rt->dst.dev); + if (rt->idev) + in_dev_hold(rt->idev); rt->dst.obsolete = -1; rt->dst.lastuse = jiffies; rt->dst.path = &rt->dst; @@ -1666,7 +1666,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, rth->rt_dst != daddr || rth->rt_src != iph->saddr || rth->fl.oif != ikeys[k] || - rt_is_input_route(rth) || + rth->fl.iif != 0 || dst_metric_locked(&rth->dst, RTAX_MTU) || !net_eq(dev_net(rth->dst.dev), net) || rt_is_expired(rth)) @@ -1728,13 +1728,33 @@ static void ipv4_dst_destroy(struct dst_entry *dst) { struct rtable *rt = (struct rtable *) dst; struct inet_peer *peer = rt->peer; + struct in_device *idev = rt->idev; if (peer) { rt->peer = NULL; inet_putpeer(peer); } + + if (idev) { + rt->idev = NULL; + in_dev_put(idev); + } } +static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, + int how) +{ + struct rtable *rt = (struct rtable *) dst; + struct in_device *idev = rt->idev; + if (dev != dev_net(dev)->loopback_dev && idev && idev->dev == dev) { + struct in_device *loopback_idev = + in_dev_get(dev_net(dev)->loopback_dev); + if (loopback_idev) { + rt->idev = loopback_idev; + in_dev_put(idev); + } + } +} static void ipv4_link_failure(struct sk_buff *skb) { @@ -1770,7 +1790,7 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt) __be32 src; struct fib_result res; - if (rt_is_output_route(rt)) + if (rt->fl.iif == 0) src = rt->rt_src; else { rcu_read_lock(); @@ -1890,6 +1910,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->fl.iif = dev->ifindex; rth->dst.dev = init_net.loopback_dev; dev_hold(rth->dst.dev); + rth->idev = in_dev_get(rth->dst.dev); rth->fl.oif = 0; rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; @@ -2029,6 +2050,7 @@ static int __mkroute_input(struct sk_buff *skb, rth->fl.iif = in_dev->dev->ifindex; rth->dst.dev = (out_dev)->dev; dev_hold(rth->dst.dev); + rth->idev = in_dev_get(rth->dst.dev); rth->fl.oif = 0; rth->rt_spec_dst= spec_dst; @@ -2089,10 +2111,12 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, { struct fib_result res; struct in_device *in_dev = __in_dev_get_rcu(dev); - struct flowi fl = { .fl4_dst = daddr, - .fl4_src = saddr, - .fl4_tos = tos, - .fl4_scope = RT_SCOPE_UNIVERSE, + struct flowi fl = { .nl_u = { .ip4_u = + { .daddr = daddr, + .saddr = saddr, + .tos = tos, + .scope = RT_SCOPE_UNIVERSE, + } }, .mark = skb->mark, .iif = dev->ifindex }; unsigned flags = 0; @@ -2207,6 +2231,7 @@ out: return err; rth->fl.iif = dev->ifindex; rth->dst.dev = net->loopback_dev; dev_hold(rth->dst.dev); + rth->idev = in_dev_get(rth->dst.dev); rth->rt_gateway = daddr; rth->rt_spec_dst= spec_dst; rth->dst.input= ip_local_deliver; @@ -2392,6 +2417,9 @@ static int __mkroute_output(struct rtable **result, if (!rth) return -ENOBUFS; + in_dev_hold(in_dev); + rth->idev = in_dev; + atomic_set(&rth->dst.__refcnt, 1); rth->dst.flags= DST_HOST; if (IN_DEV_CONF_GET(in_dev, NOXFRM)) @@ -2478,11 +2506,14 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, const struct flowi *oldflp) { u32 tos = RT_FL_TOS(oldflp); - struct flowi fl = { .fl4_dst = oldflp->fl4_dst, - .fl4_src = oldflp->fl4_src, - .fl4_tos = tos & IPTOS_RT_MASK, - .fl4_scope = ((tos & RTO_ONLINK) ? - RT_SCOPE_LINK : RT_SCOPE_UNIVERSE), + struct flowi fl = { .nl_u = { .ip4_u = + { .daddr = oldflp->fl4_dst, + .saddr = oldflp->fl4_src, + .tos = tos & IPTOS_RT_MASK, + .scope = ((tos & RTO_ONLINK) ? + RT_SCOPE_LINK : + RT_SCOPE_UNIVERSE), + } }, .mark = oldflp->mark, .iif = net->loopback_dev->ifindex, .oif = oldflp->oif }; @@ -2664,7 +2695,7 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, rth = rcu_dereference_bh(rth->dst.rt_next)) { if (rth->fl.fl4_dst == flp->fl4_dst && rth->fl.fl4_src == flp->fl4_src && - rt_is_output_route(rth) && + rth->fl.iif == 0 && rth->fl.oif == flp->oif && rth->fl.mark == flp->mark && !((rth->fl.fl4_tos ^ flp->fl4_tos) & @@ -2728,6 +2759,9 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi rt->fl = ort->fl; + rt->idev = ort->idev; + if (rt->idev) + in_dev_hold(rt->idev); rt->rt_genid = rt_genid(net); rt->rt_flags = ort->rt_flags; rt->rt_type = ort->rt_type; @@ -2819,7 +2853,7 @@ static int rt_fill_info(struct net *net, if (rt->dst.tclassid) NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid); #endif - if (rt_is_input_route(rt)) + if (rt->fl.iif) NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst); else if (rt->rt_src != rt->fl.fl4_src) NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src); @@ -2844,7 +2878,7 @@ static int rt_fill_info(struct net *net, } } - if (rt_is_input_route(rt)) { + if (rt->fl.iif) { #ifdef CONFIG_IP_MROUTE __be32 dst = rt->rt_dst; @@ -2939,9 +2973,13 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void err = -rt->dst.error; } else { struct flowi fl = { - .fl4_dst = dst, - .fl4_src = src, - .fl4_tos = rtm->rtm_tos, + .nl_u = { + .ip4_u = { + .daddr = dst, + .saddr = src, + .tos = rtm->rtm_tos, + }, + }, .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0, .mark = mark, }; diff --git a/trunk/net/ipv4/syncookies.c b/trunk/net/ipv4/syncookies.c index 47519205a014..650cace2180d 100644 --- a/trunk/net/ipv4/syncookies.c +++ b/trunk/net/ipv4/syncookies.c @@ -346,14 +346,17 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, */ { struct flowi fl = { .mark = sk->sk_mark, - .fl4_dst = ((opt && opt->srr) ? - opt->faddr : ireq->rmt_addr), - .fl4_src = ireq->loc_addr, - .fl4_tos = RT_CONN_FLAGS(sk), + .nl_u = { .ip4_u = + { .daddr = ((opt && opt->srr) ? + opt->faddr : + ireq->rmt_addr), + .saddr = ireq->loc_addr, + .tos = RT_CONN_FLAGS(sk) } }, .proto = IPPROTO_TCP, .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = th->dest, - .fl_ip_dport = th->source }; + .uli_u = { .ports = + { .sport = th->dest, + .dport = th->source } } }; security_req_classify_flow(req, &fl); if (ip_route_output_key(sock_net(sk), &rt, &fl)) { reqsk_free(req); diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index e91911d7aae2..d96c1da4b17c 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -398,7 +398,7 @@ static struct ctl_table ipv4_table[] = { .data = &sysctl_tcp_mem, .maxlen = sizeof(sysctl_tcp_mem), .mode = 0644, - .proc_handler = proc_doulongvec_minmax + .proc_handler = proc_dointvec }, { .procname = "tcp_wmem", @@ -602,7 +602,8 @@ static struct ctl_table ipv4_table[] = { .data = &sysctl_udp_mem, .maxlen = sizeof(sysctl_udp_mem), .mode = 0644, - .proc_handler = proc_doulongvec_minmax, + .proc_handler = proc_dointvec_minmax, + .extra1 = &zero }, { .procname = "udp_rmem_min", diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 2bb46d55f40c..1664a0590bb8 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -282,7 +282,7 @@ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; struct percpu_counter tcp_orphan_count; EXPORT_SYMBOL_GPL(tcp_orphan_count); -long sysctl_tcp_mem[3] __read_mostly; +int sysctl_tcp_mem[3] __read_mostly; int sysctl_tcp_wmem[3] __read_mostly; int sysctl_tcp_rmem[3] __read_mostly; @@ -290,7 +290,7 @@ EXPORT_SYMBOL(sysctl_tcp_mem); EXPORT_SYMBOL(sysctl_tcp_rmem); EXPORT_SYMBOL(sysctl_tcp_wmem); -atomic_long_t tcp_memory_allocated; /* Current allocated memory. */ +atomic_t tcp_memory_allocated; /* Current allocated memory. */ EXPORT_SYMBOL(tcp_memory_allocated); /* @@ -1193,7 +1193,7 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq), - "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n", + KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n", tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt); #endif @@ -1477,9 +1477,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, * shouldn't happen. */ if (WARN(before(*seq, TCP_SKB_CB(skb)->seq), - "recvmsg bug: copied %X seq %X rcvnxt %X fl %X\n", - *seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt, - flags)) + KERN_INFO "recvmsg bug: copied %X " + "seq %X rcvnxt %X fl %X\n", *seq, + TCP_SKB_CB(skb)->seq, tp->rcv_nxt, + flags)) break; offset = *seq - TCP_SKB_CB(skb)->seq; @@ -1489,9 +1490,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto found_ok_skb; if (tcp_hdr(skb)->fin) goto found_fin_ok; - WARN(!(flags & MSG_PEEK), - "recvmsg bug 2: copied %X seq %X rcvnxt %X fl %X\n", - *seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt, flags); + WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " + "copied %X seq %X rcvnxt %X fl %X\n", + *seq, TCP_SKB_CB(skb)->seq, + tp->rcv_nxt, flags); } /* Well, if we have backlog, try to process it now yet. */ @@ -2244,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, /* Values greater than interface MTU won't take effect. However * at the point when this call is done we typically don't yet * know which interface is going to be used */ - if (val < 64 || val > MAX_TCP_WINDOW) { + if (val < 8 || val > MAX_TCP_WINDOW) { err = -EINVAL; break; } diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 6d8ab1c4efc3..3357f69e353d 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -259,11 +259,8 @@ static void tcp_fixup_sndbuf(struct sock *sk) int sndmem = tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff); - if (sk->sk_sndbuf < 3 * sndmem) { - sk->sk_sndbuf = 3 * sndmem; - if (sk->sk_sndbuf > sysctl_tcp_wmem[2]) - sk->sk_sndbuf = sysctl_tcp_wmem[2]; - } + if (sk->sk_sndbuf < 3 * sndmem) + sk->sk_sndbuf = min(3 * sndmem, sysctl_tcp_wmem[2]); } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) @@ -399,7 +396,7 @@ static void tcp_clamp_window(struct sock *sk) if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && !tcp_memory_pressure && - atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { + atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), sysctl_tcp_rmem[2]); } @@ -4864,7 +4861,7 @@ static int tcp_should_expand_sndbuf(struct sock *sk) return 0; /* If we are under soft global TCP memory pressure, do not expand. */ - if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) + if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) return 0; /* If we filled the congestion window, do not expand. */ diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 69ccbc1dde9c..8f8527d41682 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -415,9 +415,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) !icsk->icsk_backoff) break; - if (sock_owned_by_user(sk)) - break; - icsk->icsk_backoff--; inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) << icsk->icsk_backoff; @@ -432,6 +429,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) if (remaining) { inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, remaining, TCP_RTO_MAX); + } else if (sock_owned_by_user(sk)) { + /* RTO revert clocked out retransmission, + * but socket is locked. Will defer. */ + inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, + HZ/20, TCP_RTO_MAX); } else { /* RTO revert clocked out retransmission. * Will retransmit now */ diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 5f29b2e20e23..05b1ecf36763 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -822,11 +822,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, &md5); tcp_header_size = tcp_options_size + sizeof(struct tcphdr); - if (tcp_packets_in_flight(tp) == 0) { + if (tcp_packets_in_flight(tp) == 0) tcp_ca_event(sk, CA_EVENT_TX_START); - skb->ooo_okay = 1; - } else - skb->ooo_okay = 0; skb_push(skb, tcp_header_size); skb_reset_transport_header(skb); @@ -2595,7 +2592,6 @@ int tcp_connect(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *buff; - int err; tcp_connect_init(sk); @@ -2618,9 +2614,7 @@ int tcp_connect(struct sock *sk) sk->sk_wmem_queued += buff->truesize; sk_mem_charge(sk, buff->truesize); tp->packets_out += tcp_skb_pcount(buff); - err = tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); - if (err == -ECONNREFUSED) - return err; + tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); /* We change tp->snd_nxt after the tcp_transmit_skb() call * in order to make this packet get counted in tcpOutSegs. diff --git a/trunk/net/ipv4/tcp_probe.c b/trunk/net/ipv4/tcp_probe.c index 85ee7eb7e38e..6211e2114173 100644 --- a/trunk/net/ipv4/tcp_probe.c +++ b/trunk/net/ipv4/tcp_probe.c @@ -154,7 +154,7 @@ static int tcpprobe_sprint(char *tbuf, int n) struct timespec tv = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start)); - return scnprintf(tbuf, n, + return snprintf(tbuf, n, "%lu.%09lu %pI4:%u %pI4:%u %d %#x %#x %u %u %u %u\n", (unsigned long) tv.tv_sec, (unsigned long) tv.tv_nsec, @@ -174,7 +174,7 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf, return -EINVAL; while (cnt < len) { - char tbuf[164]; + char tbuf[128]; int width; /* Wait for data in buffer */ diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index b37181da487c..28cb2d733a3c 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -110,7 +110,7 @@ struct udp_table udp_table __read_mostly; EXPORT_SYMBOL(udp_table); -long sysctl_udp_mem[3] __read_mostly; +int sysctl_udp_mem[3] __read_mostly; EXPORT_SYMBOL(sysctl_udp_mem); int sysctl_udp_rmem_min __read_mostly; @@ -119,7 +119,7 @@ EXPORT_SYMBOL(sysctl_udp_rmem_min); int sysctl_udp_wmem_min __read_mostly; EXPORT_SYMBOL(sysctl_udp_wmem_min); -atomic_long_t udp_memory_allocated; +atomic_t udp_memory_allocated; EXPORT_SYMBOL(udp_memory_allocated); #define MAX_UDP_PORTS 65536 @@ -430,7 +430,7 @@ static struct sock *udp4_lib_lookup2(struct net *net, if (result) { exact_match: - if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2))) + if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) result = NULL; else if (unlikely(compute_score2(result, net, saddr, sport, daddr, hnum, dif) < badness)) { @@ -500,7 +500,7 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, goto begin; if (result) { - if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2))) + if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) result = NULL; else if (unlikely(compute_score(result, net, saddr, hnum, sport, daddr, dport, dif) < badness)) { @@ -890,13 +890,15 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (rt == NULL) { struct flowi fl = { .oif = ipc.oif, .mark = sk->sk_mark, - .fl4_dst = faddr, - .fl4_src = saddr, - .fl4_tos = tos, + .nl_u = { .ip4_u = + { .daddr = faddr, + .saddr = saddr, + .tos = tos } }, .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet->inet_sport, - .fl_ip_dport = dport }; + .uli_u = { .ports = + { .sport = inet->inet_sport, + .dport = dport } } }; struct net *net = sock_net(sk); security_sk_classify_flow(sk, &fl); diff --git a/trunk/net/ipv4/xfrm4_policy.c b/trunk/net/ipv4/xfrm4_policy.c index b057d40addec..4464f3bff6a7 100644 --- a/trunk/net/ipv4/xfrm4_policy.c +++ b/trunk/net/ipv4/xfrm4_policy.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -23,8 +22,12 @@ static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, xfrm_address_t *daddr) { struct flowi fl = { - .fl4_dst = daddr->a4, - .fl4_tos = tos, + .nl_u = { + .ip4_u = { + .tos = tos, + .daddr = daddr->a4, + }, + }, }; struct dst_entry *dst; struct rtable *rt; @@ -77,6 +80,10 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, xdst->u.dst.dev = dev; dev_hold(dev); + xdst->u.rt.idev = in_dev_get(dev); + if (!xdst->u.rt.idev) + return -ENODEV; + xdst->u.rt.peer = rt->peer; if (rt->peer) atomic_inc(&rt->peer->refcnt); @@ -151,20 +158,6 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); } break; - - case IPPROTO_GRE: - if (pskb_may_pull(skb, xprth + 12 - skb->data)) { - __be16 *greflags = (__be16 *)xprth; - __be32 *gre_hdr = (__be32 *)xprth; - - if (greflags[0] & GRE_KEY) { - if (greflags[0] & GRE_CSUM) - gre_hdr++; - fl->fl_gre_key = gre_hdr[1]; - } - } - break; - default: fl->fl_ipsec_spi = 0; break; @@ -196,6 +189,8 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) { struct xfrm_dst *xdst = (struct xfrm_dst *)dst; + if (likely(xdst->u.rt.idev)) + in_dev_put(xdst->u.rt.idev); if (likely(xdst->u.rt.peer)) inet_putpeer(xdst->u.rt.peer); xfrm_dst_destroy(xdst); @@ -204,9 +199,27 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, int unregister) { + struct xfrm_dst *xdst; + if (!unregister) return; + xdst = (struct xfrm_dst *)dst; + if (xdst->u.rt.idev->dev == dev) { + struct in_device *loopback_idev = + in_dev_get(dev_net(dev)->loopback_dev); + BUG_ON(!loopback_idev); + + do { + in_dev_put(xdst->u.rt.idev); + xdst->u.rt.idev = loopback_idev; + in_dev_hold(loopback_idev); + xdst = (struct xfrm_dst *)xdst->u.dst.child; + } while (xdst->u.dst.xfrm); + + __in_dev_put(loopback_idev); + } + xfrm_dst_ifdown(dst, dev); } diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 1023ad0d2b15..e048ec62d109 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -98,11 +98,7 @@ #endif #define INFINITY_LIFE_TIME 0xFFFFFFFF - -static inline u32 cstamp_delta(unsigned long cstamp) -{ - return (cstamp - INITIAL_JIFFIES) * 100UL / HZ; -} +#define TIME_DELTA(a, b) ((unsigned long)((long)(a) - (long)(b))) #define ADDRCONF_TIMER_FUZZ_MINUS (HZ > 50 ? HZ/50 : 1) #define ADDRCONF_TIMER_FUZZ (HZ / 4) @@ -2744,6 +2740,10 @@ static int addrconf_ifdown(struct net_device *dev, int how) /* Flag it for later restoration when link comes up */ ifa->flags |= IFA_F_TENTATIVE; ifa->state = INET6_IFADDR_STATE_DAD; + + write_unlock_bh(&idev->lock); + + in6_ifa_hold(ifa); } else { list_del(&ifa->if_list); @@ -2758,15 +2758,19 @@ static int addrconf_ifdown(struct net_device *dev, int how) ifa->state = INET6_IFADDR_STATE_DEAD; spin_unlock_bh(&ifa->state_lock); - if (state != INET6_IFADDR_STATE_DEAD) { - __ipv6_ifa_notify(RTM_DELADDR, ifa); - atomic_notifier_call_chain(&inet6addr_chain, - NETDEV_DOWN, ifa); - } - - in6_ifa_put(ifa); - write_lock_bh(&idev->lock); + if (state == INET6_IFADDR_STATE_DEAD) + goto put_ifa; } + + __ipv6_ifa_notify(RTM_DELADDR, ifa); + if (ifa->state == INET6_IFADDR_STATE_DEAD) + atomic_notifier_call_chain(&inet6addr_chain, + NETDEV_DOWN, ifa); + +put_ifa: + in6_ifa_put(ifa); + + write_lock_bh(&idev->lock); } list_splice(&keep_list, &idev->addr_list); @@ -3448,8 +3452,10 @@ static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp, { struct ifa_cacheinfo ci; - ci.cstamp = cstamp_delta(cstamp); - ci.tstamp = cstamp_delta(tstamp); + ci.cstamp = (u32)(TIME_DELTA(cstamp, INITIAL_JIFFIES) / HZ * 100 + + TIME_DELTA(cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); + ci.tstamp = (u32)(TIME_DELTA(tstamp, INITIAL_JIFFIES) / HZ * 100 + + TIME_DELTA(tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); ci.ifa_prefered = preferred; ci.ifa_valid = valid; @@ -3800,10 +3806,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_AUTOCONF] = cnf->autoconf; array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits; array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits; - array[DEVCONF_RTR_SOLICIT_INTERVAL] = - jiffies_to_msecs(cnf->rtr_solicit_interval); - array[DEVCONF_RTR_SOLICIT_DELAY] = - jiffies_to_msecs(cnf->rtr_solicit_delay); + array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval; + array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay; array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version; #ifdef CONFIG_IPV6_PRIVACY array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr; @@ -3817,8 +3821,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo; #ifdef CONFIG_IPV6_ROUTER_PREF array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref; - array[DEVCONF_RTR_PROBE_INTERVAL] = - jiffies_to_msecs(cnf->rtr_probe_interval); + array[DEVCONF_RTR_PROBE_INTERVAL] = cnf->rtr_probe_interval; #ifdef CONFIG_IPV6_ROUTE_INFO array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen; #endif @@ -3836,15 +3839,6 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; } -static inline size_t inet6_ifla6_size(void) -{ - return nla_total_size(4) /* IFLA_INET6_FLAGS */ - + nla_total_size(sizeof(struct ifla_cacheinfo)) - + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ - + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */ - + nla_total_size(ICMP6_MIB_MAX * 8); /* IFLA_INET6_ICMP6STATS */ -} - static inline size_t inet6_if_nlmsg_size(void) { return NLMSG_ALIGN(sizeof(struct ifinfomsg)) @@ -3852,7 +3846,13 @@ static inline size_t inet6_if_nlmsg_size(void) + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ + nla_total_size(4) /* IFLA_MTU */ + nla_total_size(4) /* IFLA_LINK */ - + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */ + + nla_total_size( /* IFLA_PROTINFO */ + nla_total_size(4) /* IFLA_INET6_FLAGS */ + + nla_total_size(sizeof(struct ifla_cacheinfo)) + + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ + + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */ + + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */ + ); } static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib, @@ -3899,70 +3899,15 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, } } -static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev) -{ - struct nlattr *nla; - struct ifla_cacheinfo ci; - - NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags); - - ci.max_reasm_len = IPV6_MAXPLEN; - ci.tstamp = cstamp_delta(idev->tstamp); - ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time); - ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time); - NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); - - nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); - if (nla == NULL) - goto nla_put_failure; - ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla)); - - /* XXX - MC not implemented */ - - nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64)); - if (nla == NULL) - goto nla_put_failure; - snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla)); - - nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64)); - if (nla == NULL) - goto nla_put_failure; - snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla)); - - return 0; - -nla_put_failure: - return -EMSGSIZE; -} - -static size_t inet6_get_link_af_size(const struct net_device *dev) -{ - if (!__in6_dev_get(dev)) - return 0; - - return inet6_ifla6_size(); -} - -static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev) -{ - struct inet6_dev *idev = __in6_dev_get(dev); - - if (!idev) - return -ENODATA; - - if (inet6_fill_ifla6_attrs(skb, idev) < 0) - return -EMSGSIZE; - - return 0; -} - static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, u32 pid, u32 seq, int event, unsigned int flags) { struct net_device *dev = idev->dev; + struct nlattr *nla; struct ifinfomsg *hdr; struct nlmsghdr *nlh; void *protoinfo; + struct ifla_cacheinfo ci; nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); if (nlh == NULL) @@ -3989,8 +3934,31 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, if (protoinfo == NULL) goto nla_put_failure; - if (inet6_fill_ifla6_attrs(skb, idev) < 0) + NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags); + + ci.max_reasm_len = IPV6_MAXPLEN; + ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100 + + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); + ci.reachable_time = idev->nd_parms->reachable_time; + ci.retrans_time = idev->nd_parms->retrans_time; + NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); + + nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); + if (nla == NULL) + goto nla_put_failure; + ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla)); + + /* XXX - MC not implemented */ + + nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64)); + if (nla == NULL) goto nla_put_failure; + snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla)); + + nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64)); + if (nla == NULL) + goto nla_put_failure; + snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla)); nla_nest_end(skb, protoinfo); return nlmsg_end(skb, nlh); @@ -4661,12 +4629,6 @@ int unregister_inet6addr_notifier(struct notifier_block *nb) } EXPORT_SYMBOL(unregister_inet6addr_notifier); -static struct rtnl_af_ops inet6_ops = { - .family = AF_INET6, - .fill_link_af = inet6_fill_link_af, - .get_link_af_size = inet6_get_link_af_size, -}; - /* * Init / cleanup code */ @@ -4718,10 +4680,6 @@ int __init addrconf_init(void) addrconf_verify(0); - err = rtnl_af_register(&inet6_ops); - if (err < 0) - goto errout_af; - err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo); if (err < 0) goto errout; @@ -4737,8 +4695,6 @@ int __init addrconf_init(void) return 0; errout: - rtnl_af_unregister(&inet6_ops); -errout_af: unregister_netdevice_notifier(&ipv6_dev_notf); errlo: unregister_pernet_subsys(&addrconf_ops); @@ -4759,8 +4715,6 @@ void addrconf_cleanup(void) rtnl_lock(); - __rtnl_af_unregister(&inet6_ops); - /* clean dev list */ for_each_netdev(&init_net, dev) { if (__in6_dev_get(dev) == NULL) diff --git a/trunk/net/ipv6/inet6_connection_sock.c b/trunk/net/ipv6/inet6_connection_sock.c index 861d252bd1ba..8a1628023bd1 100644 --- a/trunk/net/ipv6/inet6_connection_sock.c +++ b/trunk/net/ipv6/inet6_connection_sock.c @@ -60,16 +60,18 @@ EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict); static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport, const u32 rnd, const u16 synq_hsize) { - u32 c; - - c = jhash_3words((__force u32)raddr->s6_addr32[0], - (__force u32)raddr->s6_addr32[1], - (__force u32)raddr->s6_addr32[2], - rnd); - - c = jhash_2words((__force u32)raddr->s6_addr32[3], - (__force u32)rport, - c); + u32 a = (__force u32)raddr->s6_addr32[0]; + u32 b = (__force u32)raddr->s6_addr32[1]; + u32 c = (__force u32)raddr->s6_addr32[2]; + + a += JHASH_GOLDEN_RATIO; + b += JHASH_GOLDEN_RATIO; + c += rnd; + __jhash_mix(a, b, c); + + a += (__force u32)raddr->s6_addr32[3]; + b += (__force u32)rport; + __jhash_mix(a, b, c); return c & (synq_hsize - 1); } diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index b1155554bb18..2a59610c2a58 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -58,6 +58,8 @@ MODULE_AUTHOR("Ville Nuorvala"); MODULE_DESCRIPTION("IPv6 tunneling device"); MODULE_LICENSE("GPL"); +#define IPV6_TLV_TEL_DST_SIZE 8 + #ifdef IP6_TNL_DEBUG #define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __func__) #else diff --git a/trunk/net/ipv6/ip6mr.c b/trunk/net/ipv6/ip6mr.c index 9fab274019c0..6f32ffce7022 100644 --- a/trunk/net/ipv6/ip6mr.c +++ b/trunk/net/ipv6/ip6mr.c @@ -1843,7 +1843,9 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, fl = (struct flowi) { .oif = vif->link, - .fl6_dst = ipv6h->daddr, + .nl_u = { .ip6_u = + { .daddr = ipv6h->daddr, } + } }; dst = ip6_route_output(net, NULL, &fl); diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index 49f986d626a0..d1444b95ad7e 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -82,7 +82,7 @@ static void *__mld2_query_bugs[] __attribute__((__unused__)) = { static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; /* Big mc list lock for all the sockets */ -static DEFINE_SPINLOCK(ipv6_sk_mc_lock); +static DEFINE_RWLOCK(ipv6_sk_mc_lock); static void igmp6_join_group(struct ifmcaddr6 *ma); static void igmp6_leave_group(struct ifmcaddr6 *ma); @@ -123,11 +123,6 @@ int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF; * socket join on multicast group */ -#define for_each_pmc_rcu(np, pmc) \ - for (pmc = rcu_dereference(np->ipv6_mc_list); \ - pmc != NULL; \ - pmc = rcu_dereference(pmc->next)) - int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) { struct net_device *dev = NULL; @@ -139,15 +134,15 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) if (!ipv6_addr_is_multicast(addr)) return -EINVAL; - rcu_read_lock(); - for_each_pmc_rcu(np, mc_lst) { + read_lock_bh(&ipv6_sk_mc_lock); + for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) { if ((ifindex == 0 || mc_lst->ifindex == ifindex) && ipv6_addr_equal(&mc_lst->addr, addr)) { - rcu_read_unlock(); + read_unlock_bh(&ipv6_sk_mc_lock); return -EADDRINUSE; } } - rcu_read_unlock(); + read_unlock_bh(&ipv6_sk_mc_lock); mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL); @@ -191,41 +186,33 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) return err; } - spin_lock(&ipv6_sk_mc_lock); + write_lock_bh(&ipv6_sk_mc_lock); mc_lst->next = np->ipv6_mc_list; - rcu_assign_pointer(np->ipv6_mc_list, mc_lst); - spin_unlock(&ipv6_sk_mc_lock); + np->ipv6_mc_list = mc_lst; + write_unlock_bh(&ipv6_sk_mc_lock); rcu_read_unlock(); return 0; } -static void ipv6_mc_socklist_reclaim(struct rcu_head *head) -{ - kfree(container_of(head, struct ipv6_mc_socklist, rcu)); -} /* * socket leave on multicast group */ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) { struct ipv6_pinfo *np = inet6_sk(sk); - struct ipv6_mc_socklist *mc_lst; - struct ipv6_mc_socklist __rcu **lnk; + struct ipv6_mc_socklist *mc_lst, **lnk; struct net *net = sock_net(sk); - spin_lock(&ipv6_sk_mc_lock); - for (lnk = &np->ipv6_mc_list; - (mc_lst = rcu_dereference_protected(*lnk, - lockdep_is_held(&ipv6_sk_mc_lock))) !=NULL ; - lnk = &mc_lst->next) { + write_lock_bh(&ipv6_sk_mc_lock); + for (lnk = &np->ipv6_mc_list; (mc_lst = *lnk) !=NULL ; lnk = &mc_lst->next) { if ((ifindex == 0 || mc_lst->ifindex == ifindex) && ipv6_addr_equal(&mc_lst->addr, addr)) { struct net_device *dev; *lnk = mc_lst->next; - spin_unlock(&ipv6_sk_mc_lock); + write_unlock_bh(&ipv6_sk_mc_lock); rcu_read_lock(); dev = dev_get_by_index_rcu(net, mc_lst->ifindex); @@ -238,12 +225,11 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) } else (void) ip6_mc_leave_src(sk, mc_lst, NULL); rcu_read_unlock(); - atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); - call_rcu(&mc_lst->rcu, ipv6_mc_socklist_reclaim); + sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); return 0; } } - spin_unlock(&ipv6_sk_mc_lock); + write_unlock_bh(&ipv6_sk_mc_lock); return -EADDRNOTAVAIL; } @@ -271,7 +257,7 @@ static struct inet6_dev *ip6_mc_find_dev_rcu(struct net *net, return NULL; idev = __in6_dev_get(dev); if (!idev) - return NULL; + return NULL;; read_lock_bh(&idev->lock); if (idev->dead) { read_unlock_bh(&idev->lock); @@ -286,13 +272,12 @@ void ipv6_sock_mc_close(struct sock *sk) struct ipv6_mc_socklist *mc_lst; struct net *net = sock_net(sk); - spin_lock(&ipv6_sk_mc_lock); - while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list, - lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) { + write_lock_bh(&ipv6_sk_mc_lock); + while ((mc_lst = np->ipv6_mc_list) != NULL) { struct net_device *dev; np->ipv6_mc_list = mc_lst->next; - spin_unlock(&ipv6_sk_mc_lock); + write_unlock_bh(&ipv6_sk_mc_lock); rcu_read_lock(); dev = dev_get_by_index_rcu(net, mc_lst->ifindex); @@ -305,13 +290,11 @@ void ipv6_sock_mc_close(struct sock *sk) } else (void) ip6_mc_leave_src(sk, mc_lst, NULL); rcu_read_unlock(); + sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); - atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); - call_rcu(&mc_lst->rcu, ipv6_mc_socklist_reclaim); - - spin_lock(&ipv6_sk_mc_lock); + write_lock_bh(&ipv6_sk_mc_lock); } - spin_unlock(&ipv6_sk_mc_lock); + write_unlock_bh(&ipv6_sk_mc_lock); } int ip6_mc_source(int add, int omode, struct sock *sk, @@ -345,7 +328,8 @@ int ip6_mc_source(int add, int omode, struct sock *sk, err = -EADDRNOTAVAIL; - for_each_pmc_rcu(inet6, pmc) { + read_lock(&ipv6_sk_mc_lock); + for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface) continue; if (ipv6_addr_equal(&pmc->addr, group)) @@ -444,6 +428,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk, done: if (pmclocked) write_unlock(&pmc->sflock); + read_unlock(&ipv6_sk_mc_lock); read_unlock_bh(&idev->lock); rcu_read_unlock(); if (leavegroup) @@ -481,13 +466,14 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) dev = idev->dev; err = 0; + read_lock(&ipv6_sk_mc_lock); if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) { leavegroup = 1; goto done; } - for_each_pmc_rcu(inet6, pmc) { + for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { if (pmc->ifindex != gsf->gf_interface) continue; if (ipv6_addr_equal(&pmc->addr, group)) @@ -535,6 +521,7 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf) write_unlock(&pmc->sflock); err = 0; done: + read_unlock(&ipv6_sk_mc_lock); read_unlock_bh(&idev->lock); rcu_read_unlock(); if (leavegroup) @@ -575,7 +562,7 @@ int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf, * so reading the list is safe. */ - for_each_pmc_rcu(inet6, pmc) { + for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { if (pmc->ifindex != gsf->gf_interface) continue; if (ipv6_addr_equal(group, &pmc->addr)) @@ -625,13 +612,13 @@ int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, struct ip6_sf_socklist *psl; int rv = 1; - rcu_read_lock(); - for_each_pmc_rcu(np, mc) { + read_lock(&ipv6_sk_mc_lock); + for (mc = np->ipv6_mc_list; mc; mc = mc->next) { if (ipv6_addr_equal(&mc->addr, mc_addr)) break; } if (!mc) { - rcu_read_unlock(); + read_unlock(&ipv6_sk_mc_lock); return 1; } read_lock(&mc->sflock); @@ -651,7 +638,7 @@ int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr, rv = 0; } read_unlock(&mc->sflock); - rcu_read_unlock(); + read_unlock(&ipv6_sk_mc_lock); return rv; } diff --git a/trunk/net/ipv6/netfilter.c b/trunk/net/ipv6/netfilter.c index 35915e8617f0..7155b2451d7c 100644 --- a/trunk/net/ipv6/netfilter.c +++ b/trunk/net/ipv6/netfilter.c @@ -18,8 +18,10 @@ int ip6_route_me_harder(struct sk_buff *skb) struct flowi fl = { .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0, .mark = skb->mark, - .fl6_dst = iph->daddr, - .fl6_src = iph->saddr, + .nl_u = + { .ip6_u = + { .daddr = iph->daddr, + .saddr = iph->saddr, } }, }; dst = ip6_route_output(net, skb->sk, &fl); diff --git a/trunk/net/ipv6/netfilter/Makefile b/trunk/net/ipv6/netfilter/Makefile index abfee91ce816..0a432c9b0795 100644 --- a/trunk/net/ipv6/netfilter/Makefile +++ b/trunk/net/ipv6/netfilter/Makefile @@ -11,13 +11,13 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o # objects for l3 independent conntrack -nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o +nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o # l3 independent conntrack obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o # defrag -nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o +nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o # matches diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 455582384ece..51df035897e7 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -1137,7 +1137,6 @@ static int get_info(struct net *net, void __user *user, private = &tmp; } #endif - memset(&info, 0, sizeof(info)); info.valid_hooks = t->valid_hooks; memcpy(info.hook_entry, private->hook_entry, sizeof(info.hook_entry)); diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 79d43aa8fa8d..3a3f129a44cb 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -286,7 +286,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, /* Check for overlap with preceding fragment. */ if (prev && - (NFCT_FRAG6_CB(prev)->offset + prev->len) > offset) + (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset > 0) goto discard_fq; /* Look for overlap with succeeding segment. */ diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index 07beeb06f752..c7ba3149633f 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -104,22 +104,26 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr, const struct in6_addr *daddr, u32 rnd) { - u32 c; + u32 a, b, c; - c = jhash_3words((__force u32)saddr->s6_addr32[0], - (__force u32)saddr->s6_addr32[1], - (__force u32)saddr->s6_addr32[2], - rnd); + a = (__force u32)saddr->s6_addr32[0]; + b = (__force u32)saddr->s6_addr32[1]; + c = (__force u32)saddr->s6_addr32[2]; - c = jhash_3words((__force u32)saddr->s6_addr32[3], - (__force u32)daddr->s6_addr32[0], - (__force u32)daddr->s6_addr32[1], - c); + a += JHASH_GOLDEN_RATIO; + b += JHASH_GOLDEN_RATIO; + c += rnd; + __jhash_mix(a, b, c); - c = jhash_3words((__force u32)daddr->s6_addr32[2], - (__force u32)daddr->s6_addr32[3], - (__force u32)id, - c); + a += (__force u32)saddr->s6_addr32[3]; + b += (__force u32)daddr->s6_addr32[0]; + c += (__force u32)daddr->s6_addr32[1]; + __jhash_mix(a, b, c); + + a += (__force u32)daddr->s6_addr32[2]; + b += (__force u32)daddr->s6_addr32[3]; + c += (__force u32)id; + __jhash_mix(a, b, c); return c & (INETFRAGS_HASHSZ - 1); } @@ -345,7 +349,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, /* Check for overlap with preceding fragment. */ if (prev && - (FRAG6_CB(prev)->offset + prev->len) > offset) + (FRAG6_CB(prev)->offset + prev->len) - offset > 0) goto discard_fq; /* Look for overlap with succeeding segment. */ diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index a0c4ad109c63..25661f968f3f 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -558,7 +558,11 @@ struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, { struct flowi fl = { .oif = oif, - .fl6_dst = *daddr, + .nl_u = { + .ip6_u = { + .daddr = *daddr, + }, + }, }; struct dst_entry *dst; int flags = strict ? RT6_LOOKUP_F_IFACE : 0; @@ -774,9 +778,13 @@ void ip6_route_input(struct sk_buff *skb) int flags = RT6_LOOKUP_F_HAS_SADDR; struct flowi fl = { .iif = skb->dev->ifindex, - .fl6_dst = iph->daddr, - .fl6_src = iph->saddr, - .fl6_flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, + .nl_u = { + .ip6_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK, + }, + }, .mark = skb->mark, .proto = iph->nexthdr, }; @@ -1455,8 +1463,12 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest, struct ip6rd_flowi rdfl = { .fl = { .oif = dev->ifindex, - .fl6_dst = *dest, - .fl6_src = *src, + .nl_u = { + .ip6_u = { + .daddr = *dest, + .saddr = *src, + }, + }, }, }; @@ -1933,12 +1945,8 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); struct neighbour *neigh; - if (rt == NULL) { - if (net_ratelimit()) - pr_warning("IPv6: Maximum number of routes reached," - " consider increasing route/max_size.\n"); + if (rt == NULL) return ERR_PTR(-ENOMEM); - } dev_hold(net->loopback_dev); in6_dev_hold(idev); @@ -2453,6 +2461,8 @@ static int ip6_route_dev_notify(struct notifier_block *this, #ifdef CONFIG_PROC_FS +#define RT6_INFO_LEN (32 + 4 + 32 + 4 + 32 + 40 + 5 + 1) + struct rt6_proc_arg { char *buffer; @@ -2731,7 +2741,6 @@ static void __net_exit ip6_route_net_exit(struct net *net) kfree(net->ipv6.ip6_prohibit_entry); kfree(net->ipv6.ip6_blk_hole_entry); #endif - dst_entries_destroy(&net->ipv6.ip6_dst_ops); } static struct pernet_operations ip6_route_net_ops = { @@ -2823,6 +2832,5 @@ void ip6_route_cleanup(void) xfrm6_fini(); fib6_gc_cleanup(); unregister_pernet_subsys(&ip6_route_net_ops); - dst_entries_destroy(&ip6_dst_blackhole_ops); kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); } diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index 6e48a80d0f25..d6bfaec3bbbf 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -730,9 +730,10 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, } { - struct flowi fl = { .fl4_dst = dst, - .fl4_src = tiph->saddr, - .fl4_tos = RT_TOS(tos), + struct flowi fl = { .nl_u = { .ip4_u = + { .daddr = dst, + .saddr = tiph->saddr, + .tos = RT_TOS(tos) } }, .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { @@ -854,9 +855,10 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) iph = &tunnel->parms.iph; if (iph->daddr) { - struct flowi fl = { .fl4_dst = iph->daddr, - .fl4_src = iph->saddr, - .fl4_tos = RT_TOS(iph->tos), + struct flowi fl = { .nl_u = { .ip4_u = + { .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos) } }, .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; struct rtable *rt; diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index b541a4e009fb..91def93bec85 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -227,7 +227,7 @@ static struct sock *udp6_lib_lookup2(struct net *net, if (result) { exact_match: - if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2))) + if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) result = NULL; else if (unlikely(compute_score2(result, net, saddr, sport, daddr, hnum, dif) < badness)) { @@ -294,7 +294,7 @@ static struct sock *__udp6_lib_lookup(struct net *net, goto begin; if (result) { - if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2))) + if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) result = NULL; else if (unlikely(compute_score(result, net, hnum, saddr, sport, daddr, dport, dif) < badness)) { diff --git a/trunk/net/irda/ircomm/Makefile b/trunk/net/irda/ircomm/Makefile index ab23b5ba7e33..48689458c086 100644 --- a/trunk/net/irda/ircomm/Makefile +++ b/trunk/net/irda/ircomm/Makefile @@ -4,5 +4,5 @@ obj-$(CONFIG_IRCOMM) += ircomm.o ircomm-tty.o -ircomm-y := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o -ircomm-tty-y := ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o ircomm_param.o +ircomm-objs := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o +ircomm-tty-objs := ircomm_tty.o ircomm_tty_attach.o ircomm_tty_ioctl.o ircomm_param.o diff --git a/trunk/net/irda/irlan/Makefile b/trunk/net/irda/irlan/Makefile index 94eefbc8e6b9..77549bc8641b 100644 --- a/trunk/net/irda/irlan/Makefile +++ b/trunk/net/irda/irlan/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_IRLAN) += irlan.o -irlan-y := irlan_common.o irlan_eth.o irlan_event.o irlan_client.o irlan_provider.o irlan_filter.o irlan_provider_event.o irlan_client_event.o +irlan-objs := irlan_common.o irlan_eth.o irlan_event.o irlan_client.o irlan_provider.o irlan_filter.o irlan_provider_event.o irlan_client_event.o diff --git a/trunk/net/irda/irnet/Makefile b/trunk/net/irda/irnet/Makefile index 61c365c8a2a0..b3ee01e0def3 100644 --- a/trunk/net/irda/irnet/Makefile +++ b/trunk/net/irda/irnet/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_IRNET) += irnet.o -irnet-y := irnet_ppp.o irnet_irda.o +irnet-objs := irnet_ppp.o irnet_irda.o diff --git a/trunk/net/irda/irttp.c b/trunk/net/irda/irttp.c index f6054f9ccbe3..285761e77d90 100644 --- a/trunk/net/irda/irttp.c +++ b/trunk/net/irda/irttp.c @@ -550,30 +550,22 @@ EXPORT_SYMBOL(irttp_close_tsap); */ int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb) { - int ret; - IRDA_ASSERT(self != NULL, return -1;); IRDA_ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;); IRDA_ASSERT(skb != NULL, return -1;); IRDA_DEBUG(4, "%s()\n", __func__); - /* Take shortcut on zero byte packets */ - if (skb->len == 0) { - ret = 0; - goto err; - } - /* Check that nothing bad happens */ - if (!self->connected) { - IRDA_WARNING("%s(), Not connected\n", __func__); - ret = -ENOTCONN; + if ((skb->len == 0) || (!self->connected)) { + IRDA_DEBUG(1, "%s(), No data, or not connected\n", + __func__); goto err; } if (skb->len > self->max_seg_size) { - IRDA_ERROR("%s(), UData is too large for IrLAP!\n", __func__); - ret = -EMSGSIZE; + IRDA_DEBUG(1, "%s(), UData is too large for IrLAP!\n", + __func__); goto err; } @@ -584,7 +576,7 @@ int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb) err: dev_kfree_skb(skb); - return ret; + return -1; } EXPORT_SYMBOL(irttp_udata_request); @@ -607,15 +599,9 @@ int irttp_data_request(struct tsap_cb *self, struct sk_buff *skb) IRDA_DEBUG(2, "%s() : queue len = %d\n", __func__, skb_queue_len(&self->tx_queue)); - /* Take shortcut on zero byte packets */ - if (skb->len == 0) { - ret = 0; - goto err; - } - /* Check that nothing bad happens */ - if (!self->connected) { - IRDA_WARNING("%s: Not connected\n", __func__); + if ((skb->len == 0) || (!self->connected)) { + IRDA_WARNING("%s: No data, or not connected\n", __func__); ret = -ENOTCONN; goto err; } diff --git a/trunk/net/l2tp/l2tp_debugfs.c b/trunk/net/l2tp/l2tp_debugfs.c index b8dbae82fab8..104ec3b283d4 100644 --- a/trunk/net/l2tp/l2tp_debugfs.c +++ b/trunk/net/l2tp/l2tp_debugfs.c @@ -249,7 +249,7 @@ static int l2tp_dfs_seq_open(struct inode *inode, struct file *file) struct seq_file *seq; int rc = -ENOMEM; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc(GFP_KERNEL, sizeof(*pd)); if (pd == NULL) goto out; diff --git a/trunk/net/l2tp/l2tp_ip.c b/trunk/net/l2tp/l2tp_ip.c index 04635e88e8ed..0bf6a59545ab 100644 --- a/trunk/net/l2tp/l2tp_ip.c +++ b/trunk/net/l2tp/l2tp_ip.c @@ -476,13 +476,15 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m { struct flowi fl = { .oif = sk->sk_bound_dev_if, - .fl4_dst = daddr, - .fl4_src = inet->inet_saddr, - .fl4_tos = RT_CONN_FLAGS(sk), + .nl_u = { .ip4_u = { + .daddr = daddr, + .saddr = inet->inet_saddr, + .tos = RT_CONN_FLAGS(sk) } }, .proto = sk->sk_protocol, .flags = inet_sk_flowi_flags(sk), - .fl_ip_sport = inet->inet_sport, - .fl_ip_dport = inet->inet_dport }; + .uli_u = { .ports = { + .sport = inet->inet_sport, + .dport = inet->inet_dport } } }; /* If this fails, retransmit mechanism of transport layer will * keep trying until route appears or the connection times diff --git a/trunk/net/lapb/Makefile b/trunk/net/lapb/Makefile index fff797dfc88c..53f7c90db163 100644 --- a/trunk/net/lapb/Makefile +++ b/trunk/net/lapb/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_LAPB) += lapb.o -lapb-y := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o +lapb-objs := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 7aa85591dbe7..f9163b12c7f1 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -391,9 +391,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, u32 hw_reconf_flags = 0; int i; - if (local->scan_sdata == sdata) - ieee80211_scan_cancel(local); - clear_bit(SDATA_STATE_RUNNING, &sdata->state); /* @@ -526,6 +523,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, synchronize_rcu(); skb_queue_purge(&sdata->skb_queue); + if (local->scan_sdata == sdata) + ieee80211_scan_cancel(local); + /* * Disable beaconing here for mesh only, AP and IBSS * are already taken care of. diff --git a/trunk/net/netfilter/core.c b/trunk/net/netfilter/core.c index 32fcbe290c04..85dabb86be6f 100644 --- a/trunk/net/netfilter/core.c +++ b/trunk/net/netfilter/core.c @@ -173,11 +173,9 @@ int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, outdev, &elem, okfn, hook_thresh); if (verdict == NF_ACCEPT || verdict == NF_STOP) { ret = 1; - } else if ((verdict & NF_VERDICT_MASK) == NF_DROP) { + } else if (verdict == NF_DROP) { kfree_skb(skb); - ret = -(verdict >> NF_VERDICT_BITS); - if (ret == 0) - ret = -EPERM; + ret = -EPERM; } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn, verdict >> NF_VERDICT_BITS)) diff --git a/trunk/net/netfilter/ipvs/Kconfig b/trunk/net/netfilter/ipvs/Kconfig index 70bd1d0774c6..a22dac227055 100644 --- a/trunk/net/netfilter/ipvs/Kconfig +++ b/trunk/net/netfilter/ipvs/Kconfig @@ -4,7 +4,6 @@ menuconfig IP_VS tristate "IP virtual server support" depends on NET && INET && NETFILTER - depends on (NF_CONNTRACK || NF_CONNTRACK=n) ---help--- IP Virtual Server support will let you build a high-performance virtual server based on cluster of two or more real servers. This diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index c6f293639220..5f5daa30b0af 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -110,8 +110,10 @@ static int __ip_vs_addr_is_local_v6(const struct in6_addr *addr) struct rt6_info *rt; struct flowi fl = { .oif = 0, - .fl6_dst = *addr, - .fl6_src = { .s6_addr32 = {0, 0, 0, 0} }, + .nl_u = { + .ip6_u = { + .daddr = *addr, + .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } }, }; rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); diff --git a/trunk/net/netfilter/ipvs/ip_vs_xmit.c b/trunk/net/netfilter/ipvs/ip_vs_xmit.c index 5325a3fbe4ac..de04ea39cde8 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_xmit.c +++ b/trunk/net/netfilter/ipvs/ip_vs_xmit.c @@ -96,8 +96,12 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, if (!(rt = (struct rtable *) __ip_vs_dst_check(dest, rtos))) { struct flowi fl = { - .fl4_dst = dest->addr.ip, - .fl4_tos = rtos, + .oif = 0, + .nl_u = { + .ip4_u = { + .daddr = dest->addr.ip, + .saddr = 0, + .tos = rtos, } }, }; if (ip_route_output_key(net, &rt, &fl)) { @@ -114,8 +118,12 @@ __ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, spin_unlock(&dest->dst_lock); } else { struct flowi fl = { - .fl4_dst = daddr, - .fl4_tos = rtos, + .oif = 0, + .nl_u = { + .ip4_u = { + .daddr = daddr, + .saddr = 0, + .tos = rtos, } }, }; if (ip_route_output_key(net, &rt, &fl)) { @@ -161,7 +169,7 @@ __ip_vs_reroute_locally(struct sk_buff *skb) struct net *net = dev_net(dev); struct iphdr *iph = ip_hdr(skb); - if (rt_is_input_route(rt)) { + if (rt->fl.iif) { unsigned long orefdst = skb->_skb_refdst; if (ip_route_input(skb, iph->daddr, iph->saddr, @@ -170,9 +178,14 @@ __ip_vs_reroute_locally(struct sk_buff *skb) refdst_drop(orefdst); } else { struct flowi fl = { - .fl4_dst = iph->daddr, - .fl4_src = iph->saddr, - .fl4_tos = RT_TOS(iph->tos), + .oif = 0, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos), + } + }, .mark = skb->mark, }; struct rtable *rt; @@ -203,7 +216,12 @@ __ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr, { struct dst_entry *dst; struct flowi fl = { - .fl6_dst = *daddr, + .oif = 0, + .nl_u = { + .ip6_u = { + .daddr = *daddr, + }, + }, }; dst = ip6_route_output(net, NULL, &fl); @@ -534,8 +552,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, #endif /* From world but DNAT to loopback address? */ - if (local && ipv4_is_loopback(rt->rt_dst) && - rt_is_input_route(skb_rtable(skb))) { + if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): " "stopping DNAT to loopback address"); goto tx_error_put; @@ -1148,8 +1165,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, #endif /* From world but DNAT to loopback address? */ - if (local && ipv4_is_loopback(rt->rt_dst) && - rt_is_input_route(skb_rtable(skb))) { + if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { IP_VS_DBG(1, "%s(): " "stopping DNAT to loopback %pI4\n", __func__, &cp->daddr.ip); diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index 27a5ea6b6a0f..1eacf8d9966a 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -1312,8 +1312,7 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls) if (!hash) { *vmalloced = 1; printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); - hash = __vmalloc(sz, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, - PAGE_KERNEL); + hash = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); } if (hash && nulls) diff --git a/trunk/net/netfilter/nf_conntrack_proto.c b/trunk/net/netfilter/nf_conntrack_proto.c index dc7bb74110df..ed6d92958023 100644 --- a/trunk/net/netfilter/nf_conntrack_proto.c +++ b/trunk/net/netfilter/nf_conntrack_proto.c @@ -292,12 +292,6 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) for (i = 0; i < MAX_NF_CT_PROTO; i++) proto_array[i] = &nf_conntrack_l4proto_generic; - - /* Before making proto_array visible to lockless readers, - * we must make sure its content is committed to memory. - */ - smp_wmb(); - nf_ct_protos[l4proto->l3proto] = proto_array; } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != &nf_conntrack_l4proto_generic) { diff --git a/trunk/net/netfilter/xt_TEE.c b/trunk/net/netfilter/xt_TEE.c index 5128a6c4cb2c..22a2d421e7eb 100644 --- a/trunk/net/netfilter/xt_TEE.c +++ b/trunk/net/netfilter/xt_TEE.c @@ -70,9 +70,9 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info) return false; fl.oif = info->priv->oif; } - fl.fl4_dst = info->gw.ip; - fl.fl4_tos = RT_TOS(iph->tos); - fl.fl4_scope = RT_SCOPE_UNIVERSE; + fl.nl_u.ip4_u.daddr = info->gw.ip; + fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); + fl.nl_u.ip4_u.scope = RT_SCOPE_UNIVERSE; if (ip_route_output_key(net, &rt, &fl) != 0) return false; @@ -150,9 +150,9 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info) return false; fl.oif = info->priv->oif; } - fl.fl6_dst = info->gw.in6; - fl.fl6_flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | - (iph->flow_lbl[1] << 8) | iph->flow_lbl[2]; + fl.nl_u.ip6_u.daddr = info->gw.in6; + fl.nl_u.ip6_u.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | + (iph->flow_lbl[1] << 8) | iph->flow_lbl[2]; dst = ip6_route_output(net, NULL, &fl); if (dst == NULL) return false; diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index 422705d62b5b..3616f27b9d46 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -164,14 +163,8 @@ struct packet_mreq_max { static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing, int tx_ring); -#define PGV_FROM_VMALLOC 1 -struct pgv { - char *buffer; - unsigned char flags; -}; - struct packet_ring_buffer { - struct pgv *pg_vec; + char **pg_vec; unsigned int head; unsigned int frames_per_block; unsigned int frame_size; @@ -290,8 +283,7 @@ static void *packet_lookup_frame(struct packet_sock *po, pg_vec_pos = position / rb->frames_per_block; frame_offset = position % rb->frames_per_block; - h.raw = rb->pg_vec[pg_vec_pos].buffer + - (frame_offset * rb->frame_size); + h.raw = rb->pg_vec[pg_vec_pos] + (frame_offset * rb->frame_size); if (status != __packet_get_status(po, h.raw)) return NULL; @@ -519,7 +511,7 @@ static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk, rcu_read_lock_bh(); filter = rcu_dereference_bh(sk->sk_filter); if (filter != NULL) - res = sk_run_filter(skb, filter->insns); + res = sk_run_filter(skb, filter->insns, filter->len); rcu_read_unlock_bh(); return res; @@ -1618,11 +1610,9 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock, err = -EINVAL; vnet_hdr_len = sizeof(vnet_hdr); - if (len < vnet_hdr_len) + if ((len -= vnet_hdr_len) < 0) goto out_free; - len -= vnet_hdr_len; - if (skb_is_gso(skb)) { struct skb_shared_info *sinfo = skb_shinfo(skb); @@ -1729,7 +1719,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); if (dev) - strncpy(uaddr->sa_data, dev->name, 14); + strlcpy(uaddr->sa_data, dev->name, 15); else memset(uaddr->sa_data, 0, 14); rcu_read_unlock(); @@ -1752,7 +1742,6 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, sll->sll_family = AF_PACKET; sll->sll_ifindex = po->ifindex; sll->sll_protocol = po->num; - sll->sll_pkttype = 0; rcu_read_lock(); dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex); if (dev) { @@ -2333,74 +2322,37 @@ static const struct vm_operations_struct packet_mmap_ops = { .close = packet_mm_close, }; -static void free_pg_vec(struct pgv *pg_vec, unsigned int order, - unsigned int len) +static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len) { int i; for (i = 0; i < len; i++) { - if (likely(pg_vec[i].buffer)) { - if (pg_vec[i].flags & PGV_FROM_VMALLOC) - vfree(pg_vec[i].buffer); - else - free_pages((unsigned long)pg_vec[i].buffer, - order); - pg_vec[i].buffer = NULL; - } + if (likely(pg_vec[i])) + free_pages((unsigned long) pg_vec[i], order); } kfree(pg_vec); } -static inline char *alloc_one_pg_vec_page(unsigned long order, - unsigned char *flags) +static inline char *alloc_one_pg_vec_page(unsigned long order) { - char *buffer = NULL; - gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | - __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY; - - buffer = (char *) __get_free_pages(gfp_flags, order); - - if (buffer) - return buffer; - - /* - * __get_free_pages failed, fall back to vmalloc - */ - *flags |= PGV_FROM_VMALLOC; - buffer = vzalloc((1 << order) * PAGE_SIZE); - - if (buffer) - return buffer; - - /* - * vmalloc failed, lets dig into swap here - */ - *flags = 0; - gfp_flags &= ~__GFP_NORETRY; - buffer = (char *)__get_free_pages(gfp_flags, order); - if (buffer) - return buffer; + gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP | __GFP_ZERO | __GFP_NOWARN; - /* - * complete and utter failure - */ - return NULL; + return (char *) __get_free_pages(gfp_flags, order); } -static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order) +static char **alloc_pg_vec(struct tpacket_req *req, int order) { unsigned int block_nr = req->tp_block_nr; - struct pgv *pg_vec; + char **pg_vec; int i; - pg_vec = kcalloc(block_nr, sizeof(struct pgv), GFP_KERNEL); + pg_vec = kzalloc(block_nr * sizeof(char *), GFP_KERNEL); if (unlikely(!pg_vec)) goto out; for (i = 0; i < block_nr; i++) { - pg_vec[i].buffer = alloc_one_pg_vec_page(order, - &pg_vec[i].flags); - if (unlikely(!pg_vec[i].buffer)) + pg_vec[i] = alloc_one_pg_vec_page(order); + if (unlikely(!pg_vec[i])) goto out_free_pgvec; } @@ -2409,7 +2361,6 @@ static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order) out_free_pgvec: free_pg_vec(pg_vec, order, block_nr); - kfree(pg_vec); pg_vec = NULL; goto out; } @@ -2417,7 +2368,7 @@ static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order) static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing, int tx_ring) { - struct pgv *pg_vec = NULL; + char **pg_vec = NULL; struct packet_sock *po = pkt_sk(sk); int was_running, order = 0; struct packet_ring_buffer *rb; @@ -2579,22 +2530,15 @@ static int packet_mmap(struct file *file, struct socket *sock, continue; for (i = 0; i < rb->pg_vec_len; i++) { - struct page *page; - void *kaddr = rb->pg_vec[i].buffer; + struct page *page = virt_to_page(rb->pg_vec[i]); int pg_num; for (pg_num = 0; pg_num < rb->pg_vec_pages; - pg_num++) { - if (rb->pg_vec[i].flags & PGV_FROM_VMALLOC) - page = vmalloc_to_page(kaddr); - else - page = virt_to_page(kaddr); - + pg_num++, page++) { err = vm_insert_page(vma, start, page); if (unlikely(err)) goto out; start += PAGE_SIZE; - kaddr += PAGE_SIZE; } } } diff --git a/trunk/net/phonet/Makefile b/trunk/net/phonet/Makefile index e10b1b182ce3..d62bbba649b3 100644 --- a/trunk/net/phonet/Makefile +++ b/trunk/net/phonet/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_PHONET) += phonet.o pn_pep.o -phonet-y := \ +phonet-objs := \ pn_dev.o \ pn_netlink.o \ socket.o \ @@ -8,4 +8,4 @@ phonet-y := \ sysctl.o \ af_phonet.o -pn_pep-y := pep.o pep-gprs.o +pn_pep-objs := pep.o pep-gprs.o diff --git a/trunk/net/rds/Makefile b/trunk/net/rds/Makefile index 56d3f6023ced..b46eca109688 100644 --- a/trunk/net/rds/Makefile +++ b/trunk/net/rds/Makefile @@ -4,7 +4,7 @@ rds-y := af_rds.o bind.o cong.o connection.o info.o message.o \ loop.o page.o rdma.o obj-$(CONFIG_RDS_RDMA) += rds_rdma.o -rds_rdma-y := rdma_transport.o \ +rds_rdma-objs := rdma_transport.o \ ib.o ib_cm.o ib_recv.o ib_ring.o ib_send.o ib_stats.o \ ib_sysctl.o ib_rdma.o \ iw.o iw_cm.o iw_recv.o iw_ring.o iw_send.o iw_stats.o \ @@ -12,8 +12,10 @@ rds_rdma-y := rdma_transport.o \ obj-$(CONFIG_RDS_TCP) += rds_tcp.o -rds_tcp-y := tcp.o tcp_connect.o tcp_listen.o tcp_recv.o \ +rds_tcp-objs := tcp.o tcp_connect.o tcp_listen.o tcp_recv.o \ tcp_send.o tcp_stats.o -ccflags-$(CONFIG_RDS_DEBUG) := -DDEBUG +ifeq ($(CONFIG_RDS_DEBUG), y) +EXTRA_CFLAGS += -DDEBUG +endif diff --git a/trunk/net/rds/loop.c b/trunk/net/rds/loop.c index aeec1d483b17..c390156b426f 100644 --- a/trunk/net/rds/loop.c +++ b/trunk/net/rds/loop.c @@ -134,12 +134,8 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp) static void rds_loop_conn_free(void *arg) { struct rds_loop_connection *lc = arg; - unsigned long flags; - rdsdebug("lc %p\n", lc); - spin_lock_irqsave(&loop_conns_lock, flags); list_del(&lc->loop_node); - spin_unlock_irqrestore(&loop_conns_lock, flags); kfree(lc); } diff --git a/trunk/net/rds/message.c b/trunk/net/rds/message.c index 1fd3d29023d7..848cff45183b 100644 --- a/trunk/net/rds/message.c +++ b/trunk/net/rds/message.c @@ -249,10 +249,8 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); rm->data.op_nents = ceil(total_len, PAGE_SIZE); rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); - if (!rm->data.op_sg) { - rds_message_put(rm); + if (!rm->data.op_sg) return ERR_PTR(-ENOMEM); - } for (i = 0; i < rm->data.op_nents; ++i) { sg_set_page(&rm->data.op_sg[i], diff --git a/trunk/net/rds/rdma.c b/trunk/net/rds/rdma.c index 4e37c1cbe8b2..8920f2a83327 100644 --- a/trunk/net/rds/rdma.c +++ b/trunk/net/rds/rdma.c @@ -567,7 +567,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, goto out; } - if (args->nr_local > UIO_MAXIOV) { + if (args->nr_local > (u64)UINT_MAX) { ret = -EMSGSIZE; goto out; } diff --git a/trunk/net/rds/tcp.c b/trunk/net/rds/tcp.c index 8e0a32001c90..08a8c6cf2d10 100644 --- a/trunk/net/rds/tcp.c +++ b/trunk/net/rds/tcp.c @@ -221,13 +221,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) static void rds_tcp_conn_free(void *arg) { struct rds_tcp_connection *tc = arg; - unsigned long flags; rdsdebug("freeing tc %p\n", tc); - - spin_lock_irqsave(&rds_tcp_conn_lock, flags); - list_del(&tc->t_tcp_node); - spin_unlock_irqrestore(&rds_tcp_conn_lock, flags); - kmem_cache_free(rds_tcp_conn_slab, tc); } diff --git a/trunk/net/rxrpc/Makefile b/trunk/net/rxrpc/Makefile index d1c3429b69ed..c46867c61c98 100644 --- a/trunk/net/rxrpc/Makefile +++ b/trunk/net/rxrpc/Makefile @@ -2,7 +2,7 @@ # Makefile for Linux kernel RxRPC # -af-rxrpc-y := \ +af-rxrpc-objs := \ af_rxrpc.o \ ar-accept.o \ ar-ack.o \ @@ -21,7 +21,7 @@ af-rxrpc-y := \ ar-transport.o ifeq ($(CONFIG_PROC_FS),y) -af-rxrpc-y += ar-proc.o +af-rxrpc-objs += ar-proc.o endif obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o diff --git a/trunk/net/rxrpc/ar-peer.c b/trunk/net/rxrpc/ar-peer.c index a53fb25a64ed..9f1729bd60de 100644 --- a/trunk/net/rxrpc/ar-peer.c +++ b/trunk/net/rxrpc/ar-peer.c @@ -47,12 +47,12 @@ static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer) case AF_INET: fl.oif = 0; fl.proto = IPPROTO_UDP, - fl.fl4_dst = peer->srx.transport.sin.sin_addr.s_addr; - fl.fl4_src = 0; - fl.fl4_tos = 0; + fl.nl_u.ip4_u.saddr = 0; + fl.nl_u.ip4_u.daddr = peer->srx.transport.sin.sin_addr.s_addr; + fl.nl_u.ip4_u.tos = 0; /* assume AFS.CM talking to AFS.FS */ - fl.fl_ip_sport = htons(7001); - fl.fl_ip_dport = htons(7000); + fl.uli_u.ports.sport = htons(7001); + fl.uli_u.ports.dport = htons(7000); break; default: BUG(); diff --git a/trunk/net/sched/cls_basic.c b/trunk/net/sched/cls_basic.c index f23d9155b1ef..efd4f95fd050 100644 --- a/trunk/net/sched/cls_basic.c +++ b/trunk/net/sched/cls_basic.c @@ -268,10 +268,6 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, goto nla_put_failure; nla_nest_end(skb, nest); - - if (tcf_exts_dump_stats(skb, &f->exts, &basic_ext_map) < 0) - goto nla_put_failure; - return skb->len; nla_put_failure: diff --git a/trunk/net/sched/cls_cgroup.c b/trunk/net/sched/cls_cgroup.c index d49c40fb7e09..37dff78e9cb1 100644 --- a/trunk/net/sched/cls_cgroup.c +++ b/trunk/net/sched/cls_cgroup.c @@ -34,6 +34,8 @@ struct cgroup_subsys net_cls_subsys = { .populate = cgrp_populate, #ifdef CONFIG_NET_CLS_CGROUP .subsys_id = net_cls_subsys_id, +#else +#define net_cls_subsys_id net_cls_subsys.subsys_id #endif .module = THIS_MODULE, }; diff --git a/trunk/net/sched/em_text.c b/trunk/net/sched/em_text.c index ea8f566e720c..763253257411 100644 --- a/trunk/net/sched/em_text.c +++ b/trunk/net/sched/em_text.c @@ -103,8 +103,7 @@ static int em_text_change(struct tcf_proto *tp, void *data, int len, static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m) { - if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) - textsearch_destroy(EM_TEXT_PRIV(m)->config); + textsearch_destroy(EM_TEXT_PRIV(m)->config); } static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index 7f0bd8952646..5dbb3cd96e59 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -60,7 +60,8 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q) /* check the reason of requeuing without tx lock first */ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); - if (!netif_tx_queue_frozen_or_stopped(txq)) { + if (!netif_tx_queue_stopped(txq) && + !netif_tx_queue_frozen(txq)) { q->gso_skb = NULL; q->q.qlen--; } else @@ -121,7 +122,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, spin_unlock(root_lock); HARD_TX_LOCK(dev, txq, smp_processor_id()); - if (!netif_tx_queue_frozen_or_stopped(txq)) + if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq)) ret = dev_hard_start_xmit(skb, dev, txq); HARD_TX_UNLOCK(dev, txq); @@ -143,7 +144,8 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, ret = dev_requeue_skb(skb, q); } - if (ret && netif_tx_queue_frozen_or_stopped(txq)) + if (ret && (netif_tx_queue_stopped(txq) || + netif_tx_queue_frozen(txq))) ret = 0; return ret; diff --git a/trunk/net/sched/sch_teql.c b/trunk/net/sched/sch_teql.c index 106479a7c94a..401af9596709 100644 --- a/trunk/net/sched/sch_teql.c +++ b/trunk/net/sched/sch_teql.c @@ -309,7 +309,8 @@ static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev) if (__netif_tx_trylock(slave_txq)) { unsigned int length = qdisc_pkt_len(skb); - if (!netif_tx_queue_frozen_or_stopped(slave_txq) && + if (!netif_tx_queue_stopped(slave_txq) && + !netif_tx_queue_frozen(slave_txq) && slave_ops->ndo_start_xmit(skb, slave) == NETDEV_TX_OK) { txq_trans_update(slave_txq); __netif_tx_unlock(slave_txq); diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index e58f9476f29c..1ef29c74d85e 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -92,7 +92,7 @@ static struct sctp_af *sctp_af_v6_specific; struct kmem_cache *sctp_chunk_cachep __read_mostly; struct kmem_cache *sctp_bucket_cachep __read_mostly; -long sysctl_sctp_mem[3]; +int sysctl_sctp_mem[3]; int sysctl_sctp_rmem[3]; int sysctl_sctp_wmem[3]; diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 6bd554323a34..e34ca9cc1167 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -111,12 +111,12 @@ static void sctp_sock_migrate(struct sock *, struct sock *, static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; extern struct kmem_cache *sctp_bucket_cachep; -extern long sysctl_sctp_mem[3]; +extern int sysctl_sctp_mem[3]; extern int sysctl_sctp_rmem[3]; extern int sysctl_sctp_wmem[3]; static int sctp_memory_pressure; -static atomic_long_t sctp_memory_allocated; +static atomic_t sctp_memory_allocated; struct percpu_counter sctp_sockets_allocated; static void sctp_enter_memory_pressure(struct sock *sk) diff --git a/trunk/net/sctp/sysctl.c b/trunk/net/sctp/sysctl.c index 50cb57f0919e..832590bbe0c0 100644 --- a/trunk/net/sctp/sysctl.c +++ b/trunk/net/sctp/sysctl.c @@ -54,7 +54,7 @@ static int sack_timer_max = 500; static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ static int rwnd_scale_max = 16; -extern long sysctl_sctp_mem[3]; +extern int sysctl_sctp_mem[3]; extern int sysctl_sctp_rmem[3]; extern int sysctl_sctp_wmem[3]; @@ -203,7 +203,7 @@ static ctl_table sctp_table[] = { .data = &sysctl_sctp_mem, .maxlen = sizeof(sysctl_sctp_mem), .mode = 0644, - .proc_handler = proc_doulongvec_minmax + .proc_handler = proc_dointvec, }, { .procname = "sctp_rmem", diff --git a/trunk/net/socket.c b/trunk/net/socket.c index c898df76e924..3ca2fd9e3720 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -156,7 +156,7 @@ static const struct file_operations socket_file_ops = { */ static DEFINE_SPINLOCK(net_family_lock); -static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly; +static const struct net_proto_family *net_families[NPROTO] __read_mostly; /* * Statistics counters of the socket lists @@ -1200,7 +1200,7 @@ int __sock_create(struct net *net, int family, int type, int protocol, * requested real, full-featured networking support upon configuration. * Otherwise module support will break! */ - if (rcu_access_pointer(net_families[family]) == NULL) + if (net_families[family] == NULL) request_module("net-pf-%d", family); #endif @@ -2332,11 +2332,10 @@ int sock_register(const struct net_proto_family *ops) } spin_lock(&net_family_lock); - if (rcu_dereference_protected(net_families[ops->family], - lockdep_is_held(&net_family_lock))) + if (net_families[ops->family]) err = -EEXIST; else { - rcu_assign_pointer(net_families[ops->family], ops); + net_families[ops->family] = ops; err = 0; } spin_unlock(&net_family_lock); @@ -2364,7 +2363,7 @@ void sock_unregister(int family) BUG_ON(family < 0 || family >= NPROTO); spin_lock(&net_family_lock); - rcu_assign_pointer(net_families[family], NULL); + net_families[family] = NULL; spin_unlock(&net_family_lock); synchronize_rcu(); diff --git a/trunk/net/sunrpc/auth_gss/Makefile b/trunk/net/sunrpc/auth_gss/Makefile index 9e4cb59ef9f0..7350d86a32ee 100644 --- a/trunk/net/sunrpc/auth_gss/Makefile +++ b/trunk/net/sunrpc/auth_gss/Makefile @@ -4,10 +4,10 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_rpcgss.o -auth_rpcgss-y := auth_gss.o gss_generic_token.o \ +auth_rpcgss-objs := auth_gss.o gss_generic_token.o \ gss_mech_switch.o svcauth_gss.o obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o -rpcsec_gss_krb5-y := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \ +rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \ gss_krb5_seqnum.o gss_krb5_wrap.o gss_krb5_crypto.o gss_krb5_keys.o diff --git a/trunk/net/tipc/socket.c b/trunk/net/tipc/socket.c index e9f0d5004483..33217fc3d697 100644 --- a/trunk/net/tipc/socket.c +++ b/trunk/net/tipc/socket.c @@ -396,7 +396,6 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; struct tipc_sock *tsock = tipc_sk(sock->sk); - memset(addr, 0, sizeof(*addr)); if (peer) { if ((sock->state != SS_CONNECTED) && ((peer != 2) || (sock->state != SS_DISCONNECTING))) diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 7ff31c60186a..3c95304a0817 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -316,8 +316,7 @@ static void unix_write_space(struct sock *sk) if (unix_writable(sk)) { wq = rcu_dereference(sk->sk_wq); if (wq_has_sleeper(wq)) - wake_up_interruptible_sync_poll(&wq->wait, - POLLOUT | POLLWRNORM | POLLWRBAND); + wake_up_interruptible_sync(&wq->wait); sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); } rcu_read_unlock(); @@ -1711,8 +1710,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, goto out_unlock; } - wake_up_interruptible_sync_poll(&u->peer_wait, - POLLOUT | POLLWRNORM | POLLWRBAND); + wake_up_interruptible_sync(&u->peer_wait); if (msg->msg_name) unix_copy_addr(msg, skb->sk); @@ -2074,12 +2072,13 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP | POLLIN | POLLRDNORM; + mask |= POLLRDHUP; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty(&sk->sk_receive_queue) || + (sk->sk_shutdown & RCV_SHUTDOWN)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ @@ -2091,19 +2090,20 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, return mask; } - /* No write status requested, avoid expensive OUT tests. */ - if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT))) - return mask; - + /* writable? */ writable = unix_writable(sk); - other = unix_peer_get(sk); - if (other) { - if (unix_peer(other) != sk) { - sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); - if (unix_recvq_full(other)) - writable = 0; + if (writable) { + other = unix_peer_get(sk); + if (other) { + if (unix_peer(other) != sk) { + sock_poll_wait(file, &unix_sk(other)->peer_wait, + wait); + if (unix_recvq_full(other)) + writable = 0; + } + + sock_put(other); } - sock_put(other); } if (writable) diff --git a/trunk/net/wanrouter/Makefile b/trunk/net/wanrouter/Makefile index 4da14bc48078..9f188ab3dcd0 100644 --- a/trunk/net/wanrouter/Makefile +++ b/trunk/net/wanrouter/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_WAN_ROUTER) += wanrouter.o -wanrouter-y := wanproc.o wanmain.o +wanrouter-objs := wanproc.o wanmain.o diff --git a/trunk/net/wireless/chan.c b/trunk/net/wireless/chan.c index 17cd0c04d139..d0c92dddb26b 100644 --- a/trunk/net/wireless/chan.c +++ b/trunk/net/wireless/chan.c @@ -44,38 +44,6 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev, return chan; } -static bool can_beacon_sec_chan(struct wiphy *wiphy, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type) -{ - struct ieee80211_channel *sec_chan; - int diff; - - switch (channel_type) { - case NL80211_CHAN_HT40PLUS: - diff = 20; - break; - case NL80211_CHAN_HT40MINUS: - diff = -20; - break; - default: - return false; - } - - sec_chan = ieee80211_get_channel(wiphy, chan->center_freq + diff); - if (!sec_chan) - return false; - - /* we'll need a DFS capability later */ - if (sec_chan->flags & (IEEE80211_CHAN_DISABLED | - IEEE80211_CHAN_PASSIVE_SCAN | - IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_RADAR)) - return false; - - return true; -} - int cfg80211_set_freq(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, int freq, enum nl80211_channel_type channel_type) @@ -100,28 +68,6 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev, if (!chan) return -EINVAL; - /* Both channels should be able to initiate communication */ - if (wdev && (wdev->iftype == NL80211_IFTYPE_ADHOC || - wdev->iftype == NL80211_IFTYPE_AP || - wdev->iftype == NL80211_IFTYPE_AP_VLAN || - wdev->iftype == NL80211_IFTYPE_MESH_POINT || - wdev->iftype == NL80211_IFTYPE_P2P_GO)) { - switch (channel_type) { - case NL80211_CHAN_HT40PLUS: - case NL80211_CHAN_HT40MINUS: - if (!can_beacon_sec_chan(&rdev->wiphy, chan, - channel_type)) { - printk(KERN_DEBUG - "cfg80211: Secondary channel not " - "allowed to initiate communication\n"); - return -EINVAL; - } - break; - default: - break; - } - } - result = rdev->ops->set_channel(&rdev->wiphy, wdev ? wdev->netdev : NULL, chan, channel_type); diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 4e78e3f26798..c506241f8637 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -224,8 +224,8 @@ static int nl80211_prepare_netdev_dump(struct sk_buff *skb, } *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(*rdev)) { - err = PTR_ERR(*rdev); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); goto out_rtnl; } diff --git a/trunk/net/x25/af_x25.c b/trunk/net/x25/af_x25.c index ad96ee90fe27..f7af98dff409 100644 --- a/trunk/net/x25/af_x25.c +++ b/trunk/net/x25/af_x25.c @@ -1357,11 +1357,11 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) void __user *argp = (void __user *)arg; int rc; + lock_kernel(); switch (cmd) { case TIOCOUTQ: { - int amount; + int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); - amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); if (amount < 0) amount = 0; rc = put_user(amount, (unsigned int __user *)argp); @@ -1375,10 +1375,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) * These two are safe on a single CPU system as * only user tasks fiddle here */ - lock_sock(sk); if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) amount = skb->len; - release_sock(sk); rc = put_user(amount, (unsigned int __user *)argp); break; } @@ -1424,11 +1422,9 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = x25_subscr_ioctl(cmd, argp); break; case SIOCX25GFACILITIES: { - lock_sock(sk); - rc = copy_to_user(argp, &x25->facilities, - sizeof(x25->facilities)) - ? -EFAULT : 0; - release_sock(sk); + struct x25_facilities fac = x25->facilities; + rc = copy_to_user(argp, &fac, + sizeof(fac)) ? -EFAULT : 0; break; } @@ -1439,19 +1435,18 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) sizeof(facilities))) break; rc = -EINVAL; - lock_sock(sk); if (sk->sk_state != TCP_LISTEN && sk->sk_state != TCP_CLOSE) - goto out_fac_release; + break; if (facilities.pacsize_in < X25_PS16 || facilities.pacsize_in > X25_PS4096) - goto out_fac_release; + break; if (facilities.pacsize_out < X25_PS16 || facilities.pacsize_out > X25_PS4096) - goto out_fac_release; + break; if (facilities.winsize_in < 1 || facilities.winsize_in > 127) - goto out_fac_release; + break; if (facilities.throughput) { int out = facilities.throughput & 0xf0; int in = facilities.throughput & 0x0f; @@ -1459,28 +1454,24 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) facilities.throughput |= X25_DEFAULT_THROUGHPUT << 4; else if (out < 0x30 || out > 0xD0) - goto out_fac_release; + break; if (!in) facilities.throughput |= X25_DEFAULT_THROUGHPUT; else if (in < 0x03 || in > 0x0D) - goto out_fac_release; + break; } if (facilities.reverse && (facilities.reverse & 0x81) != 0x81) - goto out_fac_release; + break; x25->facilities = facilities; rc = 0; -out_fac_release: - release_sock(sk); break; } case SIOCX25GDTEFACILITIES: { - lock_sock(sk); rc = copy_to_user(argp, &x25->dte_facilities, sizeof(x25->dte_facilities)); - release_sock(sk); if (rc) rc = -EFAULT; break; @@ -1492,31 +1483,26 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) break; rc = -EINVAL; - lock_sock(sk); if (sk->sk_state != TCP_LISTEN && sk->sk_state != TCP_CLOSE) - goto out_dtefac_release; + break; if (dtefacs.calling_len > X25_MAX_AE_LEN) - goto out_dtefac_release; + break; if (dtefacs.calling_ae == NULL) - goto out_dtefac_release; + break; if (dtefacs.called_len > X25_MAX_AE_LEN) - goto out_dtefac_release; + break; if (dtefacs.called_ae == NULL) - goto out_dtefac_release; + break; x25->dte_facilities = dtefacs; rc = 0; -out_dtefac_release: - release_sock(sk); break; } case SIOCX25GCALLUSERDATA: { - lock_sock(sk); - rc = copy_to_user(argp, &x25->calluserdata, - sizeof(x25->calluserdata)) - ? -EFAULT : 0; - release_sock(sk); + struct x25_calluserdata cud = x25->calluserdata; + rc = copy_to_user(argp, &cud, + sizeof(cud)) ? -EFAULT : 0; break; } @@ -1530,19 +1516,16 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -EINVAL; if (calluserdata.cudlength > X25_MAX_CUD_LEN) break; - lock_sock(sk); x25->calluserdata = calluserdata; - release_sock(sk); rc = 0; break; } case SIOCX25GCAUSEDIAG: { - lock_sock(sk); - rc = copy_to_user(argp, &x25->causediag, - sizeof(x25->causediag)) - ? -EFAULT : 0; - release_sock(sk); + struct x25_causediag causediag; + causediag = x25->causediag; + rc = copy_to_user(argp, &causediag, + sizeof(causediag)) ? -EFAULT : 0; break; } @@ -1551,9 +1534,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -EFAULT; if (copy_from_user(&causediag, argp, sizeof(causediag))) break; - lock_sock(sk); x25->causediag = causediag; - release_sock(sk); rc = 0; break; @@ -1562,37 +1543,31 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCX25SCUDMATCHLEN: { struct x25_subaddr sub_addr; rc = -EINVAL; - lock_sock(sk); if(sk->sk_state != TCP_CLOSE) - goto out_cud_release; + break; rc = -EFAULT; if (copy_from_user(&sub_addr, argp, sizeof(sub_addr))) - goto out_cud_release; + break; rc = -EINVAL; if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN) - goto out_cud_release; + break; x25->cudmatchlength = sub_addr.cudmatchlength; rc = 0; -out_cud_release: - release_sock(sk); break; } case SIOCX25CALLACCPTAPPRV: { rc = -EINVAL; - lock_kernel(); if (sk->sk_state != TCP_CLOSE) break; clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); - unlock_kernel(); rc = 0; break; } case SIOCX25SENDCALLACCPT: { rc = -EINVAL; - lock_kernel(); if (sk->sk_state != TCP_ESTABLISHED) break; /* must call accptapprv above */ @@ -1600,7 +1575,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; x25_write_internal(sk, X25_CALL_ACCEPTED); x25->state = X25_STATE_3; - unlock_kernel(); rc = 0; break; } @@ -1609,6 +1583,7 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) rc = -ENOIOCTLCMD; break; } + unlock_kernel(); return rc; } @@ -1644,20 +1619,16 @@ static int compat_x25_subscr_ioctl(unsigned int cmd, dev_put(dev); if (cmd == SIOCX25GSUBSCRIP) { - read_lock_bh(&x25_neigh_list_lock); x25_subscr.extended = nb->extended; x25_subscr.global_facil_mask = nb->global_facil_mask; - read_unlock_bh(&x25_neigh_list_lock); rc = copy_to_user(x25_subscr32, &x25_subscr, sizeof(*x25_subscr32)) ? -EFAULT : 0; } else { rc = -EINVAL; if (x25_subscr.extended == 0 || x25_subscr.extended == 1) { rc = 0; - write_lock_bh(&x25_neigh_list_lock); nb->extended = x25_subscr.extended; nb->global_facil_mask = x25_subscr.global_facil_mask; - write_unlock_bh(&x25_neigh_list_lock); } } x25_neigh_put(nb); @@ -1683,15 +1654,19 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, break; case SIOCGSTAMP: rc = -EINVAL; + lock_kernel(); if (sk) rc = compat_sock_get_timestamp(sk, (struct timeval __user*)argp); + unlock_kernel(); break; case SIOCGSTAMPNS: rc = -EINVAL; + lock_kernel(); if (sk) rc = compat_sock_get_timestampns(sk, (struct timespec __user*)argp); + unlock_kernel(); break; case SIOCGIFADDR: case SIOCSIFADDR: @@ -1710,16 +1685,22 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; + lock_kernel(); rc = x25_route_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25GSUBSCRIP: + lock_kernel(); rc = compat_x25_subscr_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25SSUBSCRIP: rc = -EPERM; if (!capable(CAP_NET_ADMIN)) break; + lock_kernel(); rc = compat_x25_subscr_ioctl(cmd, argp); + unlock_kernel(); break; case SIOCX25GFACILITIES: case SIOCX25SFACILITIES: diff --git a/trunk/net/x25/x25_facilities.c b/trunk/net/x25/x25_facilities.c index 55187c8f6420..771bab00754b 100644 --- a/trunk/net/x25/x25_facilities.c +++ b/trunk/net/x25/x25_facilities.c @@ -61,8 +61,6 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, while (len > 0) { switch (*p & X25_FAC_CLASS_MASK) { case X25_FAC_CLASS_A: - if (len < 2) - return 0; switch (*p) { case X25_FAC_REVERSE: if((p[1] & 0x81) == 0x81) { @@ -106,8 +104,6 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, len -= 2; break; case X25_FAC_CLASS_B: - if (len < 3) - return 0; switch (*p) { case X25_FAC_PACKET_SIZE: facilities->pacsize_in = p[1]; @@ -129,8 +125,6 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, len -= 3; break; case X25_FAC_CLASS_C: - if (len < 4) - return 0; printk(KERN_DEBUG "X.25: unknown facility %02X, " "values %02X, %02X, %02X\n", p[0], p[1], p[2], p[3]); @@ -138,26 +132,26 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, len -= 4; break; case X25_FAC_CLASS_D: - if (len < p[1] + 2) - return 0; switch (*p) { case X25_FAC_CALLING_AE: - if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) - return 0; + if (p[1] > X25_MAX_DTE_FACIL_LEN) + break; dte_facs->calling_len = p[2]; memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); *vc_fac_mask |= X25_MASK_CALLING_AE; break; case X25_FAC_CALLED_AE: - if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) - return 0; + if (p[1] > X25_MAX_DTE_FACIL_LEN) + break; dte_facs->called_len = p[2]; memcpy(dte_facs->called_ae, &p[3], p[1] - 1); *vc_fac_mask |= X25_MASK_CALLED_AE; break; default: printk(KERN_DEBUG "X.25: unknown facility %02X," - "length %d\n", p[0], p[1]); + "length %d, values %02X, %02X, " + "%02X, %02X\n", + p[0], p[1], p[2], p[3], p[4], p[5]); break; } len -= p[1] + 2; diff --git a/trunk/net/x25/x25_in.c b/trunk/net/x25/x25_in.c index f729f022be69..63178961efac 100644 --- a/trunk/net/x25/x25_in.c +++ b/trunk/net/x25/x25_in.c @@ -119,8 +119,6 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp &x25->vc_facil_mask); if (len > 0) skb_pull(skb, len); - else - return -1; /* * Copy any Call User Data. */ diff --git a/trunk/net/x25/x25_link.c b/trunk/net/x25/x25_link.c index 4c81f6abb65b..73e7b954ad28 100644 --- a/trunk/net/x25/x25_link.c +++ b/trunk/net/x25/x25_link.c @@ -31,8 +31,8 @@ #include #include -LIST_HEAD(x25_neigh_list); -DEFINE_RWLOCK(x25_neigh_list_lock); +static LIST_HEAD(x25_neigh_list); +static DEFINE_RWLOCK(x25_neigh_list_lock); static void x25_t20timer_expiry(unsigned long); @@ -360,20 +360,16 @@ int x25_subscr_ioctl(unsigned int cmd, void __user *arg) dev_put(dev); if (cmd == SIOCX25GSUBSCRIP) { - read_lock_bh(&x25_neigh_list_lock); x25_subscr.extended = nb->extended; x25_subscr.global_facil_mask = nb->global_facil_mask; - read_unlock_bh(&x25_neigh_list_lock); rc = copy_to_user(arg, &x25_subscr, sizeof(x25_subscr)) ? -EFAULT : 0; } else { rc = -EINVAL; if (!(x25_subscr.extended && x25_subscr.extended != 1)) { rc = 0; - write_lock_bh(&x25_neigh_list_lock); nb->extended = x25_subscr.extended; nb->global_facil_mask = x25_subscr.global_facil_mask; - write_unlock_bh(&x25_neigh_list_lock); } } x25_neigh_put(nb); diff --git a/trunk/scripts/kconfig/symbol.c b/trunk/scripts/kconfig/symbol.c index af6e9f3de950..c0efe102d655 100644 --- a/trunk/scripts/kconfig/symbol.c +++ b/trunk/scripts/kconfig/symbol.c @@ -875,7 +875,7 @@ const char *sym_expand_string_value(const char *in) symval = sym_get_string_value(sym); } - newlen = strlen(res) + strlen(symval) + strlen(src) + 1; + newlen = strlen(res) + strlen(symval) + strlen(src); if (newlen > reslen) { reslen = newlen; res = realloc(res, reslen); diff --git a/trunk/security/Kconfig b/trunk/security/Kconfig index e80da955e687..bd72ae623494 100644 --- a/trunk/security/Kconfig +++ b/trunk/security/Kconfig @@ -39,18 +39,6 @@ config KEYS_DEBUG_PROC_KEYS If you are unsure as to whether this is required, answer N. -config SECURITY_DMESG_RESTRICT - bool "Restrict unprivileged access to the kernel syslog" - default n - help - This enforces restrictions on unprivileged users reading the kernel - syslog via dmesg(8). - - If this option is not selected, no restrictions will be enforced - unless the dmesg_restrict sysctl is explicitly set to (1). - - If you are unsure how to answer this question, answer N. - config SECURITY bool "Enable different security models" depends on SYSFS diff --git a/trunk/security/apparmor/lsm.c b/trunk/security/apparmor/lsm.c index b7106f192b75..cf1de4462ccd 100644 --- a/trunk/security/apparmor/lsm.c +++ b/trunk/security/apparmor/lsm.c @@ -922,7 +922,7 @@ static int __init apparmor_init(void) error = register_security(&apparmor_ops); if (error) { AA_ERROR("Unable to register AppArmor\n"); - goto set_init_cxt_out; + goto register_security_out; } /* Report that AppArmor successfully initialized */ @@ -936,9 +936,6 @@ static int __init apparmor_init(void) return error; -set_init_cxt_out: - aa_free_task_context(current->real_cred->security); - register_security_out: aa_free_root_ns(); @@ -947,6 +944,7 @@ static int __init apparmor_init(void) apparmor_enabled = 0; return error; + } security_initcall(apparmor_init); diff --git a/trunk/security/apparmor/policy.c b/trunk/security/apparmor/policy.c index 4f0eadee78b8..52cc865f1464 100644 --- a/trunk/security/apparmor/policy.c +++ b/trunk/security/apparmor/policy.c @@ -306,7 +306,7 @@ static struct aa_namespace *alloc_namespace(const char *prefix, return ns; fail_unconfined: - kzfree(ns->base.hname); + kzfree(ns->base.name); fail_ns: kzfree(ns); return NULL; diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index 04b80f9912bf..5e632b4857e4 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -895,8 +895,6 @@ int cap_syslog(int type, bool from_file) { if (type != SYSLOG_ACTION_OPEN && from_file) return 0; - if (dmesg_restrict && !capable(CAP_SYS_ADMIN)) - return -EPERM; if ((type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN)) return -EPERM; diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 156ef93d6f7d..d9154cf90ae1 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -4524,11 +4524,11 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, if (selinux_secmark_enabled()) if (avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET, PACKET__SEND, &ad)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; if (selinux_policycap_netpeer) if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; return NF_ACCEPT; } @@ -4585,7 +4585,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, secmark_perm = PACKET__SEND; break; default: - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; } if (secmark_perm == PACKET__FORWARD_OUT) { if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) @@ -4607,7 +4607,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, if (secmark_active) if (avc_has_perm(peer_sid, skb->secmark, SECCLASS_PACKET, secmark_perm, &ad)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; if (peerlbl_active) { u32 if_sid; @@ -4617,13 +4617,13 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, return NF_DROP; if (avc_has_perm(peer_sid, if_sid, SECCLASS_NETIF, NETIF__EGRESS, &ad)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; if (sel_netnode_sid(addrp, family, &node_sid)) return NF_DROP; if (avc_has_perm(peer_sid, node_sid, SECCLASS_NODE, NODE__SENDTO, &ad)) - return NF_DROP_ERR(-ECONNREFUSED); + return NF_DROP; } return NF_ACCEPT; diff --git a/trunk/sound/pci/asihpi/hpi6000.c b/trunk/sound/pci/asihpi/hpi6000.c index 1b9bf9395cfe..f7e374ec4414 100644 --- a/trunk/sound/pci/asihpi/hpi6000.c +++ b/trunk/sound/pci/asihpi/hpi6000.c @@ -625,8 +625,6 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, control_cache_size, (struct hpi_control_cache_info *) &phw->control_cache[0] ); - if (!phw->p_cache) - pao->has_control_cache = 0; } else pao->has_control_cache = 0; diff --git a/trunk/sound/pci/asihpi/hpi6205.c b/trunk/sound/pci/asihpi/hpi6205.c index 2672f6591ceb..22c5fc625533 100644 --- a/trunk/sound/pci/asihpi/hpi6205.c +++ b/trunk/sound/pci/asihpi/hpi6205.c @@ -644,8 +644,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, interface->control_cache.size_in_bytes, (struct hpi_control_cache_info *) p_control_cache_virtual); - if (!phw->p_cache) - err = HPI_ERROR_MEMORY_ALLOC; } if (!err) { err = hpios_locked_mem_get_phys_addr(&phw-> diff --git a/trunk/sound/pci/asihpi/hpicmn.c b/trunk/sound/pci/asihpi/hpicmn.c index d67f4d3db911..dda4f1c6f658 100644 --- a/trunk/sound/pci/asihpi/hpicmn.c +++ b/trunk/sound/pci/asihpi/hpicmn.c @@ -571,20 +571,14 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 { struct hpi_control_cache *p_cache = kmalloc(sizeof(*p_cache), GFP_KERNEL); - if (!p_cache) - return NULL; - p_cache->p_info = - kmalloc(sizeof(*p_cache->p_info) * number_of_controls, - GFP_KERNEL); - if (!p_cache->p_info) { - kfree(p_cache); - return NULL; - } p_cache->cache_size_in_bytes = size_in_bytes; p_cache->control_count = number_of_controls; p_cache->p_cache = (struct hpi_control_cache_single *)pDSP_control_buffer; p_cache->init = 0; + p_cache->p_info = + kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count, + GFP_KERNEL); return p_cache; } diff --git a/trunk/sound/pci/cs46xx/dsp_spos.c b/trunk/sound/pci/cs46xx/dsp_spos.c index e377287192aa..3e5ca8fb519f 100644 --- a/trunk/sound/pci/cs46xx/dsp_spos.c +++ b/trunk/sound/pci/cs46xx/dsp_spos.c @@ -225,25 +225,39 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) { struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL); - if (ins == NULL) + if (ins == NULL) return NULL; /* better to use vmalloc for this big table */ + ins->symbol_table.nsymbols = 0; ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) * DSP_MAX_SYMBOLS); - ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); - ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL); - if (!ins->symbol_table.symbols || !ins->code.data || !ins->modules) { + ins->symbol_table.highest_frag_index = 0; + + if (ins->symbol_table.symbols == NULL) { cs46xx_dsp_spos_destroy(chip); goto error; } - ins->symbol_table.nsymbols = 0; - ins->symbol_table.highest_frag_index = 0; + ins->code.offset = 0; ins->code.size = 0; + ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); + + if (ins->code.data == NULL) { + cs46xx_dsp_spos_destroy(chip); + goto error; + } + ins->nscb = 0; ins->ntask = 0; + ins->nmodules = 0; + ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL); + + if (ins->modules == NULL) { + cs46xx_dsp_spos_destroy(chip); + goto error; + } /* default SPDIF input sample rate to 48000 khz */ @@ -257,8 +271,8 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) /* set left and right validity bits and default channel status */ - ins->spdif_csuv_default = - ins->spdif_csuv_stream = + ins->spdif_csuv_default = + ins->spdif_csuv_stream = /* byte 0 */ ((unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) | /* byte 1 */ ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) | /* byte 3 */ (unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) | @@ -267,9 +281,6 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) return ins; error: - kfree(ins->modules); - kfree(ins->code.data); - vfree(ins->symbol_table.symbols); kfree(ins); return NULL; } diff --git a/trunk/sound/pci/hda/patch_cirrus.c b/trunk/sound/pci/hda/patch_cirrus.c index 18af38ebf757..460fb2ef7e39 100644 --- a/trunk/sound/pci/hda/patch_cirrus.c +++ b/trunk/sound/pci/hda/patch_cirrus.c @@ -1166,7 +1166,6 @@ static const char *cs420x_models[CS420X_MODELS] = { static struct snd_pci_quirk cs420x_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53), - SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), diff --git a/trunk/sound/pci/lx6464es/lx6464es.c b/trunk/sound/pci/lx6464es/lx6464es.c index 1bd7a540fd49..ef9af3f4ace2 100644 --- a/trunk/sound/pci/lx6464es/lx6464es.c +++ b/trunk/sound/pci/lx6464es/lx6464es.c @@ -425,7 +425,7 @@ static int lx_pcm_hw_free(struct snd_pcm_substream *substream) static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) { struct snd_pcm_substream *substream = lx_stream->stream; - const unsigned int is_capture = lx_stream->is_capture; + const int is_capture = lx_stream->is_capture; int err; @@ -473,7 +473,7 @@ static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream) { - const unsigned int is_capture = lx_stream->is_capture; + const int is_capture = lx_stream->is_capture; int err; snd_printd(LXP "stopping: stopping stream\n"); diff --git a/trunk/sound/pci/lx6464es/lx6464es.h b/trunk/sound/pci/lx6464es/lx6464es.h index aea621eafbb5..51afc048961d 100644 --- a/trunk/sound/pci/lx6464es/lx6464es.h +++ b/trunk/sound/pci/lx6464es/lx6464es.h @@ -60,7 +60,7 @@ struct lx_stream { snd_pcm_uframes_t frame_pos; enum lx_stream_status status; /* free, open, running, draining * pause */ - unsigned int is_capture:1; + int is_capture:1; }; diff --git a/trunk/sound/pci/lx6464es/lx_core.c b/trunk/sound/pci/lx6464es/lx_core.c index 617f98b0cbae..3086b751da4a 100644 --- a/trunk/sound/pci/lx6464es/lx_core.c +++ b/trunk/sound/pci/lx6464es/lx_core.c @@ -1152,7 +1152,7 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip, struct lx_stream *lx_stream) { struct snd_pcm_substream *substream = lx_stream->stream; - const unsigned int is_capture = lx_stream->is_capture; + int is_capture = lx_stream->is_capture; int err; unsigned long flags; diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index 3b5690d28b8b..94a9d06b9027 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -25,9 +25,8 @@ config SND_SOC_ALL_CODECS select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC select SND_SOC_CS42L51 if I2C select SND_SOC_CS4270 if I2C - select SND_SOC_CX20442 select SND_SOC_DA7210 if I2C - select SND_SOC_JZ4740_CODEC if SOC_JZ4740 + select SND_SOC_JZ4740 if SOC_JZ4740 select SND_SOC_MAX98088 if I2C select SND_SOC_MAX9877 if I2C select SND_SOC_PCM3008 diff --git a/trunk/sound/soc/codecs/tlv320dac33.c b/trunk/sound/soc/codecs/tlv320dac33.c index c5ab8c805771..d251ff54a2d3 100644 --- a/trunk/sound/soc/codecs/tlv320dac33.c +++ b/trunk/sound/soc/codecs/tlv320dac33.c @@ -58,7 +58,7 @@ (1000000000 / ((rate * 1000) / samples)) #define US_TO_SAMPLES(rate, us) \ - (rate / (1000000 / (us < 1000000 ? us : 1000000))) + (rate / (1000000 / us)) #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) @@ -200,7 +200,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, u8 *value) { struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - int val, ret = 0; + int val; *value = reg & 0xff; @@ -210,7 +210,6 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, if (val < 0) { dev_err(codec->dev, "Read failed (%d)\n", val); value[0] = dac33_read_reg_cache(codec, reg); - ret = val; } else { value[0] = val; dac33_write_reg_cache(codec, reg, val); @@ -219,7 +218,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, value[0] = dac33_read_reg_cache(codec, reg); } - return ret; + return 0; } static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, @@ -330,18 +329,13 @@ static void dac33_init_chip(struct snd_soc_codec *codec) dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); } -static inline int dac33_read_id(struct snd_soc_codec *codec) +static inline void dac33_read_id(struct snd_soc_codec *codec) { - int i, ret = 0; u8 reg; - for (i = 0; i < 3; i++) { - ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, ®); - if (ret < 0) - break; - } - - return ret; + dac33_read(codec, DAC33_DEVICE_ID_MSB, ®); + dac33_read(codec, DAC33_DEVICE_ID_LSB, ®); + dac33_read(codec, DAC33_DEVICE_REV_ID, ®); } static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) @@ -1082,9 +1076,6 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) /* Number of samples under i2c latency */ dac33->alarm_threshold = US_TO_SAMPLES(rate, dac33->mode1_latency); - nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - - dac33->alarm_threshold; - if (dac33->auto_fifo_config) { if (period_size <= dac33->alarm_threshold) /* @@ -1095,8 +1086,6 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) ((dac33->alarm_threshold / period_size) + (dac33->alarm_threshold % period_size ? 1 : 0)); - else if (period_size > nsample_limit) - dac33->nsample = nsample_limit; else dac33->nsample = period_size; } else { @@ -1108,7 +1097,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) */ dac33->nsample_max = substream->runtime->buffer_size - period_size; - + nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - + dac33->alarm_threshold; if (dac33->nsample_max > nsample_limit) dac33->nsample_max = nsample_limit; @@ -1424,15 +1414,9 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) dev_err(codec->dev, "Failed to power up codec: %d\n", ret); goto err_power; } - ret = dac33_read_id(codec); + dac33_read_id(codec); dac33_hard_power(codec, 0); - if (ret < 0) { - dev_err(codec->dev, "Failed to read chip ID: %d\n", ret); - ret = -ENODEV; - goto err_power; - } - /* Check if the IRQ number is valid and request it */ if (dac33->irq >= 0) { ret = request_irq(dac33->irq, dac33_interrupt_handler, diff --git a/trunk/sound/soc/codecs/tpa6130a2.c b/trunk/sound/soc/codecs/tpa6130a2.c index ee4fb201de60..329acc1a2074 100644 --- a/trunk/sound/soc/codecs/tpa6130a2.c +++ b/trunk/sound/soc/codecs/tpa6130a2.c @@ -119,13 +119,13 @@ static int tpa6130a2_power(int power) { struct tpa6130a2_data *data; u8 val; - int ret = 0; + int ret; BUG_ON(tpa6130a2_client == NULL); data = i2c_get_clientdata(tpa6130a2_client); mutex_lock(&data->mutex); - if (power && !data->power_state) { + if (power) { /* Power on */ if (data->power_gpio >= 0) gpio_set_value(data->power_gpio, 1); @@ -153,7 +153,7 @@ static int tpa6130a2_power(int power) val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val &= ~TPA6130A2_SWS; tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); - } else if (!power && data->power_state) { + } else { /* set SWS */ val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val |= TPA6130A2_SWS; diff --git a/trunk/sound/soc/codecs/wm8900.c b/trunk/sound/soc/codecs/wm8900.c index aca4b1ea10bb..b4f11724a63f 100644 --- a/trunk/sound/soc/codecs/wm8900.c +++ b/trunk/sound/soc/codecs/wm8900.c @@ -186,6 +186,7 @@ static int wm8900_volatile_register(unsigned int reg) { switch (reg) { case WM8900_REG_ID: + case WM8900_REG_POWER1: return 1; default: return 0; @@ -1199,6 +1200,11 @@ static int wm8900_probe(struct snd_soc_codec *codec) return -ENODEV; } + /* Read back from the chip */ + reg = snd_soc_read(codec, WM8900_REG_POWER1); + reg = (reg >> 12) & 0xf; + dev_info(codec->dev, "WM8900 revision %d\n", reg); + wm8900_reset(codec); /* Turn the chip on */ diff --git a/trunk/sound/soc/codecs/wm_hubs.c b/trunk/sound/soc/codecs/wm_hubs.c index 19ca782ac970..2cb81538cd91 100644 --- a/trunk/sound/soc/codecs/wm_hubs.c +++ b/trunk/sound/soc/codecs/wm_hubs.c @@ -123,7 +123,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; break; default: - WARN(1, "Unknown DCS readback method\n"); + WARN(1, "Unknown DCS readback method"); break; } diff --git a/trunk/sound/soc/pxa/tosa.c b/trunk/sound/soc/pxa/tosa.c index 73d0edd8ded9..a3bfb2e8b70f 100644 --- a/trunk/sound/soc/pxa/tosa.c +++ b/trunk/sound/soc/pxa/tosa.c @@ -79,7 +79,7 @@ static void tosa_ext_control(struct snd_soc_codec *codec) static int tosa_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_codec *codec = rtd->card->codec; /* check the jack status at stream startup */ tosa_ext_control(codec); diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index 614a8b30d87b..1c8f3f507f54 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -165,11 +165,8 @@ static ssize_t pmdown_time_set(struct device *dev, { struct snd_soc_pcm_runtime *rtd = container_of(dev, struct snd_soc_pcm_runtime, dev); - int ret; - ret = strict_strtol(buf, 10, &rtd->pmdown_time); - if (ret) - return ret; + strict_strtol(buf, 10, &rtd->pmdown_time); return count; } diff --git a/trunk/sound/usb/mixer_quirks.c b/trunk/sound/usb/mixer_quirks.c index 782f741cd00a..7dae05d8783e 100644 --- a/trunk/sound/usb/mixer_quirks.c +++ b/trunk/sound/usb/mixer_quirks.c @@ -60,7 +60,7 @@ static const struct rc_config { { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */ { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ - { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ + { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi */ { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ }; @@ -183,13 +183,7 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e if (value > 1) return -EINVAL; changed = value != mixer->audigy2nx_leds[index]; - if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) - err = snd_usb_ctl_msg(mixer->chip->dev, - usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, - !value, 0, NULL, 0, 100); - else - err = snd_usb_ctl_msg(mixer->chip->dev, + err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, value, index + 2, NULL, 0, 100); @@ -231,12 +225,8 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) int i, err; for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { - /* USB X-Fi S51 doesn't have a CMSS LED */ - if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) - continue; if (i > 1 && /* Live24ext has 2 LEDs only */ (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || - mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) break; err = snd_ctl_add(mixer->chip->card, @@ -375,7 +365,6 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || - mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { if ((err = snd_audigy2nx_controls_create(mixer)) < 0) return err; diff --git a/trunk/sound/usb/pcm.c b/trunk/sound/usb/pcm.c index 4132522ac90f..cff3a3c465d7 100644 --- a/trunk/sound/usb/pcm.c +++ b/trunk/sound/usb/pcm.c @@ -676,10 +676,8 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, if (!needs_knot) return 0; - subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); - if (!subs->rate_list.list) - return -ENOMEM; subs->rate_list.count = count; + subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); subs->rate_list.mask = 0; count = 0; list_for_each_entry(fp, &subs->fmt_list, list) { diff --git a/trunk/tools/perf/Documentation/perf-trace.txt b/trunk/tools/perf/Documentation/perf-trace.txt index 26aff6bf9e50..122ec9dc4853 100644 --- a/trunk/tools/perf/Documentation/perf-trace.txt +++ b/trunk/tools/perf/Documentation/perf-trace.txt @@ -8,11 +8,7 @@ perf-trace - Read perf.data (created by perf record) and display trace output SYNOPSIS -------- [verse] -'perf trace' [] -'perf trace' [] record