From 0e6eadefa7d419679cfbd499b77681d54e7bd987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Fri, 22 Mar 2013 15:13:02 +0100 Subject: [PATCH] --- yaml --- r: 362919 b: refs/heads/master c: a1655100ddfa10829b7d3b055611f268a82e335a h: refs/heads/master i: 362917: 4e47ffd39ef12183c6dc64df7e4d6d98e7d950df 362915: 361da03f92240742ad4657a294ff05b137401f60 362911: 7576ee61d2438827ba88bbfec04d1c3bda2d4030 v: v3 --- [refs] | 2 +- .../Documentation/DocBook/device-drivers.tmpl | 2 +- trunk/Documentation/ia64/err_inject.txt | 2 +- trunk/Documentation/kdump/kdump.txt | 1 - trunk/Documentation/kernel-parameters.txt | 29 +- trunk/Documentation/s390/s390dbf.txt | 3 +- trunk/Documentation/scsi/LICENSE.qla2xxx | 2 +- .../sound/alsa/ALSA-Configuration.txt | 5 +- trunk/MAINTAINERS | 19 +- trunk/Makefile | 5 +- trunk/arch/alpha/Makefile | 2 +- trunk/arch/alpha/include/asm/floppy.h | 2 +- trunk/arch/alpha/kernel/irq.c | 7 + trunk/arch/alpha/kernel/irq_alpha.c | 10 +- trunk/arch/alpha/kernel/sys_nautilus.c | 5 - trunk/arch/alpha/kernel/sys_titan.c | 14 +- trunk/arch/arc/include/asm/irqflags.h | 12 +- trunk/arch/arm/Kconfig | 14 +- .../arch/arm/boot/dts/armada-370-mirabox.dts | 2 +- trunk/arch/arm/boot/dts/armada-370.dtsi | 6 - trunk/arch/arm/boot/dts/dbx5x0.dtsi | 4 +- trunk/arch/arm/boot/dts/imx28-m28evk.dts | 1 + trunk/arch/arm/boot/dts/imx28-sps1.dts | 1 + trunk/arch/arm/boot/dts/imx6qdl.dtsi | 1 - .../arch/arm/boot/dts/kirkwood-goflexnet.dts | 1 - .../arm/boot/dts/kirkwood-iomega_ix2_200.dts | 14 +- trunk/arch/arm/boot/dts/orion5x.dtsi | 9 +- trunk/arch/arm/include/asm/delay.h | 2 +- trunk/arch/arm/include/asm/glue-cache.h | 8 + trunk/arch/arm/include/asm/hardware/iop3xx.h | 2 +- trunk/arch/arm/include/asm/highmem.h | 7 - trunk/arch/arm/include/asm/mmu_context.h | 2 - trunk/arch/arm/include/asm/pgtable-3level.h | 2 +- trunk/arch/arm/include/asm/tlbflush.h | 26 +- trunk/arch/arm/kernel/entry-common.S | 12 - trunk/arch/arm/kernel/head.S | 2 +- trunk/arch/arm/kernel/hw_breakpoint.c | 8 +- trunk/arch/arm/kernel/perf_event.c | 5 +- trunk/arch/arm/kernel/sched_clock.c | 4 +- trunk/arch/arm/kernel/setup.c | 27 +- trunk/arch/arm/kernel/smp.c | 3 + trunk/arch/arm/kernel/smp_tlb.c | 66 --- trunk/arch/arm/kernel/tcm.c | 1 + trunk/arch/arm/{mm => kernel}/tcm.h | 0 trunk/arch/arm/kvm/arm.c | 1 - trunk/arch/arm/kvm/coproc.c | 4 +- trunk/arch/arm/kvm/vgic.c | 35 +- trunk/arch/arm/lib/delay.c | 8 +- trunk/arch/arm/mach-cns3xxx/core.c | 16 +- .../arm/mach-cns3xxx/include/mach/cns3xxx.h | 16 +- .../arm/mach-ep93xx/include/mach/uncompress.h | 10 +- trunk/arch/arm/mach-highbank/hotplug.c | 10 +- trunk/arch/arm/mach-imx/clk-imx35.c | 2 - trunk/arch/arm/mach-imx/clk-imx6q.c | 3 +- trunk/arch/arm/mach-imx/common.h | 2 - trunk/arch/arm/mach-imx/hotplug.c | 12 - trunk/arch/arm/mach-imx/src.c | 12 - .../arm/mach-kirkwood/board-iomega_ix2_200.c | 7 +- trunk/arch/arm/mach-kirkwood/guruplug-setup.c | 2 - trunk/arch/arm/mach-kirkwood/openrd-setup.c | 1 - .../arch/arm/mach-kirkwood/rd88f6281-setup.c | 1 - trunk/arch/arm/mach-msm/timer.c | 5 +- trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c | 24 +- trunk/arch/arm/mach-omap1/clock_data.c | 12 +- trunk/arch/arm/mach-omap2/cclock44xx_data.c | 20 - trunk/arch/arm/mach-omap2/common.h | 3 - trunk/arch/arm/mach-omap2/io.c | 18 +- trunk/arch/arm/mach-omap2/omap_hwmod.c | 7 +- trunk/arch/arm/mach-omap2/omap_hwmod.h | 9 +- .../arm/mach-omap2/omap_hwmod_3xxx_data.c | 7 +- .../arm/mach-omap2/omap_hwmod_44xx_data.c | 12 +- trunk/arch/arm/mach-omap2/timer.c | 4 - .../arch/arm/mach-s3c24xx/include/mach/irqs.h | 4 +- trunk/arch/arm/mach-s3c24xx/irq.c | 2 +- trunk/arch/arm/mach-ux500/board-mop500-sdi.c | 1 + trunk/arch/arm/mach-ux500/board-mop500.c | 12 - trunk/arch/arm/mach-ux500/board-mop500.h | 1 - trunk/arch/arm/mach-ux500/cpu-db8500.c | 5 +- trunk/arch/arm/mm/Kconfig | 5 +- trunk/arch/arm/mm/Makefile | 1 + trunk/arch/arm/mm/cache-feroceon-l2.c | 1 - trunk/arch/arm/mm/cache-l2x0.c | 11 +- trunk/arch/arm/mm/cache-v3.S | 137 ++++++ trunk/arch/arm/mm/cache-v4.S | 2 +- trunk/arch/arm/mm/context.c | 3 +- trunk/arch/arm/mm/mmu.c | 75 ++- trunk/arch/arm/mm/proc-arm740.S | 30 +- trunk/arch/arm/mm/proc-arm920.S | 2 +- trunk/arch/arm/mm/proc-arm926.S | 2 +- trunk/arch/arm/mm/proc-mohawk.S | 2 +- trunk/arch/arm/mm/proc-sa1100.S | 2 +- trunk/arch/arm/mm/proc-syms.c | 2 - trunk/arch/arm/mm/proc-v6.S | 2 +- trunk/arch/arm/mm/proc-v7.S | 19 +- trunk/arch/arm/mm/proc-xsc3.S | 2 +- trunk/arch/arm/mm/proc-xscale.S | 2 +- trunk/arch/avr32/include/asm/io.h | 4 - trunk/arch/c6x/include/asm/irqflags.h | 2 +- trunk/arch/ia64/Kconfig | 2 +- trunk/arch/ia64/include/asm/futex.h | 5 +- trunk/arch/ia64/include/asm/mca.h | 1 - trunk/arch/ia64/include/asm/numa.h | 5 +- trunk/arch/ia64/kernel/fsys.S | 49 +- trunk/arch/ia64/kernel/iosapic.c | 34 +- trunk/arch/ia64/kernel/irq.c | 8 - trunk/arch/ia64/kernel/mca.c | 37 +- trunk/arch/ia64/kernel/mca_drv.c | 2 +- trunk/arch/ia64/kernel/palinfo.c | 77 +++- trunk/arch/ia64/kvm/vtlb.c | 2 +- trunk/arch/ia64/mm/ioremap.c | 14 +- trunk/arch/ia64/mm/numa.c | 5 - trunk/arch/ia64/pci/pci.c | 11 - trunk/arch/ia64/sn/kernel/tiocx.c | 5 +- trunk/arch/m68k/include/asm/gpio.h | 20 - trunk/arch/mips/Kconfig | 7 +- .../arch/mips/bcm63xx/boards/board_bcm963xx.c | 5 +- trunk/arch/mips/bcm63xx/nvram.c | 7 +- trunk/arch/mips/bcm63xx/setup.c | 2 +- trunk/arch/mips/cavium-octeon/setup.c | 5 +- .../include/asm/mach-bcm63xx/bcm63xx_nvram.h | 4 +- .../asm/mach-sead3/cpu-feature-overrides.h | 4 + trunk/arch/mips/include/asm/mipsregs.h | 209 +-------- trunk/arch/mips/include/asm/page.h | 2 +- trunk/arch/mips/include/asm/signal.h | 2 +- trunk/arch/mips/include/uapi/asm/signal.h | 8 +- trunk/arch/mips/kernel/Makefile | 25 +- trunk/arch/mips/kernel/cpu-probe.c | 13 +- trunk/arch/mips/kernel/linux32.c | 2 +- trunk/arch/mips/kernel/mcount.S | 11 +- trunk/arch/mips/kernel/proc.c | 2 +- trunk/arch/mips/kernel/traps.c | 2 +- trunk/arch/mips/lib/bitops.c | 16 +- trunk/arch/mips/lib/csum_partial.S | 4 +- trunk/arch/mips/mm/c-r4k.c | 6 +- trunk/arch/mips/mm/sc-mips.c | 6 +- trunk/arch/mips/pci/pci-alchemy.c | 4 +- trunk/arch/mips/pci/pci.c | 8 +- trunk/arch/parisc/Makefile | 6 +- trunk/arch/parisc/include/asm/cacheflush.h | 5 +- trunk/arch/parisc/include/asm/pgtable.h | 47 +- trunk/arch/parisc/include/asm/uaccess.h | 14 +- trunk/arch/parisc/kernel/cache.c | 5 +- trunk/arch/parisc/kernel/parisc_ksyms.c | 2 - trunk/arch/parisc/lib/Makefile | 3 +- trunk/arch/parisc/lib/ucmpdi2.c | 25 - trunk/arch/powerpc/kernel/entry_64.S | 4 +- trunk/arch/powerpc/kernel/process.c | 2 - trunk/arch/powerpc/kernel/signal_32.c | 2 - trunk/arch/powerpc/kernel/signal_64.c | 2 - trunk/arch/powerpc/kernel/tm.S | 2 - trunk/arch/powerpc/kvm/e500.h | 24 +- trunk/arch/powerpc/kvm/e500_mmu_host.c | 84 ++-- trunk/arch/powerpc/kvm/e500mc.c | 7 +- trunk/arch/powerpc/platforms/pseries/lpar.c | 8 +- trunk/arch/s390/Kconfig | 13 + trunk/arch/s390/Makefile | 10 + trunk/arch/s390/hypfs/hypfs_dbfs.c | 4 +- trunk/arch/s390/include/asm/bitops.h | 117 ++--- trunk/arch/s390/include/asm/ccwdev.h | 3 +- trunk/arch/s390/include/asm/cio.h | 2 + trunk/arch/s390/include/asm/compat.h | 57 +-- trunk/arch/s390/include/asm/elf.h | 23 +- trunk/arch/s390/include/asm/io.h | 4 + trunk/arch/s390/include/asm/pci.h | 1 - trunk/arch/s390/include/asm/pci_debug.h | 9 +- trunk/arch/s390/include/asm/pci_insn.h | 203 +++++++- trunk/arch/s390/include/asm/pci_io.h | 16 +- trunk/arch/s390/include/asm/pgtable.h | 10 +- trunk/arch/s390/include/asm/processor.h | 3 +- trunk/arch/s390/include/asm/ptrace.h | 6 +- trunk/arch/s390/include/asm/syscall.h | 1 - trunk/arch/s390/include/asm/thread_info.h | 6 +- trunk/arch/s390/include/uapi/asm/ptrace.h | 20 + trunk/arch/s390/include/uapi/asm/statfs.h | 63 ++- trunk/arch/s390/kernel/Makefile | 17 +- trunk/arch/s390/kernel/asm-offsets.c | 1 - trunk/arch/s390/kernel/compat_signal.c | 2 - trunk/arch/s390/kernel/dis.c | 9 +- trunk/arch/s390/kernel/dumpstack.c | 236 ---------- trunk/arch/s390/kernel/entry.S | 39 +- trunk/arch/s390/kernel/entry.h | 1 - trunk/arch/s390/kernel/entry64.S | 43 +- trunk/arch/s390/kernel/machine_kexec.c | 30 -- trunk/arch/s390/kernel/setup.c | 9 +- trunk/arch/s390/kernel/smp.c | 15 +- trunk/arch/s390/kernel/suspend.c | 31 -- trunk/arch/s390/kernel/swsusp_asm64.S | 29 +- trunk/arch/s390/kernel/traps.c | 250 +++++++++- trunk/arch/s390/kvm/trace.h | 2 +- trunk/arch/s390/lib/uaccess_pt.c | 83 ++-- trunk/arch/s390/mm/cmm.c | 8 +- trunk/arch/s390/mm/fault.c | 9 +- trunk/arch/s390/mm/init.c | 10 +- trunk/arch/s390/mm/pageattr.c | 24 +- trunk/arch/s390/mm/pgtable.c | 235 +++------- trunk/arch/s390/net/bpf_jit_comp.c | 3 +- trunk/arch/s390/pci/Makefile | 4 +- trunk/arch/s390/pci/pci.c | 153 +++--- trunk/arch/s390/pci/pci_clp.c | 13 +- trunk/arch/s390/pci/pci_debug.c | 7 +- trunk/arch/s390/pci/pci_dma.c | 9 +- trunk/arch/s390/pci/pci_insn.c | 202 -------- trunk/arch/s390/pci/pci_msi.c | 10 +- trunk/arch/sparc/include/asm/Kbuild | 5 - trunk/arch/sparc/include/asm/cputime.h | 6 + .../sparc/include/asm/emergency-restart.h | 6 + trunk/arch/sparc/include/asm/mutex.h | 9 + trunk/arch/sparc/include/asm/pgtable_64.h | 1 - trunk/arch/sparc/include/asm/serial.h | 6 + trunk/arch/sparc/include/asm/smp_32.h | 5 + trunk/arch/sparc/include/asm/switch_to_64.h | 3 +- trunk/arch/sparc/include/asm/tlbflush_64.h | 37 +- trunk/arch/sparc/include/uapi/asm/Kbuild | 1 + trunk/arch/sparc/include/uapi/asm/types.h | 17 + trunk/arch/sparc/kernel/smp_64.c | 41 +- trunk/arch/sparc/lib/bitext.c | 6 +- trunk/arch/sparc/mm/iommu.c | 2 +- trunk/arch/sparc/mm/srmmu.c | 4 +- trunk/arch/sparc/mm/tlb.c | 39 +- trunk/arch/sparc/mm/tsb.c | 57 +-- trunk/arch/sparc/mm/ultra.S | 119 +---- trunk/arch/tile/include/asm/irqflags.h | 10 +- trunk/arch/tile/kernel/setup.c | 25 +- trunk/arch/x86/Kconfig | 1 - trunk/arch/x86/boot/compressed/Makefile | 5 +- trunk/arch/x86/boot/compressed/eboot.c | 47 -- trunk/arch/x86/include/asm/efi.h | 7 - trunk/arch/x86/include/asm/paravirt.h | 5 +- trunk/arch/x86/include/asm/paravirt_types.h | 2 - trunk/arch/x86/include/asm/syscall.h | 4 +- trunk/arch/x86/include/asm/tlb.h | 2 +- trunk/arch/x86/include/uapi/asm/bootparam.h | 1 - trunk/arch/x86/kernel/cpu/mshyperv.c | 18 +- trunk/arch/x86/kernel/cpu/perf_event_intel.c | 20 +- .../arch/x86/kernel/cpu/perf_event_intel_ds.c | 3 +- trunk/arch/x86/kernel/microcode_core_early.c | 38 +- trunk/arch/x86/kernel/paravirt.c | 25 +- trunk/arch/x86/kernel/setup.c | 45 +- trunk/arch/x86/kvm/lapic.c | 2 +- trunk/arch/x86/kvm/x86.c | 13 +- trunk/arch/x86/lguest/boot.c | 1 - trunk/arch/x86/mm/fault.c | 6 +- trunk/arch/x86/mm/pageattr-test.c | 2 +- trunk/arch/x86/mm/pageattr.c | 12 +- trunk/arch/x86/mm/pgtable.c | 7 - trunk/arch/x86/pci/common.c | 11 - trunk/arch/x86/pci/xen.c | 6 +- trunk/arch/x86/platform/efi/efi.c | 168 +------ trunk/arch/x86/xen/enlighten.c | 57 +-- trunk/arch/x86/xen/mmu.c | 13 +- trunk/arch/x86/xen/smp.c | 21 +- trunk/arch/x86/xen/spinlock.c | 25 - trunk/arch/x86/xen/time.c | 13 +- trunk/block/blk-core.c | 1 - trunk/block/blk-sysfs.c | 2 - trunk/block/partition-generic.c | 1 + trunk/crypto/algif_hash.c | 2 - trunk/crypto/algif_skcipher.c | 1 - trunk/crypto/gcm.c | 17 +- trunk/drivers/acpi/Kconfig | 2 +- trunk/drivers/acpi/acpi_i2c.c | 2 +- trunk/drivers/acpi/pci_root.c | 124 +++-- trunk/drivers/acpi/pci_slot.c | 170 ++++++- trunk/drivers/acpi/processor_idle.c | 13 +- trunk/drivers/acpi/scan.c | 1 + trunk/drivers/ata/ahci.c | 10 +- trunk/drivers/ata/ata_piix.c | 14 +- trunk/drivers/ata/libata-core.c | 6 +- trunk/drivers/ata/libata-scsi.c | 8 +- trunk/drivers/base/power/qos.c | 60 +-- trunk/drivers/base/regmap/regcache-rbtree.c | 2 +- trunk/drivers/base/regmap/regmap.c | 6 +- trunk/drivers/block/aoe/aoecmd.c | 3 +- trunk/drivers/block/loop.c | 30 +- trunk/drivers/block/mtip32xx/mtip32xx.c | 327 ++++--------- trunk/drivers/block/mtip32xx/mtip32xx.h | 18 +- trunk/drivers/block/rbd.c | 3 +- trunk/drivers/char/hpet.c | 14 +- trunk/drivers/char/hw_random/core.c | 9 - trunk/drivers/char/virtio_console.c | 44 +- trunk/drivers/clk/tegra/clk-tegra20.c | 2 +- trunk/drivers/cpufreq/cpufreq-cpu0.c | 10 +- trunk/drivers/cpufreq/cpufreq_governor.h | 6 +- trunk/drivers/cpufreq/intel_pstate.c | 1 + trunk/drivers/crypto/ux500/cryp/cryp_core.c | 2 +- trunk/drivers/dma/Kconfig | 1 - trunk/drivers/dma/at_hdmac.c | 9 +- trunk/drivers/dma/omap-dma.c | 20 +- trunk/drivers/dma/pl330.c | 38 +- trunk/drivers/eisa/eisa-bus.c | 82 ++-- trunk/drivers/eisa/pci_eisa.c | 72 +-- trunk/drivers/firmware/Kconfig | 1 - trunk/drivers/firmware/efivars.c | 110 +++-- trunk/drivers/gpio/gpio-ich.c | 2 +- trunk/drivers/gpio/gpio-pca953x.c | 2 +- trunk/drivers/gpio/gpio-pxa.c | 7 +- trunk/drivers/gpio/gpio-stmpe.c | 15 +- trunk/drivers/gpu/drm/drm_crtc.c | 2 + trunk/drivers/gpu/drm/drm_fb_helper.c | 8 +- trunk/drivers/gpu/drm/drm_fops.c | 6 +- .../gpu/drm/i915/i915_gem_execbuffer.c | 2 +- trunk/drivers/gpu/drm/i915/intel_crt.c | 40 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 3 - trunk/drivers/gpu/drm/mgag200/mgag200_mode.c | 13 +- .../gpu/drm/nouveau/core/subdev/bios/base.c | 17 - trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c | 18 +- trunk/drivers/gpu/drm/nouveau/nouveau_drm.c | 32 +- trunk/drivers/gpu/drm/nouveau/nouveau_drm.h | 2 +- trunk/drivers/gpu/drm/nouveau/nv50_display.c | 2 +- trunk/drivers/gpu/drm/radeon/radeon_bios.c | 26 -- trunk/drivers/gpu/drm/udl/udl_connector.c | 4 - trunk/drivers/hid/hid-core.c | 13 +- trunk/drivers/hid/hid-ids.h | 5 +- trunk/drivers/hid/hid-magicmouse.c | 29 +- trunk/drivers/hwspinlock/hwspinlock_core.c | 2 - .../i2c/busses/i2c-designware-platdrv.c | 1 + trunk/drivers/idle/intel_idle.c | 1 - trunk/drivers/infiniband/hw/qib/qib_sd7220.c | 2 +- trunk/drivers/input/tablet/wacom_wac.c | 8 +- trunk/drivers/iommu/amd_iommu.c | 14 +- trunk/drivers/iommu/amd_iommu_init.c | 40 +- trunk/drivers/iommu/amd_iommu_types.h | 11 +- trunk/drivers/irqchip/irq-gic.c | 3 +- trunk/drivers/md/dm-cache-target.c | 51 +- trunk/drivers/md/dm.c | 1 - trunk/drivers/md/raid5.c | 11 +- trunk/drivers/media/dvb-frontends/mb86a20s.c | 2 +- .../drivers/media/pci/cx25821/cx25821-video.c | 2 +- trunk/drivers/media/platform/Kconfig | 2 +- trunk/drivers/media/radio/radio-ma901.c | 11 - trunk/drivers/misc/vmw_vmci/Kconfig | 2 +- trunk/drivers/mtd/mtdchar.c | 59 ++- trunk/drivers/net/bonding/bond_main.c | 102 ++-- trunk/drivers/net/bonding/bond_sysfs.c | 92 ++-- trunk/drivers/net/can/mcp251x.c | 10 +- trunk/drivers/net/can/sja1000/Kconfig | 1 - trunk/drivers/net/can/sja1000/plx_pci.c | 4 +- trunk/drivers/net/can/sja1000/sja1000.c | 6 +- trunk/drivers/net/can/sja1000/sja1000.h | 2 +- .../net/can/sja1000/sja1000_of_platform.c | 31 +- trunk/drivers/net/ethernet/8390/ax88796.c | 2 +- .../net/ethernet/atheros/atl1e/atl1e.h | 3 +- .../net/ethernet/atheros/atl1e/atl1e_main.c | 20 +- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 7 +- .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 18 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 7 +- trunk/drivers/net/ethernet/broadcom/tg3.c | 7 +- trunk/drivers/net/ethernet/calxeda/xgmac.c | 9 +- trunk/drivers/net/ethernet/davicom/dm9000.c | 214 +++++---- trunk/drivers/net/ethernet/davicom/dm9000.h | 11 +- .../net/ethernet/emulex/benet/be_main.c | 5 +- trunk/drivers/net/ethernet/freescale/fec.c | 83 ++-- trunk/drivers/net/ethernet/intel/e100.c | 36 +- .../net/ethernet/intel/e1000/e1000_ethtool.c | 14 +- .../net/ethernet/intel/e1000e/netdev.c | 7 +- trunk/drivers/net/ethernet/intel/igb/igb.h | 8 + .../drivers/net/ethernet/intel/igb/igb_main.c | 110 ++++- .../net/ethernet/intel/ixgb/ixgb_main.c | 7 +- .../net/ethernet/intel/ixgbe/ixgbe_main.c | 11 +- .../net/ethernet/intel/ixgbe/ixgbe_sriov.c | 6 - trunk/drivers/net/ethernet/marvell/Kconfig | 2 +- trunk/drivers/net/ethernet/marvell/mvneta.c | 18 +- trunk/drivers/net/ethernet/marvell/sky2.c | 2 +- trunk/drivers/net/ethernet/marvell/sky2.h | 2 +- .../net/ethernet/mellanox/mlx4/en_netdev.c | 4 +- trunk/drivers/net/ethernet/micrel/ks8851.c | 2 +- .../ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 15 +- .../net/ethernet/qlogic/qlcnic/qlcnic_io.c | 3 +- .../net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 4 +- trunk/drivers/net/ethernet/qlogic/qlge/qlge.h | 2 +- .../net/ethernet/qlogic/qlge/qlge_ethtool.c | 2 +- .../net/ethernet/qlogic/qlge/qlge_main.c | 36 +- trunk/drivers/net/ethernet/realtek/r8169.c | 28 +- trunk/drivers/net/ethernet/renesas/sh_eth.c | 28 +- trunk/drivers/net/ethernet/renesas/sh_eth.h | 2 +- .../net/ethernet/stmicro/stmmac/mmc_core.c | 1 - trunk/drivers/net/ethernet/ti/cpsw.c | 4 +- trunk/drivers/net/ethernet/ti/davinci_emac.c | 2 +- trunk/drivers/net/hyperv/netvsc.c | 17 +- trunk/drivers/net/hyperv/netvsc_drv.c | 2 + trunk/drivers/net/hyperv/rndis_filter.c | 14 +- trunk/drivers/net/tun.c | 2 +- trunk/drivers/net/usb/cdc_mbim.c | 2 +- trunk/drivers/net/usb/qmi_wwan.c | 104 ----- trunk/drivers/net/usb/smsc75xx.c | 12 +- .../wireless/ath/ath9k/ar9580_1p0_initvals.h | 2 +- .../wireless/ath/ath9k/dfs_pattern_detector.c | 4 +- .../net/wireless/ath/ath9k/dfs_pri_detector.c | 4 +- .../net/wireless/ath/ath9k/htc_drv_init.c | 2 +- trunk/drivers/net/wireless/ath/ath9k/link.c | 3 +- trunk/drivers/net/wireless/ath/ath9k/main.c | 4 - trunk/drivers/net/wireless/b43/dma.c | 65 +-- trunk/drivers/net/wireless/b43/phy_n.c | 11 +- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 6 +- .../wireless/brcm80211/brcmfmac/wl_cfg80211.c | 53 +-- .../wireless/brcm80211/brcmsmac/mac80211_if.c | 264 +++++------ .../wireless/brcm80211/brcmsmac/phy/phy_lcn.c | 369 +++++++++------ .../brcm80211/brcmsmac/phy/phytbl_lcn.c | 64 +-- trunk/drivers/net/wireless/iwlegacy/4965-rs.c | 3 +- trunk/drivers/net/wireless/iwlwifi/dvm/lib.c | 9 - trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c | 18 +- trunk/drivers/net/wireless/iwlwifi/dvm/tx.c | 2 +- .../drivers/net/wireless/iwlwifi/dvm/ucode.c | 4 +- .../drivers/net/wireless/iwlwifi/pcie/trans.c | 13 - trunk/drivers/net/wireless/iwlwifi/pcie/tx.c | 2 +- trunk/drivers/net/wireless/mwifiex/cfg80211.c | 3 +- trunk/drivers/net/wireless/mwifiex/pcie.c | 1 - trunk/drivers/net/wireless/mwifiex/scan.c | 11 +- trunk/drivers/net/wireless/rt2x00/Kconfig | 7 - trunk/drivers/net/wireless/rt2x00/Makefile | 1 - trunk/drivers/net/wireless/rt2x00/rt2400pci.c | 1 - trunk/drivers/net/wireless/rt2x00/rt2500pci.c | 1 - trunk/drivers/net/wireless/rt2x00/rt2800pci.c | 1 - .../drivers/net/wireless/rt2x00/rt2x00mmio.c | 216 --------- .../drivers/net/wireless/rt2x00/rt2x00mmio.h | 119 ----- trunk/drivers/net/wireless/rt2x00/rt2x00pci.c | 176 +++++++ trunk/drivers/net/wireless/rt2x00/rt2x00pci.h | 88 ++++ trunk/drivers/net/wireless/rt2x00/rt61pci.c | 1 - trunk/drivers/nfc/microread/mei.c | 38 +- trunk/drivers/pci/bus.c | 14 +- trunk/drivers/pci/hotplug/Kconfig | 7 +- trunk/drivers/pci/hotplug/acpiphp.h | 35 +- trunk/drivers/pci/hotplug/acpiphp_core.c | 30 +- trunk/drivers/pci/hotplug/acpiphp_glue.c | 415 +++++++++++------ trunk/drivers/pci/hotplug/cpci_hotplug.h | 44 +- trunk/drivers/pci/hotplug/cpqphp.h | 70 +-- trunk/drivers/pci/hotplug/cpqphp_nvram.h | 12 +- trunk/drivers/pci/hotplug/ibmphp.h | 66 +-- trunk/drivers/pci/hotplug/pci_hotplug_core.c | 15 +- trunk/drivers/pci/hotplug/pciehp.h | 22 +- trunk/drivers/pci/hotplug/pciehp_acpi.c | 2 +- trunk/drivers/pci/hotplug/rpadlpar.h | 8 +- trunk/drivers/pci/hotplug/rpaphp.h | 16 +- trunk/drivers/pci/hotplug/s390_pci_hpc.c | 12 +- trunk/drivers/pci/hotplug/shpchp.h | 26 +- trunk/drivers/pci/hotplug/shpchp_sysfs.c | 2 +- trunk/drivers/pci/msi.c | 180 ++++---- trunk/drivers/pci/msi.h | 24 + trunk/drivers/pci/pci-acpi.c | 45 +- trunk/drivers/pci/pci-driver.c | 5 +- trunk/drivers/pci/pci-sysfs.c | 2 +- trunk/drivers/pci/pci.c | 25 +- trunk/drivers/pci/pci.h | 89 ++-- trunk/drivers/pci/pcie/Kconfig | 2 +- trunk/drivers/pci/pcie/aer/aer_inject.c | 10 +- trunk/drivers/pci/pcie/aer/aerdrv.h | 14 +- trunk/drivers/pci/pcie/aer/aerdrv_core.c | 4 +- trunk/drivers/pci/pcie/pme.c | 2 + trunk/drivers/pci/pcie/portdrv.h | 18 +- trunk/drivers/pci/pcie/portdrv_acpi.c | 1 - trunk/drivers/pci/pcie/portdrv_pci.c | 30 +- trunk/drivers/pci/probe.c | 15 +- trunk/drivers/pci/quirks.c | 148 +++--- trunk/drivers/pci/remove.c | 4 +- trunk/drivers/pci/rom.c | 67 +-- trunk/drivers/pci/setup-bus.c | 4 +- trunk/drivers/pci/setup-res.c | 2 + trunk/drivers/pci/slot.c | 7 +- trunk/drivers/platform/x86/hp-wmi.c | 4 + trunk/drivers/platform/x86/thinkpad_acpi.c | 10 + trunk/drivers/remoteproc/Kconfig | 2 +- trunk/drivers/remoteproc/remoteproc_core.c | 6 +- trunk/drivers/remoteproc/ste_modem_rproc.c | 7 +- trunk/drivers/rtc/rtc-at91rm9200.c | 50 +- trunk/drivers/rtc/rtc-at91rm9200.h | 1 - trunk/drivers/s390/block/dasd.c | 172 +------ trunk/drivers/s390/block/dasd_devmap.c | 3 +- trunk/drivers/s390/block/dasd_eckd.c | 344 +++++--------- trunk/drivers/s390/block/dasd_int.h | 10 +- trunk/drivers/s390/block/dasd_ioctl.c | 31 +- trunk/drivers/s390/block/scm_blk.c | 14 +- trunk/drivers/s390/block/scm_blk_cluster.c | 6 +- trunk/drivers/s390/block/scm_drv.c | 2 +- trunk/drivers/s390/char/con3215.c | 4 +- trunk/drivers/s390/char/monreader.c | 3 +- trunk/drivers/s390/char/raw3270.c | 6 +- trunk/drivers/s390/char/sclp_cmd.c | 4 +- trunk/drivers/s390/char/tty3270.c | 16 +- trunk/drivers/s390/char/zcore.c | 2 +- trunk/drivers/s390/cio/chp.c | 22 +- trunk/drivers/s390/cio/chp.h | 2 - trunk/drivers/s390/cio/chsc.c | 11 +- trunk/drivers/s390/cio/cio.c | 160 +++++-- trunk/drivers/s390/cio/cio.h | 11 +- trunk/drivers/s390/cio/css.c | 114 +++-- trunk/drivers/s390/cio/css.h | 4 +- trunk/drivers/s390/cio/device.c | 139 +++--- trunk/drivers/s390/cio/device.h | 2 + trunk/drivers/s390/cio/device_ops.c | 22 +- trunk/drivers/s390/cio/idset.c | 2 +- trunk/drivers/s390/net/qeth_core.h | 3 - trunk/drivers/s390/net/qeth_core_main.c | 19 - trunk/drivers/s390/net/qeth_l2_main.c | 2 - trunk/drivers/s390/net/qeth_l3_main.c | 2 - trunk/drivers/sbus/char/bbc_i2c.c | 4 +- trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 6 +- trunk/drivers/scsi/fcoe/fcoe.c | 15 +- trunk/drivers/scsi/fcoe/fcoe_ctlr.c | 60 +-- trunk/drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- trunk/drivers/scsi/ipr.c | 13 +- trunk/drivers/scsi/libfc/fc_disc.c | 26 +- trunk/drivers/scsi/libsas/sas_expander.c | 14 +- trunk/drivers/scsi/lpfc/lpfc_sli.c | 3 +- trunk/drivers/scsi/megaraid/megaraid_sas.h | 3 + .../drivers/scsi/megaraid/megaraid_sas_base.c | 4 +- trunk/drivers/scsi/mvsas/mv_init.c | 6 +- trunk/drivers/scsi/mvumi.c | 4 +- trunk/drivers/scsi/mvumi.h | 1 + trunk/drivers/scsi/qla2xxx/qla_attr.c | 5 + trunk/drivers/scsi/qla2xxx/qla_dbg.c | 3 +- trunk/drivers/scsi/qla2xxx/qla_def.h | 1 + trunk/drivers/scsi/qla2xxx/qla_gbl.h | 3 + trunk/drivers/scsi/qla2xxx/qla_init.c | 4 +- trunk/drivers/scsi/qla2xxx/qla_mbx.c | 58 +++ trunk/drivers/scsi/qla2xxx/qla_version.h | 2 +- trunk/drivers/scsi/st.c | 8 +- trunk/drivers/spi/Kconfig | 3 +- trunk/drivers/spi/spi-bcm63xx.c | 3 +- trunk/drivers/spi/spi-mpc512x-psc.c | 2 +- trunk/drivers/spi/spi-pxa2xx.c | 1 + trunk/drivers/spi/spi-s3c64xx.c | 41 +- trunk/drivers/spi/spi-tegra20-slink.c | 25 +- trunk/drivers/spi/spi.c | 17 +- trunk/drivers/ssb/driver_chipcommon_pmu.c | 29 -- trunk/drivers/target/target_core_alua.c | 3 - trunk/drivers/tty/mxser.c | 8 +- trunk/drivers/tty/serial/8250/8250_pnp.c | 12 +- trunk/drivers/tty/serial/omap-serial.c | 11 - trunk/drivers/tty/tty_io.c | 18 +- trunk/drivers/usb/core/port.c | 1 + trunk/drivers/vfio/pci/vfio_pci.c | 13 +- trunk/drivers/vhost/tcm_vhost.c | 198 +++----- trunk/drivers/video/Kconfig | 2 +- trunk/drivers/video/auo_k1900fb.c | 5 +- trunk/drivers/video/auo_k1901fb.c | 5 +- trunk/drivers/video/auo_k190x.c | 15 +- trunk/drivers/video/fbmem.c | 39 +- trunk/drivers/video/fbmon.c | 2 +- trunk/drivers/video/mmp/core.c | 2 + trunk/drivers/video/sh_mobile_lcdcfb.c | 1 - trunk/drivers/video/uvesafb.c | 3 +- trunk/drivers/watchdog/Kconfig | 2 +- trunk/drivers/xen/events.c | 52 +-- trunk/drivers/xen/xen-acpi-processor.c | 82 ++-- trunk/firmware/Makefile | 2 +- .../firmware/{qlogic => intel}/sd7220.fw.ihex | 0 trunk/fs/aio.c | 2 +- trunk/fs/binfmt_elf.c | 1 - trunk/fs/bio.c | 2 + trunk/fs/block_dev.c | 1 - trunk/fs/btrfs/tree-log.c | 48 +- trunk/fs/cifs/connect.c | 16 +- trunk/fs/ecryptfs/miscdev.c | 14 +- trunk/fs/ext4/extents.c | 11 +- trunk/fs/ext4/indirect.c | 4 +- trunk/fs/gfs2/file.c | 5 +- trunk/fs/gfs2/incore.h | 1 - trunk/fs/gfs2/lock_dlm.c | 39 +- trunk/fs/gfs2/rgrp.c | 32 +- trunk/fs/hfsplus/extents.c | 2 +- trunk/fs/hugetlbfs/inode.c | 2 +- trunk/fs/inode.c | 2 +- trunk/fs/namespace.c | 2 +- trunk/fs/nfs/nfs4client.c | 45 +- trunk/fs/nfs/nfs4proc.c | 1 - trunk/fs/nfs/nfs4state.c | 8 +- trunk/fs/nfsd/nfs4xdr.c | 2 +- trunk/fs/proc/array.c | 1 - trunk/fs/proc/generic.c | 119 ++--- trunk/fs/reiserfs/xattr.c | 4 +- trunk/fs/ubifs/super.c | 12 +- trunk/include/asm-generic/tlb.h | 7 +- trunk/include/linux/acpi.h | 9 + trunk/include/linux/ata.h | 2 +- trunk/include/linux/blktrace_api.h | 1 + trunk/include/linux/capability.h | 2 - trunk/include/linux/compat.h | 4 +- trunk/include/linux/devfreq.h | 16 +- trunk/include/linux/efi.h | 9 +- trunk/include/linux/ftrace.h | 5 +- trunk/include/linux/kexec.h | 2 - trunk/include/linux/kvm_host.h | 2 +- trunk/include/linux/kvm_types.h | 1 - trunk/include/linux/libata.h | 1 - trunk/include/linux/mm.h | 2 - trunk/include/linux/msi.h | 23 +- trunk/include/linux/mutex.h | 3 - trunk/include/linux/netdevice.h | 4 +- .../linux/netfilter/ipset/ip_set_ahash.h | 30 +- trunk/include/linux/pci-acpi.h | 29 -- trunk/include/linux/pci-aspm.h | 20 +- trunk/include/linux/pci-ats.h | 26 +- trunk/include/linux/pci.h | 118 ++--- trunk/include/linux/pci_hotplug.h | 12 +- trunk/include/linux/pci_ids.h | 1 - trunk/include/linux/pcieport_if.h | 4 +- trunk/include/linux/preempt.h | 22 +- trunk/include/linux/proc_fs.h | 2 - trunk/include/linux/sched.h | 6 +- trunk/include/linux/security.h | 12 - trunk/include/linux/signal.h | 4 +- trunk/include/linux/skbuff.h | 7 - trunk/include/linux/spinlock_up.h | 29 +- .../include/linux/ssb/ssb_driver_chipcommon.h | 2 - trunk/include/linux/swiotlb.h | 1 - trunk/include/linux/ucs2_string.h | 14 - trunk/include/net/addrconf.h | 1 - trunk/include/net/irda/irlmp.h | 3 +- trunk/include/net/iucv/af_iucv.h | 8 - trunk/include/net/scm.h | 4 +- trunk/include/scsi/libfc.h | 3 +- trunk/include/sound/max98090.h | 0 trunk/include/sound/soc-dapm.h | 1 - trunk/include/trace/events/block.h | 8 +- trunk/include/trace/events/sched.h | 2 +- trunk/include/uapi/linux/fuse.h | 436 +++++++++--------- trunk/include/uapi/linux/pci_regs.h | 30 +- trunk/include/xen/events.h | 3 +- trunk/ipc/msg.c | 1 - trunk/kernel/.gitignore | 1 - trunk/kernel/capability.c | 24 - trunk/kernel/events/core.c | 8 +- trunk/kernel/events/internal.h | 2 +- trunk/kernel/events/ring_buffer.c | 22 +- trunk/kernel/hrtimer.c | 3 +- trunk/kernel/kexec.c | 118 +---- trunk/kernel/kprobes.c | 19 +- trunk/kernel/kthread.c | 52 +-- trunk/kernel/lockdep.c | 29 +- trunk/kernel/mutex.c | 151 +----- trunk/kernel/rtmutex-tester.c | 5 +- trunk/kernel/sched/clock.c | 26 -- trunk/kernel/sched/core.c | 53 ++- trunk/kernel/sched/cputime.c | 2 +- trunk/kernel/sched/features.h | 7 + trunk/kernel/signal.c | 2 +- trunk/kernel/smpboot.c | 14 +- trunk/kernel/sys.c | 3 +- trunk/kernel/trace/blktrace.c | 26 +- trunk/kernel/trace/ftrace.c | 54 ++- trunk/kernel/trace/trace.c | 9 +- trunk/kernel/trace/trace_stack.c | 2 +- trunk/kernel/user_namespace.c | 22 +- trunk/lib/Kconfig | 3 - trunk/lib/Makefile | 2 - trunk/lib/kobject.c | 9 +- trunk/lib/swiotlb.c | 19 +- trunk/lib/ucs2_string.c | 51 -- trunk/mm/hugetlb.c | 12 +- trunk/mm/memory.c | 48 -- trunk/mm/mmap.c | 2 +- trunk/mm/nommu.c | 12 +- trunk/mm/vmscan.c | 2 +- trunk/net/802/mrp.c | 4 - trunk/net/atm/common.c | 2 - trunk/net/ax25/af_ax25.c | 1 - trunk/net/batman-adv/main.c | 5 +- trunk/net/batman-adv/main.h | 2 +- trunk/net/batman-adv/routing.c | 38 +- trunk/net/batman-adv/translation-table.c | 2 +- trunk/net/batman-adv/vis.c | 4 +- trunk/net/bluetooth/af_bluetooth.c | 4 +- trunk/net/bluetooth/rfcomm/sock.c | 1 - trunk/net/bluetooth/sco.c | 1 - trunk/net/bridge/br_if.c | 3 +- trunk/net/bridge/br_private.h | 1 - trunk/net/bridge/br_stp_if.c | 1 - trunk/net/caif/caif_socket.c | 2 - trunk/net/can/gw.c | 6 +- trunk/net/core/dev.c | 11 +- trunk/net/core/dev_addr_lists.c | 6 +- trunk/net/core/flow.c | 2 +- trunk/net/core/rtnetlink.c | 8 +- trunk/net/ipv4/devinet.c | 66 +-- trunk/net/ipv4/esp4.c | 6 +- trunk/net/ipv4/ip_fragment.c | 14 +- trunk/net/ipv4/netfilter/ipt_rpfilter.c | 8 +- trunk/net/ipv4/syncookies.c | 4 +- trunk/net/ipv4/tcp_input.c | 64 +-- trunk/net/ipv4/tcp_output.c | 9 +- trunk/net/ipv6/addrconf.c | 51 +- trunk/net/ipv6/addrconf_core.c | 19 - trunk/net/ipv6/ip6_input.c | 12 - trunk/net/ipv6/netfilter/ip6t_NPT.c | 2 +- trunk/net/ipv6/netfilter/ip6t_rpfilter.c | 8 +- trunk/net/ipv6/reassembly.c | 12 +- trunk/net/ipv6/tcp_ipv6.c | 1 - trunk/net/irda/af_irda.c | 2 - trunk/net/irda/iriap.c | 3 +- trunk/net/irda/irlmp.c | 10 +- trunk/net/iucv/af_iucv.c | 36 +- trunk/net/key/af_key.c | 1 - trunk/net/l2tp/l2tp_ip6.c | 1 - trunk/net/llc/af_llc.c | 2 - trunk/net/mac80211/cfg.c | 6 +- trunk/net/mac80211/chan.c | 17 +- trunk/net/mac80211/ieee80211_i.h | 4 +- trunk/net/mac80211/iface.c | 62 +-- trunk/net/mac80211/mesh.c | 3 +- trunk/net/mac80211/mlme.c | 30 +- trunk/net/mac80211/offchannel.c | 23 +- trunk/net/mac80211/rx.c | 14 +- trunk/net/mac80211/sta_info.c | 12 +- .../net/netfilter/ipset/ip_set_bitmap_ipmac.c | 6 +- .../netfilter/ipset/ip_set_hash_ipportnet.c | 18 - trunk/net/netfilter/ipset/ip_set_hash_net.c | 22 +- .../netfilter/ipset/ip_set_hash_netiface.c | 22 +- .../net/netfilter/ipset/ip_set_hash_netport.c | 18 - trunk/net/netfilter/ipset/ip_set_list_set.c | 10 +- trunk/net/netfilter/nf_conntrack_sip.c | 6 +- trunk/net/netfilter/nf_conntrack_standalone.c | 1 - trunk/net/netfilter/nf_nat_core.c | 40 +- trunk/net/netfilter/nfnetlink_acct.c | 2 - trunk/net/netfilter/nfnetlink_queue_core.c | 4 +- trunk/net/netrom/af_netrom.c | 1 - trunk/net/nfc/llcp/llcp.c | 8 + trunk/net/nfc/llcp/sock.c | 9 +- trunk/net/openvswitch/datapath.c | 30 +- trunk/net/openvswitch/flow.c | 2 +- trunk/net/rose/af_rose.c | 1 - trunk/net/sched/cls_fw.c | 2 +- trunk/net/sched/sch_cbq.c | 5 +- trunk/net/sched/sch_fq_codel.c | 2 +- trunk/net/sched/sch_generic.c | 2 +- trunk/net/sunrpc/clnt.c | 11 +- trunk/net/tipc/socket.c | 7 - trunk/net/unix/af_unix.c | 6 +- trunk/net/vmw_vsock/af_vsock.c | 8 +- trunk/net/vmw_vsock/vmci_transport.c | 34 +- trunk/net/vmw_vsock/vsock_addr.c | 10 + trunk/net/vmw_vsock/vsock_addr.h | 2 + trunk/net/wireless/core.c | 64 +-- trunk/net/wireless/core.h | 3 - trunk/net/wireless/nl80211.c | 52 +-- trunk/net/wireless/scan.c | 24 +- trunk/net/wireless/sme.c | 8 +- trunk/net/wireless/trace.h | 5 +- trunk/net/wireless/wext-sme.c | 6 - trunk/net/xfrm/xfrm_replay.c | 66 +-- trunk/scripts/checkpatch.pl | 1 - trunk/security/capability.c | 6 - trunk/security/security.c | 5 - trunk/security/selinux/hooks.c | 7 - trunk/sound/core/pcm_native.c | 12 +- trunk/sound/pci/hda/hda_codec.c | 2 +- trunk/sound/pci/hda/hda_eld.c | 2 +- trunk/sound/pci/hda/hda_generic.c | 2 +- trunk/sound/pci/hda/hda_intel.c | 6 +- trunk/sound/pci/hda/patch_hdmi.c | 2 +- trunk/sound/pci/hda/patch_realtek.c | 4 +- trunk/sound/soc/codecs/max98090.c | 0 trunk/sound/soc/codecs/max98090.h | 0 trunk/sound/soc/codecs/si476x.c | 1 - trunk/sound/soc/codecs/wm5102.c | 2 +- trunk/sound/soc/codecs/wm8903.c | 2 - trunk/sound/soc/codecs/wm_adsp.c | 5 +- trunk/sound/soc/fsl/imx-ssi.c | 5 - trunk/sound/soc/fsl/pcm030-audio-fabric.c | 2 +- trunk/sound/soc/samsung/i2s.c | 17 +- trunk/sound/soc/sh/dma-sh7760.c | 4 +- trunk/sound/soc/soc-compress.c | 14 +- trunk/sound/soc/soc-core.c | 10 +- trunk/sound/soc/soc-dapm.c | 14 - trunk/sound/soc/spear/spear_pcm.c | 12 +- trunk/sound/soc/tegra/tegra_pcm.c | 24 +- trunk/sound/usb/clock.c | 45 +- trunk/sound/usb/mixer_quirks.c | 4 +- trunk/sound/usb/quirks.c | 2 +- trunk/tools/power/x86/turbostat/turbostat.c | 5 +- trunk/virt/kvm/kvm_main.c | 47 +- 770 files changed, 6828 insertions(+), 9506 deletions(-) rename trunk/arch/arm/{mm => kernel}/tcm.h (100%) create mode 100644 trunk/arch/arm/mm/cache-v3.S delete mode 100644 trunk/arch/parisc/lib/ucmpdi2.c delete mode 100644 trunk/arch/s390/kernel/dumpstack.c delete mode 100644 trunk/arch/s390/pci/pci_insn.c create mode 100644 trunk/arch/sparc/include/asm/cputime.h create mode 100644 trunk/arch/sparc/include/asm/emergency-restart.h create mode 100644 trunk/arch/sparc/include/asm/mutex.h create mode 100644 trunk/arch/sparc/include/asm/serial.h create mode 100644 trunk/arch/sparc/include/uapi/asm/types.h delete mode 100644 trunk/drivers/net/wireless/rt2x00/rt2x00mmio.c delete mode 100644 trunk/drivers/net/wireless/rt2x00/rt2x00mmio.h create mode 100644 trunk/drivers/pci/msi.h rename trunk/firmware/{qlogic => intel}/sd7220.fw.ihex (100%) delete mode 100644 trunk/include/linux/ucs2_string.h mode change 100644 => 100755 trunk/include/sound/max98090.h delete mode 100644 trunk/lib/ucs2_string.c mode change 100644 => 100755 trunk/sound/soc/codecs/max98090.c mode change 100644 => 100755 trunk/sound/soc/codecs/max98090.h diff --git a/[refs] b/[refs] index 0e3b0c971758..2bea3c93fb1e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 96a3e8af5a54c324535472ca946215d5bafe6539 +refs/heads/master: a1655100ddfa10829b7d3b055611f268a82e335a diff --git a/trunk/Documentation/DocBook/device-drivers.tmpl b/trunk/Documentation/DocBook/device-drivers.tmpl index c36892c072da..7514dbf0a679 100644 --- a/trunk/Documentation/DocBook/device-drivers.tmpl +++ b/trunk/Documentation/DocBook/device-drivers.tmpl @@ -227,7 +227,7 @@ X!Isound/sound_firmware.c 16x50 UART Driver !Edrivers/tty/serial/serial_core.c -!Edrivers/tty/serial/8250/8250_core.c +!Edrivers/tty/serial/8250/8250.c diff --git a/trunk/Documentation/ia64/err_inject.txt b/trunk/Documentation/ia64/err_inject.txt index 9f651c181429..223e4f0582d0 100644 --- a/trunk/Documentation/ia64/err_inject.txt +++ b/trunk/Documentation/ia64/err_inject.txt @@ -882,7 +882,7 @@ int err_inj() cpu=parameters[i].cpu; k = cpu%64; j = cpu/64; - mask[j] = 1UL << k; + mask[j]=1< @@ -805,12 +788,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. edd= [EDD] Format: {"off" | "on" | "skip[mbr]"} - efi_no_storage_paranoia [EFI; X86] - Using this parameter you can use more than 50% of - your efi variable storage. Use this parameter only if - you are really sure that your UEFI does sane gc and - fulfills the spec otherwise your board may brick. - eisa_irq_edge= [PARISC,HW] See header of drivers/parisc/eisa.c. diff --git a/trunk/Documentation/s390/s390dbf.txt b/trunk/Documentation/s390/s390dbf.txt index fcaf0b4efba2..ae66f9b90a25 100644 --- a/trunk/Documentation/s390/s390dbf.txt +++ b/trunk/Documentation/s390/s390dbf.txt @@ -143,8 +143,7 @@ Parameter: id: handle for debug log Return Value: none -Description: frees memory for a debug log and removes all registered debug - views. +Description: frees memory for a debug log Must not be called within an interrupt handler --------------------------------------------------------------------------- diff --git a/trunk/Documentation/scsi/LICENSE.qla2xxx b/trunk/Documentation/scsi/LICENSE.qla2xxx index 5020b7b5a244..27a91cf43d6d 100644 --- a/trunk/Documentation/scsi/LICENSE.qla2xxx +++ b/trunk/Documentation/scsi/LICENSE.qla2xxx @@ -1,4 +1,4 @@ -Copyright (c) 2003-2013 QLogic Corporation +Copyright (c) 2003-2012 QLogic Corporation QLogic Linux FC-FCoE Driver This program includes a device driver for Linux 3.x. diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 95731a08f257..4499bd948860 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -890,8 +890,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) power_save - Automatic power-saving timeout (in second, 0 = disable) - power_save_controller - Reset HD-audio controller in power-saving mode - (default = on) + power_save_controller - Support runtime D3 of HD-audio controller + (-1 = on for supported chip (default), false = off, + true = force to on even for unsupported hardware) align_buffer_size - Force rounding of buffer/period sizes to multiples of 128 bytes. This is more efficient in terms of memory access but isn't required by the HDA spec and prevents diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 8bdd7a7ef2f4..74e58a4d035b 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -4941,12 +4941,6 @@ W: logfs.org S: Maintained F: fs/logfs/ -LPC32XX MACHINE SUPPORT -M: Roland Stigge -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained -F: arch/arm/mach-lpc32xx/ - LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) M: Nagalakshmi Nandigama M: Sreekanth Reddy @@ -5071,8 +5065,9 @@ S: Maintained F: drivers/net/ethernet/marvell/sk* MARVELL LIBERTAS WIRELESS DRIVER +M: Dan Williams L: libertas-dev@lists.infradead.org -S: Orphan +S: Maintained F: drivers/net/wireless/libertas/ MARVELL MV643XX ETHERNET DRIVER @@ -5574,7 +5569,6 @@ F: include/uapi/linux/if_* F: include/uapi/linux/netdevice.h NETXEN (1/10) GbE SUPPORT -M: Manish Chopra M: Sony Chacko M: Rajesh Borundia L: netdev@vger.kernel.org @@ -6631,7 +6625,7 @@ S: Supported F: fs/reiserfs/ REGISTER MAP ABSTRACTION -M: Mark Brown +M: Mark Brown T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git S: Supported F: drivers/base/regmap/ @@ -6957,6 +6951,7 @@ F: drivers/scsi/st* SCTP PROTOCOL M: Vlad Yasevich +M: Sridhar Samudrala M: Neil Horman L: linux-sctp@vger.kernel.org W: http://lksctp.sourceforge.net @@ -7379,7 +7374,7 @@ F: sound/ SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) M: Liam Girdwood -M: Mark Brown +M: Mark Brown T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git L: alsa-devel@alsa-project.org (moderated for non-subscribers) W: http://alsa-project.org/main/index.php/ASoC @@ -7468,7 +7463,7 @@ F: drivers/clk/spear/ SPI SUBSYSTEM M: Grant Likely -M: Mark Brown +M: Mark Brown L: spi-devel-general@lists.sourceforge.net Q: http://patchwork.kernel.org/project/spi-devel-general/list/ T: git git://git.secretlab.ca/git/linux-2.6.git @@ -8713,7 +8708,7 @@ F: drivers/scsi/vmw_pvscsi.h VOLTAGE AND CURRENT REGULATOR FRAMEWORK M: Liam Girdwood -M: Mark Brown +M: Mark Brown W: http://opensource.wolfsonmicro.com/node/15 W: http://www.slimlogic.co.uk/?p=48 T: git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/regulator.git diff --git a/trunk/Makefile b/trunk/Makefile index 8fe69916e726..58a165b02af1 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 9 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc5 NAME = Unicycling Gorilla # *DOCUMENTATION* @@ -513,8 +513,7 @@ ifeq ($(KBUILD_EXTMOD),) # Carefully list dependencies so we do not try to build scripts twice # in parallel PHONY += scripts -scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \ - asm-generic +scripts: scripts_basic include/config/auto.conf include/config/tristate.conf $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit diff --git a/trunk/arch/alpha/Makefile b/trunk/arch/alpha/Makefile index 2cc3cc519c54..4759fe751aa1 100644 --- a/trunk/arch/alpha/Makefile +++ b/trunk/arch/alpha/Makefile @@ -12,7 +12,7 @@ NM := $(NM) -B LDFLAGS_vmlinux := -static -N #-relax CHECKFLAGS += -D__alpha__ -m64 -cflags-y := -pipe -mno-fp-regs -ffixed-8 +cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data cflags-y += $(call cc-option, -fno-jump-tables) cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4 diff --git a/trunk/arch/alpha/include/asm/floppy.h b/trunk/arch/alpha/include/asm/floppy.h index bae97eb19d26..46cefbd50e73 100644 --- a/trunk/arch/alpha/include/asm/floppy.h +++ b/trunk/arch/alpha/include/asm/floppy.h @@ -26,7 +26,7 @@ #define fd_disable_irq() disable_irq(FLOPPY_IRQ) #define fd_cacheflush(addr,size) /* nothing */ #define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt,\ - 0, "floppy", NULL) + IRQF_DISABLED, "floppy", NULL) #define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) #ifdef CONFIG_PCI diff --git a/trunk/arch/alpha/kernel/irq.c b/trunk/arch/alpha/kernel/irq.c index 7b2be251c30f..2872accd2215 100644 --- a/trunk/arch/alpha/kernel/irq.c +++ b/trunk/arch/alpha/kernel/irq.c @@ -117,6 +117,13 @@ handle_irq(int irq) return; } + /* + * From here we must proceed with IPL_MAX. Note that we do not + * explicitly enable interrupts afterwards - some MILO PALcode + * (namely LX164 one) seems to have severe problems with RTI + * at IPL 0. + */ + local_irq_disable(); irq_enter(); generic_handle_irq_desc(irq, desc); irq_exit(); diff --git a/trunk/arch/alpha/kernel/irq_alpha.c b/trunk/arch/alpha/kernel/irq_alpha.c index f433fc11877a..772ddfdb71a8 100644 --- a/trunk/arch/alpha/kernel/irq_alpha.c +++ b/trunk/arch/alpha/kernel/irq_alpha.c @@ -45,14 +45,6 @@ do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, struct pt_regs *regs) { struct pt_regs *old_regs; - - /* - * Disable interrupts during IRQ handling. - * Note that there is no matching local_irq_enable() due to - * severe problems with RTI at IPL0 and some MILO PALcode - * (namely LX164). - */ - local_irq_disable(); switch (type) { case 0: #ifdef CONFIG_SMP @@ -70,6 +62,7 @@ do_entInt(unsigned long type, unsigned long vector, { long cpu; + local_irq_disable(); smp_percpu_timer_interrupt(regs); cpu = smp_processor_id(); if (cpu != boot_cpuid) { @@ -229,6 +222,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr, struct irqaction timer_irqaction = { .handler = timer_interrupt, + .flags = IRQF_DISABLED, .name = "timer", }; diff --git a/trunk/arch/alpha/kernel/sys_nautilus.c b/trunk/arch/alpha/kernel/sys_nautilus.c index 1383f8601a93..4d4c046f708d 100644 --- a/trunk/arch/alpha/kernel/sys_nautilus.c +++ b/trunk/arch/alpha/kernel/sys_nautilus.c @@ -188,10 +188,6 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr) extern void free_reserved_mem(void *, void *); extern void pcibios_claim_one_bus(struct pci_bus *); -static struct resource irongate_io = { - .name = "Irongate PCI IO", - .flags = IORESOURCE_IO, -}; static struct resource irongate_mem = { .name = "Irongate PCI MEM", .flags = IORESOURCE_MEM, @@ -213,7 +209,6 @@ nautilus_init_pci(void) irongate = pci_get_bus_and_slot(0, 0); bus->self = irongate; - bus->resource[0] = &irongate_io; bus->resource[1] = &irongate_mem; pci_bus_size_bridges(bus); diff --git a/trunk/arch/alpha/kernel/sys_titan.c b/trunk/arch/alpha/kernel/sys_titan.c index a53cf03f49d5..5cf4a481b8c5 100644 --- a/trunk/arch/alpha/kernel/sys_titan.c +++ b/trunk/arch/alpha/kernel/sys_titan.c @@ -280,15 +280,15 @@ titan_late_init(void) * all reported to the kernel as machine checks, so the handler * is a nop so it can be called to count the individual events. */ - titan_request_irq(63+16, titan_intr_nop, 0, + titan_request_irq(63+16, titan_intr_nop, IRQF_DISABLED, "CChip Error", NULL); - titan_request_irq(62+16, titan_intr_nop, 0, + titan_request_irq(62+16, titan_intr_nop, IRQF_DISABLED, "PChip 0 H_Error", NULL); - titan_request_irq(61+16, titan_intr_nop, 0, + titan_request_irq(61+16, titan_intr_nop, IRQF_DISABLED, "PChip 1 H_Error", NULL); - titan_request_irq(60+16, titan_intr_nop, 0, + titan_request_irq(60+16, titan_intr_nop, IRQF_DISABLED, "PChip 0 C_Error", NULL); - titan_request_irq(59+16, titan_intr_nop, 0, + titan_request_irq(59+16, titan_intr_nop, IRQF_DISABLED, "PChip 1 C_Error", NULL); /* @@ -348,9 +348,9 @@ privateer_init_pci(void) * Hook a couple of extra err interrupts that the * common titan code won't. */ - titan_request_irq(53+16, titan_intr_nop, 0, + titan_request_irq(53+16, titan_intr_nop, IRQF_DISABLED, "NMI", NULL); - titan_request_irq(50+16, titan_intr_nop, 0, + titan_request_irq(50+16, titan_intr_nop, IRQF_DISABLED, "Temperature Warning", NULL); /* diff --git a/trunk/arch/arc/include/asm/irqflags.h b/trunk/arch/arc/include/asm/irqflags.h index eac071668201..ccd84806b62f 100644 --- a/trunk/arch/arc/include/asm/irqflags.h +++ b/trunk/arch/arc/include/asm/irqflags.h @@ -39,7 +39,7 @@ static inline long arch_local_irq_save(void) " flag.nz %0 \n" : "=r"(temp), "=r"(flags) : "n"((STATUS_E1_MASK | STATUS_E2_MASK)) - : "memory", "cc"); + : "cc"); return flags; } @@ -53,8 +53,7 @@ static inline void arch_local_irq_restore(unsigned long flags) __asm__ __volatile__( " flag %0 \n" : - : "r"(flags) - : "memory"); + : "r"(flags)); } /* @@ -74,8 +73,7 @@ static inline void arch_local_irq_disable(void) " and %0, %0, %1 \n" " flag %0 \n" : "=&r"(temp) - : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK)) - : "memory"); + : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK))); } /* @@ -87,9 +85,7 @@ static inline long arch_local_save_flags(void) __asm__ __volatile__( " lr %0, [status32] \n" - : "=&r"(temp) - : - : "memory"); + : "=&r"(temp)); return temp; } diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 1cacda426a0e..13b739469c51 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -1183,9 +1183,9 @@ config ARM_NR_BANKS default 8 config IWMMXT - bool "Enable iWMMXt support" if !CPU_PJ4 + bool "Enable iWMMXt support" depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 - default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 + default y if PXA27x || PXA3xx || ARCH_MMP help Enable support for iWMMXt context switching at run time if running on a CPU that supports it. @@ -1439,16 +1439,6 @@ config ARM_ERRATA_775420 to deadlock. This workaround puts DSB before executing ISB if an abort may occur on cache maintenance. -config ARM_ERRATA_798181 - bool "ARM errata: TLBI/DSB failure on Cortex-A15" - depends on CPU_V7 && SMP - help - On Cortex-A15 (r0p0..r3p2) the TLBI*IS/DSB operations are not - adequately shooting down all use of the old entries. This - option enables the Linux kernel workaround for this erratum - which sends an IPI to the CPUs that are running the same ASID - as the one being invalidated. - endmenu source "arch/arm/common/Kconfig" diff --git a/trunk/arch/arm/boot/dts/armada-370-mirabox.dts b/trunk/arch/arm/boot/dts/armada-370-mirabox.dts index 3234875824dc..dd0c57dd9f30 100644 --- a/trunk/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/trunk/arch/arm/boot/dts/armada-370-mirabox.dts @@ -54,7 +54,7 @@ }; mvsdio@d00d4000 { - pinctrl-0 = <&sdio_pins3>; + pinctrl-0 = <&sdio_pins2>; pinctrl-names = "default"; status = "okay"; /* diff --git a/trunk/arch/arm/boot/dts/armada-370.dtsi b/trunk/arch/arm/boot/dts/armada-370.dtsi index a195debb67d3..8188d138020e 100644 --- a/trunk/arch/arm/boot/dts/armada-370.dtsi +++ b/trunk/arch/arm/boot/dts/armada-370.dtsi @@ -59,12 +59,6 @@ "mpp50", "mpp51", "mpp52"; marvell,function = "sd0"; }; - - sdio_pins3: sdio-pins3 { - marvell,pins = "mpp48", "mpp49", "mpp50", - "mpp51", "mpp52", "mpp53"; - marvell,function = "sd0"; - }; }; gpio0: gpio@d0018100 { diff --git a/trunk/arch/arm/boot/dts/dbx5x0.dtsi b/trunk/arch/arm/boot/dts/dbx5x0.dtsi index aaa63d0a8096..9de93096601a 100644 --- a/trunk/arch/arm/boot/dts/dbx5x0.dtsi +++ b/trunk/arch/arm/boot/dts/dbx5x0.dtsi @@ -191,8 +191,8 @@ prcmu: prcmu@80157000 { compatible = "stericsson,db8500-prcmu"; - reg = <0x80157000 0x1000>, <0x801b0000 0x8000>, <0x801b8000 0x1000>; - reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm"; + reg = <0x80157000 0x1000>; + reg-names = "prcmu"; interrupts = <0 47 0x4>; #address-cells = <1>; #size-cells = <1>; diff --git a/trunk/arch/arm/boot/dts/imx28-m28evk.dts b/trunk/arch/arm/boot/dts/imx28-m28evk.dts index fd36e1cca104..6ce3d17c3a29 100644 --- a/trunk/arch/arm/boot/dts/imx28-m28evk.dts +++ b/trunk/arch/arm/boot/dts/imx28-m28evk.dts @@ -152,6 +152,7 @@ i2c0: i2c@80058000 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; + clock-frequency = <400000>; status = "okay"; sgtl5000: codec@0a { diff --git a/trunk/arch/arm/boot/dts/imx28-sps1.dts b/trunk/arch/arm/boot/dts/imx28-sps1.dts index 6c6a5442800a..e6cde8aa7fff 100644 --- a/trunk/arch/arm/boot/dts/imx28-sps1.dts +++ b/trunk/arch/arm/boot/dts/imx28-sps1.dts @@ -70,6 +70,7 @@ i2c0: i2c@80058000 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; + clock-frequency = <400000>; status = "okay"; rtc: rtc@51 { diff --git a/trunk/arch/arm/boot/dts/imx6qdl.dtsi b/trunk/arch/arm/boot/dts/imx6qdl.dtsi index 281a223591ff..06ec460b4581 100644 --- a/trunk/arch/arm/boot/dts/imx6qdl.dtsi +++ b/trunk/arch/arm/boot/dts/imx6qdl.dtsi @@ -91,7 +91,6 @@ compatible = "arm,cortex-a9-twd-timer"; reg = <0x00a00600 0x20>; interrupts = <1 13 0xf01>; - clocks = <&clks 15>; }; L2: l2-cache@00a02000 { diff --git a/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts b/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts index c3573be7b92c..bd83b8fc7c83 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-goflexnet.dts @@ -77,7 +77,6 @@ }; nand@3000000 { - chip-delay = <40>; status = "okay"; partition@0 { diff --git a/trunk/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/trunk/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts index 3694e94f6e99..93c3afbef9ee 100644 --- a/trunk/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts +++ b/trunk/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts @@ -96,11 +96,11 @@ marvell,function = "gpio"; }; pmx_led_rebuild_brt_ctrl_1: pmx-led-rebuild-brt-ctrl-1 { - marvell,pins = "mpp46"; + marvell,pins = "mpp44"; marvell,function = "gpio"; }; pmx_led_rebuild_brt_ctrl_2: pmx-led-rebuild-brt-ctrl-2 { - marvell,pins = "mpp47"; + marvell,pins = "mpp45"; marvell,function = "gpio"; }; @@ -157,14 +157,14 @@ gpios = <&gpio0 16 0>; linux,default-trigger = "default-on"; }; - rebuild_led { - label = "status:white:rebuild_led"; - gpios = <&gpio1 4 0>; - }; - health_led { + health_led1 { label = "status:red:health_led"; gpios = <&gpio1 5 0>; }; + health_led2 { + label = "status:white:health_led"; + gpios = <&gpio1 4 0>; + }; backup_led { label = "status:blue:backup_led"; gpios = <&gpio0 15 0>; diff --git a/trunk/arch/arm/boot/dts/orion5x.dtsi b/trunk/arch/arm/boot/dts/orion5x.dtsi index f7bec3b1ba32..8aad00f81ed9 100644 --- a/trunk/arch/arm/boot/dts/orion5x.dtsi +++ b/trunk/arch/arm/boot/dts/orion5x.dtsi @@ -13,9 +13,6 @@ compatible = "marvell,orion5x"; interrupt-parent = <&intc>; - aliases { - gpio0 = &gpio0; - }; intc: interrupt-controller { compatible = "marvell,orion-intc", "marvell,intc"; interrupt-controller; @@ -35,9 +32,7 @@ #gpio-cells = <2>; gpio-controller; reg = <0x10100 0x40>; - ngpios = <32>; - interrupt-controller; - #interrupt-cells = <2>; + ngpio = <32>; interrupts = <6>, <7>, <8>, <9>; }; @@ -96,7 +91,7 @@ reg = <0x90000 0x10000>, <0xf2200000 0x800>; reg-names = "regs", "sram"; - interrupts = <28>; + interrupts = <22>; status = "okay"; }; }; diff --git a/trunk/arch/arm/include/asm/delay.h b/trunk/arch/arm/include/asm/delay.h index dff714d886d5..720799fd3a81 100644 --- a/trunk/arch/arm/include/asm/delay.h +++ b/trunk/arch/arm/include/asm/delay.h @@ -24,7 +24,7 @@ extern struct arm_delay_ops { void (*delay)(unsigned long); void (*const_udelay)(unsigned long); void (*udelay)(unsigned long); - unsigned long ticks_per_jiffy; + bool const_clock; } arm_delay_ops; #define __delay(n) arm_delay_ops.delay(n) diff --git a/trunk/arch/arm/include/asm/glue-cache.h b/trunk/arch/arm/include/asm/glue-cache.h index ea289e1435e7..cca9f15704ed 100644 --- a/trunk/arch/arm/include/asm/glue-cache.h +++ b/trunk/arch/arm/include/asm/glue-cache.h @@ -19,6 +19,14 @@ #undef _CACHE #undef MULTI_CACHE +#if defined(CONFIG_CPU_CACHE_V3) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v3 +# endif +#endif + #if defined(CONFIG_CPU_CACHE_V4) # ifdef _CACHE # define MULTI_CACHE 1 diff --git a/trunk/arch/arm/include/asm/hardware/iop3xx.h b/trunk/arch/arm/include/asm/hardware/iop3xx.h index ed94b1a366ae..02fe2fbe2477 100644 --- a/trunk/arch/arm/include/asm/hardware/iop3xx.h +++ b/trunk/arch/arm/include/asm/hardware/iop3xx.h @@ -37,7 +37,7 @@ extern int iop3xx_get_init_atu(void); * IOP3XX processor registers */ #define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000 -#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfedfe000 +#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfeffe000 #define IOP3XX_PERIPHERAL_SIZE 0x00002000 #define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\ IOP3XX_PERIPHERAL_SIZE - 1) diff --git a/trunk/arch/arm/include/asm/highmem.h b/trunk/arch/arm/include/asm/highmem.h index 91b99abe7a95..8c5e828f484d 100644 --- a/trunk/arch/arm/include/asm/highmem.h +++ b/trunk/arch/arm/include/asm/highmem.h @@ -41,13 +41,6 @@ extern void kunmap_high(struct page *page); #endif #endif -/* - * Needed to be able to broadcast the TLB invalidation for kmap. - */ -#ifdef CONFIG_ARM_ERRATA_798181 -#undef ARCH_NEEDS_KMAP_HIGH_GET -#endif - #ifdef ARCH_NEEDS_KMAP_HIGH_GET extern void *kmap_high_get(struct page *page); #else diff --git a/trunk/arch/arm/include/asm/mmu_context.h b/trunk/arch/arm/include/asm/mmu_context.h index a7b85e0d0cc1..863a6611323c 100644 --- a/trunk/arch/arm/include/asm/mmu_context.h +++ b/trunk/arch/arm/include/asm/mmu_context.h @@ -27,8 +27,6 @@ void __check_vmalloc_seq(struct mm_struct *mm); void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk); #define init_new_context(tsk,mm) ({ atomic64_set(&mm->context.id, 0); 0; }) -DECLARE_PER_CPU(atomic64_t, active_asids); - #else /* !CONFIG_CPU_HAS_ASID */ #ifdef CONFIG_MMU diff --git a/trunk/arch/arm/include/asm/pgtable-3level.h b/trunk/arch/arm/include/asm/pgtable-3level.h index 86b8fe398b95..6ef8afd1b64c 100644 --- a/trunk/arch/arm/include/asm/pgtable-3level.h +++ b/trunk/arch/arm/include/asm/pgtable-3level.h @@ -111,7 +111,7 @@ #define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */ #define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */ #define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */ -#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ +#define L_PTE_S2_RDWR (_AT(pteval_t, 2) << 6) /* HAP[2:1] */ /* * Hyp-mode PL2 PTE definitions for LPAE. diff --git a/trunk/arch/arm/include/asm/tlbflush.h b/trunk/arch/arm/include/asm/tlbflush.h index ab865e65a84c..4db8c8820f0d 100644 --- a/trunk/arch/arm/include/asm/tlbflush.h +++ b/trunk/arch/arm/include/asm/tlbflush.h @@ -14,6 +14,7 @@ #include +#define TLB_V3_PAGE (1 << 0) #define TLB_V4_U_PAGE (1 << 1) #define TLB_V4_D_PAGE (1 << 2) #define TLB_V4_I_PAGE (1 << 3) @@ -21,6 +22,7 @@ #define TLB_V6_D_PAGE (1 << 5) #define TLB_V6_I_PAGE (1 << 6) +#define TLB_V3_FULL (1 << 8) #define TLB_V4_U_FULL (1 << 9) #define TLB_V4_D_FULL (1 << 10) #define TLB_V4_I_FULL (1 << 11) @@ -50,6 +52,7 @@ * ============= * * We have the following to choose from: + * v3 - ARMv3 * v4 - ARMv4 without write buffer * v4wb - ARMv4 with write buffer without I TLB flush entry instruction * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction @@ -327,6 +330,7 @@ static inline void local_flush_tlb_all(void) if (tlb_flag(TLB_WB)) dsb(); + tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); @@ -347,8 +351,9 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) if (tlb_flag(TLB_WB)) dsb(); - if (possible_tlb_flags & (TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { + if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { + tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); @@ -380,8 +385,9 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) if (tlb_flag(TLB_WB)) dsb(); - if (possible_tlb_flags & (TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && + if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { + tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr); tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr); tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr); @@ -412,6 +418,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) if (tlb_flag(TLB_WB)) dsb(); + tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr); tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); @@ -443,21 +450,6 @@ static inline void local_flush_bp_all(void) isb(); } -#ifdef CONFIG_ARM_ERRATA_798181 -static inline void dummy_flush_tlb_a15_erratum(void) -{ - /* - * Dummy TLBIMVAIS. Using the unmapped address 0 and ASID 0. - */ - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); - dsb(); -} -#else -static inline void dummy_flush_tlb_a15_erratum(void) -{ -} -#endif - /* * flush_pmd_entry * diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index fefd7f971437..3248cde504ed 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -276,13 +276,7 @@ ENDPROC(ftrace_graph_caller_old) */ .macro mcount_enter -/* - * This pad compensates for the push {lr} at the call site. Note that we are - * unable to unwind through a function which does not otherwise save its lr. - */ - UNWIND(.pad #4) stmdb sp!, {r0-r3, lr} - UNWIND(.save {r0-r3, lr}) .endm .macro mcount_get_lr reg @@ -295,7 +289,6 @@ ENDPROC(ftrace_graph_caller_old) .endm ENTRY(__gnu_mcount_nc) -UNWIND(.fnstart) #ifdef CONFIG_DYNAMIC_FTRACE mov ip, lr ldmia sp!, {lr} @@ -303,22 +296,17 @@ UNWIND(.fnstart) #else __mcount #endif -UNWIND(.fnend) ENDPROC(__gnu_mcount_nc) #ifdef CONFIG_DYNAMIC_FTRACE ENTRY(ftrace_caller) -UNWIND(.fnstart) __ftrace_caller -UNWIND(.fnend) ENDPROC(ftrace_caller) #endif #ifdef CONFIG_FUNCTION_GRAPH_TRACER ENTRY(ftrace_graph_caller) -UNWIND(.fnstart) __ftrace_graph_caller -UNWIND(.fnend) ENDPROC(ftrace_graph_caller) #endif diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 8bac553fe213..e0eb9a1cae77 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -267,7 +267,7 @@ __create_page_tables: addne r6, r6, #1 << SECTION_SHIFT strne r6, [r3] -#if defined(CONFIG_ARM_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8) +#if defined(CONFIG_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8) sub r4, r4, #4 @ Fixup page table pointer @ for 64-bit descriptors #endif diff --git a/trunk/arch/arm/kernel/hw_breakpoint.c b/trunk/arch/arm/kernel/hw_breakpoint.c index 1fd749ee4a1b..96093b75ab90 100644 --- a/trunk/arch/arm/kernel/hw_breakpoint.c +++ b/trunk/arch/arm/kernel/hw_breakpoint.c @@ -966,7 +966,7 @@ static void reset_ctrl_regs(void *unused) } if (err) { - pr_warn_once("CPU %d debug is powered down!\n", cpu); + pr_warning("CPU %d debug is powered down!\n", cpu); cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); return; } @@ -987,7 +987,7 @@ static void reset_ctrl_regs(void *unused) isb(); if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { - pr_warn_once("CPU %d failed to disable vector catch\n", cpu); + pr_warning("CPU %d failed to disable vector catch\n", cpu); return; } @@ -1007,7 +1007,7 @@ static void reset_ctrl_regs(void *unused) } if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { - pr_warn_once("CPU %d failed to clear debug register pairs\n", cpu); + pr_warning("CPU %d failed to clear debug register pairs\n", cpu); return; } @@ -1043,7 +1043,7 @@ static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action, return NOTIFY_OK; } -static struct notifier_block dbg_cpu_pm_nb = { +static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = { .notifier_call = dbg_cpu_pm_notify, }; diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 8c3094d0f7b7..146157dfe27c 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -253,10 +253,7 @@ validate_event(struct pmu_hw_events *hw_events, struct arm_pmu *armpmu = to_arm_pmu(event->pmu); struct pmu *leader_pmu = event->group_leader->pmu; - if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) - return 1; - - if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) + if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF) return 1; return armpmu->get_event_idx(hw_events, event) >= 0; diff --git a/trunk/arch/arm/kernel/sched_clock.c b/trunk/arch/arm/kernel/sched_clock.c index 59d2adb764a9..bd6f56b9ec21 100644 --- a/trunk/arch/arm/kernel/sched_clock.c +++ b/trunk/arch/arm/kernel/sched_clock.c @@ -45,12 +45,12 @@ static u32 notrace jiffy_sched_clock_read(void) static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read; -static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift) +static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) { return (cyc * mult) >> shift; } -static unsigned long long notrace cyc_to_sched_clock(u32 cyc, u32 mask) +static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask) { u64 epoch_ns; u32 epoch_cyc; diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 234e339196c0..3f6cbb2e3eda 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -56,6 +56,7 @@ #include #include "atags.h" +#include "tcm.h" #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) @@ -352,23 +353,6 @@ void __init early_print(const char *str, ...) printk("%s", buf); } -static void __init cpuid_init_hwcaps(void) -{ - unsigned int divide_instrs; - - if (cpu_architecture() < CPU_ARCH_ARMv7) - return; - - divide_instrs = (read_cpuid_ext(CPUID_EXT_ISAR0) & 0x0f000000) >> 24; - - switch (divide_instrs) { - case 2: - elf_hwcap |= HWCAP_IDIVA; - case 1: - elf_hwcap |= HWCAP_IDIVT; - } -} - static void __init feat_v6_fixup(void) { int id = read_cpuid_id(); @@ -499,11 +483,8 @@ static void __init setup_processor(void) snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; - - cpuid_init_hwcaps(); - #ifndef CONFIG_ARM_THUMB - elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT); + elf_hwcap &= ~HWCAP_THUMB; #endif feat_v6_fixup(); @@ -543,7 +524,7 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size) size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); -#ifndef CONFIG_ARM_LPAE +#ifndef CONFIG_LPAE if (bank->start + size < bank->start) { printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " "32-bit physical address space\n", (long long)start); @@ -797,6 +778,8 @@ void __init setup_arch(char **cmdline_p) reserve_crashkernel(); + tcm_init(); + #ifdef CONFIG_MULTI_IRQ_HANDLER handle_arch_irq = mdesc->handle_irq; #endif diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 1f2ccccaf009..79078edbb9bc 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -673,6 +673,9 @@ static int cpufreq_callback(struct notifier_block *nb, if (freq->flags & CPUFREQ_CONST_LOOPS) return NOTIFY_OK; + if (arm_delay_ops.const_clock) + return NOTIFY_OK; + if (!per_cpu(l_p_j_ref, cpu)) { per_cpu(l_p_j_ref, cpu) = per_cpu(cpu_data, cpu).loops_per_jiffy; diff --git a/trunk/arch/arm/kernel/smp_tlb.c b/trunk/arch/arm/kernel/smp_tlb.c index e82e1d248772..bd0300531399 100644 --- a/trunk/arch/arm/kernel/smp_tlb.c +++ b/trunk/arch/arm/kernel/smp_tlb.c @@ -12,7 +12,6 @@ #include #include -#include /**********************************************************************/ @@ -70,72 +69,12 @@ static inline void ipi_flush_bp_all(void *ignored) local_flush_bp_all(); } -#ifdef CONFIG_ARM_ERRATA_798181 -static int erratum_a15_798181(void) -{ - unsigned int midr = read_cpuid_id(); - - /* Cortex-A15 r0p0..r3p2 affected */ - if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2) - return 0; - return 1; -} -#else -static int erratum_a15_798181(void) -{ - return 0; -} -#endif - -static void ipi_flush_tlb_a15_erratum(void *arg) -{ - dmb(); -} - -static void broadcast_tlb_a15_erratum(void) -{ - if (!erratum_a15_798181()) - return; - - dummy_flush_tlb_a15_erratum(); - smp_call_function_many(cpu_online_mask, ipi_flush_tlb_a15_erratum, - NULL, 1); -} - -static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) -{ - int cpu; - cpumask_t mask = { CPU_BITS_NONE }; - - if (!erratum_a15_798181()) - return; - - dummy_flush_tlb_a15_erratum(); - for_each_online_cpu(cpu) { - if (cpu == smp_processor_id()) - continue; - /* - * We only need to send an IPI if the other CPUs are running - * the same ASID as the one being invalidated. There is no - * need for locking around the active_asids check since the - * switch_mm() function has at least one dmb() (as required by - * this workaround) in case a context switch happens on - * another CPU after the condition below. - */ - if (atomic64_read(&mm->context.id) == - atomic64_read(&per_cpu(active_asids, cpu))) - cpumask_set_cpu(cpu, &mask); - } - smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1); -} - void flush_tlb_all(void) { if (tlb_ops_need_broadcast()) on_each_cpu(ipi_flush_tlb_all, NULL, 1); else local_flush_tlb_all(); - broadcast_tlb_a15_erratum(); } void flush_tlb_mm(struct mm_struct *mm) @@ -144,7 +83,6 @@ void flush_tlb_mm(struct mm_struct *mm) on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); else local_flush_tlb_mm(mm); - broadcast_tlb_mm_a15_erratum(mm); } void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) @@ -157,7 +95,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) &ta, 1); } else local_flush_tlb_page(vma, uaddr); - broadcast_tlb_mm_a15_erratum(vma->vm_mm); } void flush_tlb_kernel_page(unsigned long kaddr) @@ -168,7 +105,6 @@ void flush_tlb_kernel_page(unsigned long kaddr) on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); } else local_flush_tlb_kernel_page(kaddr); - broadcast_tlb_a15_erratum(); } void flush_tlb_range(struct vm_area_struct *vma, @@ -183,7 +119,6 @@ void flush_tlb_range(struct vm_area_struct *vma, &ta, 1); } else local_flush_tlb_range(vma, start, end); - broadcast_tlb_mm_a15_erratum(vma->vm_mm); } void flush_tlb_kernel_range(unsigned long start, unsigned long end) @@ -195,7 +130,6 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end) on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1); } else local_flush_tlb_kernel_range(start, end); - broadcast_tlb_a15_erratum(); } void flush_bp_all(void) diff --git a/trunk/arch/arm/kernel/tcm.c b/trunk/arch/arm/kernel/tcm.c index f50f19e5c138..30ae6bb4a310 100644 --- a/trunk/arch/arm/kernel/tcm.c +++ b/trunk/arch/arm/kernel/tcm.c @@ -17,6 +17,7 @@ #include #include #include +#include "tcm.h" static struct gen_pool *tcm_pool; static bool dtcm_present; diff --git a/trunk/arch/arm/mm/tcm.h b/trunk/arch/arm/kernel/tcm.h similarity index 100% rename from trunk/arch/arm/mm/tcm.h rename to trunk/arch/arm/kernel/tcm.h diff --git a/trunk/arch/arm/kvm/arm.c b/trunk/arch/arm/kvm/arm.c index c1fe498983ac..5a936988eb24 100644 --- a/trunk/arch/arm/kvm/arm.c +++ b/trunk/arch/arm/kvm/arm.c @@ -201,7 +201,6 @@ int kvm_dev_ioctl_check_extension(long ext) break; case KVM_CAP_ARM_SET_DEVICE_ADDR: r = 1; - break; case KVM_CAP_NR_VCPUS: r = num_online_cpus(); break; diff --git a/trunk/arch/arm/kvm/coproc.c b/trunk/arch/arm/kvm/coproc.c index 7bed7556077a..4ea9a982269c 100644 --- a/trunk/arch/arm/kvm/coproc.c +++ b/trunk/arch/arm/kvm/coproc.c @@ -79,11 +79,11 @@ static bool access_dcsw(struct kvm_vcpu *vcpu, u32 val; int cpu; + cpu = get_cpu(); + if (!p->is_write) return read_from_write_only(vcpu, p); - cpu = get_cpu(); - cpumask_setall(&vcpu->arch.require_dcache_flush); cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush); diff --git a/trunk/arch/arm/kvm/vgic.c b/trunk/arch/arm/kvm/vgic.c index 0e4cfe123b38..c9a17316e9fe 100644 --- a/trunk/arch/arm/kvm/vgic.c +++ b/trunk/arch/arm/kvm/vgic.c @@ -883,7 +883,8 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) lr, irq, vgic_cpu->vgic_lr[lr]); BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT; - return true; + + goto out; } /* Try to use another LR for this interrupt */ @@ -897,6 +898,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) vgic_cpu->vgic_irq_lr_map[irq] = lr; set_bit(lr, vgic_cpu->lr_used); +out: if (!vgic_irq_is_edge(vcpu, irq)) vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI; @@ -1016,6 +1018,21 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr); + /* + * We do not need to take the distributor lock here, since the only + * action we perform is clearing the irq_active_bit for an EOIed + * level interrupt. There is a potential race with + * the queuing of an interrupt in __kvm_vgic_flush_hwstate(), where we + * check if the interrupt is already active. Two possibilities: + * + * - The queuing is occurring on the same vcpu: cannot happen, + * as we're already in the context of this vcpu, and + * executing the handler + * - The interrupt has been migrated to another vcpu, and we + * ignore this interrupt for this run. Big deal. It is still + * pending though, and will get considered when this vcpu + * exits. + */ if (vgic_cpu->vgic_misr & GICH_MISR_EOI) { /* * Some level interrupts have been EOIed. Clear their @@ -1037,13 +1054,6 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } else { vgic_cpu_irq_clear(vcpu, irq); } - - /* - * Despite being EOIed, the LR may not have - * been marked as empty. - */ - set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); - vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT; } } @@ -1054,8 +1064,9 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } /* - * Sync back the VGIC state after a guest run. The distributor lock is - * needed so we don't get preempted in the middle of the state processing. + * Sync back the VGIC state after a guest run. We do not really touch + * the distributor here (the irq_pending_on_cpu bit is safe to set), + * so there is no need for taking its lock. */ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { @@ -1101,14 +1112,10 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { - struct vgic_dist *dist = &vcpu->kvm->arch.vgic; - if (!irqchip_in_kernel(vcpu->kvm)) return; - spin_lock(&dist->lock); __kvm_vgic_sync_hwstate(vcpu); - spin_unlock(&dist->lock); } int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/arm/lib/delay.c b/trunk/arch/arm/lib/delay.c index 64dbfa57204a..6b93f6a1a3c7 100644 --- a/trunk/arch/arm/lib/delay.c +++ b/trunk/arch/arm/lib/delay.c @@ -58,7 +58,7 @@ static void __timer_delay(unsigned long cycles) static void __timer_const_udelay(unsigned long xloops) { unsigned long long loops = xloops; - loops *= arm_delay_ops.ticks_per_jiffy; + loops *= loops_per_jiffy; __timer_delay(loops >> UDELAY_SHIFT); } @@ -73,13 +73,11 @@ void __init register_current_timer_delay(const struct delay_timer *timer) pr_info("Switching to timer-based delay loop\n"); delay_timer = timer; lpj_fine = timer->freq / HZ; - - /* cpufreq may scale loops_per_jiffy, so keep a private copy */ - arm_delay_ops.ticks_per_jiffy = lpj_fine; + loops_per_jiffy = lpj_fine; arm_delay_ops.delay = __timer_delay; arm_delay_ops.const_udelay = __timer_const_udelay; arm_delay_ops.udelay = __timer_udelay; - + arm_delay_ops.const_clock = true; delay_calibrated = true; } else { pr_info("Ignoring duplicate/late registration of read_current_timer delay\n"); diff --git a/trunk/arch/arm/mach-cns3xxx/core.c b/trunk/arch/arm/mach-cns3xxx/core.c index 52e4bb5cf12d..e698f26cc0cb 100644 --- a/trunk/arch/arm/mach-cns3xxx/core.c +++ b/trunk/arch/arm/mach-cns3xxx/core.c @@ -22,9 +22,19 @@ static struct map_desc cns3xxx_io_desc[] __initdata = { { - .virtual = CNS3XXX_TC11MP_SCU_BASE_VIRT, - .pfn = __phys_to_pfn(CNS3XXX_TC11MP_SCU_BASE), - .length = SZ_8K, + .virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE), + .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT, diff --git a/trunk/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/trunk/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h index b1021aafa481..191c8e57f289 100644 --- a/trunk/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h +++ b/trunk/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h @@ -94,10 +94,10 @@ #define RTC_INTR_STS_OFFSET 0x34 #define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */ -#define CNS3XXX_MISC_BASE_VIRT 0xFB000000 /* Misc Control */ +#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */ #define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */ -#define CNS3XXX_PM_BASE_VIRT 0xFB001000 +#define CNS3XXX_PM_BASE_VIRT 0xFFF08000 #define PM_CLK_GATE_OFFSET 0x00 #define PM_SOFT_RST_OFFSET 0x04 @@ -109,7 +109,7 @@ #define PM_PLL_HM_PD_OFFSET 0x1C #define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */ -#define CNS3XXX_UART0_BASE_VIRT 0xFB002000 +#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000 #define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */ #define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000 @@ -130,7 +130,7 @@ #define CNS3XXX_I2S_BASE_VIRT 0xFFF10000 #define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */ -#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFB003000 +#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800 #define TIMER1_COUNTER_OFFSET 0x00 #define TIMER1_AUTO_RELOAD_OFFSET 0x04 @@ -227,16 +227,16 @@ * Testchip peripheral and fpga gic regions */ #define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */ -#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFB004000 +#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000 #define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */ -#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x100) +#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100 #define CNS3XXX_TC11MP_TWD_BASE 0x90000600 -#define CNS3XXX_TC11MP_TWD_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x600) +#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600 #define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */ -#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x1000) +#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000 #define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */ #define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000 diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/uncompress.h b/trunk/arch/arm/mach-ep93xx/include/mach/uncompress.h index b5cc77d2380b..d2afb4dd82ab 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/uncompress.h @@ -47,13 +47,9 @@ static void __raw_writel(unsigned int value, unsigned int ptr) static inline void putc(int c) { - int i; - - for (i = 0; i < 10000; i++) { - /* Transmit fifo not full? */ - if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF)) - break; - } + /* Transmit fifo not full? */ + while (__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF) + ; __raw_writeb(c, PHYS_UART_DATA); } diff --git a/trunk/arch/arm/mach-highbank/hotplug.c b/trunk/arch/arm/mach-highbank/hotplug.c index 890cae23c12a..f30c52843396 100644 --- a/trunk/arch/arm/mach-highbank/hotplug.c +++ b/trunk/arch/arm/mach-highbank/hotplug.c @@ -28,11 +28,13 @@ extern void secondary_startup(void); */ void __ref highbank_cpu_die(unsigned int cpu) { - highbank_set_cpu_jump(cpu, phys_to_virt(0)); + flush_cache_all(); - flush_cache_louis(); + highbank_set_cpu_jump(cpu, phys_to_virt(0)); highbank_set_core_pwr(); - while (1) - cpu_do_idle(); + cpu_do_idle(); + + /* We should never return from idle */ + panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu); } diff --git a/trunk/arch/arm/mach-imx/clk-imx35.c b/trunk/arch/arm/mach-imx/clk-imx35.c index 2193c834f55c..e13a8fa5e62c 100644 --- a/trunk/arch/arm/mach-imx/clk-imx35.c +++ b/trunk/arch/arm/mach-imx/clk-imx35.c @@ -257,7 +257,6 @@ int __init mx35_clocks_init(void) clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); - clk_register_clkdev(clk[admux_gate], "audmux", NULL); clk_prepare_enable(clk[spba_gate]); clk_prepare_enable(clk[gpio1_gate]); @@ -266,7 +265,6 @@ int __init mx35_clocks_init(void) clk_prepare_enable(clk[iim_gate]); clk_prepare_enable(clk[emi_gate]); clk_prepare_enable(clk[max_gate]); - clk_prepare_enable(clk[iomuxc_gate]); /* * SCC is needed to boot via mmc after a watchdog reset. The clock code diff --git a/trunk/arch/arm/mach-imx/clk-imx6q.c b/trunk/arch/arm/mach-imx/clk-imx6q.c index d38e54f5b6d7..2f9ff93a4e61 100644 --- a/trunk/arch/arm/mach-imx/clk-imx6q.c +++ b/trunk/arch/arm/mach-imx/clk-imx6q.c @@ -115,7 +115,7 @@ static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m" static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; -static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; +static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", }; static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; @@ -443,6 +443,7 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); + clk_register_clkdev(clk[twd], NULL, "smp_twd"); clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); clk_register_clkdev(clk[ahb], "ahb", NULL); clk_register_clkdev(clk[cko1], "cko1", NULL); diff --git a/trunk/arch/arm/mach-imx/common.h b/trunk/arch/arm/mach-imx/common.h index 5bf4a97ab241..5a800bfcec5b 100644 --- a/trunk/arch/arm/mach-imx/common.h +++ b/trunk/arch/arm/mach-imx/common.h @@ -110,8 +110,6 @@ void tzic_handle_irq(struct pt_regs *); extern void imx_enable_cpu(int cpu, bool enable); extern void imx_set_cpu_jump(int cpu, void *jump_addr); -extern u32 imx_get_cpu_arg(int cpu); -extern void imx_set_cpu_arg(int cpu, u32 arg); extern void v7_cpu_resume(void); extern u32 *pl310_get_save_ptr(void); #ifdef CONFIG_SMP diff --git a/trunk/arch/arm/mach-imx/hotplug.c b/trunk/arch/arm/mach-imx/hotplug.c index 361a253e2b63..7bc5fe15dda2 100644 --- a/trunk/arch/arm/mach-imx/hotplug.c +++ b/trunk/arch/arm/mach-imx/hotplug.c @@ -46,23 +46,11 @@ static inline void cpu_enter_lowpower(void) void imx_cpu_die(unsigned int cpu) { cpu_enter_lowpower(); - /* - * We use the cpu jumping argument register to sync with - * imx_cpu_kill() which is running on cpu0 and waiting for - * the register being cleared to kill the cpu. - */ - imx_set_cpu_arg(cpu, ~0); cpu_do_idle(); } int imx_cpu_kill(unsigned int cpu) { - unsigned long timeout = jiffies + msecs_to_jiffies(50); - - while (imx_get_cpu_arg(cpu) == 0) - if (time_after(jiffies, timeout)) - return 0; imx_enable_cpu(cpu, false); - imx_set_cpu_arg(cpu, 0); return 1; } diff --git a/trunk/arch/arm/mach-imx/src.c b/trunk/arch/arm/mach-imx/src.c index 09a742f8c7ab..e15f1555c59b 100644 --- a/trunk/arch/arm/mach-imx/src.c +++ b/trunk/arch/arm/mach-imx/src.c @@ -43,18 +43,6 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) src_base + SRC_GPR1 + cpu * 8); } -u32 imx_get_cpu_arg(int cpu) -{ - cpu = cpu_logical_map(cpu); - return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); -} - -void imx_set_cpu_arg(int cpu, u32 arg) -{ - cpu = cpu_logical_map(cpu); - writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); -} - void imx_src_prepare_restart(void) { u32 val; diff --git a/trunk/arch/arm/mach-kirkwood/board-iomega_ix2_200.c b/trunk/arch/arm/mach-kirkwood/board-iomega_ix2_200.c index e5f70415905a..f655b2637b0e 100644 --- a/trunk/arch/arm/mach-kirkwood/board-iomega_ix2_200.c +++ b/trunk/arch/arm/mach-kirkwood/board-iomega_ix2_200.c @@ -20,15 +20,10 @@ static struct mv643xx_eth_platform_data iomega_ix2_200_ge00_data = { .duplex = DUPLEX_FULL, }; -static struct mv643xx_eth_platform_data iomega_ix2_200_ge01_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(11), -}; - void __init iomega_ix2_200_init(void) { /* * Basic setup. Needs to be called early. */ - kirkwood_ge00_init(&iomega_ix2_200_ge00_data); - kirkwood_ge01_init(&iomega_ix2_200_ge01_data); + kirkwood_ge01_init(&iomega_ix2_200_ge00_data); } diff --git a/trunk/arch/arm/mach-kirkwood/guruplug-setup.c b/trunk/arch/arm/mach-kirkwood/guruplug-setup.c index 08dd739aa709..1c6e736cbbf8 100644 --- a/trunk/arch/arm/mach-kirkwood/guruplug-setup.c +++ b/trunk/arch/arm/mach-kirkwood/guruplug-setup.c @@ -53,8 +53,6 @@ static struct mv_sata_platform_data guruplug_sata_data = { static struct mvsdio_platform_data guruplug_mvsdio_data = { /* unfortunately the CD signal has not been connected */ - .gpio_card_detect = -1, - .gpio_write_protect = -1, }; static struct gpio_led guruplug_led_pins[] = { diff --git a/trunk/arch/arm/mach-kirkwood/openrd-setup.c b/trunk/arch/arm/mach-kirkwood/openrd-setup.c index 6a6eb548307d..8ddd69fdc937 100644 --- a/trunk/arch/arm/mach-kirkwood/openrd-setup.c +++ b/trunk/arch/arm/mach-kirkwood/openrd-setup.c @@ -55,7 +55,6 @@ static struct mv_sata_platform_data openrd_sata_data = { static struct mvsdio_platform_data openrd_mvsdio_data = { .gpio_card_detect = 29, /* MPP29 used as SD card detect */ - .gpio_write_protect = -1, }; static unsigned int openrd_mpp_config[] __initdata = { diff --git a/trunk/arch/arm/mach-kirkwood/rd88f6281-setup.c b/trunk/arch/arm/mach-kirkwood/rd88f6281-setup.c index d24223166e06..c7d93b48926b 100644 --- a/trunk/arch/arm/mach-kirkwood/rd88f6281-setup.c +++ b/trunk/arch/arm/mach-kirkwood/rd88f6281-setup.c @@ -69,7 +69,6 @@ static struct mv_sata_platform_data rd88f6281_sata_data = { static struct mvsdio_platform_data rd88f6281_mvsdio_data = { .gpio_card_detect = 28, - .gpio_write_protect = -1, }; static unsigned int rd88f6281_mpp_config[] __initdata = { diff --git a/trunk/arch/arm/mach-msm/timer.c b/trunk/arch/arm/mach-msm/timer.c index f9fd77e8f1f5..2969027f02fa 100644 --- a/trunk/arch/arm/mach-msm/timer.c +++ b/trunk/arch/arm/mach-msm/timer.c @@ -62,10 +62,7 @@ static int msm_timer_set_next_event(unsigned long cycles, { u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); - ctrl &= ~TIMER_ENABLE_EN; - writel_relaxed(ctrl, event_base + TIMER_ENABLE); - - writel_relaxed(ctrl, event_base + TIMER_CLEAR); + writel_relaxed(0, event_base + TIMER_CLEAR); writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); return 0; diff --git a/trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c b/trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c index d5970f5a1e8d..274ff58271de 100644 --- a/trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c +++ b/trunk/arch/arm/mach-mvebu/irq-armada-370-xp.c @@ -44,8 +44,6 @@ #define ARMADA_370_XP_MAX_PER_CPU_IRQS (28) -#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5) - #define ACTIVE_DOORBELLS (8) static DEFINE_RAW_SPINLOCK(irq_controller_lock); @@ -61,26 +59,36 @@ static struct irq_domain *armada_370_xp_mpic_domain; */ static void armada_370_xp_irq_mask(struct irq_data *d) { +#ifdef CONFIG_SMP irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) + if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS) writel(hwirq, main_int_base + ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS); else writel(hwirq, per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); +#else + writel(irqd_to_hwirq(d), + per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); +#endif } static void armada_370_xp_irq_unmask(struct irq_data *d) { +#ifdef CONFIG_SMP irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) + if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS) writel(hwirq, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); else writel(hwirq, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); +#else + writel(irqd_to_hwirq(d), + per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); +#endif } #ifdef CONFIG_SMP @@ -136,14 +144,10 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { armada_370_xp_irq_mask(irq_get_irq_data(virq)); - if (hw != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) - writel(hw, per_cpu_int_base + - ARMADA_370_XP_INT_CLEAR_MASK_OFFS); - else - writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); + writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); irq_set_status_flags(virq, IRQ_LEVEL); - if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) { + if (hw < ARMADA_370_XP_MAX_PER_CPU_IRQS) { irq_set_percpu_devid(virq); irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip, handle_percpu_devid_irq); diff --git a/trunk/arch/arm/mach-omap1/clock_data.c b/trunk/arch/arm/mach-omap1/clock_data.c index 6c4f766365a2..cb7c6ae2e3fc 100644 --- a/trunk/arch/arm/mach-omap1/clock_data.c +++ b/trunk/arch/arm/mach-omap1/clock_data.c @@ -538,6 +538,15 @@ static struct clk usb_hhc_ck16xx = { }; static struct clk usb_dc_ck = { + .name = "usb_dc_ck", + .ops = &clkops_generic, + /* Direct from ULPD, no parent */ + .rate = 48000000, + .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), + .enable_bit = USB_REQ_EN_SHIFT, +}; + +static struct clk usb_dc_ck7xx = { .name = "usb_dc_ck", .ops = &clkops_generic, /* Direct from ULPD, no parent */ @@ -718,7 +727,8 @@ static struct omap_clk omap_clks[] = { CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310), CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310), CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX), - CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX | CK_7XX), + CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX), + CLK(NULL, "usb_dc_ck", &usb_dc_ck7xx, CK_7XX), CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310), CLK(NULL, "mclk", &mclk_16xx, CK_16XX), CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310), diff --git a/trunk/arch/arm/mach-omap2/cclock44xx_data.c b/trunk/arch/arm/mach-omap2/cclock44xx_data.c index 0c6834ae1fc4..3d58f335f173 100644 --- a/trunk/arch/arm/mach-omap2/cclock44xx_data.c +++ b/trunk/arch/arm/mach-omap2/cclock44xx_data.c @@ -52,13 +52,6 @@ */ #define OMAP4_DPLL_ABE_DEFFREQ 98304000 -/* - * OMAP4 USB DPLL default frequency. In OMAP4430 TRM version V, section - * "3.6.3.9.5 DPLL_USB Preferred Settings" shows that the preferred - * locked frequency for the USB DPLL is 960MHz. - */ -#define OMAP4_DPLL_USB_DEFFREQ 960000000 - /* Root clocks */ DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0); @@ -1018,10 +1011,6 @@ DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel, OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK, hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops); -DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0, - OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, - OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL); - DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0, OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); @@ -1549,7 +1538,6 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "per_mcbsp4_gfclk", &per_mcbsp4_gfclk, CK_443X), CLK(NULL, "hsmmc1_fclk", &hsmmc1_fclk, CK_443X), CLK(NULL, "hsmmc2_fclk", &hsmmc2_fclk, CK_443X), - CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X), CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X), CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X), CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X), @@ -1717,13 +1705,5 @@ int __init omap4xxx_clk_init(void) if (rc) pr_err("%s: failed to configure ABE DPLL!\n", __func__); - /* - * Lock USB DPLL on OMAP4 devices so that the L3INIT power - * domain can transition to retention state when not in use. - */ - rc = clk_set_rate(&dpll_usb_ck, OMAP4_DPLL_USB_DEFFREQ); - if (rc) - pr_err("%s: failed to configure USB DPLL!\n", __func__); - return 0; } diff --git a/trunk/arch/arm/mach-omap2/common.h b/trunk/arch/arm/mach-omap2/common.h index d6ba13e1c540..40f4a03d728f 100644 --- a/trunk/arch/arm/mach-omap2/common.h +++ b/trunk/arch/arm/mach-omap2/common.h @@ -293,8 +293,5 @@ extern void omap_reserve(void); struct omap_hwmod; extern int omap_dss_reset(struct omap_hwmod *); -/* SoC specific clock initializer */ -extern int (*omap_clk_init)(void); - #endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ diff --git a/trunk/arch/arm/mach-omap2/io.c b/trunk/arch/arm/mach-omap2/io.c index 5c445ca1e271..2c3fdd65387b 100644 --- a/trunk/arch/arm/mach-omap2/io.c +++ b/trunk/arch/arm/mach-omap2/io.c @@ -54,12 +54,6 @@ #include "prm3xxx.h" #include "prm44xx.h" -/* - * omap_clk_init: points to a function that does the SoC-specific - * clock initializations - */ -int (*omap_clk_init)(void); - /* * The machine specific code may provide the extra mapping besides the * default mapping provided here. @@ -403,7 +397,7 @@ void __init omap2420_init_early(void) omap242x_clockdomains_init(); omap2420_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap2420_clk_init; + omap2420_clk_init(); } void __init omap2420_init_late(void) @@ -433,7 +427,7 @@ void __init omap2430_init_early(void) omap243x_clockdomains_init(); omap2430_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap2430_clk_init; + omap2430_clk_init(); } void __init omap2430_init_late(void) @@ -468,7 +462,7 @@ void __init omap3_init_early(void) omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap3xxx_clk_init; + omap3xxx_clk_init(); } void __init omap3430_init_early(void) @@ -506,7 +500,7 @@ void __init ti81xx_init_early(void) omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap3xxx_clk_init; + omap3xxx_clk_init(); } void __init omap3_init_late(void) @@ -574,7 +568,7 @@ void __init am33xx_init_early(void) am33xx_clockdomains_init(); am33xx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = am33xx_clk_init; + am33xx_clk_init(); } #endif @@ -599,7 +593,7 @@ void __init omap4430_init_early(void) omap44xx_clockdomains_init(); omap44xx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_init = omap4xxx_clk_init; + omap4xxx_clk_init(); } void __init omap4430_init_late(void) diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index a202a4785104..c2c798c08c2b 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -1368,9 +1368,7 @@ static void _enable_sysc(struct omap_hwmod *oh) } if (sf & SYSC_HAS_MIDLEMODE) { - if (oh->flags & HWMOD_FORCE_MSTANDBY) { - idlemode = HWMOD_IDLEMODE_FORCE; - } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) { + if (oh->flags & HWMOD_SWSUP_MSTANDBY) { idlemode = HWMOD_IDLEMODE_NO; } else { if (sf & SYSC_HAS_ENAWAKEUP) @@ -1442,8 +1440,7 @@ static void _idle_sysc(struct omap_hwmod *oh) } if (sf & SYSC_HAS_MIDLEMODE) { - if ((oh->flags & HWMOD_SWSUP_MSTANDBY) || - (oh->flags & HWMOD_FORCE_MSTANDBY)) { + if (oh->flags & HWMOD_SWSUP_MSTANDBY) { idlemode = HWMOD_IDLEMODE_FORCE; } else { if (sf & SYSC_HAS_ENAWAKEUP) diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.h b/trunk/arch/arm/mach-omap2/omap_hwmod.h index d5dc935f6060..d43d9b608eda 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.h +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.h @@ -427,8 +427,8 @@ struct omap_hwmod_omap4_prcm { * * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out * of idle, rather than relying on module smart-idle - * HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and - * out of standby, rather than relying on module smart-standby + * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out + * of standby, rather than relying on module smart-standby * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for * SDRAM controller, etc. XXX probably belongs outside the main hwmod file * XXX Should be HWMOD_SETUP_NO_RESET @@ -459,10 +459,6 @@ struct omap_hwmod_omap4_prcm { * correctly, or this is being abused to deal with some PM latency * issues -- but we're currently suffering from a shortage of * folks who are able to track these issues down properly. - * HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device - * is kept in force-standby mode. Failing to do so causes PM problems - * with musb on OMAP3630 at least. Note that musb has a dedicated register - * to control MSTANDBY signal when MIDLEMODE is set to force-standby. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -475,7 +471,6 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_16BIT_REG (1 << 8) #define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) #define HWMOD_BLOCK_WFI (1 << 10) -#define HWMOD_FORCE_MSTANDBY (1 << 11) /* * omap_hwmod._int_flags definitions diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 5112d04e7b79..ac7e03ec952f 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1707,14 +1707,9 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = { * Erratum ID: i479 idle_req / idle_ack mechanism potentially * broken when autoidle is enabled * workaround is to disable the autoidle bit at module level. - * - * Enabling the device in any other MIDLEMODE setting but force-idle - * causes core_pwrdm not enter idle states at least on OMAP3630. - * Note that musb has OTG_FORCESTDBY register that controls MSTANDBY - * signal when MIDLEMODE is set to force-idle. */ .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE - | HWMOD_FORCE_MSTANDBY, + | HWMOD_SWSUP_MSTANDBY, }; /* usb_otg_hs */ diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index eaba9dc91a0d..0e47d2e1687c 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2719,17 +2719,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .name = "ocp2scp_usb_phy", .class = &omap44xx_ocp2scp_hwmod_class, .clkdm_name = "l3_init_clkdm", - /* - * ocp2scp_usb_phy_phy_48m is provided by the OMAP4 PRCM IP - * block as an "optional clock," and normally should never be - * specified as the main_clk for an OMAP IP block. However it - * turns out that this clock is actually the main clock for - * the ocp2scp_usb_phy IP block: - * http://lists.infradead.org/pipermail/linux-arm-kernel/2012-September/119943.html - * So listing ocp2scp_usb_phy_phy_48m as a main_clk here seems - * to be the best workaround. - */ - .main_clk = "ocp2scp_usb_phy_phy_48m", + .main_clk = "func_48m_fclk", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, diff --git a/trunk/arch/arm/mach-omap2/timer.c b/trunk/arch/arm/mach-omap2/timer.c index f62b509ed08d..2bdd4cf17a8f 100644 --- a/trunk/arch/arm/mach-omap2/timer.c +++ b/trunk/arch/arm/mach-omap2/timer.c @@ -547,8 +547,6 @@ static inline void __init realtime_counter_init(void) clksrc_nr, clksrc_src) \ void __init omap##name##_gptimer_timer_init(void) \ { \ - if (omap_clk_init) \ - omap_clk_init(); \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ @@ -558,8 +556,6 @@ void __init omap##name##_gptimer_timer_init(void) \ clksrc_nr, clksrc_src) \ void __init omap##name##_sync32k_timer_init(void) \ { \ - if (omap_clk_init) \ - omap_clk_init(); \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ /* Enable the use of clocksource="gp_timer" kernel parameter */ \ diff --git a/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h b/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h index 1e73f5fa8659..b7a9f4d469e8 100644 --- a/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/trunk/arch/arm/mach-s3c24xx/include/mach/irqs.h @@ -188,8 +188,10 @@ #if defined(CONFIG_CPU_S3C2416) #define NR_IRQS (IRQ_S3C2416_I2S1 + 1) +#elif defined(CONFIG_CPU_S3C2443) +#define NR_IRQS (IRQ_S3C2443_AC97+1) #else -#define NR_IRQS (IRQ_S3C2443_AC97 + 1) +#define NR_IRQS (IRQ_S3C2440_AC97+1) #endif /* compatibility define. */ diff --git a/trunk/arch/arm/mach-s3c24xx/irq.c b/trunk/arch/arm/mach-s3c24xx/irq.c index d8ba9bee4c7e..cb9f5e011e73 100644 --- a/trunk/arch/arm/mach-s3c24xx/irq.c +++ b/trunk/arch/arm/mach-s3c24xx/irq.c @@ -500,7 +500,7 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, base = (void *)0xfd000000; intc->reg_mask = base + 0xa4; - intc->reg_pending = base + 0xa8; + intc->reg_pending = base + 0x08; irq_num = 20; irq_start = S3C2410_IRQ(32); irq_offset = 4; diff --git a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c index 7f2cb6c5e2c1..051b62c27102 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c @@ -81,6 +81,7 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { #endif struct mmci_platform_data mop500_sdi0_data = { + .ios_handler = mop500_sdi0_ios_handler, .ocr_mask = MMC_VDD_29_30, .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | diff --git a/trunk/arch/arm/mach-ux500/board-mop500.c b/trunk/arch/arm/mach-ux500/board-mop500.c index 87d2d7b38ce9..b03457881c4b 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.c +++ b/trunk/arch/arm/mach-ux500/board-mop500.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -440,15 +439,6 @@ static void mop500_prox_deactivate(struct device *dev) regulator_put(prox_regulator); } -void mop500_snowball_ethernet_clock_enable(void) -{ - struct clk *clk; - - clk = clk_get_sys("fsmc", NULL); - if (!IS_ERR(clk)) - clk_prepare_enable(clk); -} - static struct cryp_platform_data u8500_cryp1_platform_data = { .mem_to_engine = { .dir = STEDMA40_MEM_TO_PERIPH, @@ -693,8 +683,6 @@ static void __init snowball_init_machine(void) mop500_audio_init(parent); mop500_uart_init(parent); - mop500_snowball_ethernet_clock_enable(); - /* This board has full regulator constraints */ regulator_has_full_constraints(); } diff --git a/trunk/arch/arm/mach-ux500/board-mop500.h b/trunk/arch/arm/mach-ux500/board-mop500.h index d38951be70df..eaa605f5d90d 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500.h +++ b/trunk/arch/arm/mach-ux500/board-mop500.h @@ -104,7 +104,6 @@ void __init mop500_pinmaps_init(void); void __init snowball_pinmaps_init(void); void __init hrefv60_pinmaps_init(void); void mop500_audio_init(struct device *parent); -void mop500_snowball_ethernet_clock_enable(void); int __init mop500_uib_init(void); void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, diff --git a/trunk/arch/arm/mach-ux500/cpu-db8500.c b/trunk/arch/arm/mach-ux500/cpu-db8500.c index f1a581844372..19235cf7bbe3 100644 --- a/trunk/arch/arm/mach-ux500/cpu-db8500.c +++ b/trunk/arch/arm/mach-ux500/cpu-db8500.c @@ -312,10 +312,9 @@ static void __init u8500_init_machine(void) /* Pinmaps must be in place before devices register */ if (of_machine_is_compatible("st-ericsson,mop500")) mop500_pinmaps_init(); - else if (of_machine_is_compatible("calaosystems,snowball-a9500")) { + else if (of_machine_is_compatible("calaosystems,snowball-a9500")) snowball_pinmaps_init(); - mop500_snowball_ethernet_clock_enable(); - } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) + else if (of_machine_is_compatible("st-ericsson,hrefv60+")) hrefv60_pinmaps_init(); else if (of_machine_is_compatible("st-ericsson,ccu9540")) {} /* TODO: Add pinmaps for ccu9540 board. */ diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 4045c4931a30..025d17328730 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -43,7 +43,7 @@ config CPU_ARM740T depends on !MMU select CPU_32v4T select CPU_ABRT_LV4T - select CPU_CACHE_V4 + select CPU_CACHE_V3 # although the core is v4t select CPU_CP15_MPU select CPU_PABRT_LEGACY help @@ -469,6 +469,9 @@ config CPU_PABRT_V7 bool # The cache model +config CPU_CACHE_V3 + bool + config CPU_CACHE_V4 bool diff --git a/trunk/arch/arm/mm/Makefile b/trunk/arch/arm/mm/Makefile index 9e51be96f635..4e333fa2756f 100644 --- a/trunk/arch/arm/mm/Makefile +++ b/trunk/arch/arm/mm/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o +obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o diff --git a/trunk/arch/arm/mm/cache-feroceon-l2.c b/trunk/arch/arm/mm/cache-feroceon-l2.c index 48bc3c0a87ce..dd3d59122cc3 100644 --- a/trunk/arch/arm/mm/cache-feroceon-l2.c +++ b/trunk/arch/arm/mm/cache-feroceon-l2.c @@ -343,7 +343,6 @@ void __init feroceon_l2_init(int __l2_wt_override) outer_cache.inv_range = feroceon_l2_inv_range; outer_cache.clean_range = feroceon_l2_clean_range; outer_cache.flush_range = feroceon_l2_flush_range; - outer_cache.inv_all = l2_inv_all; enable_l2(); diff --git a/trunk/arch/arm/mm/cache-l2x0.c b/trunk/arch/arm/mm/cache-l2x0.c index c465faca51b0..c2f37390308a 100644 --- a/trunk/arch/arm/mm/cache-l2x0.c +++ b/trunk/arch/arm/mm/cache-l2x0.c @@ -299,7 +299,7 @@ static void l2x0_unlock(u32 cache_id) int lockregs; int i; - switch (cache_id & L2X0_CACHE_ID_PART_MASK) { + switch (cache_id) { case L2X0_CACHE_ID_PART_L310: lockregs = 8; break; @@ -333,14 +333,15 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) if (cache_id_part_number_from_dt) cache_id = cache_id_part_number_from_dt; else - cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID); + cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID) + & L2X0_CACHE_ID_PART_MASK; aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); aux &= aux_mask; aux |= aux_val; /* Determine the number of ways */ - switch (cache_id & L2X0_CACHE_ID_PART_MASK) { + switch (cache_id) { case L2X0_CACHE_ID_PART_L310: if (aux & (1 << 16)) ways = 16; @@ -724,6 +725,7 @@ static const struct l2x0_of_data pl310_data = { .flush_all = l2x0_flush_all, .inv_all = l2x0_inv_all, .disable = l2x0_disable, + .set_debug = pl310_set_debug, }, }; @@ -812,9 +814,10 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask) data->save(); of_init = true; - memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache)); l2x0_init(l2x0_base, aux_val, aux_mask); + memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache)); + return 0; } #endif diff --git a/trunk/arch/arm/mm/cache-v3.S b/trunk/arch/arm/mm/cache-v3.S new file mode 100644 index 000000000000..8a3fadece8d3 --- /dev/null +++ b/trunk/arch/arm/mm/cache-v3.S @@ -0,0 +1,137 @@ +/* + * linux/arch/arm/mm/cache-v3.S + * + * Copyright (C) 1997-2002 Russell king + * + * 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. + */ +#include +#include +#include +#include "proc-macros.S" + +/* + * flush_icache_all() + * + * Unconditionally clean and invalidate the entire icache. + */ +ENTRY(v3_flush_icache_all) + mov pc, lr +ENDPROC(v3_flush_icache_all) + +/* + * flush_user_cache_all() + * + * Invalidate all cache entries in a particular address + * space. + * + * - mm - mm_struct describing address space + */ +ENTRY(v3_flush_user_cache_all) + /* FALLTHROUGH */ +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(v3_flush_kern_cache_all) + /* FALLTHROUGH */ + +/* + * flush_user_cache_range(start, end, flags) + * + * Invalidate a range of cache entries in the specified + * address space. + * + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * - flags - vma_area_struct flags describing address space + */ +ENTRY(v3_flush_user_cache_range) + mov ip, #0 + mcreq p15, 0, ip, c7, c0, 0 @ flush ID cache + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_coherent_user_range) + mov r0, #0 + mov pc, lr + +/* + * flush_kern_dcache_area(void *page, size_t size) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - kernel address + * - size - region size + */ +ENTRY(v3_flush_kern_dcache_area) + /* FALLTHROUGH */ + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(v3_dma_flush_range) + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ flush ID cache + mov pc, lr + +/* + * dma_unmap_area(start, size, dir) + * - start - kernel virtual start address + * - size - size of region + * - dir - DMA direction + */ +ENTRY(v3_dma_unmap_area) + teq r2, #DMA_TO_DEVICE + bne v3_dma_flush_range + /* FALLTHROUGH */ + +/* + * dma_map_area(start, size, dir) + * - start - kernel virtual start address + * - size - size of region + * - dir - DMA direction + */ +ENTRY(v3_dma_map_area) + mov pc, lr +ENDPROC(v3_dma_unmap_area) +ENDPROC(v3_dma_map_area) + + .globl v3_flush_kern_cache_louis + .equ v3_flush_kern_cache_louis, v3_flush_kern_cache_all + + __INITDATA + + @ define struct cpu_cache_fns (see and proc-macros.S) + define_cache_functions v3 diff --git a/trunk/arch/arm/mm/cache-v4.S b/trunk/arch/arm/mm/cache-v4.S index a7ba68f59f0c..43e5d77be677 100644 --- a/trunk/arch/arm/mm/cache-v4.S +++ b/trunk/arch/arm/mm/cache-v4.S @@ -58,7 +58,7 @@ ENTRY(v4_flush_kern_cache_all) ENTRY(v4_flush_user_cache_range) #ifdef CONFIG_CPU_CP15 mov ip, #0 - mcr p15, 0, ip, c7, c7, 0 @ flush ID cache + mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache mov pc, lr #else /* FALLTHROUGH */ diff --git a/trunk/arch/arm/mm/context.c b/trunk/arch/arm/mm/context.c index 2ac37372ef52..a5a4b2bc42ba 100644 --- a/trunk/arch/arm/mm/context.c +++ b/trunk/arch/arm/mm/context.c @@ -48,7 +48,7 @@ static DEFINE_RAW_SPINLOCK(cpu_asid_lock); static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION); static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS); -DEFINE_PER_CPU(atomic64_t, active_asids); +static DEFINE_PER_CPU(atomic64_t, active_asids); static DEFINE_PER_CPU(u64, reserved_asids); static cpumask_t tlb_flush_pending; @@ -215,7 +215,6 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) { local_flush_bp_all(); local_flush_tlb_all(); - dummy_flush_tlb_a15_erratum(); } atomic64_set(&per_cpu(active_asids, cpu), asid); diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index a84ff763ac39..e95a996ab78f 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -34,7 +34,6 @@ #include #include "mm.h" -#include "tcm.h" /* * empty_zero_page is a special page that is used for @@ -599,60 +598,39 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, } while (pte++, addr += PAGE_SIZE, addr != end); } -static void __init map_init_section(pmd_t *pmd, unsigned long addr, - unsigned long end, phys_addr_t phys, - const struct mem_type *type) -{ -#ifndef CONFIG_ARM_LPAE - /* - * In classic MMU format, puds and pmds are folded in to - * the pgds. pmd_offset gives the PGD entry. PGDs refer to a - * group of L1 entries making up one logical pointer to - * an L2 table (2MB), where as PMDs refer to the individual - * L1 entries (1MB). Hence increment to get the correct - * offset for odd 1MB sections. - * (See arch/arm/include/asm/pgtable-2level.h) - */ - if (addr & SECTION_SIZE) - pmd++; -#endif - do { - *pmd = __pmd(phys | type->prot_sect); - phys += SECTION_SIZE; - } while (pmd++, addr += SECTION_SIZE, addr != end); - - flush_pmd_entry(pmd); -} - -static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, +static void __init alloc_init_section(pud_t *pud, unsigned long addr, unsigned long end, phys_addr_t phys, const struct mem_type *type) { pmd_t *pmd = pmd_offset(pud, addr); - unsigned long next; - do { - /* - * With LPAE, we must loop over to map - * all the pmds for the given range. - */ - next = pmd_addr_end(addr, end); + /* + * Try a section mapping - end, addr and phys must all be aligned + * to a section boundary. Note that PMDs refer to the individual + * L1 entries, whereas PGDs refer to a group of L1 entries making + * up one logical pointer to an L2 table. + */ + if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) { + pmd_t *p = pmd; - /* - * Try a section mapping - addr, next and phys must all be - * aligned to a section boundary. - */ - if (type->prot_sect && - ((addr | next | phys) & ~SECTION_MASK) == 0) { - map_init_section(pmd, addr, next, phys, type); - } else { - alloc_init_pte(pmd, addr, next, - __phys_to_pfn(phys), type); - } +#ifndef CONFIG_ARM_LPAE + if (addr & SECTION_SIZE) + pmd++; +#endif - phys += next - addr; + do { + *pmd = __pmd(phys | type->prot_sect); + phys += SECTION_SIZE; + } while (pmd++, addr += SECTION_SIZE, addr != end); - } while (pmd++, addr = next, addr != end); + flush_pmd_entry(p); + } else { + /* + * No need to loop; pte's aren't interested in the + * individual L1 entries. + */ + alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type); + } } static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, @@ -663,7 +641,7 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, do { next = pud_addr_end(addr, end); - alloc_init_pmd(pud, addr, next, phys, type); + alloc_init_section(pud, addr, next, phys, type); phys += next - addr; } while (pud++, addr = next, addr != end); } @@ -1278,7 +1256,6 @@ void __init paging_init(struct machine_desc *mdesc) dma_contiguous_remap(); devicemaps_init(mdesc); kmap_init(); - tcm_init(); top_pmd = pmd_off_k(0xffff0000); diff --git a/trunk/arch/arm/mm/proc-arm740.S b/trunk/arch/arm/mm/proc-arm740.S index fde2d2a794cf..dc5de5d53f20 100644 --- a/trunk/arch/arm/mm/proc-arm740.S +++ b/trunk/arch/arm/mm/proc-arm740.S @@ -77,27 +77,24 @@ __arm740_setup: mcr p15, 0, r0, c6, c0 @ set area 0, default ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM - ldr r3, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) - mov r4, #10 @ 11 is the minimum (4KB) -1: add r4, r4, #1 @ area size *= 2 - movs r3, r3, lsr #1 + ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 bne 1b @ count not zero r-shift - orr r0, r0, r4, lsl #1 @ the area register value + orr r0, r0, r2, lsl #1 @ the area register value orr r0, r0, #1 @ set enable bit mcr p15, 0, r0, c6, c1 @ set area 1, RAM ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH - ldr r3, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) - cmp r3, #0 - moveq r0, #0 - beq 2f - mov r4, #10 @ 11 is the minimum (4KB) -1: add r4, r4, #1 @ area size *= 2 - movs r3, r3, lsr #1 + ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 bne 1b @ count not zero r-shift - orr r0, r0, r4, lsl #1 @ the area register value + orr r0, r0, r2, lsl #1 @ the area register value orr r0, r0, #1 @ set enable bit -2: mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH + mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH mov r0, #0x06 mcr p15, 0, r0, c2, c0 @ Region 1&2 cacheable @@ -140,14 +137,13 @@ __arm740_proc_info: .long 0x41807400 .long 0xfffffff0 .long 0 - .long 0 b __arm740_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT .long cpu_arm740_name .long arm740_processor_functions .long 0 .long 0 - .long v4_cache_fns @ cache model + .long v3_cache_fns @ cache model .size __arm740_proc_info, . - __arm740_proc_info diff --git a/trunk/arch/arm/mm/proc-arm920.S b/trunk/arch/arm/mm/proc-arm920.S index 2556cf1c2da1..2c3b9421ab5e 100644 --- a/trunk/arch/arm/mm/proc-arm920.S +++ b/trunk/arch/arm/mm/proc-arm920.S @@ -387,7 +387,7 @@ ENTRY(cpu_arm920_set_pte_ext) /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ .globl cpu_arm920_suspend_size .equ cpu_arm920_suspend_size, 4 * 3 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_arm920_do_suspend) stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c13, c0, 0 @ PID diff --git a/trunk/arch/arm/mm/proc-arm926.S b/trunk/arch/arm/mm/proc-arm926.S index 344c8a548cc0..f1803f7e2972 100644 --- a/trunk/arch/arm/mm/proc-arm926.S +++ b/trunk/arch/arm/mm/proc-arm926.S @@ -402,7 +402,7 @@ ENTRY(cpu_arm926_set_pte_ext) /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ .globl cpu_arm926_suspend_size .equ cpu_arm926_suspend_size, 4 * 3 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_arm926_do_suspend) stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c13, c0, 0 @ PID diff --git a/trunk/arch/arm/mm/proc-mohawk.S b/trunk/arch/arm/mm/proc-mohawk.S index 0b60dd3d742a..82f9cdc751d6 100644 --- a/trunk/arch/arm/mm/proc-mohawk.S +++ b/trunk/arch/arm/mm/proc-mohawk.S @@ -350,7 +350,7 @@ ENTRY(cpu_mohawk_set_pte_ext) .globl cpu_mohawk_suspend_size .equ cpu_mohawk_suspend_size, 4 * 6 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_mohawk_do_suspend) stmfd sp!, {r4 - r9, lr} mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode diff --git a/trunk/arch/arm/mm/proc-sa1100.S b/trunk/arch/arm/mm/proc-sa1100.S index d92dfd081429..3aa0da11fd84 100644 --- a/trunk/arch/arm/mm/proc-sa1100.S +++ b/trunk/arch/arm/mm/proc-sa1100.S @@ -172,7 +172,7 @@ ENTRY(cpu_sa1100_set_pte_ext) .globl cpu_sa1100_suspend_size .equ cpu_sa1100_suspend_size, 4 * 3 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_sa1100_do_suspend) stmfd sp!, {r4 - r6, lr} mrc p15, 0, r4, c3, c0, 0 @ domain ID diff --git a/trunk/arch/arm/mm/proc-syms.c b/trunk/arch/arm/mm/proc-syms.c index 054b491ff764..3e6210b4d6d4 100644 --- a/trunk/arch/arm/mm/proc-syms.c +++ b/trunk/arch/arm/mm/proc-syms.c @@ -17,9 +17,7 @@ #ifndef MULTI_CPU EXPORT_SYMBOL(cpu_dcache_clean_area); -#ifdef CONFIG_MMU EXPORT_SYMBOL(cpu_set_pte_ext); -#endif #else EXPORT_SYMBOL(processor); #endif diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index 5c07ee4fe3eb..bcaaa8de9325 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -138,7 +138,7 @@ ENTRY(cpu_v6_set_pte_ext) /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */ .globl cpu_v6_suspend_size .equ cpu_v6_suspend_size, 4 * 6 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_v6_do_suspend) stmfd sp!, {r4 - r9, lr} mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index f584d3f5b37c..3a3c015f8d5c 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -420,7 +420,7 @@ __v7_pj4b_proc_info: __v7_ca7mp_proc_info: .long 0x410fc070 .long 0xff0ffff0 - __v7_proc __v7_ca7mp_setup + __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info /* @@ -430,24 +430,9 @@ __v7_ca7mp_proc_info: __v7_ca15mp_proc_info: .long 0x410fc0f0 .long 0xff0ffff0 - __v7_proc __v7_ca15mp_setup + __v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV .size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info - /* - * Qualcomm Inc. Krait processors. - */ - .type __krait_proc_info, #object -__krait_proc_info: - .long 0x510f0400 @ Required ID value - .long 0xff0ffc00 @ Mask for ID - /* - * Some Krait processors don't indicate support for SDIV and UDIV - * instructions in the ARM instruction set, even though they actually - * do support them. - */ - __v7_proc __v7_setup, hwcaps = HWCAP_IDIV - .size __krait_proc_info, . - __krait_proc_info - /* * Match any ARMv7 processor core. */ diff --git a/trunk/arch/arm/mm/proc-xsc3.S b/trunk/arch/arm/mm/proc-xsc3.S index e8efd83b6f25..eb93d6487f35 100644 --- a/trunk/arch/arm/mm/proc-xsc3.S +++ b/trunk/arch/arm/mm/proc-xsc3.S @@ -413,7 +413,7 @@ ENTRY(cpu_xsc3_set_pte_ext) .globl cpu_xsc3_suspend_size .equ cpu_xsc3_suspend_size, 4 * 6 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_xsc3_do_suspend) stmfd sp!, {r4 - r9, lr} mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S index e766f889bfd6..25510361aa18 100644 --- a/trunk/arch/arm/mm/proc-xscale.S +++ b/trunk/arch/arm/mm/proc-xscale.S @@ -528,7 +528,7 @@ ENTRY(cpu_xscale_set_pte_ext) .globl cpu_xscale_suspend_size .equ cpu_xscale_suspend_size, 4 * 6 -#ifdef CONFIG_ARM_CPU_SUSPEND +#ifdef CONFIG_PM_SLEEP ENTRY(cpu_xscale_do_suspend) stmfd sp!, {r4 - r9, lr} mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode diff --git a/trunk/arch/avr32/include/asm/io.h b/trunk/arch/avr32/include/asm/io.h index fc6483f83ccc..cf60d0a9f176 100644 --- a/trunk/arch/avr32/include/asm/io.h +++ b/trunk/arch/avr32/include/asm/io.h @@ -165,10 +165,6 @@ BUILDIO_IOPORT(l, u32) #define readw_be __raw_readw #define readl_be __raw_readl -#define writeb_relaxed writeb -#define writew_relaxed writew -#define writel_relaxed writel - #define writeb_be __raw_writeb #define writew_be __raw_writew #define writel_be __raw_writel diff --git a/trunk/arch/c6x/include/asm/irqflags.h b/trunk/arch/c6x/include/asm/irqflags.h index 2c71d5634ec2..cf78e09e18c3 100644 --- a/trunk/arch/c6x/include/asm/irqflags.h +++ b/trunk/arch/c6x/include/asm/irqflags.h @@ -27,7 +27,7 @@ static inline unsigned long arch_local_save_flags(void) /* set interrupt enabled status */ static inline void arch_local_irq_restore(unsigned long flags) { - asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags) : "memory"); + asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags)); } /* unconditionally enable interrupts */ diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index e7e55a00f94f..9a02f71c6b1f 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -187,7 +187,7 @@ config IA64_DIG config IA64_DIG_VTD bool "DIG+Intel+IOMMU" - select INTEL_IOMMU + select DMAR select PCI_MSI config IA64_HP_ZX1 diff --git a/trunk/arch/ia64/include/asm/futex.h b/trunk/arch/ia64/include/asm/futex.h index 76acbcd5c060..d2bf1fd5e44f 100644 --- a/trunk/arch/ia64/include/asm/futex.h +++ b/trunk/arch/ia64/include/asm/futex.h @@ -106,15 +106,16 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; { - register unsigned long r8 __asm ("r8") = 0; + register unsigned long r8 __asm ("r8"); unsigned long prev; __asm__ __volatile__( " mf;; \n" + " mov %0=r0 \n" " mov ar.ccv=%4;; \n" "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" " .xdata4 \"__ex_table\", 1b-., 2f-. \n" "[2:]" - : "+r" (r8), "=&r" (prev) + : "=r" (r8), "=r" (prev) : "r" (uaddr), "r" (newval), "rO" ((long) (unsigned) oldval) : "memory"); diff --git a/trunk/arch/ia64/include/asm/mca.h b/trunk/arch/ia64/include/asm/mca.h index 8c7096168716..43f96ab18fa0 100644 --- a/trunk/arch/ia64/include/asm/mca.h +++ b/trunk/arch/ia64/include/asm/mca.h @@ -143,7 +143,6 @@ extern unsigned long __per_cpu_mca[NR_CPUS]; extern int cpe_vector; extern int ia64_cpe_irq; extern void ia64_mca_init(void); -extern void ia64_mca_irq_init(void); extern void ia64_mca_cpu_init(void *); extern void ia64_os_mca_dispatch(void); extern void ia64_os_mca_dispatch_end(void); diff --git a/trunk/arch/ia64/include/asm/numa.h b/trunk/arch/ia64/include/asm/numa.h index 2db0a6c6daa5..2e27ef175652 100644 --- a/trunk/arch/ia64/include/asm/numa.h +++ b/trunk/arch/ia64/include/asm/numa.h @@ -67,13 +67,14 @@ extern int paddr_to_nid(unsigned long paddr); extern void map_cpu_to_node(int cpu, int nid); extern void unmap_cpu_from_node(int cpu, int nid); -extern void numa_clear_node(int cpu); + #else /* !CONFIG_NUMA */ #define map_cpu_to_node(cpu, nid) do{}while(0) #define unmap_cpu_from_node(cpu, nid) do{}while(0) + #define paddr_to_nid(addr) 0 -#define numa_clear_node(cpu) do { } while (0) + #endif /* CONFIG_NUMA */ #endif /* _ASM_IA64_NUMA_H */ diff --git a/trunk/arch/ia64/kernel/fsys.S b/trunk/arch/ia64/kernel/fsys.S index abc6dee3799c..c4cd45d97749 100644 --- a/trunk/arch/ia64/kernel/fsys.S +++ b/trunk/arch/ia64/kernel/fsys.S @@ -90,6 +90,53 @@ ENTRY(fsys_getpid) FSYS_RETURN END(fsys_getpid) +ENTRY(fsys_getppid) + .prologue + .altrp b6 + .body + add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16 + ;; + ld8 r17=[r17] // r17 = current->group_leader + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 + ;; + + ld4 r9=[r9] + add r17=IA64_TASK_REAL_PARENT_OFFSET,r17 // r17 = ¤t->group_leader->real_parent + ;; + and r9=TIF_ALLWORK_MASK,r9 + +1: ld8 r18=[r17] // r18 = current->group_leader->real_parent + ;; + cmp.ne p8,p0=0,r9 + add r8=IA64_TASK_TGID_OFFSET,r18 // r8 = ¤t->group_leader->real_parent->tgid + ;; + + /* + * The .acq is needed to ensure that the read of tgid has returned its data before + * we re-check "real_parent". + */ + ld4.acq r8=[r8] // r8 = current->group_leader->real_parent->tgid +#ifdef CONFIG_SMP + /* + * Re-read current->group_leader->real_parent. + */ + ld8 r19=[r17] // r19 = current->group_leader->real_parent +(p8) br.spnt.many fsys_fallback_syscall + ;; + cmp.ne p6,p0=r18,r19 // did real_parent change? + mov r19=0 // i must not leak kernel bits... +(p6) br.cond.spnt.few 1b // yes -> redo the read of tgid and the check + ;; + mov r17=0 // i must not leak kernel bits... + mov r18=0 // i must not leak kernel bits... +#else + mov r17=0 // i must not leak kernel bits... + mov r18=0 // i must not leak kernel bits... + mov r19=0 // i must not leak kernel bits... +#endif + FSYS_RETURN +END(fsys_getppid) + ENTRY(fsys_set_tid_address) .prologue .altrp b6 @@ -567,7 +614,7 @@ paravirt_fsyscall_table: data8 0 // chown data8 0 // lseek // 1040 data8 fsys_getpid // getpid - data8 0 // getppid + data8 fsys_getppid // getppid data8 0 // mount data8 0 // umount data8 0 // setuid // 1045 diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index 19f107be734e..ee33c3aaa2fc 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -76,7 +76,7 @@ * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ * * Note: The term "IRQ" is loosely used everywhere in Linux kernel to - * describe interrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ + * describeinterrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ * (isa_irq) is the only exception in this source code. */ @@ -1010,26 +1010,6 @@ iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) return 0; } -static int -iosapic_delete_rte(unsigned int irq, unsigned int gsi) -{ - struct iosapic_rte_info *rte, *temp; - - list_for_each_entry_safe(rte, temp, &iosapic_intr_info[irq].rtes, - rte_list) { - if (rte->iosapic->gsi_base + rte->rte_index == gsi) { - if (rte->refcnt) - return -EBUSY; - - list_del(&rte->rte_list); - kfree(rte); - return 0; - } - } - - return -EINVAL; -} - int iosapic_init(unsigned long phys_addr, unsigned int gsi_base) { int num_rte, err, index; @@ -1089,7 +1069,7 @@ int iosapic_init(unsigned long phys_addr, unsigned int gsi_base) int iosapic_remove(unsigned int gsi_base) { - int i, irq, index, err = 0; + int index, err = 0; unsigned long flags; spin_lock_irqsave(&iosapic_lock, flags); @@ -1107,16 +1087,6 @@ int iosapic_remove(unsigned int gsi_base) goto out; } - for (i = gsi_base; i < gsi_base + iosapic_lists[index].num_rte; i++) { - irq = __gsi_to_irq(i); - if (irq < 0) - continue; - - err = iosapic_delete_rte(irq, i); - if (err) - goto out; - } - iounmap(iosapic_lists[index].addr); iosapic_free(index); out: diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index f2c418281130..ad69606613eb 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -23,8 +23,6 @@ #include #include -#include - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -85,12 +83,6 @@ bool is_affinity_mask_valid(const struct cpumask *cpumask) #endif /* CONFIG_SMP */ -int __init arch_early_irq_init(void) -{ - ia64_mca_irq_init(); - return 0; -} - #ifdef CONFIG_HOTPLUG_CPU unsigned int vectors_in_migration[NR_IRQS]; diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index d7396dbb07bb..65bf9cd39044 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -2074,16 +2074,22 @@ ia64_mca_init(void) printk(KERN_INFO "MCA related initialization done\n"); } - /* - * These pieces cannot be done in ia64_mca_init() because it is called before - * early_irq_init() which would wipe out our percpu irq registrations. But we - * cannot leave them until ia64_mca_late_init() because by then all the other - * processors have been brought online and have set their own CMC vectors to - * point at a non-existant action. Called from arch_early_irq_init(). + * ia64_mca_late_init + * + * Opportunity to setup things that require initialization later + * than ia64_mca_init. Setup a timer to poll for CPEs if the + * platform doesn't support an interrupt driven mechanism. + * + * Inputs : None + * Outputs : Status */ -void __init ia64_mca_irq_init(void) +static int __init +ia64_mca_late_init(void) { + if (!mca_init) + return 0; + /* * Configure the CMCI/P vector and handler. Interrupts for CMC are * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c). @@ -2102,23 +2108,6 @@ void __init ia64_mca_irq_init(void) /* Setup the CPEI/P handler */ register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); #endif -} - -/* - * ia64_mca_late_init - * - * Opportunity to setup things that require initialization later - * than ia64_mca_init. Setup a timer to poll for CPEs if the - * platform doesn't support an interrupt driven mechanism. - * - * Inputs : None - * Outputs : Status - */ -static int __init -ia64_mca_late_init(void) -{ - if (!mca_init) - return 0; register_hotcpu_notifier(&mca_cpu_notifier); diff --git a/trunk/arch/ia64/kernel/mca_drv.c b/trunk/arch/ia64/kernel/mca_drv.c index 94f8bf777afa..9392e021c93b 100644 --- a/trunk/arch/ia64/kernel/mca_drv.c +++ b/trunk/arch/ia64/kernel/mca_drv.c @@ -349,7 +349,7 @@ init_record_index_pools(void) /* - 3 - */ slidx_pool.max_idx = (rec_max_size/sect_min_size) * 2 + 1; - slidx_pool.buffer = + slidx_pool.buffer = (slidx_list_t *) kmalloc(slidx_pool.max_idx * sizeof(slidx_list_t), GFP_KERNEL); return slidx_pool.buffer ? 0 : -ENOMEM; diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index 79521d5499f9..77597e5ea60a 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -849,6 +849,17 @@ static palinfo_entry_t palinfo_entries[]={ #define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries) +/* + * this array is used to keep track of the proc entries we create. This is + * required in the module mode when we need to remove all entries. The procfs code + * does not do recursion of deletion + * + * Notes: + * - +1 accounts for the cpuN directory entry in /proc/pal + */ +#define NR_PALINFO_PROC_ENTRIES (NR_CPUS*(NR_PALINFO_ENTRIES+1)) + +static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES]; static struct proc_dir_entry *palinfo_dir; /* @@ -960,32 +971,60 @@ palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, voi static void __cpuinit create_palinfo_proc_entries(unsigned int cpu) { +# define CPUSTR "cpu%d" + pal_func_cpu_u_t f; + struct proc_dir_entry **pdir; struct proc_dir_entry *cpu_dir; int j; - char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */ - sprintf(cpustr, "cpu%d", cpu); + char cpustr[sizeof(CPUSTR)]; + + + /* + * we keep track of created entries in a depth-first order for + * cleanup purposes. Each entry is stored into palinfo_proc_entries + */ + sprintf(cpustr,CPUSTR, cpu); cpu_dir = proc_mkdir(cpustr, palinfo_dir); - if (!cpu_dir) - return; f.req_cpu = cpu; + /* + * Compute the location to store per cpu entries + * We dont store the top level entry in this list, but + * remove it finally after removing all cpu entries. + */ + pdir = &palinfo_proc_entries[cpu*(NR_PALINFO_ENTRIES+1)]; + *pdir++ = cpu_dir; for (j=0; j < NR_PALINFO_ENTRIES; j++) { f.func_id = j; - create_proc_read_entry( - palinfo_entries[j].name, 0, cpu_dir, - palinfo_read_entry, (void *)f.value); + *pdir = create_proc_read_entry( + palinfo_entries[j].name, 0, cpu_dir, + palinfo_read_entry, (void *)f.value); + pdir++; } } static void remove_palinfo_proc_entries(unsigned int hcpu) { - char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */ - sprintf(cpustr, "cpu%d", hcpu); - remove_proc_subtree(cpustr, palinfo_dir); + int j; + struct proc_dir_entry *cpu_dir, **pdir; + + pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)]; + cpu_dir = *pdir; + *pdir++=NULL; + for (j=0; j < (NR_PALINFO_ENTRIES); j++) { + if ((*pdir)) { + remove_proc_entry ((*pdir)->name, cpu_dir); + *pdir ++= NULL; + } + } + + if (cpu_dir) { + remove_proc_entry(cpu_dir->name, palinfo_dir); + } } static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, @@ -1019,8 +1058,6 @@ palinfo_init(void) printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION); palinfo_dir = proc_mkdir("pal", NULL); - if (!palinfo_dir) - return -ENOMEM; /* Create palinfo dirs in /proc for all online cpus */ for_each_online_cpu(i) { @@ -1036,8 +1073,22 @@ palinfo_init(void) static void __exit palinfo_exit(void) { + int i = 0; + + /* remove all nodes: depth first pass. Could optimize this */ + for_each_online_cpu(i) { + remove_palinfo_proc_entries(i); + } + + /* + * Remove the top level entry finally + */ + remove_proc_entry(palinfo_dir->name, NULL); + + /* + * Unregister from cpu notifier callbacks + */ unregister_hotcpu_notifier(&palinfo_cpu_notifier); - remove_proc_subtree("pal", NULL); } module_init(palinfo_init); diff --git a/trunk/arch/ia64/kvm/vtlb.c b/trunk/arch/ia64/kvm/vtlb.c index a7869f8f49a6..4332f7ee5203 100644 --- a/trunk/arch/ia64/kvm/vtlb.c +++ b/trunk/arch/ia64/kvm/vtlb.c @@ -256,7 +256,7 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte) "srlz.d;;" "ssm psr.i;;" "srlz.d;;" - : "=&r"(ret) : "r"(iha), "r"(pte) : "memory"); + : "=r"(ret) : "r"(iha), "r"(pte):"memory"); return ret; } diff --git a/trunk/arch/ia64/mm/ioremap.c b/trunk/arch/ia64/mm/ioremap.c index 43964cde6214..3dccdd8eb275 100644 --- a/trunk/arch/ia64/mm/ioremap.c +++ b/trunk/arch/ia64/mm/ioremap.c @@ -16,7 +16,7 @@ #include static inline void __iomem * -__ioremap_uc(unsigned long phys_addr) +__ioremap (unsigned long phys_addr) { return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr); } @@ -24,11 +24,7 @@ __ioremap_uc(unsigned long phys_addr) void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size) { - u64 attr; - attr = kern_mem_attribute(phys_addr, size); - if (attr & EFI_MEMORY_WB) - return (void __iomem *) phys_to_virt(phys_addr); - return __ioremap_uc(phys_addr); + return __ioremap(phys_addr); } void __iomem * @@ -51,7 +47,7 @@ ioremap (unsigned long phys_addr, unsigned long size) if (attr & EFI_MEMORY_WB) return (void __iomem *) phys_to_virt(phys_addr); else if (attr & EFI_MEMORY_UC) - return __ioremap_uc(phys_addr); + return __ioremap(phys_addr); /* * Some chipsets don't support UC access to memory. If @@ -97,7 +93,7 @@ ioremap (unsigned long phys_addr, unsigned long size) return (void __iomem *) (offset + (char __iomem *)addr); } - return __ioremap_uc(phys_addr); + return __ioremap(phys_addr); } EXPORT_SYMBOL(ioremap); @@ -107,7 +103,7 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size) if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB) return NULL; - return __ioremap_uc(phys_addr); + return __ioremap(phys_addr); } EXPORT_SYMBOL(ioremap_nocache); diff --git a/trunk/arch/ia64/mm/numa.c b/trunk/arch/ia64/mm/numa.c index def782e31aac..3efea7d0a351 100644 --- a/trunk/arch/ia64/mm/numa.c +++ b/trunk/arch/ia64/mm/numa.c @@ -73,11 +73,6 @@ int __meminit __early_pfn_to_nid(unsigned long pfn) return -1; } -void __cpuinit numa_clear_node(int cpu) -{ - unmap_cpu_from_node(cpu, NUMA_NO_NODE); -} - #ifdef CONFIG_MEMORY_HOTPLUG /* * SRAT information is stored in node_memblk[], then we can use SRAT diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index de1474ff0bc5..60532ab27346 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -459,16 +458,6 @@ void pcibios_fixup_bus(struct pci_bus *b) platform_pci_fixup_bus(b); } -void pcibios_add_bus(struct pci_bus *bus) -{ - acpi_pci_add_bus(bus); -} - -void pcibios_remove_bus(struct pci_bus *bus) -{ - acpi_pci_remove_bus(bus); -} - void pcibios_set_master (struct pci_dev *dev) { /* No special bus mastering setup handling */ diff --git a/trunk/arch/ia64/sn/kernel/tiocx.c b/trunk/arch/ia64/sn/kernel/tiocx.c index e35f6485c1fd..14c1711238c0 100644 --- a/trunk/arch/ia64/sn/kernel/tiocx.c +++ b/trunk/arch/ia64/sn/kernel/tiocx.c @@ -490,14 +490,11 @@ static int __init tiocx_init(void) { cnodeid_t cnodeid; int found_tiocx_device = 0; - int err; if (!ia64_platform_is("sn2")) return 0; - err = bus_register(&tiocx_bus_type); - if (err) - return err; + bus_register(&tiocx_bus_type); for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) { nasid_t nasid; diff --git a/trunk/arch/m68k/include/asm/gpio.h b/trunk/arch/m68k/include/asm/gpio.h index 8cc83431805b..4395ffc51fdb 100644 --- a/trunk/arch/m68k/include/asm/gpio.h +++ b/trunk/arch/m68k/include/asm/gpio.h @@ -86,24 +86,4 @@ static inline int gpio_cansleep(unsigned gpio) return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); } -static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) -{ - int err; - - err = gpio_request(gpio, label); - if (err) - return err; - - if (flags & GPIOF_DIR_IN) - err = gpio_direction_input(gpio); - else - err = gpio_direction_output(gpio, - (flags & GPIOF_INIT_HIGH) ? 1 : 0); - - if (err) - gpio_free(gpio); - - return err; -} - #endif diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 51244bf97271..cd2e21ff562a 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -18,7 +18,7 @@ config MIPS select HAVE_KRETPROBES select HAVE_DEBUG_KMEMLEAK select ARCH_BINFMT_ELF_RANDOMIZE_PIE - select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT + select HAVE_ARCH_TRANSPARENT_HUGEPAGE select RTC_LIB if !MACH_LOONGSON select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE @@ -657,7 +657,7 @@ config SNI_RM bool "SNI RM200/300/400" select FW_ARC if CPU_LITTLE_ENDIAN select FW_ARC32 if CPU_LITTLE_ENDIAN - select FW_SNIPROM if CPU_BIG_ENDIAN + select SNIPROM if CPU_BIG_ENDIAN select ARCH_MAY_HAVE_PC_FDC select BOOT_ELF32 select CEVT_R4K @@ -1144,7 +1144,7 @@ config DEFAULT_SGI_PARTITION config FW_ARC32 bool -config FW_SNIPROM +config SNIPROM bool config BOOT_ELF32 @@ -1493,6 +1493,7 @@ config CPU_XLP select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select CPU_HAS_LLSC select WEAK_ORDERING select WEAK_REORDERING_BEYOND_LLSC select CPU_HAS_PREFETCH diff --git a/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c b/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c index 9aa7d44898ed..ed1949c29508 100644 --- a/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/trunk/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -745,7 +745,10 @@ void __init board_prom_init(void) strcpy(cfe_version, "unknown"); printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); - bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET); + if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) { + printk(KERN_ERR PFX "invalid nvram checksum\n"); + return; + } board_name = bcm63xx_nvram_get_name(); /* find board by name */ diff --git a/trunk/arch/mips/bcm63xx/nvram.c b/trunk/arch/mips/bcm63xx/nvram.c index a4b8864f9307..620611680839 100644 --- a/trunk/arch/mips/bcm63xx/nvram.c +++ b/trunk/arch/mips/bcm63xx/nvram.c @@ -38,7 +38,7 @@ struct bcm963xx_nvram { static struct bcm963xx_nvram nvram; static int mac_addr_used; -void __init bcm63xx_nvram_init(void *addr) +int __init bcm63xx_nvram_init(void *addr) { unsigned int check_len; u32 crc, expected_crc; @@ -60,8 +60,9 @@ void __init bcm63xx_nvram_init(void *addr) crc = crc32_le(~0, (u8 *)&nvram, check_len); if (crc != expected_crc) - pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", - expected_crc, crc); + return -EINVAL; + + return 0; } u8 *bcm63xx_nvram_get_name(void) diff --git a/trunk/arch/mips/bcm63xx/setup.c b/trunk/arch/mips/bcm63xx/setup.c index 35e18e98beb9..314231be788c 100644 --- a/trunk/arch/mips/bcm63xx/setup.c +++ b/trunk/arch/mips/bcm63xx/setup.c @@ -157,4 +157,4 @@ int __init bcm63xx_register_devices(void) return board_register_devices(); } -arch_initcall(bcm63xx_register_devices); +device_initcall(bcm63xx_register_devices); diff --git a/trunk/arch/mips/cavium-octeon/setup.c b/trunk/arch/mips/cavium-octeon/setup.c index b0baa299f899..c594a3d4f743 100644 --- a/trunk/arch/mips/cavium-octeon/setup.c +++ b/trunk/arch/mips/cavium-octeon/setup.c @@ -174,10 +174,7 @@ static int octeon_kexec_prepare(struct kimage *image) static void octeon_generic_shutdown(void) { - int i; -#ifdef CONFIG_SMP - int cpu; -#endif + int cpu, i; struct cvmx_bootmem_desc *bootmem_desc; void *named_block_array_ptr; diff --git a/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 4e0b6bc1165e..62d6a3b4d3b7 100644 --- a/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/trunk/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h @@ -9,8 +9,10 @@ * * Initialized the local nvram copy from the target address and checks * its checksum. + * + * Returns 0 on success. */ -void bcm63xx_nvram_init(void *nvram); +int __init bcm63xx_nvram_init(void *nvram); /** * bcm63xx_nvram_get_name() - returns the board name according to nvram diff --git a/trunk/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h b/trunk/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h index 193c0912d38e..d9c828419037 100644 --- a/trunk/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h +++ b/trunk/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h @@ -28,7 +28,11 @@ /* #define cpu_has_prefetch ? */ #define cpu_has_mcheck 1 /* #define cpu_has_ejtag ? */ +#ifdef CONFIG_CPU_HAS_LLSC #define cpu_has_llsc 1 +#else +#define cpu_has_llsc 0 +#endif /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ diff --git a/trunk/arch/mips/include/asm/mipsregs.h b/trunk/arch/mips/include/asm/mipsregs.h index 0da44d422f5b..12b70c25906a 100644 --- a/trunk/arch/mips/include/asm/mipsregs.h +++ b/trunk/arch/mips/include/asm/mipsregs.h @@ -1166,10 +1166,7 @@ do { \ unsigned int __dspctl; \ \ __asm__ __volatile__( \ - " .set push \n" \ - " .set dsp \n" \ " rddsp %0, %x1 \n" \ - " .set pop \n" \ : "=r" (__dspctl) \ : "i" (mask)); \ __dspctl; \ @@ -1178,198 +1175,30 @@ do { \ #define wrdsp(val, mask) \ do { \ __asm__ __volatile__( \ - " .set push \n" \ - " .set dsp \n" \ " wrdsp %0, %x1 \n" \ - " .set pop \n" \ : \ : "r" (val), "i" (mask)); \ } while (0) -#define mflo0() \ -({ \ - long mflo0; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mflo %0, $ac0 \n" \ - " .set pop \n" \ - : "=r" (mflo0)); \ - mflo0; \ -}) - -#define mflo1() \ -({ \ - long mflo1; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mflo %0, $ac1 \n" \ - " .set pop \n" \ - : "=r" (mflo1)); \ - mflo1; \ -}) - -#define mflo2() \ -({ \ - long mflo2; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mflo %0, $ac2 \n" \ - " .set pop \n" \ - : "=r" (mflo2)); \ - mflo2; \ -}) - -#define mflo3() \ -({ \ - long mflo3; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mflo %0, $ac3 \n" \ - " .set pop \n" \ - : "=r" (mflo3)); \ - mflo3; \ -}) - -#define mfhi0() \ -({ \ - long mfhi0; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mfhi %0, $ac0 \n" \ - " .set pop \n" \ - : "=r" (mfhi0)); \ - mfhi0; \ -}) - -#define mfhi1() \ -({ \ - long mfhi1; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mfhi %0, $ac1 \n" \ - " .set pop \n" \ - : "=r" (mfhi1)); \ - mfhi1; \ -}) - -#define mfhi2() \ -({ \ - long mfhi2; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mfhi %0, $ac2 \n" \ - " .set pop \n" \ - : "=r" (mfhi2)); \ - mfhi2; \ -}) - -#define mfhi3() \ -({ \ - long mfhi3; \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mfhi %0, $ac3 \n" \ - " .set pop \n" \ - : "=r" (mfhi3)); \ - mfhi3; \ -}) - - -#define mtlo0(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mtlo %0, $ac0 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mtlo1(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mtlo %0, $ac1 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mtlo2(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mtlo %0, $ac2 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mtlo3(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mtlo %0, $ac3 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mthi0(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mthi %0, $ac0 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mthi1(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mthi %0, $ac1 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mthi2(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mthi %0, $ac2 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) - -#define mthi3(x) \ -({ \ - __asm__( \ - " .set push \n" \ - " .set dsp \n" \ - " mthi %0, $ac3 \n" \ - " .set pop \n" \ - : \ - : "r" (x)); \ -}) +#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;}) +#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;}) +#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;}) +#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;}) + +#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;}) +#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;}) +#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;}) +#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;}) + +#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x)) +#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x)) +#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x)) +#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x)) + +#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x)) +#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x)) +#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x)) +#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x)) #else diff --git a/trunk/arch/mips/include/asm/page.h b/trunk/arch/mips/include/asm/page.h index eab99e536b5c..99fc547af9d3 100644 --- a/trunk/arch/mips/include/asm/page.h +++ b/trunk/arch/mips/include/asm/page.h @@ -31,7 +31,7 @@ #define PAGE_SHIFT 16 #endif #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +#define PAGE_MASK (~(PAGE_SIZE - 1)) #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) diff --git a/trunk/arch/mips/include/asm/signal.h b/trunk/arch/mips/include/asm/signal.h index 8efe5a9e2c3e..197f6367c201 100644 --- a/trunk/arch/mips/include/asm/signal.h +++ b/trunk/arch/mips/include/asm/signal.h @@ -21,6 +21,6 @@ #include #include -#define __ARCH_HAS_IRIX_SIGACTION +#define __ARCH_HAS_ODD_SIGACTION #endif /* _ASM_SIGNAL_H */ diff --git a/trunk/arch/mips/include/uapi/asm/signal.h b/trunk/arch/mips/include/uapi/asm/signal.h index addb9f556b71..d6b18b4d0f3a 100644 --- a/trunk/arch/mips/include/uapi/asm/signal.h +++ b/trunk/arch/mips/include/uapi/asm/signal.h @@ -72,12 +72,6 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ * * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single * Unix names RESETHAND and NODEFER respectively. - * - * SA_RESTORER used to be defined as 0x04000000 but only the O32 ABI ever - * supported its use and no libc was using it, so the entire sa-restorer - * functionality was removed with lmo commit 39bffc12c3580ab for 2.5.48 - * retaining only the SA_RESTORER definition as a reminder to avoid - * accidental reuse of the mask bit. */ #define SA_ONSTACK 0x08000000 #define SA_RESETHAND 0x80000000 @@ -90,6 +84,8 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ #define SA_NOMASK SA_NODEFER #define SA_ONESHOT SA_RESETHAND +#define SA_RESTORER 0x04000000 /* Only for o32 */ + #define MINSIGSTKSZ 2048 #define SIGSTKSZ 8192 diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index de75fb50562b..f81d98f6184c 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -100,16 +100,29 @@ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o # -# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is not -# safe to unconditionnaly use the assembler -mdsp / -mdspr2 switches -# here because the compiler may use DSP ASE instructions (such as lwx) in -# code paths where we cannot check that the CPU we are running on supports it. -# Proper abstraction using HAVE_AS_DSP and macros is done in -# arch/mips/include/asm/mipsregs.h. +# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is safe +# to enable DSP assembler support here even if the MIPS Release 2 CPU we +# are targetting does not support DSP because all code-paths making use of +# it properly check that the running CPU *actually does* support these +# instructions. # ifeq ($(CONFIG_CPU_MIPSR2), y) CFLAGS_DSP = -DHAVE_AS_DSP +# +# Check if assembler supports DSP ASE +# +ifeq ($(call cc-option-yn,-mdsp), y) +CFLAGS_DSP += -mdsp +endif + +# +# Check if assembler supports DSP ASE Rev2 +# +ifeq ($(call cc-option-yn,-mdspr2), y) +CFLAGS_DSP += -mdspr2 +endif + CFLAGS_signal.o = $(CFLAGS_DSP) CFLAGS_signal32.o = $(CFLAGS_DSP) CFLAGS_process.o = $(CFLAGS_DSP) diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 5fe66a0c3224..6bfccc227a95 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -580,9 +580,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->tlbsize = 48; break; case PRID_IMP_VR41XX: - set_isa(c, MIPS_CPU_ISA_III); - c->options = R4K_OPTS; - c->tlbsize = 32; switch (c->processor_id & 0xf0) { case PRID_REV_VR4111: c->cputype = CPU_VR4111; @@ -607,7 +604,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "NEC VR4131"; } else { c->cputype = CPU_VR4133; - c->options |= MIPS_CPU_LLSC; __cpu_name[cpu] = "NEC VR4133"; } break; @@ -617,6 +613,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "NEC Vr41xx"; break; } + set_isa(c, MIPS_CPU_ISA_III); + c->options = R4K_OPTS; + c->tlbsize = 32; break; case PRID_IMP_R4300: c->cputype = CPU_R4300; @@ -1227,8 +1226,10 @@ __cpuinit void cpu_probe(void) if (c->options & MIPS_CPU_FPU) { c->fpu_id = cpu_get_fpu_id(); - if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | - MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { + if (c->isa_level == MIPS_CPU_ISA_M32R1 || + c->isa_level == MIPS_CPU_ISA_M32R2 || + c->isa_level == MIPS_CPU_ISA_M64R1 || + c->isa_level == MIPS_CPU_ISA_M64R2) { if (c->fpu_id & MIPS_FPIR_3D) c->ases |= MIPS_ASE_MIPS3D; } diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index db9655f08892..8eeee1c860c0 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -171,7 +171,7 @@ SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third, err = compat_sys_shmctl(first, second, compat_ptr(ptr)); break; default: - err = -ENOSYS; + err = -EINVAL; break; } diff --git a/trunk/arch/mips/kernel/mcount.S b/trunk/arch/mips/kernel/mcount.S index 33d067148e61..165867673357 100644 --- a/trunk/arch/mips/kernel/mcount.S +++ b/trunk/arch/mips/kernel/mcount.S @@ -46,9 +46,10 @@ PTR_L a5, PT_R9(sp) PTR_L a6, PT_R10(sp) PTR_L a7, PT_R11(sp) -#endif +#else PTR_ADDIU sp, PT_SIZE - .endm +#endif +.endm .macro RETURN_BACK jr ra @@ -67,11 +68,7 @@ NESTED(ftrace_caller, PT_SIZE, ra) .globl _mcount _mcount: b ftrace_stub -#ifdef CONFIG_32BIT - addiu sp,sp,8 -#else - nop -#endif + addiu sp,sp,8 /* When tracing is activated, it calls ftrace_caller+8 (aka here) */ lw t1, function_trace_stop diff --git a/trunk/arch/mips/kernel/proc.c b/trunk/arch/mips/kernel/proc.c index 7a54f74b7818..135c4aadccbe 100644 --- a/trunk/arch/mips/kernel/proc.c +++ b/trunk/arch/mips/kernel/proc.c @@ -67,7 +67,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (cpu_has_mips_r) { seq_printf(m, "isa\t\t\t:"); if (cpu_has_mips_1) - seq_printf(m, "%s", " mips1"); + seq_printf(m, "%s", "mips1"); if (cpu_has_mips_2) seq_printf(m, "%s", " mips2"); if (cpu_has_mips_3) diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index c3abb88170fc..a200b5bdbb87 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -1571,7 +1571,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) #ifdef CONFIG_64BIT status_set |= ST0_FR|ST0_KX|ST0_SX|ST0_UX; #endif - if (current_cpu_data.isa_level & MIPS_CPU_ISA_IV) + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) status_set |= ST0_XX; if (cpu_has_dsp) status_set |= ST0_MX; diff --git a/trunk/arch/mips/lib/bitops.c b/trunk/arch/mips/lib/bitops.c index a64daee740ee..81f1dcfdcab8 100644 --- a/trunk/arch/mips/lib/bitops.c +++ b/trunk/arch/mips/lib/bitops.c @@ -90,12 +90,12 @@ int __mips_test_and_set_bit(unsigned long nr, unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - int res; + unsigned long res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a) != 0; + res = (mask & *a); *a |= mask; raw_local_irq_restore(flags); return res; @@ -116,12 +116,12 @@ int __mips_test_and_set_bit_lock(unsigned long nr, unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - int res; + unsigned long res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a) != 0; + res = (mask & *a); *a |= mask; raw_local_irq_restore(flags); return res; @@ -141,12 +141,12 @@ int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - int res; + unsigned long res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a) != 0; + res = (mask & *a); *a &= ~mask; raw_local_irq_restore(flags); return res; @@ -166,12 +166,12 @@ int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - int res; + unsigned long res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a) != 0; + res = (mask & *a); *a ^= mask; raw_local_irq_restore(flags); return res; diff --git a/trunk/arch/mips/lib/csum_partial.S b/trunk/arch/mips/lib/csum_partial.S index a6adffbb4e5f..507147aebd41 100644 --- a/trunk/arch/mips/lib/csum_partial.S +++ b/trunk/arch/mips/lib/csum_partial.S @@ -270,7 +270,7 @@ LEAF(csum_partial) #endif /* odd buffer alignment? */ -#ifdef CONFIG_CPU_MIPSR2 +#ifdef CPU_MIPSR2 wsbh v1, sum movn sum, v1, t7 #else @@ -670,7 +670,7 @@ EXC( sb t0, NBYTES-2(dst), .Ls_exc) addu sum, v1 #endif -#ifdef CONFIG_CPU_MIPSR2 +#ifdef CPU_MIPSR2 wsbh v1, sum movn sum, v1, odd #else diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index 2078915eacb9..ecca559b8d7b 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -1247,8 +1247,10 @@ static void __cpuinit setup_scache(void) return; default: - if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | - MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { + if (c->isa_level == MIPS_CPU_ISA_M32R1 || + c->isa_level == MIPS_CPU_ISA_M32R2 || + c->isa_level == MIPS_CPU_ISA_M64R1 || + c->isa_level == MIPS_CPU_ISA_M64R2) { #ifdef CONFIG_MIPS_CPU_SCACHE if (mips_sc_init ()) { scache_size = c->scache.ways * c->scache.sets * c->scache.linesz; diff --git a/trunk/arch/mips/mm/sc-mips.c b/trunk/arch/mips/mm/sc-mips.c index df96da7e939b..93d937b4b1ba 100644 --- a/trunk/arch/mips/mm/sc-mips.c +++ b/trunk/arch/mips/mm/sc-mips.c @@ -98,8 +98,10 @@ static inline int __init mips_sc_probe(void) c->scache.flags |= MIPS_CACHE_NOT_PRESENT; /* Ignore anything but MIPSxx processors */ - if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | - MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2))) + if (c->isa_level != MIPS_CPU_ISA_M32R1 && + c->isa_level != MIPS_CPU_ISA_M32R2 && + c->isa_level != MIPS_CPU_ISA_M64R1 && + c->isa_level != MIPS_CPU_ISA_M64R2) return 0; /* Does this MIPS32/MIPS64 CPU have a config2 register? */ diff --git a/trunk/arch/mips/pci/pci-alchemy.c b/trunk/arch/mips/pci/pci-alchemy.c index d1faece21b6a..38a80c83fd67 100644 --- a/trunk/arch/mips/pci/pci-alchemy.c +++ b/trunk/arch/mips/pci/pci-alchemy.c @@ -19,7 +19,7 @@ #include #include -#ifdef CONFIG_PCI_DEBUG +#ifdef CONFIG_DEBUG_PCI #define DBG(x...) printk(KERN_DEBUG x) #else #define DBG(x...) do {} while (0) @@ -162,7 +162,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, if (status & (1 << 29)) { *data = 0xffffffff; error = -1; - DBG("alchemy-pci: master abort on cfg access %d bus %d dev %d\n", + DBG("alchemy-pci: master abort on cfg access %d bus %d dev %d", access_type, bus->number, device); } else if ((status >> 28) & 0xf) { DBG("alchemy-pci: PCI ERR detected: dev %d, status %lx\n", diff --git a/trunk/arch/mips/pci/pci.c b/trunk/arch/mips/pci/pci.c index 594e60d6a43b..0872f12f268d 100644 --- a/trunk/arch/mips/pci/pci.c +++ b/trunk/arch/mips/pci/pci.c @@ -115,6 +115,7 @@ static void pcibios_scanbus(struct pci_controller *hose) pci_bus_assign_resources(bus); pci_enable_bridges(bus); } + bus->dev.of_node = hose->of_node; } } @@ -168,13 +169,6 @@ void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) } } } - -struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) -{ - struct pci_controller *hose = bus->sysdata; - - return of_node_get(hose->of_node); -} #endif static DEFINE_MUTEX(pci_scan_mutex); diff --git a/trunk/arch/parisc/Makefile b/trunk/arch/parisc/Makefile index 113e28206503..01d95e2f0581 100644 --- a/trunk/arch/parisc/Makefile +++ b/trunk/arch/parisc/Makefile @@ -65,10 +65,8 @@ ifndef CONFIG_FUNCTION_TRACER endif # Use long jumps instead of long branches (needed if your linker fails to -# link a too big vmlinux executable). Not enabled for building modules. -ifdef CONFIG_MLONGCALLS -KBUILD_CFLAGS_KERNEL += -mlong-calls -endif +# link a too big vmlinux executable) +cflags-$(CONFIG_MLONGCALLS) += -mlong-calls # select which processor to optimise for cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100 diff --git a/trunk/arch/parisc/include/asm/cacheflush.h b/trunk/arch/parisc/include/asm/cacheflush.h index f0e2784e7cca..79f694f3ad9b 100644 --- a/trunk/arch/parisc/include/asm/cacheflush.h +++ b/trunk/arch/parisc/include/asm/cacheflush.h @@ -140,10 +140,7 @@ static inline void *kmap(struct page *page) return page_address(page); } -static inline void kunmap(struct page *page) -{ - kunmap_parisc(page_address(page)); -} +#define kunmap(page) kunmap_parisc(page_address(page)) static inline void *kmap_atomic(struct page *page) { diff --git a/trunk/arch/parisc/include/asm/pgtable.h b/trunk/arch/parisc/include/asm/pgtable.h index 1e40d7f86be3..7df49fad29f9 100644 --- a/trunk/arch/parisc/include/asm/pgtable.h +++ b/trunk/arch/parisc/include/asm/pgtable.h @@ -16,8 +16,6 @@ #include #include -extern spinlock_t pa_dbit_lock; - /* * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel * memory. For the return value to be meaningful, ADDR must be >= @@ -46,11 +44,8 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned long); #define set_pte_at(mm, addr, ptep, pteval) \ do { \ - unsigned long flags; \ - spin_lock_irqsave(&pa_dbit_lock, flags); \ set_pte(ptep, pteval); \ purge_tlb_entries(mm, addr); \ - spin_unlock_irqrestore(&pa_dbit_lock, flags); \ } while (0) #endif /* !__ASSEMBLY__ */ @@ -440,46 +435,48 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { - pte_t pte; - unsigned long flags; - +#ifdef CONFIG_SMP if (!pte_young(*ptep)) return 0; - - spin_lock_irqsave(&pa_dbit_lock, flags); - pte = *ptep; - if (!pte_young(pte)) { - spin_unlock_irqrestore(&pa_dbit_lock, flags); + return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), &pte_val(*ptep)); +#else + pte_t pte = *ptep; + if (!pte_young(pte)) return 0; - } - set_pte(ptep, pte_mkold(pte)); - purge_tlb_entries(vma->vm_mm, addr); - spin_unlock_irqrestore(&pa_dbit_lock, flags); + set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte)); return 1; +#endif } +extern spinlock_t pa_dbit_lock; + struct mm_struct; static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t old_pte; - unsigned long flags; - spin_lock_irqsave(&pa_dbit_lock, flags); + spin_lock(&pa_dbit_lock); old_pte = *ptep; pte_clear(mm,addr,ptep); - purge_tlb_entries(mm, addr); - spin_unlock_irqrestore(&pa_dbit_lock, flags); + spin_unlock(&pa_dbit_lock); return old_pte; } static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - unsigned long flags; - spin_lock_irqsave(&pa_dbit_lock, flags); - set_pte(ptep, pte_wrprotect(*ptep)); +#ifdef CONFIG_SMP + unsigned long new, old; + + do { + old = pte_val(*ptep); + new = pte_val(pte_wrprotect(__pte (old))); + } while (cmpxchg((unsigned long *) ptep, old, new) != old); purge_tlb_entries(mm, addr); - spin_unlock_irqrestore(&pa_dbit_lock, flags); +#else + pte_t old_pte = *ptep; + set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); +#endif } #define pte_same(A,B) (pte_val(A) == pte_val(B)) diff --git a/trunk/arch/parisc/include/asm/uaccess.h b/trunk/arch/parisc/include/asm/uaccess.h index e0a82358517e..4ba2c93770f1 100644 --- a/trunk/arch/parisc/include/asm/uaccess.h +++ b/trunk/arch/parisc/include/asm/uaccess.h @@ -181,24 +181,30 @@ struct exception_data { #if !defined(CONFIG_64BIT) #define __put_kernel_asm64(__val,ptr) do { \ + u64 __val64 = (u64)(__val); \ + u32 hi = (__val64) >> 32; \ + u32 lo = (__val64) & 0xffffffff; \ __asm__ __volatile__ ( \ "\n1:\tstw %2,0(%1)" \ - "\n2:\tstw %R2,4(%1)\n\t" \ + "\n2:\tstw %3,4(%1)\n\t" \ ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ : "=r"(__pu_err) \ - : "r"(ptr), "r"(__val), "0"(__pu_err) \ + : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \ : "r1"); \ } while (0) #define __put_user_asm64(__val,ptr) do { \ + u64 __val64 = (u64)(__val); \ + u32 hi = (__val64) >> 32; \ + u32 lo = (__val64) & 0xffffffff; \ __asm__ __volatile__ ( \ "\n1:\tstw %2,0(%%sr3,%1)" \ - "\n2:\tstw %R2,4(%%sr3,%1)\n\t" \ + "\n2:\tstw %3,4(%%sr3,%1)\n\t" \ ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ : "=r"(__pu_err) \ - : "r"(ptr), "r"(__val), "0"(__pu_err) \ + : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \ : "r1"); \ } while (0) diff --git a/trunk/arch/parisc/kernel/cache.c b/trunk/arch/parisc/kernel/cache.c index 83ded26cad06..4b12890642eb 100644 --- a/trunk/arch/parisc/kernel/cache.c +++ b/trunk/arch/parisc/kernel/cache.c @@ -421,11 +421,14 @@ void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) /* Note: purge_tlb_entries can be called at startup with no context. */ - purge_tlb_start(flags); + /* Disable preemption while we play with %sr1. */ + preempt_disable(); mtsp(mm->context, 1); + purge_tlb_start(flags); pdtlb(addr); pitlb(addr); purge_tlb_end(flags); + preempt_enable(); } EXPORT_SYMBOL(purge_tlb_entries); diff --git a/trunk/arch/parisc/kernel/parisc_ksyms.c b/trunk/arch/parisc/kernel/parisc_ksyms.c index 568b2c61ea02..6795dc6c995f 100644 --- a/trunk/arch/parisc/kernel/parisc_ksyms.c +++ b/trunk/arch/parisc/kernel/parisc_ksyms.c @@ -120,13 +120,11 @@ extern void __ashrdi3(void); extern void __ashldi3(void); extern void __lshrdi3(void); extern void __muldi3(void); -extern void __ucmpdi2(void); EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__muldi3); -EXPORT_SYMBOL(__ucmpdi2); asmlinkage void * __canonicalize_funcptr_for_compare(void *); EXPORT_SYMBOL(__canonicalize_funcptr_for_compare); diff --git a/trunk/arch/parisc/lib/Makefile b/trunk/arch/parisc/lib/Makefile index 5651536ac733..5f2e6904d14a 100644 --- a/trunk/arch/parisc/lib/Makefile +++ b/trunk/arch/parisc/lib/Makefile @@ -2,7 +2,6 @@ # Makefile for parisc-specific library files # -lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \ - ucmpdi2.o +lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o obj-y := iomap.o diff --git a/trunk/arch/parisc/lib/ucmpdi2.c b/trunk/arch/parisc/lib/ucmpdi2.c deleted file mode 100644 index 149c016f32c5..000000000000 --- a/trunk/arch/parisc/lib/ucmpdi2.c +++ /dev/null @@ -1,25 +0,0 @@ -#include - -union ull_union { - unsigned long long ull; - struct { - unsigned int high; - unsigned int low; - } ui; -}; - -int __ucmpdi2(unsigned long long a, unsigned long long b) -{ - union ull_union au = {.ull = a}; - union ull_union bu = {.ull = b}; - - if (au.ui.high < bu.ui.high) - return 0; - else if (au.ui.high > bu.ui.high) - return 2; - if (au.ui.low < bu.ui.low) - return 0; - else if (au.ui.low > bu.ui.low) - return 2; - return 1; -} diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 04d69c4a5ac2..256c5bf0adb7 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -304,7 +304,7 @@ syscall_exit_work: subi r12,r12,TI_FLAGS 4: /* Anything else left to do? */ - SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ + SET_DEFAULT_THREAD_PPR(r3, r9) /* Set thread.ppr = 3 */ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) beq .ret_from_except_lite @@ -657,7 +657,7 @@ resume_kernel: /* Clear _TIF_EMULATE_STACK_STORE flag */ lis r11,_TIF_EMULATE_STACK_STORE@h addi r5,r9,TI_FLAGS -0: ldarx r4,0,r5 + ldarx r4,0,r5 andc r4,r4,r11 stdcx. r4,0,r5 bne- 0b diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 16e77a81ab4f..59dd545fdde1 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -555,12 +555,10 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new) new->thread.regs->msr |= (MSR_FP | new->thread.fpexc_mode); } -#ifdef CONFIG_ALTIVEC if (msr & MSR_VEC) { do_load_up_transact_altivec(&new->thread); new->thread.regs->msr |= MSR_VEC; } -#endif /* We may as well turn on VSX too since all the state is restored now */ if (msr & MSR_VSX) new->thread.regs->msr |= MSR_VSX; diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index 95068bf569ad..3acb28e245b4 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -866,12 +866,10 @@ static long restore_tm_user_regs(struct pt_regs *regs, do_load_up_transact_fpu(¤t->thread); regs->msr |= (MSR_FP | current->thread.fpexc_mode); } -#ifdef CONFIG_ALTIVEC if (msr & MSR_VEC) { do_load_up_transact_altivec(¤t->thread); regs->msr |= MSR_VEC; } -#endif return 0; } diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index c1794286098c..995f8543cb57 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -522,12 +522,10 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, do_load_up_transact_fpu(¤t->thread); regs->msr |= (MSR_FP | current->thread.fpexc_mode); } -#ifdef CONFIG_ALTIVEC if (msr & MSR_VEC) { do_load_up_transact_altivec(¤t->thread); regs->msr |= MSR_VEC; } -#endif return err; } diff --git a/trunk/arch/powerpc/kernel/tm.S b/trunk/arch/powerpc/kernel/tm.S index 2da67e7a16d5..84dbace657ce 100644 --- a/trunk/arch/powerpc/kernel/tm.S +++ b/trunk/arch/powerpc/kernel/tm.S @@ -309,7 +309,6 @@ _GLOBAL(tm_recheckpoint) or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */ mtmsr r5 -#ifdef CONFIG_ALTIVEC /* FP and VEC registers: These are recheckpointed from thread.fpr[] * and thread.vr[] respectively. The thread.transact_fpr[] version * is more modern, and will be loaded subsequently by any FPUnavailable @@ -324,7 +323,6 @@ _GLOBAL(tm_recheckpoint) REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ ld r5, THREAD_VRSAVE(r3) mtspr SPRN_VRSAVE, r5 -#endif dont_restore_vec: andi. r0, r4, MSR_FP diff --git a/trunk/arch/powerpc/kvm/e500.h b/trunk/arch/powerpc/kvm/e500.h index 33db48a8ce24..41cefd43655f 100644 --- a/trunk/arch/powerpc/kvm/e500.h +++ b/trunk/arch/powerpc/kvm/e500.h @@ -26,20 +26,17 @@ #define E500_PID_NUM 3 #define E500_TLB_NUM 2 -/* entry is mapped somewhere in host TLB */ -#define E500_TLB_VALID (1 << 0) -/* TLB1 entry is mapped by host TLB1, tracked by bitmaps */ -#define E500_TLB_BITMAP (1 << 1) -/* TLB1 entry is mapped by host TLB0 */ +#define E500_TLB_VALID 1 +#define E500_TLB_BITMAP 2 #define E500_TLB_TLB0 (1 << 2) struct tlbe_ref { - pfn_t pfn; /* valid only for TLB0, except briefly */ - unsigned int flags; /* E500_TLB_* */ + pfn_t pfn; + unsigned int flags; /* E500_TLB_* */ }; struct tlbe_priv { - struct tlbe_ref ref; + struct tlbe_ref ref; /* TLB0 only -- TLB1 uses tlb_refs */ }; #ifdef CONFIG_KVM_E500V2 @@ -66,6 +63,17 @@ struct kvmppc_vcpu_e500 { unsigned int gtlb_nv[E500_TLB_NUM]; + /* + * information associated with each host TLB entry -- + * TLB1 only for now. If/when guest TLB1 entries can be + * mapped with host TLB0, this will be used for that too. + * + * We don't want to use this for guest TLB0 because then we'd + * have the overhead of doing the translation again even if + * the entry is still in the guest TLB (e.g. we swapped out + * and back, and our host TLB entries got evicted). + */ + struct tlbe_ref *tlb_refs[E500_TLB_NUM]; unsigned int host_tlb1_nv; u32 svr; diff --git a/trunk/arch/powerpc/kvm/e500_mmu_host.c b/trunk/arch/powerpc/kvm/e500_mmu_host.c index 1c6a9d729df4..a222edfb9a9b 100644 --- a/trunk/arch/powerpc/kvm/e500_mmu_host.c +++ b/trunk/arch/powerpc/kvm/e500_mmu_host.c @@ -193,11 +193,8 @@ void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[tlbsel][esel].ref; /* Don't bother with unmapped entries */ - if (!(ref->flags & E500_TLB_VALID)) { - WARN(ref->flags & (E500_TLB_BITMAP | E500_TLB_TLB0), - "%s: flags %x\n", __func__, ref->flags); - WARN_ON(tlbsel == 1 && vcpu_e500->g2h_tlb1_map[esel]); - } + if (!(ref->flags & E500_TLB_VALID)) + return; if (tlbsel == 1 && ref->flags & E500_TLB_BITMAP) { u64 tmp = vcpu_e500->g2h_tlb1_map[esel]; @@ -251,7 +248,7 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, pfn_t pfn) { ref->pfn = pfn; - ref->flags |= E500_TLB_VALID; + ref->flags = E500_TLB_VALID; if (tlbe_is_writable(gtlbe)) kvm_set_pfn_dirty(pfn); @@ -260,7 +257,6 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref) { if (ref->flags & E500_TLB_VALID) { - /* FIXME: don't log bogus pfn for TLB1 */ trace_kvm_booke206_ref_release(ref->pfn, ref->flags); ref->flags = 0; } @@ -278,23 +274,36 @@ static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500) static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) { - int tlbsel; + int tlbsel = 0; int i; - for (tlbsel = 0; tlbsel <= 1; tlbsel++) { - for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) { - struct tlbe_ref *ref = - &vcpu_e500->gtlb_priv[tlbsel][i].ref; - kvmppc_e500_ref_release(ref); - } + for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) { + struct tlbe_ref *ref = + &vcpu_e500->gtlb_priv[tlbsel][i].ref; + kvmppc_e500_ref_release(ref); } } -void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu) +static void clear_tlb_refs(struct kvmppc_vcpu_e500 *vcpu_e500) { - struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); + int stlbsel = 1; + int i; + kvmppc_e500_tlbil_all(vcpu_e500); + + for (i = 0; i < host_tlb_params[stlbsel].entries; i++) { + struct tlbe_ref *ref = + &vcpu_e500->tlb_refs[stlbsel][i]; + kvmppc_e500_ref_release(ref); + } + clear_tlb_privs(vcpu_e500); +} + +void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu) +{ + struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); + clear_tlb_refs(vcpu_e500); clear_tlb1_bitmap(vcpu_e500); } @@ -449,6 +458,8 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1); } + /* Drop old ref and setup new one. */ + kvmppc_e500_ref_release(ref); kvmppc_e500_ref_setup(ref, gtlbe, pfn); kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, @@ -496,15 +507,14 @@ static int kvmppc_e500_tlb1_map_tlb1(struct kvmppc_vcpu_e500 *vcpu_e500, if (unlikely(vcpu_e500->host_tlb1_nv >= tlb1_max_shadow_size())) vcpu_e500->host_tlb1_nv = 0; + vcpu_e500->tlb_refs[1][sesel] = *ref; + vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel; + vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP; if (vcpu_e500->h2g_tlb1_rmap[sesel]) { - unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel] - 1; + unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel]; vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << sesel); } - - vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP; - vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel; - vcpu_e500->h2g_tlb1_rmap[sesel] = esel + 1; - WARN_ON(!(ref->flags & E500_TLB_VALID)); + vcpu_e500->h2g_tlb1_rmap[sesel] = esel; return sesel; } @@ -516,12 +526,13 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe, struct kvm_book3e_206_tlb_entry *stlbe, int esel) { - struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[1][esel].ref; + struct tlbe_ref ref; int sesel; int r; + ref.flags = 0; r = kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, stlbe, - ref); + &ref); if (r) return r; @@ -533,7 +544,7 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, } /* Otherwise map into TLB1 */ - sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, ref, esel); + sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, &ref, esel); write_stlbe(vcpu_e500, gtlbe, stlbe, 1, sesel); return 0; @@ -554,7 +565,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr, case 0: priv = &vcpu_e500->gtlb_priv[tlbsel][esel]; - /* Triggers after clear_tlb_privs or on initial mapping */ + /* Triggers after clear_tlb_refs or on initial mapping */ if (!(priv->ref.flags & E500_TLB_VALID)) { kvmppc_e500_tlb0_map(vcpu_e500, esel, &stlbe); } else { @@ -654,16 +665,35 @@ int e500_mmu_host_init(struct kvmppc_vcpu_e500 *vcpu_e500) host_tlb_params[0].entries / host_tlb_params[0].ways; host_tlb_params[1].sets = 1; + vcpu_e500->tlb_refs[0] = + kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[0].entries, + GFP_KERNEL); + if (!vcpu_e500->tlb_refs[0]) + goto err; + + vcpu_e500->tlb_refs[1] = + kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[1].entries, + GFP_KERNEL); + if (!vcpu_e500->tlb_refs[1]) + goto err; + vcpu_e500->h2g_tlb1_rmap = kzalloc(sizeof(unsigned int) * host_tlb_params[1].entries, GFP_KERNEL); if (!vcpu_e500->h2g_tlb1_rmap) - return -EINVAL; + goto err; return 0; + +err: + kfree(vcpu_e500->tlb_refs[0]); + kfree(vcpu_e500->tlb_refs[1]); + return -EINVAL; } void e500_mmu_host_uninit(struct kvmppc_vcpu_e500 *vcpu_e500) { kfree(vcpu_e500->h2g_tlb1_rmap); + kfree(vcpu_e500->tlb_refs[0]); + kfree(vcpu_e500->tlb_refs[1]); } diff --git a/trunk/arch/powerpc/kvm/e500mc.c b/trunk/arch/powerpc/kvm/e500mc.c index 2f4baa074b2e..1f89d26e65fb 100644 --- a/trunk/arch/powerpc/kvm/e500mc.c +++ b/trunk/arch/powerpc/kvm/e500mc.c @@ -108,8 +108,6 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) { } -static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu); - void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); @@ -138,11 +136,8 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) mtspr(SPRN_GDEAR, vcpu->arch.shared->dar); mtspr(SPRN_GESR, vcpu->arch.shared->esr); - if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || - __get_cpu_var(last_vcpu_on_cpu) != vcpu) { + if (vcpu->arch.oldpir != mfspr(SPRN_PIR)) kvmppc_e500_tlbil_all(vcpu_e500); - __get_cpu_var(last_vcpu_on_cpu) = vcpu; - } kvmppc_load_guest_fp(vcpu); } diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index 299731e9036b..0da39fed355a 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -186,13 +186,7 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group) (0x1UL << 4), &dummy1, &dummy2); if (lpar_rc == H_SUCCESS) return i; - - /* - * The test for adjunct partition is performed before the - * ANDCOND test. H_RESOURCE may be returned, so we need to - * check for that as well. - */ - BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE); + BUG_ON(lpar_rc != H_NOT_FOUND); slot_offset++; slot_offset &= 0x7; diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index bda6ba6f3cf5..eb8fb629f00b 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -375,6 +375,19 @@ config PACK_STACK Say Y if you are unsure. +config SMALL_STACK + def_bool n + prompt "Use 8kb for kernel stack instead of 16kb" + depends on PACK_STACK && 64BIT && !LOCKDEP + help + If you say Y here and the compiler supports the -mkernel-backchain + option the kernel will use a smaller kernel stack size. The reduced + size is 8kb instead of 16kb. This allows to run more threads on a + system and reduces the pressure on the memory management for higher + order page allocations. + + Say N if you are unsure. + config CHECK_STACK def_bool y prompt "Detect kernel stack overflow" diff --git a/trunk/arch/s390/Makefile b/trunk/arch/s390/Makefile index a7d68a467ce8..7e3ce78d4290 100644 --- a/trunk/arch/s390/Makefile +++ b/trunk/arch/s390/Makefile @@ -55,12 +55,22 @@ cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls ifeq ($(call cc-option-yn,-mkernel-backchain),y) cflags-$(CONFIG_PACK_STACK) += -mkernel-backchain -D__PACK_STACK aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK +cflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK +aflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK +ifdef CONFIG_SMALL_STACK +STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) ) +endif endif # new style option for packed stacks ifeq ($(call cc-option-yn,-mpacked-stack),y) cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK +cflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK +aflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK +ifdef CONFIG_SMALL_STACK +STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) ) +endif endif ifeq ($(call cc-option-yn,-mstack-size=8192 -mstack-guard=128),y) diff --git a/trunk/arch/s390/hypfs/hypfs_dbfs.c b/trunk/arch/s390/hypfs/hypfs_dbfs.c index bb5dd496614f..9fd4a40c6752 100644 --- a/trunk/arch/s390/hypfs/hypfs_dbfs.c +++ b/trunk/arch/s390/hypfs/hypfs_dbfs.c @@ -105,7 +105,9 @@ void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df) int hypfs_dbfs_init(void) { dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); - return PTR_RET(dbfs_dir); + if (IS_ERR(dbfs_dir)) + return PTR_ERR(dbfs_dir); + return 0; } void hypfs_dbfs_exit(void) diff --git a/trunk/arch/s390/include/asm/bitops.h b/trunk/arch/s390/include/asm/bitops.h index 4d8604e311f3..15422933c60b 100644 --- a/trunk/arch/s390/include/asm/bitops.h +++ b/trunk/arch/s390/include/asm/bitops.h @@ -61,6 +61,8 @@ extern const char _sb_findmap[]; #ifndef CONFIG_64BIT +#define __BITOPS_ALIGN 3 +#define __BITOPS_WORDSIZE 32 #define __BITOPS_OR "or" #define __BITOPS_AND "nr" #define __BITOPS_XOR "xr" @@ -79,6 +81,8 @@ extern const char _sb_findmap[]; #else /* CONFIG_64BIT */ +#define __BITOPS_ALIGN 7 +#define __BITOPS_WORDSIZE 64 #define __BITOPS_OR "ogr" #define __BITOPS_AND "ngr" #define __BITOPS_XOR "xgr" @@ -97,7 +101,8 @@ extern const char _sb_findmap[]; #endif /* CONFIG_64BIT */ -#define __BITOPS_WORDS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG) +#define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) +#define __BITOPS_BARRIER() asm volatile("" : : : "memory") #ifdef CONFIG_SMP /* @@ -109,9 +114,9 @@ static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make OR mask */ - mask = 1UL << (nr & (BITS_PER_LONG - 1)); + mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); } @@ -125,9 +130,9 @@ static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make AND mask */ - mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); + mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); } @@ -141,9 +146,9 @@ static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make XOR mask */ - mask = 1UL << (nr & (BITS_PER_LONG - 1)); + mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); } @@ -158,12 +163,12 @@ test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make OR/test mask */ - mask = 1UL << (nr & (BITS_PER_LONG - 1)); + mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); - barrier(); + __BITOPS_BARRIER(); return (old & mask) != 0; } @@ -177,12 +182,12 @@ test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make AND/test mask */ - mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); + mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); - barrier(); + __BITOPS_BARRIER(); return (old ^ new) != 0; } @@ -196,12 +201,12 @@ test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr; /* calculate address for CS */ - addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; + addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; /* make XOR/test mask */ - mask = 1UL << (nr & (BITS_PER_LONG - 1)); + mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); /* Do the atomic update. */ __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); - barrier(); + __BITOPS_BARRIER(); return (old & mask) != 0; } #endif /* CONFIG_SMP */ @@ -213,7 +218,7 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); asm volatile( " oc %O0(1,%R0),%1" : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); @@ -224,7 +229,7 @@ __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); *(unsigned char *) addr |= 1 << (nr & 7); } @@ -241,7 +246,7 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); asm volatile( " nc %O0(1,%R0),%1" : "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc" ); @@ -252,7 +257,7 @@ __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); *(unsigned char *) addr &= ~(1 << (nr & 7)); } @@ -268,7 +273,7 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); asm volatile( " xc %O0(1,%R0),%1" : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); @@ -279,7 +284,7 @@ __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) { unsigned long addr; - addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); *(unsigned char *) addr ^= 1 << (nr & 7); } @@ -297,7 +302,7 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; asm volatile( " oc %O0(1,%R0),%1" @@ -316,7 +321,7 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; asm volatile( " nc %O0(1,%R0),%1" @@ -335,7 +340,7 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; asm volatile( " xc %O0(1,%R0),%1" @@ -371,7 +376,7 @@ static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr unsigned long addr; unsigned char ch; - addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); + addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(volatile unsigned char *) addr; return (ch >> (nr & 7)) & 1; } @@ -379,7 +384,7 @@ static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr static inline int __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { return (((volatile char *) addr) - [(nr^(BITS_PER_LONG-8))>>3] & (1<<(nr&7))) != 0; + [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7))) != 0; } #define test_bit(nr,addr) \ @@ -688,18 +693,18 @@ static inline int find_next_bit_left(const unsigned long *addr, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { set = __flo_word(0, *p & (~0UL << bit)); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_bit_left(p, size); @@ -731,22 +736,22 @@ static inline int find_next_zero_bit (const unsigned long * addr, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * __ffz_word returns BITS_PER_LONG + * __ffz_word returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ set = __ffz_word(bit, *p >> bit); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_zero_bit(p, size); @@ -768,22 +773,22 @@ static inline int find_next_bit (const unsigned long * addr, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * __ffs_word returns BITS_PER_LONG + * __ffs_word returns __BITOPS_WORDSIZE * if no one bit is present in the word. */ set = __ffs_word(0, *p & (~0UL << bit)); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_bit(p, size); @@ -838,22 +843,22 @@ static inline int find_next_zero_bit_le(void *vaddr, unsigned long size, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * s390 version of ffz returns BITS_PER_LONG + * s390 version of ffz returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ set = __ffz_word(bit, __load_ulong_le(p, 0) >> bit); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_zero_bit_le(p, size); @@ -880,22 +885,22 @@ static inline int find_next_bit_le(void *vaddr, unsigned long size, if (offset >= size) return size; - bit = offset & (BITS_PER_LONG - 1); + bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; - p = addr + offset / BITS_PER_LONG; + p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* - * s390 version of ffz returns BITS_PER_LONG + * s390 version of ffz returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ set = __ffs_word(0, __load_ulong_le(p, 0) & (~0UL << bit)); if (set >= size) return size + offset; - if (set < BITS_PER_LONG) + if (set < __BITOPS_WORDSIZE) return set + offset; - offset += BITS_PER_LONG; - size -= BITS_PER_LONG; + offset += __BITOPS_WORDSIZE; + size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_bit_le(p, size); diff --git a/trunk/arch/s390/include/asm/ccwdev.h b/trunk/arch/s390/include/asm/ccwdev.h index f201af8be580..e6061617a50b 100644 --- a/trunk/arch/s390/include/asm/ccwdev.h +++ b/trunk/arch/s390/include/asm/ccwdev.h @@ -220,8 +220,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) extern struct ccw_device *ccw_device_probe_console(void); -extern void ccw_device_wait_idle(struct ccw_device *); -extern int ccw_device_force_console(struct ccw_device *); +extern int ccw_device_force_console(void); int ccw_device_siosl(struct ccw_device *); diff --git a/trunk/arch/s390/include/asm/cio.h b/trunk/arch/s390/include/asm/cio.h index ffb898961c8d..ad2b924167d7 100644 --- a/trunk/arch/s390/include/asm/cio.h +++ b/trunk/arch/s390/include/asm/cio.h @@ -296,6 +296,8 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, return 0; } +extern void wait_cons_dev(void); + extern void css_schedule_reprobe(void); extern void reipl_ccw_dev(struct ccw_dev_id *id); diff --git a/trunk/arch/s390/include/asm/compat.h b/trunk/arch/s390/include/asm/compat.h index c1e7c646727c..f8c6df6cd1f0 100644 --- a/trunk/arch/s390/include/asm/compat.h +++ b/trunk/arch/s390/include/asm/compat.h @@ -70,22 +70,6 @@ typedef u32 compat_ulong_t; typedef u64 compat_u64; typedef u32 compat_uptr_t; -typedef struct { - u32 mask; - u32 addr; -} __aligned(8) psw_compat_t; - -typedef struct { - psw_compat_t psw; - u32 gprs[NUM_GPRS]; - u32 acrs[NUM_ACRS]; - u32 orig_gpr2; -} s390_compat_regs; - -typedef struct { - u32 gprs_high[NUM_GPRS]; -} s390_compat_regs_high; - struct compat_timespec { compat_time_t tv_sec; s32 tv_nsec; @@ -140,33 +124,18 @@ struct compat_flock64 { }; struct compat_statfs { - u32 f_type; - u32 f_bsize; - u32 f_blocks; - u32 f_bfree; - u32 f_bavail; - u32 f_files; - u32 f_ffree; - compat_fsid_t f_fsid; - u32 f_namelen; - u32 f_frsize; - u32 f_flags; - u32 f_spare[4]; -}; - -struct compat_statfs64 { - u32 f_type; - u32 f_bsize; - u64 f_blocks; - u64 f_bfree; - u64 f_bavail; - u64 f_files; - u64 f_ffree; + s32 f_type; + s32 f_bsize; + s32 f_blocks; + s32 f_bfree; + s32 f_bavail; + s32 f_files; + s32 f_ffree; compat_fsid_t f_fsid; - u32 f_namelen; - u32 f_frsize; - u32 f_flags; - u32 f_spare[4]; + s32 f_namelen; + s32 f_frsize; + s32 f_flags; + s32 f_spare[5]; }; #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff @@ -279,6 +248,8 @@ static inline int is_compat_task(void) return is_32bit_task(); } +#endif + static inline void __user *arch_compat_alloc_user_space(long len) { unsigned long stack; @@ -289,8 +260,6 @@ static inline void __user *arch_compat_alloc_user_space(long len) return (void __user *) (stack - len); } -#endif - struct compat_ipc64_perm { compat_key_t key; __compat_uid32_t uid; diff --git a/trunk/arch/s390/include/asm/elf.h b/trunk/arch/s390/include/asm/elf.h index 78f4f8711d58..1bfdf24b85a2 100644 --- a/trunk/arch/s390/include/asm/elf.h +++ b/trunk/arch/s390/include/asm/elf.h @@ -119,8 +119,6 @@ */ #include -#include -#include #include typedef s390_fp_regs elf_fpregset_t; @@ -182,31 +180,18 @@ extern unsigned long elf_hwcap; extern char elf_platform[]; #define ELF_PLATFORM (elf_platform) -#ifndef CONFIG_COMPAT -#define SET_PERSONALITY(ex) \ -do { \ - set_personality(PER_LINUX | \ - (current->personality & (~PER_MASK))); \ - current_thread_info()->sys_call_table = \ - (unsigned long) &sys_call_table; \ -} while (0) -#else /* CONFIG_COMPAT */ +#ifdef CONFIG_64BIT #define SET_PERSONALITY(ex) \ do { \ if (personality(current->personality) != PER_LINUX32) \ set_personality(PER_LINUX | \ (current->personality & ~PER_MASK)); \ - if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ set_thread_flag(TIF_31BIT); \ - current_thread_info()->sys_call_table = \ - (unsigned long) &sys_call_table_emu; \ - } else { \ + else \ clear_thread_flag(TIF_31BIT); \ - current_thread_info()->sys_call_table = \ - (unsigned long) &sys_call_table; \ - } \ } while (0) -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_64BIT */ #define STACK_RND_MASK 0x7ffUL diff --git a/trunk/arch/s390/include/asm/io.h b/trunk/arch/s390/include/asm/io.h index 379d96e2105e..27cb32185ce1 100644 --- a/trunk/arch/s390/include/asm/io.h +++ b/trunk/arch/s390/include/asm/io.h @@ -50,6 +50,10 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr); #define ioremap_nocache(addr, size) ioremap(addr, size) #define ioremap_wc ioremap_nocache +/* TODO: s390 cannot support io_remap_pfn_range... */ +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + static inline void __iomem *ioremap(unsigned long offset, unsigned long size) { return (void __iomem *) offset; diff --git a/trunk/arch/s390/include/asm/pci.h b/trunk/arch/s390/include/asm/pci.h index 6c1801235db9..05333b7f0469 100644 --- a/trunk/arch/s390/include/asm/pci.h +++ b/trunk/arch/s390/include/asm/pci.h @@ -140,7 +140,6 @@ static inline bool zdev_enabled(struct zpci_dev *zdev) struct zpci_dev *zpci_alloc_device(void); int zpci_create_device(struct zpci_dev *); int zpci_enable_device(struct zpci_dev *); -int zpci_disable_device(struct zpci_dev *); void zpci_stop_device(struct zpci_dev *); void zpci_free_device(struct zpci_dev *); int zpci_scan_device(struct zpci_dev *); diff --git a/trunk/arch/s390/include/asm/pci_debug.h b/trunk/arch/s390/include/asm/pci_debug.h index 1ca5d1047c71..6bbec4265b6e 100644 --- a/trunk/arch/s390/include/asm/pci_debug.h +++ b/trunk/arch/s390/include/asm/pci_debug.h @@ -7,11 +7,14 @@ extern debug_info_t *pci_debug_msg_id; extern debug_info_t *pci_debug_err_id; #ifdef CONFIG_PCI_DEBUG -#define zpci_dbg(imp, fmt, args...) \ - debug_sprintf_event(pci_debug_msg_id, imp, fmt, ##args) +#define zpci_dbg(fmt, args...) \ + do { \ + if (pci_debug_msg_id->level >= 2) \ + debug_sprintf_event(pci_debug_msg_id, 2, fmt , ## args);\ + } while (0) #else /* !CONFIG_PCI_DEBUG */ -#define zpci_dbg(imp, fmt, args...) do { } while (0) +#define zpci_dbg(fmt, args...) do { } while (0) #endif #define zpci_err(text...) \ diff --git a/trunk/arch/s390/include/asm/pci_insn.h b/trunk/arch/s390/include/asm/pci_insn.h index e6a2bdd4d705..1486a98d5dad 100644 --- a/trunk/arch/s390/include/asm/pci_insn.h +++ b/trunk/arch/s390/include/asm/pci_insn.h @@ -1,6 +1,10 @@ #ifndef _ASM_S390_PCI_INSN_H #define _ASM_S390_PCI_INSN_H +#include + +#define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */ + /* Load/Store status codes */ #define ZPCI_PCI_ST_FUNC_NOT_ENABLED 4 #define ZPCI_PCI_ST_FUNC_IN_ERR 8 @@ -78,12 +82,199 @@ struct zpci_fib { u64 reserved7; } __packed; +/* Modify PCI Function Controls */ +static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) +{ + u8 cc; + + asm volatile ( + " .insn rxy,0xe300000000d0,%[req],%[fib]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib) + : : "cc"); + *status = req >> 24 & 0xff; + return cc; +} + +static inline int mpcifc_instr(u64 req, struct zpci_fib *fib) +{ + u8 cc, status; + + do { + cc = __mpcifc(req, fib, &status); + if (cc == 2) + msleep(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); + + if (cc) + printk_once(KERN_ERR "%s: error cc: %d status: %d\n", + __func__, cc, status); + return (cc) ? -EIO : 0; +} + +/* Refresh PCI Translations */ +static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) +{ + register u64 __addr asm("2") = addr; + register u64 __range asm("3") = range; + u8 cc; + + asm volatile ( + " .insn rre,0xb9d30000,%[fn],%[addr]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [fn] "+d" (fn) + : [addr] "d" (__addr), "d" (__range) + : "cc"); + *status = fn >> 24 & 0xff; + return cc; +} + +static inline int rpcit_instr(u64 fn, u64 addr, u64 range) +{ + u8 cc, status; + + do { + cc = __rpcit(fn, addr, range, &status); + if (cc == 2) + udelay(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); + + if (cc) + printk_once(KERN_ERR "%s: error cc: %d status: %d dma_addr: %Lx size: %Lx\n", + __func__, cc, status, addr, range); + return (cc) ? -EIO : 0; +} + +/* Store PCI function controls */ +static inline u8 __stpcifc(u32 handle, u8 space, struct zpci_fib *fib, u8 *status) +{ + u64 fn = (u64) handle << 32 | space << 16; + u8 cc; + + asm volatile ( + " .insn rxy,0xe300000000d4,%[fn],%[fib]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [fn] "+d" (fn), [fib] "=m" (*fib) + : : "cc"); + *status = fn >> 24 & 0xff; + return cc; +} + +/* Set Interruption Controls */ +static inline void sic_instr(u16 ctl, char *unused, u8 isc) +{ + asm volatile ( + " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" + : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); +} + +/* PCI Load */ +static inline u8 __pcilg(u64 *data, u64 req, u64 offset, u8 *status) +{ + register u64 __req asm("2") = req; + register u64 __offset asm("3") = offset; + u64 __data; + u8 cc; + + asm volatile ( + " .insn rre,0xb9d20000,%[data],%[req]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [data] "=d" (__data), [req] "+d" (__req) + : "d" (__offset) + : "cc"); + *status = __req >> 24 & 0xff; + *data = __data; + return cc; +} + +static inline int pcilg_instr(u64 *data, u64 req, u64 offset) +{ + u8 cc, status; + + do { + cc = __pcilg(data, req, offset, &status); + if (cc == 2) + udelay(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); + + if (cc) { + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", + __func__, cc, status, req, offset); + /* TODO: on IO errors set data to 0xff... + * here or in users of pcilg (le conversion)? + */ + } + return (cc) ? -EIO : 0; +} + +/* PCI Store */ +static inline u8 __pcistg(u64 data, u64 req, u64 offset, u8 *status) +{ + register u64 __req asm("2") = req; + register u64 __offset asm("3") = offset; + u8 cc; + + asm volatile ( + " .insn rre,0xb9d00000,%[data],%[req]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [req] "+d" (__req) + : "d" (__offset), [data] "d" (data) + : "cc"); + *status = __req >> 24 & 0xff; + return cc; +} + +static inline int pcistg_instr(u64 data, u64 req, u64 offset) +{ + u8 cc, status; + + do { + cc = __pcistg(data, req, offset, &status); + if (cc == 2) + udelay(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); + + if (cc) + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", + __func__, cc, status, req, offset); + return (cc) ? -EIO : 0; +} + +/* PCI Store Block */ +static inline u8 __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) +{ + u8 cc; + + asm volatile ( + " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=d" (cc), [req] "+d" (req) + : [offset] "d" (offset), [data] "Q" (*data) + : "cc"); + *status = req >> 24 & 0xff; + return cc; +} + +static inline int pcistb_instr(const u64 *data, u64 req, u64 offset) +{ + u8 cc, status; + + do { + cc = __pcistb(data, req, offset, &status); + if (cc == 2) + udelay(ZPCI_INSN_BUSY_DELAY); + } while (cc == 2); -int s390pci_mod_fc(u64 req, struct zpci_fib *fib); -int s390pci_refresh_trans(u64 fn, u64 addr, u64 range); -int s390pci_load(u64 *data, u64 req, u64 offset); -int s390pci_store(u64 data, u64 req, u64 offset); -int s390pci_store_block(const u64 *data, u64 req, u64 offset); -void set_irq_ctrl(u16 ctl, char *unused, u8 isc); + if (cc) + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", + __func__, cc, status, req, offset); + return (cc) ? -EIO : 0; +} #endif diff --git a/trunk/arch/s390/include/asm/pci_io.h b/trunk/arch/s390/include/asm/pci_io.h index 83a9caa6ae53..5fd81f31d6c7 100644 --- a/trunk/arch/s390/include/asm/pci_io.h +++ b/trunk/arch/s390/include/asm/pci_io.h @@ -36,7 +36,7 @@ static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr) \ u64 data; \ int rc; \ \ - rc = s390pci_load(&data, req, ZPCI_OFFSET(addr)); \ + rc = pcilg_instr(&data, req, ZPCI_OFFSET(addr)); \ if (rc) \ data = -1ULL; \ return (RETTYPE) data; \ @@ -50,7 +50,7 @@ static inline void zpci_write_##VALTYPE(VALTYPE val, \ u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ u64 data = (VALTYPE) val; \ \ - s390pci_store(data, req, ZPCI_OFFSET(addr)); \ + pcistg_instr(data, req, ZPCI_OFFSET(addr)); \ } zpci_read(8, u64) @@ -83,18 +83,15 @@ static inline int zpci_write_single(u64 req, const u64 *data, u64 offset, u8 len val = 0; /* let FW report error */ break; } - return s390pci_store(val, req, offset); + return pcistg_instr(val, req, offset); } static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) { u64 data; - int cc; - - cc = s390pci_load(&data, req, offset); - if (cc) - goto out; + u8 cc; + cc = pcilg_instr(&data, req, offset); switch (len) { case 1: *((u8 *) dst) = (u8) data; @@ -109,13 +106,12 @@ static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) *((u64 *) dst) = (u64) data; break; } -out: return cc; } static inline int zpci_write_block(u64 req, const u64 *data, u64 offset) { - return s390pci_store_block(data, req, offset); + return pcistb_instr(data, req, offset); } static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) diff --git a/trunk/arch/s390/include/asm/pgtable.h b/trunk/arch/s390/include/asm/pgtable.h index 4a64c0e5428f..4a2930844d43 100644 --- a/trunk/arch/s390/include/asm/pgtable.h +++ b/trunk/arch/s390/include/asm/pgtable.h @@ -57,10 +57,6 @@ extern unsigned long zero_page_mask; (((unsigned long)(vaddr)) &zero_page_mask)))) #define __HAVE_COLOR_ZERO_PAGE -/* TODO: s390 cannot support io_remap_pfn_range... */ -#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ - remap_pfn_range(vma, vaddr, pfn, size, prot) - #endif /* !__ASSEMBLY__ */ /* @@ -348,7 +344,6 @@ extern unsigned long MODULES_END; #define _REGION3_ENTRY_CO 0x100 /* change-recording override */ /* Bits in the segment table entry */ -#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ @@ -764,8 +759,6 @@ void gmap_disable(struct gmap *gmap); int gmap_map_segment(struct gmap *gmap, unsigned long from, unsigned long to, unsigned long length); int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len); -unsigned long __gmap_translate(unsigned long address, struct gmap *); -unsigned long gmap_translate(unsigned long address, struct gmap *); unsigned long __gmap_fault(unsigned long address, struct gmap *); unsigned long gmap_fault(unsigned long address, struct gmap *); void gmap_discard(unsigned long from, unsigned long to, struct gmap *); @@ -1538,8 +1531,7 @@ extern int s390_enable_sie(void); /* * No page table caches to initialise */ -static inline void pgtable_cache_init(void) { } -static inline void check_pgt_cache(void) { } +#define pgtable_cache_init() do { } while (0) #include diff --git a/trunk/arch/s390/include/asm/processor.h b/trunk/arch/s390/include/asm/processor.h index 6b499870662f..94e749c90230 100644 --- a/trunk/arch/s390/include/asm/processor.h +++ b/trunk/arch/s390/include/asm/processor.h @@ -161,8 +161,7 @@ extern unsigned long thread_saved_pc(struct task_struct *t); extern void show_code(struct pt_regs *regs); extern void print_fn_code(unsigned char *code, unsigned long len); -extern int insn_to_mnemonic(unsigned char *instruction, char *buf, - unsigned int len); +extern int insn_to_mnemonic(unsigned char *instruction, char buf[8]); unsigned long get_wchan(struct task_struct *p); #define task_pt_regs(tsk) ((struct pt_regs *) \ diff --git a/trunk/arch/s390/include/asm/ptrace.h b/trunk/arch/s390/include/asm/ptrace.h index 559512a455da..3ee5da3bc10c 100644 --- a/trunk/arch/s390/include/asm/ptrace.h +++ b/trunk/arch/s390/include/asm/ptrace.h @@ -9,7 +9,9 @@ #include #ifndef __ASSEMBLY__ - +#ifndef __s390x__ +#else /* __s390x__ */ +#endif /* __s390x__ */ extern long psw_kernel_bits; extern long psw_user_bits; @@ -75,6 +77,8 @@ struct per_struct_kernel { #define PER_CONTROL_SUSPENSION 0x00400000UL #define PER_CONTROL_ALTERATION 0x00200000UL +#ifdef __s390x__ +#endif /* __s390x__ */ /* * These are defined as per linux/ptrace.h, which see. */ diff --git a/trunk/arch/s390/include/asm/syscall.h b/trunk/arch/s390/include/asm/syscall.h index cd29d2f4e4f3..fe7b99759e12 100644 --- a/trunk/arch/s390/include/asm/syscall.h +++ b/trunk/arch/s390/include/asm/syscall.h @@ -23,7 +23,6 @@ * type here is what we want [need] for both 32 bit and 64 bit systems. */ extern const unsigned int sys_call_table[]; -extern const unsigned int sys_call_table_emu[]; static inline long syscall_get_nr(struct task_struct *task, struct pt_regs *regs) diff --git a/trunk/arch/s390/include/asm/thread_info.h b/trunk/arch/s390/include/asm/thread_info.h index eb5f64d26d06..9e2cfe0349c3 100644 --- a/trunk/arch/s390/include/asm/thread_info.h +++ b/trunk/arch/s390/include/asm/thread_info.h @@ -14,8 +14,13 @@ #define THREAD_ORDER 1 #define ASYNC_ORDER 1 #else /* CONFIG_64BIT */ +#ifndef __SMALL_STACK #define THREAD_ORDER 2 #define ASYNC_ORDER 2 +#else +#define THREAD_ORDER 1 +#define ASYNC_ORDER 1 +#endif #endif /* CONFIG_64BIT */ #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) @@ -36,7 +41,6 @@ struct thread_info { struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ - unsigned long sys_call_table; /* System call table address */ unsigned int cpu; /* current CPU */ int preempt_count; /* 0 => preemptable, <0 => BUG */ struct restart_block restart_block; diff --git a/trunk/arch/s390/include/uapi/asm/ptrace.h b/trunk/arch/s390/include/uapi/asm/ptrace.h index 3aa9f1ec5b29..a5ca214b34fd 100644 --- a/trunk/arch/s390/include/uapi/asm/ptrace.h +++ b/trunk/arch/s390/include/uapi/asm/ptrace.h @@ -215,6 +215,12 @@ typedef struct unsigned long addr; } __attribute__ ((aligned(8))) psw_t; +typedef struct +{ + __u32 mask; + __u32 addr; +} __attribute__ ((aligned(8))) psw_compat_t; + #ifndef __s390x__ #define PSW_MASK_PER 0x40000000UL @@ -289,6 +295,20 @@ typedef struct unsigned long orig_gpr2; } s390_regs; +typedef struct +{ + psw_compat_t psw; + __u32 gprs[NUM_GPRS]; + __u32 acrs[NUM_ACRS]; + __u32 orig_gpr2; +} s390_compat_regs; + +typedef struct +{ + __u32 gprs_high[NUM_GPRS]; +} s390_compat_regs_high; + + /* * Now for the user space program event recording (trace) definitions. * The following structures are used only for the ptrace interface, don't diff --git a/trunk/arch/s390/include/uapi/asm/statfs.h b/trunk/arch/s390/include/uapi/asm/statfs.h index a61d538756f2..5acca0a34c20 100644 --- a/trunk/arch/s390/include/uapi/asm/statfs.h +++ b/trunk/arch/s390/include/uapi/asm/statfs.h @@ -7,6 +7,9 @@ #ifndef _S390_STATFS_H #define _S390_STATFS_H +#ifndef __s390x__ +#include +#else /* * We can't use because in 64-bit mode * we mix ints of different sizes in our struct statfs. @@ -18,33 +21,49 @@ typedef __kernel_fsid_t fsid_t; #endif struct statfs { - unsigned int f_type; - unsigned int f_bsize; - unsigned long f_blocks; - unsigned long f_bfree; - unsigned long f_bavail; - unsigned long f_files; - unsigned long f_ffree; + int f_type; + int f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; __kernel_fsid_t f_fsid; - unsigned int f_namelen; - unsigned int f_frsize; - unsigned int f_flags; - unsigned int f_spare[4]; + int f_namelen; + int f_frsize; + int f_flags; + int f_spare[4]; }; struct statfs64 { - unsigned int f_type; - unsigned int f_bsize; - unsigned long f_blocks; - unsigned long f_bfree; - unsigned long f_bavail; - unsigned long f_files; - unsigned long f_ffree; + int f_type; + int f_bsize; + long f_blocks; + long f_bfree; + long f_bavail; + long f_files; + long f_ffree; __kernel_fsid_t f_fsid; - unsigned int f_namelen; - unsigned int f_frsize; - unsigned int f_flags; - unsigned int f_spare[4]; + int f_namelen; + int f_frsize; + int f_flags; + int f_spare[4]; }; +struct compat_statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_flags; + __u32 f_spare[4]; +}; + +#endif /* __s390x__ */ #endif diff --git a/trunk/arch/s390/kernel/Makefile b/trunk/arch/s390/kernel/Makefile index 1386fcaf4ef6..2ac311ef5c9b 100644 --- a/trunk/arch/s390/kernel/Makefile +++ b/trunk/arch/s390/kernel/Makefile @@ -13,14 +13,6 @@ endif # CFLAGS_smp.o := -Wno-nonnull -# -# Disable tailcall optimizations for stack / callchain walking functions -# since this might generate broken code when accessing register 15 and -# passing its content to other functions. -# -CFLAGS_stacktrace.o += -fno-optimize-sibling-calls -CFLAGS_dumpstack.o += -fno-optimize-sibling-calls - # # Pass UTS_MACHINE for user_regset definition # @@ -28,11 +20,10 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w -obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o -obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o -obj-y += debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o -obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o -obj-y += dumpstack.o +obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \ + processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \ + debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \ + sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) diff --git a/trunk/arch/s390/kernel/asm-offsets.c b/trunk/arch/s390/kernel/asm-offsets.c index 7a82f9f70100..fface87056eb 100644 --- a/trunk/arch/s390/kernel/asm-offsets.c +++ b/trunk/arch/s390/kernel/asm-offsets.c @@ -35,7 +35,6 @@ int main(void) DEFINE(__TI_task, offsetof(struct thread_info, task)); DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); DEFINE(__TI_flags, offsetof(struct thread_info, flags)); - DEFINE(__TI_sysc_table, offsetof(struct thread_info, sys_call_table)); DEFINE(__TI_cpu, offsetof(struct thread_info, cpu)); DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count)); DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer)); diff --git a/trunk/arch/s390/kernel/compat_signal.c b/trunk/arch/s390/kernel/compat_signal.c index c439ac9ced09..6de049fbe62d 100644 --- a/trunk/arch/s390/kernel/compat_signal.c +++ b/trunk/arch/s390/kernel/compat_signal.c @@ -362,7 +362,6 @@ static int setup_frame32(int sig, struct k_sigaction *ka, /* set extra registers only for synchronous signals */ regs->gprs[4] = regs->int_code & 127; regs->gprs[5] = regs->int_parm_long; - regs->gprs[6] = task_thread_info(current)->last_break; } /* Place signal number on stack to allow backtrace from handler. */ @@ -422,7 +421,6 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, regs->gprs[2] = map_signal(sig); regs->gprs[3] = (__force __u64) &frame->info; regs->gprs[4] = (__force __u64) &frame->uc; - regs->gprs[5] = task_thread_info(current)->last_break; return 0; give_sigsegv: diff --git a/trunk/arch/s390/kernel/dis.c b/trunk/arch/s390/kernel/dis.c index 7f4a4a8c847c..3ad5e9540160 100644 --- a/trunk/arch/s390/kernel/dis.c +++ b/trunk/arch/s390/kernel/dis.c @@ -1696,15 +1696,14 @@ static struct insn *find_insn(unsigned char *code) * insn_to_mnemonic - decode an s390 instruction * @instruction: instruction to decode * @buf: buffer to fill with mnemonic - * @len: length of buffer * * Decode the instruction at @instruction and store the corresponding - * mnemonic into @buf of length @len. + * mnemonic into @buf. * @buf is left unchanged if the instruction could not be decoded. * Returns: * %0 on success, %-ENOENT if the instruction was not found. */ -int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len) +int insn_to_mnemonic(unsigned char *instruction, char buf[8]) { struct insn *insn; @@ -1712,10 +1711,10 @@ int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len) if (!insn) return -ENOENT; if (insn->name[0] == '\0') - snprintf(buf, len, "%s", + snprintf(buf, 8, "%s", long_insn_name[(int) insn->name[1]]); else - snprintf(buf, len, "%.5s", insn->name); + snprintf(buf, 8, "%.5s", insn->name); return 0; } EXPORT_SYMBOL_GPL(insn_to_mnemonic); diff --git a/trunk/arch/s390/kernel/dumpstack.c b/trunk/arch/s390/kernel/dumpstack.c deleted file mode 100644 index 03dce39d01ee..000000000000 --- a/trunk/arch/s390/kernel/dumpstack.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Stack dumping functions - * - * Copyright IBM Corp. 1999, 2013 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_64BIT -#define LONG "%08lx " -#define FOURLONG "%08lx %08lx %08lx %08lx\n" -static int kstack_depth_to_print = 12; -#else /* CONFIG_64BIT */ -#define LONG "%016lx " -#define FOURLONG "%016lx %016lx %016lx %016lx\n" -static int kstack_depth_to_print = 20; -#endif /* CONFIG_64BIT */ - -/* - * For show_trace we have tree different stack to consider: - * - the panic stack which is used if the kernel stack has overflown - * - the asynchronous interrupt stack (cpu related) - * - the synchronous kernel stack (process related) - * The stack trace can start at any of the three stack and can potentially - * touch all of them. The order is: panic stack, async stack, sync stack. - */ -static unsigned long -__show_trace(unsigned long sp, unsigned long low, unsigned long high) -{ - struct stack_frame *sf; - struct pt_regs *regs; - - while (1) { - sp = sp & PSW_ADDR_INSN; - if (sp < low || sp > high - sizeof(*sf)) - return sp; - sf = (struct stack_frame *) sp; - printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); - print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); - /* Follow the backchain. */ - while (1) { - low = sp; - sp = sf->back_chain & PSW_ADDR_INSN; - if (!sp) - break; - if (sp <= low || sp > high - sizeof(*sf)) - return sp; - sf = (struct stack_frame *) sp; - printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); - print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); - } - /* Zero backchain detected, check for interrupt frame. */ - sp = (unsigned long) (sf + 1); - if (sp <= low || sp > high - sizeof(*regs)) - return sp; - regs = (struct pt_regs *) sp; - printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); - print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); - low = sp; - sp = regs->gprs[15]; - } -} - -static void show_trace(struct task_struct *task, unsigned long *stack) -{ - register unsigned long __r15 asm ("15"); - unsigned long sp; - - sp = (unsigned long) stack; - if (!sp) - sp = task ? task->thread.ksp : __r15; - printk("Call Trace:\n"); -#ifdef CONFIG_CHECK_STACK - sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, - S390_lowcore.panic_stack); -#endif - sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, - S390_lowcore.async_stack); - if (task) - __show_trace(sp, (unsigned long) task_stack_page(task), - (unsigned long) task_stack_page(task) + THREAD_SIZE); - else - __show_trace(sp, S390_lowcore.thread_info, - S390_lowcore.thread_info + THREAD_SIZE); - if (!task) - task = current; - debug_show_held_locks(task); -} - -void show_stack(struct task_struct *task, unsigned long *sp) -{ - register unsigned long *__r15 asm ("15"); - unsigned long *stack; - int i; - - if (!sp) - stack = task ? (unsigned long *) task->thread.ksp : __r15; - else - stack = sp; - - for (i = 0; i < kstack_depth_to_print; i++) { - if (((addr_t) stack & (THREAD_SIZE-1)) == 0) - break; - if ((i * sizeof(long) % 32) == 0) - printk("%s ", i == 0 ? "" : "\n"); - printk(LONG, *stack++); - } - printk("\n"); - show_trace(task, sp); -} - -static void show_last_breaking_event(struct pt_regs *regs) -{ -#ifdef CONFIG_64BIT - printk("Last Breaking-Event-Address:\n"); - printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); - print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); -#endif -} - -/* - * The architecture-independent dump_stack generator - */ -void dump_stack(void) -{ - printk("CPU: %d %s %s %.*s\n", - task_thread_info(current)->cpu, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); - printk("Process %s (pid: %d, task: %p, ksp: %p)\n", - current->comm, current->pid, current, - (void *) current->thread.ksp); - show_stack(NULL, NULL); -} -EXPORT_SYMBOL(dump_stack); - -static inline int mask_bits(struct pt_regs *regs, unsigned long bits) -{ - return (regs->psw.mask & bits) / ((~bits + 1) & bits); -} - -void show_registers(struct pt_regs *regs) -{ - char *mode; - - mode = user_mode(regs) ? "User" : "Krnl"; - printk("%s PSW : %p %p", - mode, (void *) regs->psw.mask, - (void *) regs->psw.addr); - print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); - printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " - "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), - mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), - mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY), - mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT), - mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC), - mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM)); -#ifdef CONFIG_64BIT - printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA)); -#endif - printk("\n%s GPRS: " FOURLONG, mode, - regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); - printk(" " FOURLONG, - regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); - printk(" " FOURLONG, - regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]); - printk(" " FOURLONG, - regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); - show_code(regs); -} - -void show_regs(struct pt_regs *regs) -{ - printk("CPU: %d %s %s %.*s\n", - task_thread_info(current)->cpu, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); - printk("Process %s (pid: %d, task: %p, ksp: %p)\n", - current->comm, current->pid, current, - (void *) current->thread.ksp); - show_registers(regs); - /* Show stack backtrace if pt_regs is from kernel mode */ - if (!user_mode(regs)) - show_trace(NULL, (unsigned long *) regs->gprs[15]); - show_last_breaking_event(regs); -} - -static DEFINE_SPINLOCK(die_lock); - -void die(struct pt_regs *regs, const char *str) -{ - static int die_counter; - - oops_enter(); - lgr_info_log(); - debug_stop_all(); - console_verbose(); - spin_lock_irq(&die_lock); - bust_spinlocks(1); - printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); -#ifdef CONFIG_PREEMPT - printk("PREEMPT "); -#endif -#ifdef CONFIG_SMP - printk("SMP "); -#endif -#ifdef CONFIG_DEBUG_PAGEALLOC - printk("DEBUG_PAGEALLOC"); -#endif - printk("\n"); - notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); - print_modules(); - show_regs(regs); - bust_spinlocks(0); - add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - spin_unlock_irq(&die_lock); - if (in_interrupt()) - panic("Fatal exception in interrupt"); - if (panic_on_oops) - panic("Fatal exception: panic_on_oops"); - oops_exit(); - do_exit(SIGSEGV); -} diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S index 4d5e6f8a7978..94feff7d6132 100644 --- a/trunk/arch/s390/kernel/entry.S +++ b/trunk/arch/s390/kernel/entry.S @@ -45,7 +45,6 @@ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SIZE = 1 << STACK_SHIFT -STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE #define BASED(name) name-system_call(%r13) @@ -98,10 +97,10 @@ STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE sra %r14,\shift jnz 1f CHECK_STACK 1<<\shift,\savearea - ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j 2f 1: l %r15,\stack # load target stack -2: la %r11,STACK_FRAME_OVERHEAD(%r15) +2: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) + la %r11,STACK_FRAME_OVERHEAD(%r15) .endm .macro ADD64 high,low,timer @@ -151,7 +150,7 @@ ENTRY(__switch_to) l %r4,__THREAD_info(%r2) # get thread_info of prev l %r5,__THREAD_info(%r3) # get thread_info of next lr %r15,%r5 - ahi %r15,STACK_INIT # end of kernel stack of next + ahi %r15,STACK_SIZE # end of kernel stack of next st %r3,__LC_CURRENT # store task struct of next st %r5,__LC_THREAD_INFO # store thread info of next st %r15,__LC_KERNEL_STACK # store end of kernel stack @@ -179,6 +178,7 @@ sysc_stm: l %r13,__LC_SVC_NEW_PSW+4 sysc_per: l %r15,__LC_KERNEL_STACK + ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs sysc_vtime: UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER @@ -188,7 +188,6 @@ sysc_vtime: mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC sysc_do_svc: oi __TI_flags+3(%r12),_TIF_SYSCALL - l %r10,__TI_sysc_table(%r12) # 31 bit system call table lh %r8,__PT_INT_CODE+2(%r11) sla %r8,2 # shift and test for svc0 jnz sysc_nr_ok @@ -199,6 +198,7 @@ sysc_do_svc: lr %r8,%r1 sla %r8,2 sysc_nr_ok: + l %r10,BASED(.Lsys_call_table) # 31 bit system call table xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) st %r2,__PT_ORIG_GPR2(%r11) st %r7,STACK_FRAME_OVERHEAD(%r15) @@ -359,11 +359,11 @@ ENTRY(pgm_check_handler) tm __LC_PGM_ILC+3,0x80 # check for per exception jnz pgm_svcper # -> single stepped svc 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC - ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j 2f 1: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER l %r15,__LC_KERNEL_STACK -2: la %r11,STACK_FRAME_OVERHEAD(%r15) +2: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) + la %r11,STACK_FRAME_OVERHEAD(%r15) stm %r0,%r7,__PT_R0(%r11) mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC stm %r8,%r9,__PT_PSW(%r11) @@ -485,6 +485,7 @@ io_work: # io_work_user: l %r1,__LC_KERNEL_STACK + ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) la %r11,STACK_FRAME_OVERHEAD(%r1) @@ -645,6 +646,7 @@ mcck_skip: tm __PT_PSW+1(%r11),0x01 # returning to user ? jno mcck_return l %r1,__LC_KERNEL_STACK # switch to kernel stack + ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) la %r11,STACK_FRAME_OVERHEAD(%r15) @@ -672,7 +674,6 @@ mcck_panic: sra %r14,PAGE_SHIFT jz 0f l %r15,__LC_PANIC_STACK - j mcck_skip 0: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j mcck_skip @@ -713,10 +714,12 @@ ENTRY(restart_int_handler) */ stack_overflow: l %r15,__LC_PANIC_STACK # change to panic stack - la %r11,STACK_FRAME_OVERHEAD(%r15) - stm %r0,%r7,__PT_R0(%r11) - stm %r8,%r9,__PT_PSW(%r11) + ahi %r15,-__PT_SIZE # create pt_regs + stm %r0,%r7,__PT_R0(%r15) + stm %r8,%r9,__PT_PSW(%r15) mvc __PT_R8(32,%r11),0(%r14) + lr %r15,%r11 + ahi %r15,-STACK_FRAME_OVERHEAD l %r1,BASED(1f) xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) lr %r2,%r11 # pass pointer to pt_regs @@ -796,14 +799,15 @@ cleanup_system_call: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER # set up saved register 11 l %r15,__LC_KERNEL_STACK - la %r9,STACK_FRAME_OVERHEAD(%r15) - st %r9,12(%r11) # r11 pt_regs pointer + ahi %r15,-__PT_SIZE + st %r15,12(%r11) # r11 pt_regs pointer # fill pt_regs - mvc __PT_R8(32,%r9),__LC_SAVE_AREA_SYNC - stm %r0,%r7,__PT_R0(%r9) - mvc __PT_PSW(8,%r9),__LC_SVC_OLD_PSW - mvc __PT_INT_CODE(4,%r9),__LC_SVC_ILC + mvc __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC + stm %r0,%r7,__PT_R0(%r15) + mvc __PT_PSW(8,%r15),__LC_SVC_OLD_PSW + mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC # setup saved register 15 + ahi %r15,-STACK_FRAME_OVERHEAD st %r15,28(%r11) # r15 stack pointer # set new psw address and exit l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000 @@ -906,6 +910,7 @@ cleanup_idle_wait: .Ltrace_enter: .long do_syscall_trace_enter .Ltrace_exit: .long do_syscall_trace_exit .Lschedule_tail: .long schedule_tail +.Lsys_call_table: .long sys_call_table .Lsysc_per: .long sysc_per + 0x80000000 #ifdef CONFIG_TRACE_IRQFLAGS .Lhardirqs_on: .long trace_hardirqs_on_caller diff --git a/trunk/arch/s390/kernel/entry.h b/trunk/arch/s390/kernel/entry.h index aa0ab02e9595..c3a736a3ed44 100644 --- a/trunk/arch/s390/kernel/entry.h +++ b/trunk/arch/s390/kernel/entry.h @@ -7,7 +7,6 @@ #include extern void *restart_stack; -extern unsigned long suspend_zero_pages; void system_call(void); void pgm_check_handler(void); diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S index 4c17eece707e..2e6d60c55f90 100644 --- a/trunk/arch/s390/kernel/entry64.S +++ b/trunk/arch/s390/kernel/entry64.S @@ -39,7 +39,6 @@ __PT_R15 = __PT_GPRS + 120 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SIZE = 1 << STACK_SHIFT -STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_MCCK_PENDING | _TIF_PER_TRAP ) @@ -125,10 +124,10 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) srag %r14,%r14,\shift jnz 1f CHECK_STACK 1<<\shift,\savearea - aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j 2f 1: lg %r15,\stack # load target stack -2: la %r11,STACK_FRAME_OVERHEAD(%r15) +2: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) + la %r11,STACK_FRAME_OVERHEAD(%r15) .endm .macro UPDATE_VTIME scratch,enter_timer @@ -178,7 +177,7 @@ ENTRY(__switch_to) lg %r4,__THREAD_info(%r2) # get thread_info of prev lg %r5,__THREAD_info(%r3) # get thread_info of next lgr %r15,%r5 - aghi %r15,STACK_INIT # end of kernel stack of next + aghi %r15,STACK_SIZE # end of kernel stack of next stg %r3,__LC_CURRENT # store task struct of next stg %r5,__LC_THREAD_INFO # store thread info of next stg %r15,__LC_KERNEL_STACK # store end of kernel stack @@ -204,8 +203,10 @@ sysc_stmg: stmg %r8,%r15,__LC_SAVE_AREA_SYNC lg %r10,__LC_LAST_BREAK lg %r12,__LC_THREAD_INFO + larl %r13,system_call sysc_per: lg %r15,__LC_KERNEL_STACK + aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs sysc_vtime: UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER @@ -216,7 +217,6 @@ sysc_vtime: mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC sysc_do_svc: oi __TI_flags+7(%r12),_TIF_SYSCALL - lg %r10,__TI_sysc_table(%r12) # address of system call table llgh %r8,__PT_INT_CODE+2(%r11) slag %r8,%r8,2 # shift and test for svc 0 jnz sysc_nr_ok @@ -227,6 +227,13 @@ sysc_do_svc: sth %r1,__PT_INT_CODE+2(%r11) slag %r8,%r1,2 sysc_nr_ok: + larl %r10,sys_call_table # 64 bit system call table +#ifdef CONFIG_COMPAT + tm __TI_flags+5(%r12),(_TIF_31BIT>>16) + jno sysc_noemu + larl %r10,sys_call_table_emu # 31 bit system call table +sysc_noemu: +#endif xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) stg %r2,__PT_ORIG_GPR2(%r11) stg %r7,STACK_FRAME_OVERHEAD(%r15) @@ -382,7 +389,6 @@ ENTRY(pgm_check_handler) tm __LC_PGM_ILC+3,0x80 # check for per exception jnz pgm_svcper # -> single stepped svc 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC - aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) j 2f 1: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER LAST_BREAK %r14 @@ -392,7 +398,8 @@ ENTRY(pgm_check_handler) tm __LC_PGM_ILC+2,0x02 # check for transaction abort jz 2f mvc __THREAD_trap_tdb(256,%r14),0(%r13) -2: la %r11,STACK_FRAME_OVERHEAD(%r15) +2: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) + la %r11,STACK_FRAME_OVERHEAD(%r15) stmg %r0,%r7,__PT_R0(%r11) mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC stmg %r8,%r9,__PT_PSW(%r11) @@ -519,6 +526,7 @@ io_work: # io_work_user: lg %r1,__LC_KERNEL_STACK + aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) la %r11,STACK_FRAME_OVERHEAD(%r1) @@ -680,6 +688,7 @@ mcck_skip: tm __PT_PSW+1(%r11),0x01 # returning to user ? jno mcck_return lg %r1,__LC_KERNEL_STACK # switch to kernel stack + aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) la %r11,STACK_FRAME_OVERHEAD(%r1) @@ -746,12 +755,14 @@ ENTRY(restart_int_handler) * Setup a pt_regs so that show_trace can provide a good call trace. */ stack_overflow: - lg %r15,__LC_PANIC_STACK # change to panic stack - la %r11,STACK_FRAME_OVERHEAD(%r15) + lg %r11,__LC_PANIC_STACK # change to panic stack + aghi %r11,-__PT_SIZE # create pt_regs stmg %r0,%r7,__PT_R0(%r11) stmg %r8,%r9,__PT_PSW(%r11) mvc __PT_R8(64,%r11),0(%r14) stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 + lgr %r15,%r11 + aghi %r15,-STACK_FRAME_OVERHEAD xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) lgr %r2,%r11 # pass pointer to pt_regs jg kernel_stack_overflow @@ -835,14 +846,15 @@ cleanup_system_call: mvc __TI_last_break(8,%r12),16(%r11) 0: # set up saved register r11 lg %r15,__LC_KERNEL_STACK - la %r9,STACK_FRAME_OVERHEAD(%r15) - stg %r9,24(%r11) # r11 pt_regs pointer + aghi %r15,-__PT_SIZE + stg %r15,24(%r11) # r11 pt_regs pointer # fill pt_regs - mvc __PT_R8(64,%r9),__LC_SAVE_AREA_SYNC - stmg %r0,%r7,__PT_R0(%r9) - mvc __PT_PSW(16,%r9),__LC_SVC_OLD_PSW - mvc __PT_INT_CODE(4,%r9),__LC_SVC_ILC + mvc __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC + stmg %r0,%r7,__PT_R0(%r15) + mvc __PT_PSW(16,%r15),__LC_SVC_OLD_PSW + mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC # setup saved register r15 + aghi %r15,-STACK_FRAME_OVERHEAD stg %r15,56(%r11) # r15 stack pointer # set new psw address and exit larl %r9,sysc_do_svc @@ -999,7 +1011,6 @@ sys_call_table: #ifdef CONFIG_COMPAT #define SYSCALL(esa,esame,emu) .long emu - .globl sys_call_table_emu sys_call_table_emu: #include "syscalls.S" #undef SYSCALL diff --git a/trunk/arch/s390/kernel/machine_kexec.c b/trunk/arch/s390/kernel/machine_kexec.c index ac2178161ec3..b3de27700016 100644 --- a/trunk/arch/s390/kernel/machine_kexec.c +++ b/trunk/arch/s390/kernel/machine_kexec.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -68,35 +67,6 @@ void setup_regs(void) memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area)); } -/* - * PM notifier callback for kdump - */ -static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, - void *ptr) -{ - switch (action) { - case PM_SUSPEND_PREPARE: - case PM_HIBERNATION_PREPARE: - if (crashk_res.start) - crash_map_reserved_pages(); - break; - case PM_POST_SUSPEND: - case PM_POST_HIBERNATION: - if (crashk_res.start) - crash_unmap_reserved_pages(); - break; - default: - return NOTIFY_DONE; - } - return NOTIFY_OK; -} - -static int __init machine_kdump_pm_init(void) -{ - pm_notifier(machine_kdump_pm_cb, 0); - return 0; -} -arch_initcall(machine_kdump_pm_init); #endif /* diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 0f419c5765c8..29268859d8ee 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -377,14 +377,11 @@ static void __init setup_lowcore(void) PSW_MASK_DAT | PSW_MASK_MCHECK; lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; lc->clock_comparator = -1ULL; - lc->kernel_stack = ((unsigned long) &init_thread_union) - + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; lc->async_stack = (unsigned long) - __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) - + ASYNC_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; lc->panic_stack = (unsigned long) - __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) - + PAGE_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; lc->current_task = (unsigned long) init_thread_union.thread_info.task; lc->thread_info = (unsigned long) &init_thread_union; lc->machine_flags = S390_lowcore.machine_flags; diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 8bde89eafd88..549c9d173c0f 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -181,10 +181,8 @@ static int __cpuinit pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) lc = pcpu->lowcore; memcpy(lc, &S390_lowcore, 512); memset((char *) lc + 512, 0, sizeof(*lc) - 512); - lc->async_stack = pcpu->async_stack + ASYNC_SIZE - - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); - lc->panic_stack = pcpu->panic_stack + PAGE_SIZE - - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + lc->async_stack = pcpu->async_stack + ASYNC_SIZE; + lc->panic_stack = pcpu->panic_stack + PAGE_SIZE; lc->cpu_nr = cpu; #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) { @@ -255,8 +253,7 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) struct _lowcore *lc = pcpu->lowcore; struct thread_info *ti = task_thread_info(tsk); - lc->kernel_stack = (unsigned long) task_stack_page(tsk) - + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); + lc->kernel_stack = (unsigned long) task_stack_page(tsk) + THREAD_SIZE; lc->thread_info = (unsigned long) task_thread_info(tsk); lc->current_task = (unsigned long) tsk; lc->user_timer = ti->user_timer; @@ -813,10 +810,8 @@ void __init smp_prepare_boot_cpu(void) pcpu->state = CPU_STATE_CONFIGURED; pcpu->address = boot_cpu_address; pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); - pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE - + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); - pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE - + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); + pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE; + pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE; S390_lowcore.percpu_offset = __per_cpu_offset[0]; smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); set_cpu_present(0, true); diff --git a/trunk/arch/s390/kernel/suspend.c b/trunk/arch/s390/kernel/suspend.c index c479d2f9605b..aa1494d0e380 100644 --- a/trunk/arch/s390/kernel/suspend.c +++ b/trunk/arch/s390/kernel/suspend.c @@ -41,7 +41,6 @@ struct page_key_data { static struct page_key_data *page_key_data; static struct page_key_data *page_key_rp, *page_key_wp; static unsigned long page_key_rx, page_key_wx; -unsigned long suspend_zero_pages; /* * For each page in the hibernation image one additional byte is @@ -150,36 +149,6 @@ int pfn_is_nosave(unsigned long pfn) return 0; } -/* - * PM notifier callback for suspend - */ -static int suspend_pm_cb(struct notifier_block *nb, unsigned long action, - void *ptr) -{ - switch (action) { - case PM_SUSPEND_PREPARE: - case PM_HIBERNATION_PREPARE: - suspend_zero_pages = __get_free_pages(GFP_KERNEL, LC_ORDER); - if (!suspend_zero_pages) - return NOTIFY_BAD; - break; - case PM_POST_SUSPEND: - case PM_POST_HIBERNATION: - free_pages(suspend_zero_pages, LC_ORDER); - break; - default: - return NOTIFY_DONE; - } - return NOTIFY_OK; -} - -static int __init suspend_pm_init(void) -{ - pm_notifier(suspend_pm_cb, 0); - return 0; -} -arch_initcall(suspend_pm_init); - void save_processor_state(void) { /* swsusp_arch_suspend() actually saves all cpu register contents. diff --git a/trunk/arch/s390/kernel/swsusp_asm64.S b/trunk/arch/s390/kernel/swsusp_asm64.S index c487be4cfc81..d4ca4e0617b5 100644 --- a/trunk/arch/s390/kernel/swsusp_asm64.S +++ b/trunk/arch/s390/kernel/swsusp_asm64.S @@ -36,8 +36,8 @@ ENTRY(swsusp_arch_suspend) /* Store prefix register on stack */ stpx __SF_EMPTY(%r15) - /* Save prefix register contents for lowcore copy */ - llgf %r10,__SF_EMPTY(%r15) + /* Save prefix register contents for lowcore */ + llgf %r4,__SF_EMPTY(%r15) /* Get pointer to save area */ lghi %r1,0x1000 @@ -91,18 +91,7 @@ ENTRY(swsusp_arch_suspend) xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) spx __SF_EMPTY(%r15) - /* Save absolute zero pages */ - larl %r2,suspend_zero_pages - lg %r2,0(%r2) - lghi %r4,0 - lghi %r3,2*PAGE_SIZE - lghi %r5,2*PAGE_SIZE -1: mvcle %r2,%r4,0 - jo 1b - - /* Copy lowcore to absolute zero lowcore */ lghi %r2,0 - lgr %r4,%r10 lghi %r3,2*PAGE_SIZE lghi %r5,2*PAGE_SIZE 1: mvcle %r2,%r4,0 @@ -259,20 +248,8 @@ restore_registers: /* Load old stack */ lg %r15,0x2f8(%r13) - /* Save prefix register */ - mvc __SF_EMPTY(4,%r15),0x318(%r13) - - /* Restore absolute zero pages */ - lghi %r2,0 - larl %r4,suspend_zero_pages - lg %r4,0(%r4) - lghi %r3,2*PAGE_SIZE - lghi %r5,2*PAGE_SIZE -1: mvcle %r2,%r4,0 - jo 1b - /* Restore prefix register */ - spx __SF_EMPTY(%r15) + spx 0x318(%r13) /* Activate DAT */ stosm __SF_EMPTY(%r15),0x04 diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c index c5762324d9ee..13dd63fba367 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -12,16 +12,49 @@ * 'Traps.c' handles hardware traps and faults after we have saved some * state in 'asm.s'. */ -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "entry.h" int show_unhandled_signals = 1; +#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) + +#ifndef CONFIG_64BIT +#define LONG "%08lx " +#define FOURLONG "%08lx %08lx %08lx %08lx\n" +static int kstack_depth_to_print = 12; +#else /* CONFIG_64BIT */ +#define LONG "%016lx " +#define FOURLONG "%016lx %016lx %016lx %016lx\n" +static int kstack_depth_to_print = 20; +#endif /* CONFIG_64BIT */ + static inline void __user *get_trap_ip(struct pt_regs *regs) { #ifdef CONFIG_64BIT @@ -39,6 +72,215 @@ static inline void __user *get_trap_ip(struct pt_regs *regs) #endif } +/* + * For show_trace we have tree different stack to consider: + * - the panic stack which is used if the kernel stack has overflown + * - the asynchronous interrupt stack (cpu related) + * - the synchronous kernel stack (process related) + * The stack trace can start at any of the three stack and can potentially + * touch all of them. The order is: panic stack, async stack, sync stack. + */ +static unsigned long +__show_trace(unsigned long sp, unsigned long low, unsigned long high) +{ + struct stack_frame *sf; + struct pt_regs *regs; + + while (1) { + sp = sp & PSW_ADDR_INSN; + if (sp < low || sp > high - sizeof(*sf)) + return sp; + sf = (struct stack_frame *) sp; + printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); + print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); + /* Follow the backchain. */ + while (1) { + low = sp; + sp = sf->back_chain & PSW_ADDR_INSN; + if (!sp) + break; + if (sp <= low || sp > high - sizeof(*sf)) + return sp; + sf = (struct stack_frame *) sp; + printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); + print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); + } + /* Zero backchain detected, check for interrupt frame. */ + sp = (unsigned long) (sf + 1); + if (sp <= low || sp > high - sizeof(*regs)) + return sp; + regs = (struct pt_regs *) sp; + printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); + print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); + low = sp; + sp = regs->gprs[15]; + } +} + +static void show_trace(struct task_struct *task, unsigned long *stack) +{ + register unsigned long __r15 asm ("15"); + unsigned long sp; + + sp = (unsigned long) stack; + if (!sp) + sp = task ? task->thread.ksp : __r15; + printk("Call Trace:\n"); +#ifdef CONFIG_CHECK_STACK + sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, + S390_lowcore.panic_stack); +#endif + sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, + S390_lowcore.async_stack); + if (task) + __show_trace(sp, (unsigned long) task_stack_page(task), + (unsigned long) task_stack_page(task) + THREAD_SIZE); + else + __show_trace(sp, S390_lowcore.thread_info, + S390_lowcore.thread_info + THREAD_SIZE); + if (!task) + task = current; + debug_show_held_locks(task); +} + +void show_stack(struct task_struct *task, unsigned long *sp) +{ + register unsigned long * __r15 asm ("15"); + unsigned long *stack; + int i; + + if (!sp) + stack = task ? (unsigned long *) task->thread.ksp : __r15; + else + stack = sp; + + for (i = 0; i < kstack_depth_to_print; i++) { + if (((addr_t) stack & (THREAD_SIZE-1)) == 0) + break; + if ((i * sizeof(long) % 32) == 0) + printk("%s ", i == 0 ? "" : "\n"); + printk(LONG, *stack++); + } + printk("\n"); + show_trace(task, sp); +} + +static void show_last_breaking_event(struct pt_regs *regs) +{ +#ifdef CONFIG_64BIT + printk("Last Breaking-Event-Address:\n"); + printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); + print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); +#endif +} + +/* + * The architecture-independent dump_stack generator + */ +void dump_stack(void) +{ + printk("CPU: %d %s %s %.*s\n", + task_thread_info(current)->cpu, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + printk("Process %s (pid: %d, task: %p, ksp: %p)\n", + current->comm, current->pid, current, + (void *) current->thread.ksp); + show_stack(NULL, NULL); +} +EXPORT_SYMBOL(dump_stack); + +static inline int mask_bits(struct pt_regs *regs, unsigned long bits) +{ + return (regs->psw.mask & bits) / ((~bits + 1) & bits); +} + +void show_registers(struct pt_regs *regs) +{ + char *mode; + + mode = user_mode(regs) ? "User" : "Krnl"; + printk("%s PSW : %p %p", + mode, (void *) regs->psw.mask, + (void *) regs->psw.addr); + print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); + printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " + "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), + mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), + mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY), + mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT), + mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC), + mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM)); +#ifdef CONFIG_64BIT + printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA)); +#endif + printk("\n%s GPRS: " FOURLONG, mode, + regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); + printk(" " FOURLONG, + regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); + printk(" " FOURLONG, + regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]); + printk(" " FOURLONG, + regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); + + show_code(regs); +} + +void show_regs(struct pt_regs *regs) +{ + printk("CPU: %d %s %s %.*s\n", + task_thread_info(current)->cpu, print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), + init_utsname()->version); + printk("Process %s (pid: %d, task: %p, ksp: %p)\n", + current->comm, current->pid, current, + (void *) current->thread.ksp); + show_registers(regs); + /* Show stack backtrace if pt_regs is from kernel mode */ + if (!user_mode(regs)) + show_trace(NULL, (unsigned long *) regs->gprs[15]); + show_last_breaking_event(regs); +} + +static DEFINE_SPINLOCK(die_lock); + +void die(struct pt_regs *regs, const char *str) +{ + static int die_counter; + + oops_enter(); + lgr_info_log(); + debug_stop_all(); + console_verbose(); + spin_lock_irq(&die_lock); + bust_spinlocks(1); + printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); +#ifdef CONFIG_PREEMPT + printk("PREEMPT "); +#endif +#ifdef CONFIG_SMP + printk("SMP "); +#endif +#ifdef CONFIG_DEBUG_PAGEALLOC + printk("DEBUG_PAGEALLOC"); +#endif + printk("\n"); + notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); + print_modules(); + show_regs(regs); + bust_spinlocks(0); + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); + spin_unlock_irq(&die_lock); + if (in_interrupt()) + panic("Fatal exception in interrupt"); + if (panic_on_oops) + panic("Fatal exception: panic_on_oops"); + oops_exit(); + do_exit(SIGSEGV); +} + static inline void report_user_fault(struct pt_regs *regs, int signr) { if ((task_pid_nr(current) > 1) && !show_unhandled_signals) diff --git a/trunk/arch/s390/kvm/trace.h b/trunk/arch/s390/kvm/trace.h index 53252d2d4720..2b29e62351d3 100644 --- a/trunk/arch/s390/kvm/trace.h +++ b/trunk/arch/s390/kvm/trace.h @@ -117,7 +117,7 @@ TRACE_EVENT(kvm_s390_intercept_instruction, __entry->instruction, insn_to_mnemonic((unsigned char *) &__entry->instruction, - __entry->insn, sizeof(__entry->insn)) ? + __entry->insn) ? "unknown" : __entry->insn) ); diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c index 466fb3383960..dff631d34b45 100644 --- a/trunk/arch/s390/lib/uaccess_pt.c +++ b/trunk/arch/s390/lib/uaccess_pt.c @@ -77,68 +77,41 @@ static size_t copy_in_kernel(size_t count, void __user *to, * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address * contains the (negative) exception code. */ -#ifdef CONFIG_64BIT -static unsigned long follow_table(struct mm_struct *mm, - unsigned long address, int write) +static __always_inline unsigned long follow_table(struct mm_struct *mm, + unsigned long addr, int write) { - unsigned long *table = (unsigned long *)__pa(mm->pgd); - - switch (mm->context.asce_bits & _ASCE_TYPE_MASK) { - case _ASCE_TYPE_REGION1: - table = table + ((address >> 53) & 0x7ff); - if (unlikely(*table & _REGION_ENTRY_INV)) - return -0x39UL; - table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - case _ASCE_TYPE_REGION2: - table = table + ((address >> 42) & 0x7ff); - if (unlikely(*table & _REGION_ENTRY_INV)) - return -0x3aUL; - table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - case _ASCE_TYPE_REGION3: - table = table + ((address >> 31) & 0x7ff); - if (unlikely(*table & _REGION_ENTRY_INV)) - return -0x3bUL; - table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); - case _ASCE_TYPE_SEGMENT: - table = table + ((address >> 20) & 0x7ff); - if (unlikely(*table & _SEGMENT_ENTRY_INV)) - return -0x10UL; - if (unlikely(*table & _SEGMENT_ENTRY_LARGE)) { - if (write && (*table & _SEGMENT_ENTRY_RO)) - return -0x04UL; - return (*table & _SEGMENT_ENTRY_ORIGIN_LARGE) + - (address & ~_SEGMENT_ENTRY_ORIGIN_LARGE); - } - table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); - } - table = table + ((address >> 12) & 0xff); - if (unlikely(*table & _PAGE_INVALID)) - return -0x11UL; - if (write && (*table & _PAGE_RO)) - return -0x04UL; - return (*table & PAGE_MASK) + (address & ~PAGE_MASK); -} + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *ptep; -#else /* CONFIG_64BIT */ + pgd = pgd_offset(mm, addr); + if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) + return -0x3aUL; -static unsigned long follow_table(struct mm_struct *mm, - unsigned long address, int write) -{ - unsigned long *table = (unsigned long *)__pa(mm->pgd); + pud = pud_offset(pgd, addr); + if (pud_none(*pud) || unlikely(pud_bad(*pud))) + return -0x3bUL; - table = table + ((address >> 20) & 0x7ff); - if (unlikely(*table & _SEGMENT_ENTRY_INV)) + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) return -0x10UL; - table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); - table = table + ((address >> 12) & 0xff); - if (unlikely(*table & _PAGE_INVALID)) + if (pmd_large(*pmd)) { + if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) + return -0x04UL; + return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); + } + if (unlikely(pmd_bad(*pmd))) + return -0x10UL; + + ptep = pte_offset_map(pmd, addr); + if (!pte_present(*ptep)) return -0x11UL; - if (write && (*table & _PAGE_RO)) + if (write && (!pte_write(*ptep) || !pte_dirty(*ptep))) return -0x04UL; - return (*table & PAGE_MASK) + (address & ~PAGE_MASK); -} -#endif /* CONFIG_64BIT */ + return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK); +} static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, size_t n, int write_user) @@ -224,7 +197,7 @@ size_t copy_to_user_pt(size_t n, void __user *to, const void *from) static size_t clear_user_pt(size_t n, void __user *to) { - void *zpage = (void *) empty_zero_page; + void *zpage = &empty_zero_page; long done, size, ret; done = 0; diff --git a/trunk/arch/s390/mm/cmm.c b/trunk/arch/s390/mm/cmm.c index 9d84a1feefef..479e94282910 100644 --- a/trunk/arch/s390/mm/cmm.c +++ b/trunk/arch/s390/mm/cmm.c @@ -458,10 +458,12 @@ static int __init cmm_init(void) if (rc) goto out_pm; cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); - if (!IS_ERR(cmm_thread_ptr)) - return 0; + rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0; + if (rc) + goto out_kthread; + return 0; - rc = PTR_ERR(cmm_thread_ptr); +out_kthread: unregister_pm_notifier(&cmm_power_notifier); out_pm: unregister_oom_notifier(&cmm_oom_nb); diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 047c3e4c59a2..2fb9e63b8fc4 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -395,13 +395,8 @@ void __kprobes do_protection_exception(struct pt_regs *regs) int fault; trans_exc_code = regs->int_parm_long; - /* - * Protection exceptions are suppressing, decrement psw address. - * The exception to this rule are aborted transactions, for these - * the PSW already points to the correct location. - */ - if (!(regs->int_code & 0x200)) - regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); + /* Protection exception is suppressing, decrement psw address. */ + regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); /* * Check for low-address protection. This needs to be treated * as a special case because the translation exception code diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index 9f9c315b4c07..49ce6bb2c641 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -63,18 +63,10 @@ static unsigned long __init setup_zero_pages(void) break; case 0x2097: /* z10 */ case 0x2098: /* z10 */ - case 0x2817: /* z196 */ - case 0x2818: /* z196 */ - order = 2; - break; - case 0x2827: /* zEC12 */ default: - order = 5; + order = 2; break; } - /* Limit number of empty zero pages for small memory sizes */ - if (order > 2 && totalram_pages <= 16384) - order = 2; empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); if (!empty_zero_page) diff --git a/trunk/arch/s390/mm/pageattr.c b/trunk/arch/s390/mm/pageattr.c index 80adfbf75065..d21040ed5e59 100644 --- a/trunk/arch/s390/mm/pageattr.c +++ b/trunk/arch/s390/mm/pageattr.c @@ -9,25 +9,31 @@ #include #include -static inline unsigned long sske_frame(unsigned long addr, unsigned char skey) -{ - asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],9,0" - : [addr] "+a" (addr) : [skey] "d" (skey)); - return addr; -} - void storage_key_init_range(unsigned long start, unsigned long end) { - unsigned long boundary, size; + unsigned long boundary, function, size; while (start < end) { + if (MACHINE_HAS_EDAT2) { + /* set storage keys for a 2GB frame */ + function = 0x22000 | PAGE_DEFAULT_KEY; + size = 1UL << 31; + boundary = (start + size) & ~(size - 1); + if (boundary <= end) { + do { + start = pfmf(function, start); + } while (start < boundary); + continue; + } + } if (MACHINE_HAS_EDAT1) { /* set storage keys for a 1MB frame */ + function = 0x21000 | PAGE_DEFAULT_KEY; size = 1UL << 20; boundary = (start + size) & ~(size - 1); if (boundary <= end) { do { - start = sske_frame(start, PAGE_DEFAULT_KEY); + start = pfmf(function, start); } while (start < boundary); continue; } diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index bd954e96f51c..ae44d2a34313 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -379,183 +379,75 @@ int gmap_map_segment(struct gmap *gmap, unsigned long from, } EXPORT_SYMBOL_GPL(gmap_map_segment); -static unsigned long *gmap_table_walk(unsigned long address, struct gmap *gmap) +/* + * this function is assumed to be called with mmap_sem held + */ +unsigned long __gmap_fault(unsigned long address, struct gmap *gmap) { - unsigned long *table; + unsigned long *table, vmaddr, segment; + struct mm_struct *mm; + struct gmap_pgtable *mp; + struct gmap_rmap *rmap; + struct vm_area_struct *vma; + struct page *page; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + current->thread.gmap_addr = address; + mm = gmap->mm; + /* Walk the gmap address space page table */ table = gmap->table + ((address >> 53) & 0x7ff); if (unlikely(*table & _REGION_ENTRY_INV)) - return ERR_PTR(-EFAULT); + return -EFAULT; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); table = table + ((address >> 42) & 0x7ff); if (unlikely(*table & _REGION_ENTRY_INV)) - return ERR_PTR(-EFAULT); + return -EFAULT; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); table = table + ((address >> 31) & 0x7ff); if (unlikely(*table & _REGION_ENTRY_INV)) - return ERR_PTR(-EFAULT); + return -EFAULT; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); table = table + ((address >> 20) & 0x7ff); - return table; -} - -/** - * __gmap_translate - translate a guest address to a user space address - * @address: guest address - * @gmap: pointer to guest mapping meta data structure - * - * Returns user space address which corresponds to the guest address or - * -EFAULT if no such mapping exists. - * This function does not establish potentially missing page table entries. - * The mmap_sem of the mm that belongs to the address space must be held - * when this function gets called. - */ -unsigned long __gmap_translate(unsigned long address, struct gmap *gmap) -{ - unsigned long *segment_ptr, vmaddr, segment; - struct gmap_pgtable *mp; - struct page *page; - current->thread.gmap_addr = address; - segment_ptr = gmap_table_walk(address, gmap); - if (IS_ERR(segment_ptr)) - return PTR_ERR(segment_ptr); /* Convert the gmap address to an mm address. */ - segment = *segment_ptr; - if (!(segment & _SEGMENT_ENTRY_INV)) { + segment = *table; + if (likely(!(segment & _SEGMENT_ENTRY_INV))) { page = pfn_to_page(segment >> PAGE_SHIFT); mp = (struct gmap_pgtable *) page->index; return mp->vmaddr | (address & ~PMD_MASK); } else if (segment & _SEGMENT_ENTRY_RO) { vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; - return vmaddr | (address & ~PMD_MASK); - } - return -EFAULT; -} -EXPORT_SYMBOL_GPL(__gmap_translate); - -/** - * gmap_translate - translate a guest address to a user space address - * @address: guest address - * @gmap: pointer to guest mapping meta data structure - * - * Returns user space address which corresponds to the guest address or - * -EFAULT if no such mapping exists. - * This function does not establish potentially missing page table entries. - */ -unsigned long gmap_translate(unsigned long address, struct gmap *gmap) -{ - unsigned long rc; - - down_read(&gmap->mm->mmap_sem); - rc = __gmap_translate(address, gmap); - up_read(&gmap->mm->mmap_sem); - return rc; -} -EXPORT_SYMBOL_GPL(gmap_translate); - -static int gmap_connect_pgtable(unsigned long segment, - unsigned long *segment_ptr, - struct gmap *gmap) -{ - unsigned long vmaddr; - struct vm_area_struct *vma; - struct gmap_pgtable *mp; - struct gmap_rmap *rmap; - struct mm_struct *mm; - struct page *page; - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - - mm = gmap->mm; - vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; - vma = find_vma(mm, vmaddr); - if (!vma || vma->vm_start > vmaddr) - return -EFAULT; - /* Walk the parent mm page table */ - pgd = pgd_offset(mm, vmaddr); - pud = pud_alloc(mm, pgd, vmaddr); - if (!pud) - return -ENOMEM; - pmd = pmd_alloc(mm, pud, vmaddr); - if (!pmd) - return -ENOMEM; - if (!pmd_present(*pmd) && - __pte_alloc(mm, vma, pmd, vmaddr)) - return -ENOMEM; - /* pmd now points to a valid segment table entry. */ - rmap = kmalloc(sizeof(*rmap), GFP_KERNEL|__GFP_REPEAT); - if (!rmap) - return -ENOMEM; - /* Link gmap segment table entry location to page table. */ - page = pmd_page(*pmd); - mp = (struct gmap_pgtable *) page->index; - rmap->entry = segment_ptr; - spin_lock(&mm->page_table_lock); - if (*segment_ptr == segment) { + vma = find_vma(mm, vmaddr); + if (!vma || vma->vm_start > vmaddr) + return -EFAULT; + + /* Walk the parent mm page table */ + pgd = pgd_offset(mm, vmaddr); + pud = pud_alloc(mm, pgd, vmaddr); + if (!pud) + return -ENOMEM; + pmd = pmd_alloc(mm, pud, vmaddr); + if (!pmd) + return -ENOMEM; + if (!pmd_present(*pmd) && + __pte_alloc(mm, vma, pmd, vmaddr)) + return -ENOMEM; + /* pmd now points to a valid segment table entry. */ + rmap = kmalloc(sizeof(*rmap), GFP_KERNEL|__GFP_REPEAT); + if (!rmap) + return -ENOMEM; + /* Link gmap segment table entry location to page table. */ + page = pmd_page(*pmd); + mp = (struct gmap_pgtable *) page->index; + rmap->entry = table; + spin_lock(&mm->page_table_lock); list_add(&rmap->list, &mp->mapper); + spin_unlock(&mm->page_table_lock); /* Set gmap segment table entry to page table. */ - *segment_ptr = pmd_val(*pmd) & PAGE_MASK; - rmap = NULL; - } - spin_unlock(&mm->page_table_lock); - kfree(rmap); - return 0; -} - -static void gmap_disconnect_pgtable(struct mm_struct *mm, unsigned long *table) -{ - struct gmap_rmap *rmap, *next; - struct gmap_pgtable *mp; - struct page *page; - int flush; - - flush = 0; - spin_lock(&mm->page_table_lock); - page = pfn_to_page(__pa(table) >> PAGE_SHIFT); - mp = (struct gmap_pgtable *) page->index; - list_for_each_entry_safe(rmap, next, &mp->mapper, list) { - *rmap->entry = - _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | mp->vmaddr; - list_del(&rmap->list); - kfree(rmap); - flush = 1; - } - spin_unlock(&mm->page_table_lock); - if (flush) - __tlb_flush_global(); -} - -/* - * this function is assumed to be called with mmap_sem held - */ -unsigned long __gmap_fault(unsigned long address, struct gmap *gmap) -{ - unsigned long *segment_ptr, segment; - struct gmap_pgtable *mp; - struct page *page; - int rc; - - current->thread.gmap_addr = address; - segment_ptr = gmap_table_walk(address, gmap); - if (IS_ERR(segment_ptr)) - return -EFAULT; - /* Convert the gmap address to an mm address. */ - while (1) { - segment = *segment_ptr; - if (!(segment & _SEGMENT_ENTRY_INV)) { - /* Page table is present */ - page = pfn_to_page(segment >> PAGE_SHIFT); - mp = (struct gmap_pgtable *) page->index; - return mp->vmaddr | (address & ~PMD_MASK); - } - if (!(segment & _SEGMENT_ENTRY_RO)) - /* Nothing mapped in the gmap address space. */ - break; - rc = gmap_connect_pgtable(segment, segment_ptr, gmap); - if (rc) - return rc; + *table = pmd_val(*pmd) & PAGE_MASK; + return vmaddr | (address & ~PMD_MASK); } return -EFAULT; } @@ -619,6 +511,29 @@ void gmap_discard(unsigned long from, unsigned long to, struct gmap *gmap) } EXPORT_SYMBOL_GPL(gmap_discard); +void gmap_unmap_notifier(struct mm_struct *mm, unsigned long *table) +{ + struct gmap_rmap *rmap, *next; + struct gmap_pgtable *mp; + struct page *page; + int flush; + + flush = 0; + spin_lock(&mm->page_table_lock); + page = pfn_to_page(__pa(table) >> PAGE_SHIFT); + mp = (struct gmap_pgtable *) page->index; + list_for_each_entry_safe(rmap, next, &mp->mapper, list) { + *rmap->entry = + _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | mp->vmaddr; + list_del(&rmap->list); + kfree(rmap); + flush = 1; + } + spin_unlock(&mm->page_table_lock); + if (flush) + __tlb_flush_global(); +} + static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, unsigned long vmaddr) { @@ -671,8 +586,8 @@ static inline void page_table_free_pgste(unsigned long *table) { } -static inline void gmap_disconnect_pgtable(struct mm_struct *mm, - unsigned long *table) +static inline void gmap_unmap_notifier(struct mm_struct *mm, + unsigned long *table) { } @@ -738,7 +653,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) unsigned int bit, mask; if (mm_has_pgste(mm)) { - gmap_disconnect_pgtable(mm, table); + gmap_unmap_notifier(mm, table); return page_table_free_pgste(table); } /* Free 1K/2K page table fragment of a 4K page */ @@ -781,7 +696,7 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table) mm = tlb->mm; if (mm_has_pgste(mm)) { - gmap_disconnect_pgtable(mm, table); + gmap_unmap_notifier(mm, table); table = (unsigned long *) (__pa(table) | FRAG_MASK); tlb_remove_table(tlb, table); return; diff --git a/trunk/arch/s390/net/bpf_jit_comp.c b/trunk/arch/s390/net/bpf_jit_comp.c index 82f165f8078c..0972e91cced2 100644 --- a/trunk/arch/s390/net/bpf_jit_comp.c +++ b/trunk/arch/s390/net/bpf_jit_comp.c @@ -747,9 +747,10 @@ void bpf_jit_compile(struct sk_filter *fp) if (!bpf_jit_enable) return; - addrs = kcalloc(fp->len, sizeof(*addrs), GFP_KERNEL); + addrs = kmalloc(fp->len * sizeof(*addrs), GFP_KERNEL); if (addrs == NULL) return; + memset(addrs, 0, fp->len * sizeof(*addrs)); memset(&jit, 0, sizeof(cjit)); memset(&cjit, 0, sizeof(cjit)); diff --git a/trunk/arch/s390/pci/Makefile b/trunk/arch/s390/pci/Makefile index 086a2e37935d..f0f426a113ce 100644 --- a/trunk/arch/s390/pci/Makefile +++ b/trunk/arch/s390/pci/Makefile @@ -2,5 +2,5 @@ # Makefile for the s390 PCI subsystem. # -obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o pci_sysfs.o \ - pci_event.o pci_debug.o pci_insn.o +obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \ + pci_sysfs.o pci_event.o pci_debug.o diff --git a/trunk/arch/s390/pci/pci.c b/trunk/arch/s390/pci/pci.c index e6f15b5d8b7d..27b4c17855b9 100644 --- a/trunk/arch/s390/pci/pci.c +++ b/trunk/arch/s390/pci/pci.c @@ -99,6 +99,9 @@ static int __read_mostly aisb_max; static struct kmem_cache *zdev_irq_cache; static struct kmem_cache *zdev_fmb_cache; +debug_info_t *pci_debug_msg_id; +debug_info_t *pci_debug_err_id; + static inline int irq_to_msi_nr(unsigned int irq) { return irq & ZPCI_MSI_MASK; @@ -176,7 +179,7 @@ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, fib->aisb = (u64) bucket->aisb + aisb / 8; fib->aisbo = aisb & ZPCI_MSI_MASK; - rc = s390pci_mod_fc(req, fib); + rc = mpcifc_instr(req, fib); pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); free_page((unsigned long) fib); @@ -206,7 +209,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args fib->iota = args->iota; fib->fmb_addr = args->fmb_addr; - rc = s390pci_mod_fc(req, fib); + rc = mpcifc_instr(req, fib); free_page((unsigned long) fib); return rc; } @@ -246,9 +249,10 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev) if (zdev->fmb) return -EINVAL; - zdev->fmb = kmem_cache_zalloc(zdev_fmb_cache, GFP_KERNEL); + zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL); if (!zdev->fmb) return -ENOMEM; + memset(zdev->fmb, 0, sizeof(*zdev->fmb)); WARN_ON((u64) zdev->fmb & 0xf); args.fmb_addr = virt_to_phys(zdev->fmb); @@ -280,12 +284,12 @@ static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) u64 data; int rc; - rc = s390pci_load(&data, req, offset); - if (!rc) { - data = data << ((8 - len) * 8); - data = le64_to_cpu(data); + rc = pcilg_instr(&data, req, offset); + data = data << ((8 - len) * 8); + data = le64_to_cpu(data); + if (!rc) *val = (u32) data; - } else + else *val = 0xffffffff; return rc; } @@ -298,7 +302,7 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) data = cpu_to_le64(data); data = data >> ((8 - len) * 8); - rc = s390pci_store(data, req, offset); + rc = pcistg_instr(data, req, offset); return rc; } @@ -405,28 +409,20 @@ static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { struct zpci_dev *zdev = get_zdev_by_bus(bus); - int ret; if (!zdev || devfn != ZPCI_DEVFN) - ret = -ENODEV; - else - ret = zpci_cfg_load(zdev, where, val, size); - - return ret; + return 0; + return zpci_cfg_load(zdev, where, val, size); } static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { struct zpci_dev *zdev = get_zdev_by_bus(bus); - int ret; if (!zdev || devfn != ZPCI_DEVFN) - ret = -ENODEV; - else - ret = zpci_cfg_store(zdev, where, val, size); - - return ret; + return 0; + return zpci_cfg_store(zdev, where, val, size); } static struct pci_ops pci_root_ops = { @@ -478,7 +474,7 @@ static void zpci_irq_handler(void *dont, void *need) } /* enable interrupts again */ - set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); + sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); /* check again to not lose initiative */ rmb(); @@ -600,6 +596,19 @@ static void zpci_map_resources(struct zpci_dev *zdev) } }; +static void zpci_unmap_resources(struct pci_dev *pdev) +{ + resource_size_t len; + int i; + + for (i = 0; i < PCI_BAR_COUNT; i++) { + len = pci_resource_len(pdev, i); + if (!len) + continue; + pci_iounmap(pdev, (void *) pdev->resource[i].start); + } +}; + struct zpci_dev *zpci_alloc_device(void) { struct zpci_dev *zdev; @@ -627,6 +636,32 @@ void zpci_free_device(struct zpci_dev *zdev) kfree(zdev); } +/* Called on removal of pci_dev, leaves zpci and bus device */ +static void zpci_remove_device(struct pci_dev *pdev) +{ + struct zpci_dev *zdev = get_zdev(pdev); + + dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); + zdev->state = ZPCI_FN_STATE_CONFIGURED; + zpci_dma_exit_device(zdev); + zpci_fmb_disable_device(zdev); + zpci_sysfs_remove_device(&pdev->dev); + zpci_unmap_resources(pdev); + list_del(&zdev->entry); /* can be called from init */ + zdev->pdev = NULL; +} + +static void zpci_scan_devices(void) +{ + struct zpci_dev *zdev; + + mutex_lock(&zpci_list_lock); + list_for_each_entry(zdev, &zpci_list, entry) + if (zdev->state == ZPCI_FN_STATE_CONFIGURED) + zpci_scan_device(zdev); + mutex_unlock(&zpci_list_lock); +} + /* * Too late for any s390 specific setup, since interrupts must be set up * already which requires DMA setup too and the pci scan will access the @@ -653,6 +688,12 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask) return 0; } +void pcibios_disable_device(struct pci_dev *pdev) +{ + zpci_remove_device(pdev); + pdev->sysdata = NULL; +} + int pcibios_add_platform_entries(struct pci_dev *pdev) { return zpci_sysfs_add_device(&pdev->dev); @@ -748,7 +789,7 @@ static int __init zpci_irq_init(void) spin_lock_init(&bucket->lock); /* set summary to 1 to be called every time for the ISC */ *zpci_irq_si = 1; - set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); + sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); return 0; out_ai: @@ -831,19 +872,7 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) spin_unlock(&zpci_iomap_lock); } -int pcibios_add_device(struct pci_dev *pdev) -{ - struct zpci_dev *zdev = get_zdev(pdev); - - zdev->pdev = pdev; - zpci_debug_init_device(zdev); - zpci_fmb_enable_device(zdev); - zpci_map_resources(zdev); - - return 0; -} - -static int zpci_scan_bus(struct zpci_dev *zdev) +static int zpci_create_device_bus(struct zpci_dev *zdev) { struct resource *res; LIST_HEAD(resources); @@ -880,8 +909,8 @@ static int zpci_scan_bus(struct zpci_dev *zdev) pci_add_resource(&resources, res); } - zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, - zdev, &resources); + zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, + zdev, &resources); if (!zdev->bus) return -EIO; @@ -930,13 +959,6 @@ int zpci_enable_device(struct zpci_dev *zdev) } EXPORT_SYMBOL_GPL(zpci_enable_device); -int zpci_disable_device(struct zpci_dev *zdev) -{ - zpci_dma_exit_device(zdev); - return clp_disable_fh(zdev); -} -EXPORT_SYMBOL_GPL(zpci_disable_device); - int zpci_create_device(struct zpci_dev *zdev) { int rc; @@ -945,16 +967,9 @@ int zpci_create_device(struct zpci_dev *zdev) if (rc) goto out; - if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { - rc = zpci_enable_device(zdev); - if (rc) - goto out_free; - - zdev->state = ZPCI_FN_STATE_ONLINE; - } - rc = zpci_scan_bus(zdev); + rc = zpci_create_device_bus(zdev); if (rc) - goto out_disable; + goto out_bus; mutex_lock(&zpci_list_lock); list_add_tail(&zdev->entry, &zpci_list); @@ -962,12 +977,21 @@ int zpci_create_device(struct zpci_dev *zdev) hotplug_ops->create_slot(zdev); mutex_unlock(&zpci_list_lock); + if (zdev->state == ZPCI_FN_STATE_STANDBY) + return 0; + + rc = zpci_enable_device(zdev); + if (rc) + goto out_start; return 0; -out_disable: - if (zdev->state == ZPCI_FN_STATE_ONLINE) - zpci_disable_device(zdev); -out_free: +out_start: + mutex_lock(&zpci_list_lock); + list_del(&zdev->entry); + if (hotplug_ops) + hotplug_ops->remove_slot(zdev); + mutex_unlock(&zpci_list_lock); +out_bus: zpci_free_domain(zdev); out: return rc; @@ -992,9 +1016,15 @@ int zpci_scan_device(struct zpci_dev *zdev) goto out; } + zpci_debug_init_device(zdev); + zpci_fmb_enable_device(zdev); + zpci_map_resources(zdev); pci_bus_add_devices(zdev->bus); + /* now that pdev was added to the bus mark it as used */ + zdev->state = ZPCI_FN_STATE_ONLINE; return 0; + out: zpci_dma_exit_device(zdev); clp_disable_fh(zdev); @@ -1057,13 +1087,13 @@ void zpci_deregister_hp_ops(void) } EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); -unsigned int s390_pci_probe; +unsigned int s390_pci_probe = 1; EXPORT_SYMBOL_GPL(s390_pci_probe); char * __init pcibios_setup(char *str) { - if (!strcmp(str, "on")) { - s390_pci_probe = 1; + if (!strcmp(str, "off")) { + s390_pci_probe = 0; return NULL; } return str; @@ -1108,6 +1138,7 @@ static int __init pci_base_init(void) if (rc) goto out_find; + zpci_scan_devices(); return 0; out_find: diff --git a/trunk/arch/s390/pci/pci_clp.c b/trunk/arch/s390/pci/pci_clp.c index bd34359d1546..f339fe2feb15 100644 --- a/trunk/arch/s390/pci/pci_clp.c +++ b/trunk/arch/s390/pci/pci_clp.c @@ -13,7 +13,6 @@ #include #include #include -#include #include /* @@ -145,7 +144,6 @@ int clp_add_pci_device(u32 fid, u32 fh, int configured) struct zpci_dev *zdev; int rc; - zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, configured); zdev = zpci_alloc_device(); if (IS_ERR(zdev)) return PTR_ERR(zdev); @@ -206,8 +204,8 @@ static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) *fh = rrb->response.fh; else { - zpci_dbg(0, "SPF fh:%x, cc:%d, resp:%x\n", *fh, rc, - rrb->response.hdr.rsp); + pr_err("Set PCI FN failed with response: %x cc: %d\n", + rrb->response.hdr.rsp, rc); rc = -EIO; } clp_free_block(rrb); @@ -223,8 +221,6 @@ int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as) if (!rc) /* Success -> store enabled handle in zdev */ zdev->fh = fh; - - zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc); return rc; } @@ -241,8 +237,9 @@ int clp_disable_fh(struct zpci_dev *zdev) if (!rc) /* Success -> store disabled handle in zdev */ zdev->fh = fh; - - zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc); + else + dev_err(&zdev->pdev->dev, + "Failed to disable fn handle: 0x%x\n", fh); return rc; } diff --git a/trunk/arch/s390/pci/pci_debug.c b/trunk/arch/s390/pci/pci_debug.c index 771b82359af4..a5d07bc2a547 100644 --- a/trunk/arch/s390/pci/pci_debug.c +++ b/trunk/arch/s390/pci/pci_debug.c @@ -11,17 +11,12 @@ #include #include #include -#include #include #include #include static struct dentry *debugfs_root; -debug_info_t *pci_debug_msg_id; -EXPORT_SYMBOL_GPL(pci_debug_msg_id); -debug_info_t *pci_debug_err_id; -EXPORT_SYMBOL_GPL(pci_debug_err_id); static char *pci_perf_names[] = { /* hardware counters */ @@ -173,6 +168,7 @@ int __init zpci_debug_init(void) return -EINVAL; debug_register_view(pci_debug_msg_id, &debug_sprintf_view); debug_set_level(pci_debug_msg_id, 3); + zpci_dbg("Debug view initialized\n"); /* error log */ pci_debug_err_id = debug_register("pci_error", 2, 1, 16); @@ -180,6 +176,7 @@ int __init zpci_debug_init(void) return -EINVAL; debug_register_view(pci_debug_err_id, &debug_hex_ascii_view); debug_set_level(pci_debug_err_id, 6); + zpci_err("Debug view initialized\n"); debugfs_root = debugfs_create_dir("pci", NULL); return 0; diff --git a/trunk/arch/s390/pci/pci_dma.c b/trunk/arch/s390/pci/pci_dma.c index f8e69d5bc0a9..a547419907c3 100644 --- a/trunk/arch/s390/pci/pci_dma.c +++ b/trunk/arch/s390/pci/pci_dma.c @@ -169,9 +169,8 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa, * needs to be redone! */ goto no_refresh; - - rc = s390pci_refresh_trans((u64) zdev->fh << 32, start_dma_addr, - nr_pages * PAGE_SIZE); + rc = rpcit_instr((u64) zdev->fh << 32, start_dma_addr, + nr_pages * PAGE_SIZE); no_refresh: spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags); @@ -269,6 +268,8 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, int flags = ZPCI_PTE_VALID; dma_addr_t dma_addr; + WARN_ON_ONCE(offset > PAGE_SIZE); + /* This rounds up number of pages based on size and offset */ nr_pages = iommu_num_pages(pa, size, PAGE_SIZE); iommu_page_index = dma_alloc_iommu(zdev, nr_pages); @@ -290,7 +291,7 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) { atomic64_add(nr_pages, (atomic64_t *) &zdev->fmb->mapped_pages); - return dma_addr + (offset & ~PAGE_MASK); + return dma_addr + offset; } out_free: diff --git a/trunk/arch/s390/pci/pci_insn.c b/trunk/arch/s390/pci/pci_insn.c deleted file mode 100644 index 22eeb9d7ffeb..000000000000 --- a/trunk/arch/s390/pci/pci_insn.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * s390 specific pci instructions - * - * Copyright IBM Corp. 2013 - */ - -#include -#include -#include -#include -#include - -#define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */ - -/* Modify PCI Function Controls */ -static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) -{ - u8 cc; - - asm volatile ( - " .insn rxy,0xe300000000d0,%[req],%[fib]\n" - " ipm %[cc]\n" - " srl %[cc],28\n" - : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib) - : : "cc"); - *status = req >> 24 & 0xff; - return cc; -} - -int s390pci_mod_fc(u64 req, struct zpci_fib *fib) -{ - u8 cc, status; - - do { - cc = __mpcifc(req, fib, &status); - if (cc == 2) - msleep(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d\n", - __func__, cc, status); - return (cc) ? -EIO : 0; -} - -/* Refresh PCI Translations */ -static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) -{ - register u64 __addr asm("2") = addr; - register u64 __range asm("3") = range; - u8 cc; - - asm volatile ( - " .insn rre,0xb9d30000,%[fn],%[addr]\n" - " ipm %[cc]\n" - " srl %[cc],28\n" - : [cc] "=d" (cc), [fn] "+d" (fn) - : [addr] "d" (__addr), "d" (__range) - : "cc"); - *status = fn >> 24 & 0xff; - return cc; -} - -int s390pci_refresh_trans(u64 fn, u64 addr, u64 range) -{ - u8 cc, status; - - do { - cc = __rpcit(fn, addr, range, &status); - if (cc == 2) - udelay(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d dma_addr: %Lx size: %Lx\n", - __func__, cc, status, addr, range); - return (cc) ? -EIO : 0; -} - -/* Set Interruption Controls */ -void set_irq_ctrl(u16 ctl, char *unused, u8 isc) -{ - asm volatile ( - " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" - : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); -} - -/* PCI Load */ -static inline int __pcilg(u64 *data, u64 req, u64 offset, u8 *status) -{ - register u64 __req asm("2") = req; - register u64 __offset asm("3") = offset; - int cc = -ENXIO; - u64 __data; - - asm volatile ( - " .insn rre,0xb9d20000,%[data],%[req]\n" - "0: ipm %[cc]\n" - " srl %[cc],28\n" - "1:\n" - EX_TABLE(0b, 1b) - : [cc] "+d" (cc), [data] "=d" (__data), [req] "+d" (__req) - : "d" (__offset) - : "cc"); - *status = __req >> 24 & 0xff; - if (!cc) - *data = __data; - - return cc; -} - -int s390pci_load(u64 *data, u64 req, u64 offset) -{ - u8 status; - int cc; - - do { - cc = __pcilg(data, req, offset, &status); - if (cc == 2) - udelay(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", - __func__, cc, status, req, offset); - return (cc > 0) ? -EIO : cc; -} -EXPORT_SYMBOL_GPL(s390pci_load); - -/* PCI Store */ -static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status) -{ - register u64 __req asm("2") = req; - register u64 __offset asm("3") = offset; - int cc = -ENXIO; - - asm volatile ( - " .insn rre,0xb9d00000,%[data],%[req]\n" - "0: ipm %[cc]\n" - " srl %[cc],28\n" - "1:\n" - EX_TABLE(0b, 1b) - : [cc] "+d" (cc), [req] "+d" (__req) - : "d" (__offset), [data] "d" (data) - : "cc"); - *status = __req >> 24 & 0xff; - return cc; -} - -int s390pci_store(u64 data, u64 req, u64 offset) -{ - u8 status; - int cc; - - do { - cc = __pcistg(data, req, offset, &status); - if (cc == 2) - udelay(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", - __func__, cc, status, req, offset); - return (cc > 0) ? -EIO : cc; -} -EXPORT_SYMBOL_GPL(s390pci_store); - -/* PCI Store Block */ -static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) -{ - int cc = -ENXIO; - - asm volatile ( - " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n" - "0: ipm %[cc]\n" - " srl %[cc],28\n" - "1:\n" - EX_TABLE(0b, 1b) - : [cc] "+d" (cc), [req] "+d" (req) - : [offset] "d" (offset), [data] "Q" (*data) - : "cc"); - *status = req >> 24 & 0xff; - return cc; -} - -int s390pci_store_block(const u64 *data, u64 req, u64 offset) -{ - u8 status; - int cc; - - do { - cc = __pcistb(data, req, offset, &status); - if (cc == 2) - udelay(ZPCI_INSN_BUSY_DELAY); - } while (cc == 2); - - if (cc) - printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", - __func__, cc, status, req, offset); - return (cc > 0) ? -EIO : cc; -} -EXPORT_SYMBOL_GPL(s390pci_store_block); diff --git a/trunk/arch/s390/pci/pci_msi.c b/trunk/arch/s390/pci/pci_msi.c index b097aed05a9b..0297931335e1 100644 --- a/trunk/arch/s390/pci/pci_msi.c +++ b/trunk/arch/s390/pci/pci_msi.c @@ -18,9 +18,8 @@ /* mapping of irq numbers to msi_desc */ static struct hlist_head *msi_hash; -static const unsigned int msi_hash_bits = 8; -#define MSI_HASH_BUCKETS (1U << msi_hash_bits) -#define msi_hashfn(nr) hash_long(nr, msi_hash_bits) +static unsigned int msihash_shift = 6; +#define msi_hashfn(nr) hash_long(nr, msihash_shift) static DEFINE_SPINLOCK(msi_map_lock); @@ -75,7 +74,6 @@ int zpci_setup_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi, map->irq = nr; map->msi = msi; zdev->msi_map[nr & ZPCI_MSI_MASK] = map; - INIT_HLIST_NODE(&map->msi_chain); pr_debug("%s hashing irq: %u to bucket nr: %llu\n", __func__, nr, msi_hashfn(nr)); @@ -127,11 +125,11 @@ int __init zpci_msihash_init(void) { unsigned int i; - msi_hash = kmalloc(MSI_HASH_BUCKETS * sizeof(*msi_hash), GFP_KERNEL); + msi_hash = kmalloc(256 * sizeof(*msi_hash), GFP_KERNEL); if (!msi_hash) return -ENOMEM; - for (i = 0; i < MSI_HASH_BUCKETS; i++) + for (i = 0; i < (1U << msihash_shift); i++) INIT_HLIST_HEAD(&msi_hash[i]); return 0; } diff --git a/trunk/arch/sparc/include/asm/Kbuild b/trunk/arch/sparc/include/asm/Kbuild index ff18e3cfb6b1..e26d430ce2fd 100644 --- a/trunk/arch/sparc/include/asm/Kbuild +++ b/trunk/arch/sparc/include/asm/Kbuild @@ -2,16 +2,11 @@ generic-y += clkdev.h -generic-y += cputime.h generic-y += div64.h -generic-y += emergency-restart.h generic-y += exec.h generic-y += local64.h -generic-y += mutex.h generic-y += irq_regs.h generic-y += local.h generic-y += module.h -generic-y += serial.h generic-y += trace_clock.h -generic-y += types.h generic-y += word-at-a-time.h diff --git a/trunk/arch/sparc/include/asm/cputime.h b/trunk/arch/sparc/include/asm/cputime.h new file mode 100644 index 000000000000..1a642b81e019 --- /dev/null +++ b/trunk/arch/sparc/include/asm/cputime.h @@ -0,0 +1,6 @@ +#ifndef __SPARC_CPUTIME_H +#define __SPARC_CPUTIME_H + +#include + +#endif /* __SPARC_CPUTIME_H */ diff --git a/trunk/arch/sparc/include/asm/emergency-restart.h b/trunk/arch/sparc/include/asm/emergency-restart.h new file mode 100644 index 000000000000..108d8c48e42e --- /dev/null +++ b/trunk/arch/sparc/include/asm/emergency-restart.h @@ -0,0 +1,6 @@ +#ifndef _ASM_EMERGENCY_RESTART_H +#define _ASM_EMERGENCY_RESTART_H + +#include + +#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/trunk/arch/sparc/include/asm/mutex.h b/trunk/arch/sparc/include/asm/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/trunk/arch/sparc/include/asm/mutex.h @@ -0,0 +1,9 @@ +/* + * Pull in the generic implementation for the mutex fastpath. + * + * TODO: implement optimized primitives instead, or leave the generic + * implementation in place, or pick the atomic_xchg() based generic + * implementation. (see asm-generic/mutex-xchg.h for details) + */ + +#include diff --git a/trunk/arch/sparc/include/asm/pgtable_64.h b/trunk/arch/sparc/include/asm/pgtable_64.h index 7619f2f792af..08fcce90316b 100644 --- a/trunk/arch/sparc/include/asm/pgtable_64.h +++ b/trunk/arch/sparc/include/asm/pgtable_64.h @@ -915,7 +915,6 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); } -#include #include /* We provide our own get_unmapped_area to cope with VA holes and diff --git a/trunk/arch/sparc/include/asm/serial.h b/trunk/arch/sparc/include/asm/serial.h new file mode 100644 index 000000000000..f90d61c28059 --- /dev/null +++ b/trunk/arch/sparc/include/asm/serial.h @@ -0,0 +1,6 @@ +#ifndef __SPARC_SERIAL_H +#define __SPARC_SERIAL_H + +#define BASE_BAUD ( 1843200 / 16 ) + +#endif /* __SPARC_SERIAL_H */ diff --git a/trunk/arch/sparc/include/asm/smp_32.h b/trunk/arch/sparc/include/asm/smp_32.h index 3c8917f054de..b73da3c5f10a 100644 --- a/trunk/arch/sparc/include/asm/smp_32.h +++ b/trunk/arch/sparc/include/asm/smp_32.h @@ -36,6 +36,7 @@ typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); void cpu_panic(void); +extern void smp4m_irq_rotate(int cpu); /* * General functions that each host system must provide. @@ -45,6 +46,7 @@ void sun4m_init_smp(void); void sun4d_init_smp(void); void smp_callin(void); +void smp_boot_cpus(void); void smp_store_cpu_info(int); void smp_resched_interrupt(void); @@ -105,6 +107,9 @@ extern int hard_smp_processor_id(void); #define raw_smp_processor_id() (current_thread_info()->cpu) +#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier +#define prof_counter(__cpu) cpu_data(__cpu).counter + void smp_setup_cpu_possible_map(void); #endif /* !(__ASSEMBLY__) */ diff --git a/trunk/arch/sparc/include/asm/switch_to_64.h b/trunk/arch/sparc/include/asm/switch_to_64.h index c7de3323819c..cad36f56fa03 100644 --- a/trunk/arch/sparc/include/asm/switch_to_64.h +++ b/trunk/arch/sparc/include/asm/switch_to_64.h @@ -18,7 +18,8 @@ do { \ * and 2 stores in this critical code path. -DaveM */ #define switch_to(prev, next, last) \ -do { save_and_clear_fpu(); \ +do { flush_tlb_pending(); \ + save_and_clear_fpu(); \ /* If you are tempted to conditionalize the following */ \ /* so that ASI is only written if it changes, think again. */ \ __asm__ __volatile__("wr %%g0, %0, %%asi" \ diff --git a/trunk/arch/sparc/include/asm/tlbflush_64.h b/trunk/arch/sparc/include/asm/tlbflush_64.h index f0d6a9700f4c..2ef463494153 100644 --- a/trunk/arch/sparc/include/asm/tlbflush_64.h +++ b/trunk/arch/sparc/include/asm/tlbflush_64.h @@ -11,40 +11,24 @@ struct tlb_batch { struct mm_struct *mm; unsigned long tlb_nr; - unsigned long active; unsigned long vaddrs[TLB_BATCH_NR]; }; extern void flush_tsb_kernel_range(unsigned long start, unsigned long end); extern void flush_tsb_user(struct tlb_batch *tb); -extern void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr); /* TLB flush operations. */ -static inline void flush_tlb_mm(struct mm_struct *mm) -{ -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long vmaddr) -{ -} - -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ -} - -#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE - extern void flush_tlb_pending(void); -extern void arch_enter_lazy_mmu_mode(void); -extern void arch_leave_lazy_mmu_mode(void); -#define arch_flush_lazy_mmu_mode() do {} while (0) + +#define flush_tlb_range(vma,start,end) \ + do { (void)(start); flush_tlb_pending(); } while (0) +#define flush_tlb_page(vma,addr) flush_tlb_pending() +#define flush_tlb_mm(mm) flush_tlb_pending() /* Local cpu only. */ extern void __flush_tlb_all(void); -extern void __flush_tlb_page(unsigned long context, unsigned long vaddr); + extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); #ifndef CONFIG_SMP @@ -54,24 +38,15 @@ do { flush_tsb_kernel_range(start,end); \ __flush_tlb_kernel_range(start,end); \ } while (0) -static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) -{ - __flush_tlb_page(CTX_HWBITS(mm->context), vaddr); -} - #else /* CONFIG_SMP */ extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); -extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr); #define flush_tlb_kernel_range(start, end) \ do { flush_tsb_kernel_range(start,end); \ smp_flush_tlb_kernel_range(start, end); \ } while (0) -#define global_flush_tlb_page(mm, vaddr) \ - smp_flush_tlb_page(mm, vaddr) - #endif /* ! CONFIG_SMP */ #endif /* _SPARC64_TLBFLUSH_H */ diff --git a/trunk/arch/sparc/include/uapi/asm/Kbuild b/trunk/arch/sparc/include/uapi/asm/Kbuild index b5843ee09fb5..ce175aff71b7 100644 --- a/trunk/arch/sparc/include/uapi/asm/Kbuild +++ b/trunk/arch/sparc/include/uapi/asm/Kbuild @@ -44,6 +44,7 @@ header-y += swab.h header-y += termbits.h header-y += termios.h header-y += traps.h +header-y += types.h header-y += uctx.h header-y += unistd.h header-y += utrap.h diff --git a/trunk/arch/sparc/include/uapi/asm/types.h b/trunk/arch/sparc/include/uapi/asm/types.h new file mode 100644 index 000000000000..383d156cde9c --- /dev/null +++ b/trunk/arch/sparc/include/uapi/asm/types.h @@ -0,0 +1,17 @@ +#ifndef _SPARC_TYPES_H +#define _SPARC_TYPES_H +/* + * This file is never included by application software unless + * explicitly requested (e.g., via linux/types.h) in which case the + * application is Linux specific so (user-) name space pollution is + * not a major issue. However, for interoperability, libraries still + * need to be careful to avoid a name clashes. + */ + +#if defined(__sparc__) + +#include + +#endif /* defined(__sparc__) */ + +#endif /* defined(_SPARC_TYPES_H) */ diff --git a/trunk/arch/sparc/kernel/smp_64.c b/trunk/arch/sparc/kernel/smp_64.c index ca64d2a86ec0..537eb66abd06 100644 --- a/trunk/arch/sparc/kernel/smp_64.c +++ b/trunk/arch/sparc/kernel/smp_64.c @@ -849,7 +849,7 @@ void smp_tsb_sync(struct mm_struct *mm) } extern unsigned long xcall_flush_tlb_mm; -extern unsigned long xcall_flush_tlb_page; +extern unsigned long xcall_flush_tlb_pending; extern unsigned long xcall_flush_tlb_kernel_range; extern unsigned long xcall_fetch_glob_regs; extern unsigned long xcall_fetch_glob_pmu; @@ -1074,56 +1074,23 @@ void smp_flush_tlb_mm(struct mm_struct *mm) put_cpu(); } -struct tlb_pending_info { - unsigned long ctx; - unsigned long nr; - unsigned long *vaddrs; -}; - -static void tlb_pending_func(void *info) -{ - struct tlb_pending_info *t = info; - - __flush_tlb_pending(t->ctx, t->nr, t->vaddrs); -} - void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) { u32 ctx = CTX_HWBITS(mm->context); - struct tlb_pending_info info; int cpu = get_cpu(); - info.ctx = ctx; - info.nr = nr; - info.vaddrs = vaddrs; - if (mm == current->mm && atomic_read(&mm->mm_users) == 1) cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); else - smp_call_function_many(mm_cpumask(mm), tlb_pending_func, - &info, 1); + smp_cross_call_masked(&xcall_flush_tlb_pending, + ctx, nr, (unsigned long) vaddrs, + mm_cpumask(mm)); __flush_tlb_pending(ctx, nr, vaddrs); put_cpu(); } -void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) -{ - unsigned long context = CTX_HWBITS(mm->context); - int cpu = get_cpu(); - - if (mm == current->mm && atomic_read(&mm->mm_users) == 1) - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); - else - smp_cross_call_masked(&xcall_flush_tlb_page, - context, vaddr, 0, - mm_cpumask(mm)); - __flush_tlb_page(context, vaddr); - - put_cpu(); -} - void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end) { start &= PAGE_MASK; diff --git a/trunk/arch/sparc/lib/bitext.c b/trunk/arch/sparc/lib/bitext.c index 8ec4e9c0251a..48d00e72ce15 100644 --- a/trunk/arch/sparc/lib/bitext.c +++ b/trunk/arch/sparc/lib/bitext.c @@ -119,7 +119,11 @@ void bit_map_clear(struct bit_map *t, int offset, int len) void bit_map_init(struct bit_map *t, unsigned long *map, int size) { - bitmap_zero(map, size); + + if ((size & 07) != 0) + BUG(); + memset(map, 0, size>>3); + memset(t, 0, sizeof *t); spin_lock_init(&t->lock); t->map = map; diff --git a/trunk/arch/sparc/mm/iommu.c b/trunk/arch/sparc/mm/iommu.c index 28f96f27c768..0f4f7191fbba 100644 --- a/trunk/arch/sparc/mm/iommu.c +++ b/trunk/arch/sparc/mm/iommu.c @@ -34,7 +34,7 @@ #define IOMMU_RNGE IOMMU_RNGE_256MB #define IOMMU_START 0xF0000000 #define IOMMU_WINSIZE (256*1024*1024U) -#define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 256KB */ +#define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 265KB */ #define IOMMU_ORDER 6 /* 4096 * (1<<6) */ /* srmmu.c */ diff --git a/trunk/arch/sparc/mm/srmmu.c b/trunk/arch/sparc/mm/srmmu.c index 036c2797dece..c38bb72e3e80 100644 --- a/trunk/arch/sparc/mm/srmmu.c +++ b/trunk/arch/sparc/mm/srmmu.c @@ -280,9 +280,7 @@ static void __init srmmu_nocache_init(void) SRMMU_NOCACHE_ALIGN_MAX, 0UL); memset(srmmu_nocache_pool, 0, srmmu_nocache_size); - srmmu_nocache_bitmap = - __alloc_bootmem(BITS_TO_LONGS(bitmap_bits) * sizeof(long), - SMP_CACHE_BYTES, 0UL); + srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL); bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits); srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); diff --git a/trunk/arch/sparc/mm/tlb.c b/trunk/arch/sparc/mm/tlb.c index 83d89bcb44af..ba6ae7ffdc2c 100644 --- a/trunk/arch/sparc/mm/tlb.c +++ b/trunk/arch/sparc/mm/tlb.c @@ -24,17 +24,11 @@ static DEFINE_PER_CPU(struct tlb_batch, tlb_batch); void flush_tlb_pending(void) { struct tlb_batch *tb = &get_cpu_var(tlb_batch); - struct mm_struct *mm = tb->mm; - if (!tb->tlb_nr) - goto out; + if (tb->tlb_nr) { + flush_tsb_user(tb); - flush_tsb_user(tb); - - if (CTX_VALID(mm->context)) { - if (tb->tlb_nr == 1) { - global_flush_tlb_page(mm, tb->vaddrs[0]); - } else { + if (CTX_VALID(tb->mm->context)) { #ifdef CONFIG_SMP smp_flush_tlb_pending(tb->mm, tb->tlb_nr, &tb->vaddrs[0]); @@ -43,30 +37,12 @@ void flush_tlb_pending(void) tb->tlb_nr, &tb->vaddrs[0]); #endif } + tb->tlb_nr = 0; } - tb->tlb_nr = 0; - -out: put_cpu_var(tlb_batch); } -void arch_enter_lazy_mmu_mode(void) -{ - struct tlb_batch *tb = &__get_cpu_var(tlb_batch); - - tb->active = 1; -} - -void arch_leave_lazy_mmu_mode(void) -{ - struct tlb_batch *tb = &__get_cpu_var(tlb_batch); - - if (tb->tlb_nr) - flush_tlb_pending(); - tb->active = 0; -} - static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, bool exec) { @@ -84,12 +60,6 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, nr = 0; } - if (!tb->active) { - global_flush_tlb_page(mm, vaddr); - flush_tsb_user_page(mm, vaddr); - goto out; - } - if (nr == 0) tb->mm = mm; @@ -98,7 +68,6 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, if (nr >= TLB_BATCH_NR) flush_tlb_pending(); -out: put_cpu_var(tlb_batch); } diff --git a/trunk/arch/sparc/mm/tsb.c b/trunk/arch/sparc/mm/tsb.c index 2cc3bce5ee91..428982b9becf 100644 --- a/trunk/arch/sparc/mm/tsb.c +++ b/trunk/arch/sparc/mm/tsb.c @@ -7,10 +7,11 @@ #include #include #include -#include +#include +#include #include +#include #include -#include #include extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; @@ -45,56 +46,28 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end) } } -static void __flush_tsb_one_entry(unsigned long tsb, unsigned long v, - unsigned long hash_shift, - unsigned long nentries) -{ - unsigned long tag, ent, hash; - - v &= ~0x1UL; - hash = tsb_hash(v, hash_shift, nentries); - ent = tsb + (hash * sizeof(struct tsb)); - tag = (v >> 22UL); - - tsb_flush(ent, tag); -} - static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift, unsigned long tsb, unsigned long nentries) { unsigned long i; - for (i = 0; i < tb->tlb_nr; i++) - __flush_tsb_one_entry(tsb, tb->vaddrs[i], hash_shift, nentries); -} - -void flush_tsb_user(struct tlb_batch *tb) -{ - struct mm_struct *mm = tb->mm; - unsigned long nentries, base, flags; + for (i = 0; i < tb->tlb_nr; i++) { + unsigned long v = tb->vaddrs[i]; + unsigned long tag, ent, hash; - spin_lock_irqsave(&mm->context.lock, flags); + v &= ~0x1UL; - base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb; - nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; - if (tlb_type == cheetah_plus || tlb_type == hypervisor) - base = __pa(base); - __flush_tsb_one(tb, PAGE_SHIFT, base, nentries); + hash = tsb_hash(v, hash_shift, nentries); + ent = tsb + (hash * sizeof(struct tsb)); + tag = (v >> 22UL); -#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) - if (mm->context.tsb_block[MM_TSB_HUGE].tsb) { - base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb; - nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; - if (tlb_type == cheetah_plus || tlb_type == hypervisor) - base = __pa(base); - __flush_tsb_one(tb, HPAGE_SHIFT, base, nentries); + tsb_flush(ent, tag); } -#endif - spin_unlock_irqrestore(&mm->context.lock, flags); } -void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) +void flush_tsb_user(struct tlb_batch *tb) { + struct mm_struct *mm = tb->mm; unsigned long nentries, base, flags; spin_lock_irqsave(&mm->context.lock, flags); @@ -103,7 +76,7 @@ void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; if (tlb_type == cheetah_plus || tlb_type == hypervisor) base = __pa(base); - __flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries); + __flush_tsb_one(tb, PAGE_SHIFT, base, nentries); #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) if (mm->context.tsb_block[MM_TSB_HUGE].tsb) { @@ -111,7 +84,7 @@ void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; if (tlb_type == cheetah_plus || tlb_type == hypervisor) base = __pa(base); - __flush_tsb_one_entry(base, vaddr, HPAGE_SHIFT, nentries); + __flush_tsb_one(tb, HPAGE_SHIFT, base, nentries); } #endif spin_unlock_irqrestore(&mm->context.lock, flags); diff --git a/trunk/arch/sparc/mm/ultra.S b/trunk/arch/sparc/mm/ultra.S index 432aa0cb1b38..f8e13d421fcb 100644 --- a/trunk/arch/sparc/mm/ultra.S +++ b/trunk/arch/sparc/mm/ultra.S @@ -52,33 +52,6 @@ __flush_tlb_mm: /* 18 insns */ nop nop - .align 32 - .globl __flush_tlb_page -__flush_tlb_page: /* 22 insns */ - /* %o0 = context, %o1 = vaddr */ - rdpr %pstate, %g7 - andn %g7, PSTATE_IE, %g2 - wrpr %g2, %pstate - mov SECONDARY_CONTEXT, %o4 - ldxa [%o4] ASI_DMMU, %g2 - stxa %o0, [%o4] ASI_DMMU - andcc %o1, 1, %g0 - andn %o1, 1, %o3 - be,pn %icc, 1f - or %o3, 0x10, %o3 - stxa %g0, [%o3] ASI_IMMU_DEMAP -1: stxa %g0, [%o3] ASI_DMMU_DEMAP - membar #Sync - stxa %g2, [%o4] ASI_DMMU - sethi %hi(KERNBASE), %o4 - flush %o4 - retl - wrpr %g7, 0x0, %pstate - nop - nop - nop - nop - .align 32 .globl __flush_tlb_pending __flush_tlb_pending: /* 26 insns */ @@ -230,31 +203,6 @@ __cheetah_flush_tlb_mm: /* 19 insns */ retl wrpr %g7, 0x0, %pstate -__cheetah_flush_tlb_page: /* 22 insns */ - /* %o0 = context, %o1 = vaddr */ - rdpr %pstate, %g7 - andn %g7, PSTATE_IE, %g2 - wrpr %g2, 0x0, %pstate - wrpr %g0, 1, %tl - mov PRIMARY_CONTEXT, %o4 - ldxa [%o4] ASI_DMMU, %g2 - srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3 - sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3 - or %o0, %o3, %o0 /* Preserve nucleus page size fields */ - stxa %o0, [%o4] ASI_DMMU - andcc %o1, 1, %g0 - be,pn %icc, 1f - andn %o1, 1, %o3 - stxa %g0, [%o3] ASI_IMMU_DEMAP -1: stxa %g0, [%o3] ASI_DMMU_DEMAP - membar #Sync - stxa %g2, [%o4] ASI_DMMU - sethi %hi(KERNBASE), %o4 - flush %o4 - wrpr %g0, 0, %tl - retl - wrpr %g7, 0x0, %pstate - __cheetah_flush_tlb_pending: /* 27 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ rdpr %pstate, %g7 @@ -321,20 +269,6 @@ __hypervisor_flush_tlb_mm: /* 10 insns */ retl nop -__hypervisor_flush_tlb_page: /* 11 insns */ - /* %o0 = context, %o1 = vaddr */ - mov %o0, %g2 - mov %o1, %o0 /* ARG0: vaddr + IMMU-bit */ - mov %g2, %o1 /* ARG1: mmu context */ - mov HV_MMU_ALL, %o2 /* ARG2: flags */ - srlx %o0, PAGE_SHIFT, %o0 - sllx %o0, PAGE_SHIFT, %o0 - ta HV_MMU_UNMAP_ADDR_TRAP - brnz,pn %o0, __hypervisor_tlb_tl0_error - mov HV_MMU_UNMAP_ADDR_TRAP, %o1 - retl - nop - __hypervisor_flush_tlb_pending: /* 16 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ sllx %o1, 3, %g1 @@ -405,13 +339,6 @@ cheetah_patch_cachetlbops: call tlb_patch_one mov 19, %o2 - sethi %hi(__flush_tlb_page), %o0 - or %o0, %lo(__flush_tlb_page), %o0 - sethi %hi(__cheetah_flush_tlb_page), %o1 - or %o1, %lo(__cheetah_flush_tlb_page), %o1 - call tlb_patch_one - mov 22, %o2 - sethi %hi(__flush_tlb_pending), %o0 or %o0, %lo(__flush_tlb_pending), %o0 sethi %hi(__cheetah_flush_tlb_pending), %o1 @@ -470,9 +397,10 @@ xcall_flush_tlb_mm: /* 21 insns */ nop nop - .globl xcall_flush_tlb_page -xcall_flush_tlb_page: /* 17 insns */ - /* %g5=context, %g1=vaddr */ + .globl xcall_flush_tlb_pending +xcall_flush_tlb_pending: /* 21 insns */ + /* %g5=context, %g1=nr, %g7=vaddrs[] */ + sllx %g1, 3, %g1 mov PRIMARY_CONTEXT, %g4 ldxa [%g4] ASI_DMMU, %g2 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4 @@ -480,16 +408,20 @@ xcall_flush_tlb_page: /* 17 insns */ or %g5, %g4, %g5 mov PRIMARY_CONTEXT, %g4 stxa %g5, [%g4] ASI_DMMU - andcc %g1, 0x1, %g0 +1: sub %g1, (1 << 3), %g1 + ldx [%g7 + %g1], %g5 + andcc %g5, 0x1, %g0 be,pn %icc, 2f - andn %g1, 0x1, %g5 + + andn %g5, 0x1, %g5 stxa %g0, [%g5] ASI_IMMU_DEMAP 2: stxa %g0, [%g5] ASI_DMMU_DEMAP membar #Sync + brnz,pt %g1, 1b + nop stxa %g2, [%g4] ASI_DMMU retry nop - nop .globl xcall_flush_tlb_kernel_range xcall_flush_tlb_kernel_range: /* 25 insns */ @@ -724,13 +656,15 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */ membar #Sync retry - .globl __hypervisor_xcall_flush_tlb_page -__hypervisor_xcall_flush_tlb_page: /* 17 insns */ - /* %g5=ctx, %g1=vaddr */ + .globl __hypervisor_xcall_flush_tlb_pending +__hypervisor_xcall_flush_tlb_pending: /* 21 insns */ + /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */ + sllx %g1, 3, %g1 mov %o0, %g2 mov %o1, %g3 mov %o2, %g4 - mov %g1, %o0 /* ARG0: virtual address */ +1: sub %g1, (1 << 3), %g1 + ldx [%g7 + %g1], %o0 /* ARG0: virtual address */ mov %g5, %o1 /* ARG1: mmu context */ mov HV_MMU_ALL, %o2 /* ARG2: flags */ srlx %o0, PAGE_SHIFT, %o0 @@ -739,6 +673,8 @@ __hypervisor_xcall_flush_tlb_page: /* 17 insns */ mov HV_MMU_UNMAP_ADDR_TRAP, %g6 brnz,a,pn %o0, __hypervisor_tlb_xcall_error mov %o0, %g5 + brnz,pt %g1, 1b + nop mov %g2, %o0 mov %g3, %o1 mov %g4, %o2 @@ -821,13 +757,6 @@ hypervisor_patch_cachetlbops: call tlb_patch_one mov 10, %o2 - sethi %hi(__flush_tlb_page), %o0 - or %o0, %lo(__flush_tlb_page), %o0 - sethi %hi(__hypervisor_flush_tlb_page), %o1 - or %o1, %lo(__hypervisor_flush_tlb_page), %o1 - call tlb_patch_one - mov 11, %o2 - sethi %hi(__flush_tlb_pending), %o0 or %o0, %lo(__flush_tlb_pending), %o0 sethi %hi(__hypervisor_flush_tlb_pending), %o1 @@ -859,12 +788,12 @@ hypervisor_patch_cachetlbops: call tlb_patch_one mov 21, %o2 - sethi %hi(xcall_flush_tlb_page), %o0 - or %o0, %lo(xcall_flush_tlb_page), %o0 - sethi %hi(__hypervisor_xcall_flush_tlb_page), %o1 - or %o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1 + sethi %hi(xcall_flush_tlb_pending), %o0 + or %o0, %lo(xcall_flush_tlb_pending), %o0 + sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1 + or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1 call tlb_patch_one - mov 17, %o2 + mov 21, %o2 sethi %hi(xcall_flush_tlb_kernel_range), %o0 or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 diff --git a/trunk/arch/tile/include/asm/irqflags.h b/trunk/arch/tile/include/asm/irqflags.h index c96f9bbb760d..241c0bb60b12 100644 --- a/trunk/arch/tile/include/asm/irqflags.h +++ b/trunk/arch/tile/include/asm/irqflags.h @@ -40,15 +40,7 @@ #include #include -/* - * Set and clear kernel interrupt masks. - * - * NOTE: __insn_mtspr() is a compiler builtin marked as a memory - * clobber. We rely on it being equivalent to a compiler barrier in - * this code since arch_local_irq_save() and friends must act as - * compiler barriers. This compiler semantic is baked into enough - * places that the compiler will maintain it going forward. - */ +/* Set and clear kernel interrupt masks. */ #if CHIP_HAS_SPLIT_INTR_MASK() #if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32 || INT_MEM_ERROR >= 32 # error Fix assumptions about which word various interrupts are in diff --git a/trunk/arch/tile/kernel/setup.c b/trunk/arch/tile/kernel/setup.c index 7a5aa1a7864e..d1e15f7b59c6 100644 --- a/trunk/arch/tile/kernel/setup.c +++ b/trunk/arch/tile/kernel/setup.c @@ -1004,8 +1004,15 @@ void __cpuinit setup_cpu(int boot) #ifdef CONFIG_BLK_DEV_INITRD +/* + * Note that the kernel can potentially support other compression + * techniques than gz, though we don't do so by default. If we ever + * decide to do so we can either look for other filename extensions, + * or just allow a file with this name to be compressed with an + * arbitrary compressor (somewhat counterintuitively). + */ static int __initdata set_initramfs_file; -static char __initdata initramfs_file[128] = "initramfs"; +static char __initdata initramfs_file[128] = "initramfs.cpio.gz"; static int __init setup_initramfs_file(char *str) { @@ -1019,9 +1026,9 @@ static int __init setup_initramfs_file(char *str) early_param("initramfs_file", setup_initramfs_file); /* - * We look for a file called "initramfs" in the hvfs. If there is one, we - * allocate some memory for it and it will be unpacked to the initramfs. - * If it's compressed, the initd code will uncompress it first. + * We look for an "initramfs.cpio.gz" file in the hvfs. + * If there is one, we allocate some memory for it and it will be + * unpacked to the initramfs. */ static void __init load_hv_initrd(void) { @@ -1031,16 +1038,10 @@ static void __init load_hv_initrd(void) fd = hv_fs_findfile((HV_VirtAddr) initramfs_file); if (fd == HV_ENOENT) { - if (set_initramfs_file) { + if (set_initramfs_file) pr_warning("No such hvfs initramfs file '%s'\n", initramfs_file); - return; - } else { - /* Try old backwards-compatible name. */ - fd = hv_fs_findfile((HV_VirtAddr)"initramfs.cpio.gz"); - if (fd == HV_ENOENT) - return; - } + return; } BUG_ON(fd < 0); stat = hv_fs_fstat(fd); diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 15b5cef4aa38..70c0f3da0476 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1549,7 +1549,6 @@ config X86_SMAP config EFI bool "EFI runtime service support" depends on ACPI - select UCS2_STRING ---help--- This enables the kernel to use EFI runtime services that are available (such as the EFI variable services). diff --git a/trunk/arch/x86/boot/compressed/Makefile b/trunk/arch/x86/boot/compressed/Makefile index 5ef205c5f37b..8a84501acb1b 100644 --- a/trunk/arch/x86/boot/compressed/Makefile +++ b/trunk/arch/x86/boot/compressed/Makefile @@ -4,7 +4,7 @@ # create a compressed vmlinux image from the original vmlinux # -targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo +targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo head_$(BITS).o misc.o string.o cmdline.o early_serial_console.o piggy.o KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC @@ -29,6 +29,7 @@ VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ $(obj)/piggy.o $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone +$(obj)/efi_stub_$(BITS).o: KBUILD_CLFAGS += -fshort-wchar -mno-red-zone ifeq ($(CONFIG_EFI_STUB), y) VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o @@ -42,7 +43,7 @@ OBJCOPYFLAGS_vmlinux.bin := -R .comment -S $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) -targets += $(patsubst $(obj)/%,%,$(VMLINUX_OBJS)) vmlinux.bin.all vmlinux.relocs +targets += vmlinux.bin.all vmlinux.relocs CMD_RELOCS = arch/x86/tools/relocs quiet_cmd_relocs = RELOCS $@ diff --git a/trunk/arch/x86/boot/compressed/eboot.c b/trunk/arch/x86/boot/compressed/eboot.c index 35ee62fccf98..c205035a6b96 100644 --- a/trunk/arch/x86/boot/compressed/eboot.c +++ b/trunk/arch/x86/boot/compressed/eboot.c @@ -251,51 +251,6 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) *size = len; } -static efi_status_t setup_efi_vars(struct boot_params *params) -{ - struct setup_data *data; - struct efi_var_bootdata *efidata; - u64 store_size, remaining_size, var_size; - efi_status_t status; - - if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION) - return EFI_UNSUPPORTED; - - data = (struct setup_data *)(unsigned long)params->hdr.setup_data; - - while (data && data->next) - data = (struct setup_data *)(unsigned long)data->next; - - status = efi_call_phys4((void *)sys_table->runtime->query_variable_info, - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS, &store_size, - &remaining_size, &var_size); - - if (status != EFI_SUCCESS) - return status; - - status = efi_call_phys3(sys_table->boottime->allocate_pool, - EFI_LOADER_DATA, sizeof(*efidata), &efidata); - - if (status != EFI_SUCCESS) - return status; - - efidata->data.type = SETUP_EFI_VARS; - efidata->data.len = sizeof(struct efi_var_bootdata) - - sizeof(struct setup_data); - efidata->data.next = 0; - efidata->store_size = store_size; - efidata->remaining_size = remaining_size; - efidata->max_var_size = var_size; - - if (data) - data->next = (unsigned long)efidata; - else - params->hdr.setup_data = (unsigned long)efidata; - -} - static efi_status_t setup_efi_pci(struct boot_params *params) { efi_pci_io_protocol *pci; @@ -1202,8 +1157,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, setup_graphics(boot_params); - setup_efi_vars(boot_params); - setup_efi_pci(boot_params); status = efi_call_phys3(sys_table->boottime->allocate_pool, diff --git a/trunk/arch/x86/include/asm/efi.h b/trunk/arch/x86/include/asm/efi.h index 2fb5d5884e23..60c89f30c727 100644 --- a/trunk/arch/x86/include/asm/efi.h +++ b/trunk/arch/x86/include/asm/efi.h @@ -102,13 +102,6 @@ extern void efi_call_phys_epilog(void); extern void efi_unmap_memmap(void); extern void efi_memory_uc(u64 addr, unsigned long size); -struct efi_var_bootdata { - struct setup_data data; - u64 store_size; - u64 remaining_size; - u64 max_var_size; -}; - #ifdef CONFIG_EFI static inline bool efi_is_native(void) diff --git a/trunk/arch/x86/include/asm/paravirt.h b/trunk/arch/x86/include/asm/paravirt.h index 7361e47db79f..5edd1742cfd0 100644 --- a/trunk/arch/x86/include/asm/paravirt.h +++ b/trunk/arch/x86/include/asm/paravirt.h @@ -703,10 +703,7 @@ static inline void arch_leave_lazy_mmu_mode(void) PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); } -static inline void arch_flush_lazy_mmu_mode(void) -{ - PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush); -} +void arch_flush_lazy_mmu_mode(void); static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, phys_addr_t phys, pgprot_t flags) diff --git a/trunk/arch/x86/include/asm/paravirt_types.h b/trunk/arch/x86/include/asm/paravirt_types.h index b3b0ec1dac86..142236ed83af 100644 --- a/trunk/arch/x86/include/asm/paravirt_types.h +++ b/trunk/arch/x86/include/asm/paravirt_types.h @@ -91,7 +91,6 @@ struct pv_lazy_ops { /* Set deferred update mode, used for batching operations. */ void (*enter)(void); void (*leave)(void); - void (*flush)(void); }; struct pv_time_ops { @@ -680,7 +679,6 @@ void paravirt_end_context_switch(struct task_struct *next); void paravirt_enter_lazy_mmu(void); void paravirt_leave_lazy_mmu(void); -void paravirt_flush_lazy_mmu(void); void _paravirt_nop(void); u32 _paravirt_ident_32(u32); diff --git a/trunk/arch/x86/include/asm/syscall.h b/trunk/arch/x86/include/asm/syscall.h index 2e188d68397c..1ace47b62592 100644 --- a/trunk/arch/x86/include/asm/syscall.h +++ b/trunk/arch/x86/include/asm/syscall.h @@ -29,13 +29,13 @@ extern const unsigned long sys_call_table[]; */ static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return regs->orig_ax; + return regs->orig_ax & __SYSCALL_MASK; } static inline void syscall_rollback(struct task_struct *task, struct pt_regs *regs) { - regs->ax = regs->orig_ax; + regs->ax = regs->orig_ax & __SYSCALL_MASK; } static inline long syscall_get_error(struct task_struct *task, diff --git a/trunk/arch/x86/include/asm/tlb.h b/trunk/arch/x86/include/asm/tlb.h index c7797307fc2b..4fef20773b8f 100644 --- a/trunk/arch/x86/include/asm/tlb.h +++ b/trunk/arch/x86/include/asm/tlb.h @@ -7,7 +7,7 @@ #define tlb_flush(tlb) \ { \ - if (!tlb->fullmm && !tlb->need_flush_all) \ + if (tlb->fullmm == 0) \ flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \ else \ flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL); \ diff --git a/trunk/arch/x86/include/uapi/asm/bootparam.h b/trunk/arch/x86/include/uapi/asm/bootparam.h index 08744242b8d2..c15ddaf90710 100644 --- a/trunk/arch/x86/include/uapi/asm/bootparam.h +++ b/trunk/arch/x86/include/uapi/asm/bootparam.h @@ -6,7 +6,6 @@ #define SETUP_E820_EXT 1 #define SETUP_DTB 2 #define SETUP_PCI 3 -#define SETUP_EFI_VARS 4 /* ram_size flags */ #define RAMDISK_IMAGE_START_MASK 0x07FF diff --git a/trunk/arch/x86/kernel/cpu/mshyperv.c b/trunk/arch/x86/kernel/cpu/mshyperv.c index 8f4be53ea04b..a7d26d83fb70 100644 --- a/trunk/arch/x86/kernel/cpu/mshyperv.c +++ b/trunk/arch/x86/kernel/cpu/mshyperv.c @@ -35,6 +35,13 @@ static bool __init ms_hyperv_platform(void) if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) return false; + /* + * Xen emulates Hyper-V to support enlightened Windows. + * Check to see first if we are on a Xen Hypervisor. + */ + if (xen_cpuid_base()) + return false; + cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); @@ -75,6 +82,12 @@ static void __init ms_hyperv_init_platform(void) if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); +#if IS_ENABLED(CONFIG_HYPERV) + /* + * Setup the IDT for hypervisor callback. + */ + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); +#endif } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { @@ -90,11 +103,6 @@ static irq_handler_t vmbus_isr; void hv_register_vmbus_handler(int irq, irq_handler_t handler) { - /* - * Setup the IDT for hypervisor callback. - */ - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); - vmbus_irq = irq; vmbus_isr = handler; } diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c index cc45deb791b0..dab7580c47ae 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c @@ -153,14 +153,8 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly = }; static struct extra_reg intel_snb_extra_regs[] __read_mostly = { - INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), - INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), - EVENT_EXTRA_END -}; - -static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { - INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), - INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), + INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0), + INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1), EVENT_EXTRA_END }; @@ -2103,10 +2097,7 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_snb_event_constraints; x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; x86_pmu.pebs_aliases = intel_pebs_aliases_snb; - if (boot_cpu_data.x86_model == 45) - x86_pmu.extra_regs = intel_snbep_extra_regs; - else - x86_pmu.extra_regs = intel_snb_extra_regs; + x86_pmu.extra_regs = intel_snb_extra_regs; /* all extra regs are per-cpu when HT is on */ x86_pmu.er_flags |= ERF_HAS_RSP_1; x86_pmu.er_flags |= ERF_NO_HT_SHARING; @@ -2132,10 +2123,7 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_ivb_event_constraints; x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints; x86_pmu.pebs_aliases = intel_pebs_aliases_snb; - if (boot_cpu_data.x86_model == 62) - x86_pmu.extra_regs = intel_snbep_extra_regs; - else - x86_pmu.extra_regs = intel_snb_extra_regs; + x86_pmu.extra_regs = intel_snb_extra_regs; /* all extra regs are per-cpu when HT is on */ x86_pmu.er_flags |= ERF_HAS_RSP_1; x86_pmu.er_flags |= ERF_NO_HT_SHARING; diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c index 26830f3af0df..b05a575d56f4 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -314,11 +314,10 @@ int intel_pmu_drain_bts_buffer(void) if (top <= at) return 0; - memset(®s, 0, sizeof(regs)); - ds->bts_index = ds->bts_buffer_base; perf_sample_data_init(&data, 0, event->hw.last_period); + regs.ip = 0; /* * Prepare a generic sample, i.e. fill in the invariant fields. diff --git a/trunk/arch/x86/kernel/microcode_core_early.c b/trunk/arch/x86/kernel/microcode_core_early.c index 833d51d6ee06..577db8417d15 100644 --- a/trunk/arch/x86/kernel/microcode_core_early.c +++ b/trunk/arch/x86/kernel/microcode_core_early.c @@ -45,6 +45,9 @@ static int __cpuinit x86_vendor(void) u32 eax = 0x00000000; u32 ebx, ecx = 0, edx; + if (!have_cpuid_p()) + return X86_VENDOR_UNKNOWN; + native_cpuid(&eax, &ebx, &ecx, &edx); if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) @@ -56,45 +59,18 @@ static int __cpuinit x86_vendor(void) return X86_VENDOR_UNKNOWN; } -static int __cpuinit x86_family(void) -{ - u32 eax = 0x00000001; - u32 ebx, ecx = 0, edx; - int x86; - - native_cpuid(&eax, &ebx, &ecx, &edx); - - x86 = (eax >> 8) & 0xf; - if (x86 == 15) - x86 += (eax >> 20) & 0xff; - - return x86; -} - void __init load_ucode_bsp(void) { - int vendor, x86; - - if (!have_cpuid_p()) - return; + int vendor = x86_vendor(); - vendor = x86_vendor(); - x86 = x86_family(); - - if (vendor == X86_VENDOR_INTEL && x86 >= 6) + if (vendor == X86_VENDOR_INTEL) load_ucode_intel_bsp(); } void __cpuinit load_ucode_ap(void) { - int vendor, x86; - - if (!have_cpuid_p()) - return; - - vendor = x86_vendor(); - x86 = x86_family(); + int vendor = x86_vendor(); - if (vendor == X86_VENDOR_INTEL && x86 >= 6) + if (vendor == X86_VENDOR_INTEL) load_ucode_intel_ap(); } diff --git a/trunk/arch/x86/kernel/paravirt.c b/trunk/arch/x86/kernel/paravirt.c index 8bfb335f74bb..17fff18a1031 100644 --- a/trunk/arch/x86/kernel/paravirt.c +++ b/trunk/arch/x86/kernel/paravirt.c @@ -263,18 +263,6 @@ void paravirt_leave_lazy_mmu(void) leave_lazy(PARAVIRT_LAZY_MMU); } -void paravirt_flush_lazy_mmu(void) -{ - preempt_disable(); - - if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { - arch_leave_lazy_mmu_mode(); - arch_enter_lazy_mmu_mode(); - } - - preempt_enable(); -} - void paravirt_start_context_switch(struct task_struct *prev) { BUG_ON(preemptible()); @@ -304,6 +292,18 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) return this_cpu_read(paravirt_lazy_mode); } +void arch_flush_lazy_mmu_mode(void) +{ + preempt_disable(); + + if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { + arch_leave_lazy_mmu_mode(); + arch_enter_lazy_mmu_mode(); + } + + preempt_enable(); +} + struct pv_info pv_info = { .name = "bare hardware", .paravirt_enabled = 0, @@ -475,7 +475,6 @@ struct pv_mmu_ops pv_mmu_ops = { .lazy_mode = { .enter = paravirt_nop, .leave = paravirt_nop, - .flush = paravirt_nop, }, .set_fixmap = native_set_fixmap, diff --git a/trunk/arch/x86/kernel/setup.c b/trunk/arch/x86/kernel/setup.c index fae9134a2de9..90d8cc930f5e 100644 --- a/trunk/arch/x86/kernel/setup.c +++ b/trunk/arch/x86/kernel/setup.c @@ -507,14 +507,11 @@ static void __init memblock_x86_reserve_range_setup_data(void) /* * Keep the crash kernel below this limit. On 32 bits earlier kernels * would limit the kernel to the low 512 MiB due to mapping restrictions. - * On 64bit, old kexec-tools need to under 896MiB. */ #ifdef CONFIG_X86_32 -# define CRASH_KERNEL_ADDR_LOW_MAX (512 << 20) -# define CRASH_KERNEL_ADDR_HIGH_MAX (512 << 20) +# define CRASH_KERNEL_ADDR_MAX (512 << 20) #else -# define CRASH_KERNEL_ADDR_LOW_MAX (896UL<<20) -# define CRASH_KERNEL_ADDR_HIGH_MAX MAXMEM +# define CRASH_KERNEL_ADDR_MAX MAXMEM #endif static void __init reserve_crashkernel_low(void) @@ -524,35 +521,19 @@ static void __init reserve_crashkernel_low(void) unsigned long long low_base = 0, low_size = 0; unsigned long total_low_mem; unsigned long long base; - bool auto_set = false; int ret; total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); - /* crashkernel=Y,low */ ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base); - if (ret != 0) { - /* - * two parts from lib/swiotlb.c: - * swiotlb size: user specified with swiotlb= or default. - * swiotlb overflow buffer: now is hardcoded to 32k. - * We round it to 8M for other buffers that - * may need to stay low too. - */ - low_size = swiotlb_size_or_default() + (8UL<<20); - auto_set = true; - } else { - /* passed with crashkernel=0,low ? */ - if (!low_size) - return; - } + if (ret != 0 || low_size <= 0) + return; low_base = memblock_find_in_range(low_size, (1ULL<<32), low_size, alignment); if (!low_base) { - if (!auto_set) - pr_info("crashkernel low reservation failed - No suitable area found.\n"); + pr_info("crashkernel low reservation failed - No suitable area found.\n"); return; } @@ -573,22 +554,14 @@ static void __init reserve_crashkernel(void) const unsigned long long alignment = 16<<20; /* 16M */ unsigned long long total_mem; unsigned long long crash_size, crash_base; - bool high = false; int ret; total_mem = memblock_phys_mem_size(); - /* crashkernel=XM */ ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base); - if (ret != 0 || crash_size <= 0) { - /* crashkernel=X,high */ - ret = parse_crashkernel_high(boot_command_line, total_mem, - &crash_size, &crash_base); - if (ret != 0 || crash_size <= 0) - return; - high = true; - } + if (ret != 0 || crash_size <= 0) + return; /* 0 means: find the address automatically */ if (crash_base <= 0) { @@ -596,9 +569,7 @@ static void __init reserve_crashkernel(void) * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX */ crash_base = memblock_find_in_range(alignment, - high ? CRASH_KERNEL_ADDR_HIGH_MAX : - CRASH_KERNEL_ADDR_LOW_MAX, - crash_size, alignment); + CRASH_KERNEL_ADDR_MAX, crash_size, alignment); if (!crash_base) { pr_info("crashkernel reservation failed - No suitable area found.\n"); diff --git a/trunk/arch/x86/kvm/lapic.c b/trunk/arch/x86/kvm/lapic.c index f77df1c5de6e..02b51dd4e4ad 100644 --- a/trunk/arch/x86/kvm/lapic.c +++ b/trunk/arch/x86/kvm/lapic.c @@ -1857,7 +1857,7 @@ int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data) if (!pv_eoi_enabled(vcpu)) return 0; return kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_eoi.data, - addr, sizeof(u8)); + addr); } void kvm_lapic_init(void) diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index e1721324c271..f19ac0aca60d 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -1823,8 +1823,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) return 0; } - if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa, - sizeof(u32))) + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa)) return 1; vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS); @@ -1953,9 +1952,12 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) gpa_offset = data & ~(PAGE_MASK | 1); + /* Check that the address is 32-byte aligned. */ + if (gpa_offset & (sizeof(struct pvclock_vcpu_time_info) - 1)) + break; + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, - &vcpu->arch.pv_time, data & ~1ULL, - sizeof(struct pvclock_vcpu_time_info))) + &vcpu->arch.pv_time, data & ~1ULL)) vcpu->arch.pv_time_enabled = false; else vcpu->arch.pv_time_enabled = true; @@ -1975,8 +1977,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 1; if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime, - data & KVM_STEAL_VALID_BITS, - sizeof(struct kvm_steal_time))) + data & KVM_STEAL_VALID_BITS)) return 1; vcpu->arch.st.msr_val = data; diff --git a/trunk/arch/x86/lguest/boot.c b/trunk/arch/x86/lguest/boot.c index 7114c63f047d..1cbd89ca5569 100644 --- a/trunk/arch/x86/lguest/boot.c +++ b/trunk/arch/x86/lguest/boot.c @@ -1334,7 +1334,6 @@ __init void lguest_init(void) pv_mmu_ops.read_cr3 = lguest_read_cr3; pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode; - pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu; pv_mmu_ops.pte_update = lguest_pte_update; pv_mmu_ops.pte_update_defer = lguest_pte_update; diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index 0e883364abb5..2b97525246d4 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -378,12 +378,10 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) if (pgd_none(*pgd_ref)) return -1; - if (pgd_none(*pgd)) { + if (pgd_none(*pgd)) set_pgd(pgd, *pgd_ref); - arch_flush_lazy_mmu_mode(); - } else { + else BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); - } /* * Below here mismatches are bugs because these lower tables diff --git a/trunk/arch/x86/mm/pageattr-test.c b/trunk/arch/x86/mm/pageattr-test.c index 0e38951e65eb..b0086567271c 100644 --- a/trunk/arch/x86/mm/pageattr-test.c +++ b/trunk/arch/x86/mm/pageattr-test.c @@ -68,7 +68,7 @@ static int print_split(struct split_state *s) s->gpg++; i += GPS/PAGE_SIZE; } else if (level == PG_LEVEL_2M) { - if ((pte_val(*pte) & _PAGE_PRESENT) && !(pte_val(*pte) & _PAGE_PSE)) { + if (!(pte_val(*pte) & _PAGE_PSE)) { printk(KERN_ERR "%lx level %d but not PSE %Lx\n", addr, level, (u64)pte_val(*pte)); diff --git a/trunk/arch/x86/mm/pageattr.c b/trunk/arch/x86/mm/pageattr.c index fb4e73ec24d8..091934e1d0d9 100644 --- a/trunk/arch/x86/mm/pageattr.c +++ b/trunk/arch/x86/mm/pageattr.c @@ -467,7 +467,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, * We are safe now. Check whether the new pgprot is the same: */ old_pte = *kpte; - old_prot = req_prot = pte_pgprot(old_pte); + old_prot = new_prot = req_prot = pte_pgprot(old_pte); pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); pgprot_val(req_prot) |= pgprot_val(cpa->mask_set); @@ -478,12 +478,12 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL * for the ancient hardware that doesn't support it. */ - if (pgprot_val(req_prot) & _PAGE_PRESENT) - pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL; + if (pgprot_val(new_prot) & _PAGE_PRESENT) + pgprot_val(new_prot) |= _PAGE_PSE | _PAGE_GLOBAL; else - pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); + pgprot_val(new_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); - req_prot = canon_pgprot(req_prot); + new_prot = canon_pgprot(new_prot); /* * old_pte points to the large page base address. So we need @@ -1413,8 +1413,6 @@ void kernel_map_pages(struct page *page, int numpages, int enable) * but that can deadlock->flush only current cpu: */ __flush_tlb_all(); - - arch_flush_lazy_mmu_mode(); } #ifdef CONFIG_HIBERNATION diff --git a/trunk/arch/x86/mm/pgtable.c b/trunk/arch/x86/mm/pgtable.c index 17fda6a8b3c2..193350b51f90 100644 --- a/trunk/arch/x86/mm/pgtable.c +++ b/trunk/arch/x86/mm/pgtable.c @@ -58,13 +58,6 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); - /* - * NOTE! For PAE, any changes to the top page-directory-pointer-table - * entries need a full cr3 reload to flush. - */ -#ifdef CONFIG_X86_PAE - tlb->need_flush_all = 1; -#endif tlb_remove_page(tlb, virt_to_page(pmd)); } diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 305c68b8d538..901177d75ff5 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -171,16 +170,6 @@ void pcibios_fixup_bus(struct pci_bus *b) pcibios_fixup_device_resources(dev); } -void pcibios_add_bus(struct pci_bus *bus) -{ - acpi_pci_add_bus(bus); -} - -void pcibios_remove_bus(struct pci_bus *bus) -{ - acpi_pci_remove_bus(bus); -} - /* * Only use DMI information to set this if nothing was passed * on the kernel command line (which was parsed earlier). diff --git a/trunk/arch/x86/pci/xen.c b/trunk/arch/x86/pci/xen.c index 4a9be6ddf054..94e76620460f 100644 --- a/trunk/arch/x86/pci/xen.c +++ b/trunk/arch/x86/pci/xen.c @@ -177,7 +177,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) goto error; i = 0; list_for_each_entry(msidesc, &dev->msi_list, list) { - irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0, (type == PCI_CAP_ID_MSIX) ? "pcifront-msi-x" : "pcifront-msi", @@ -244,7 +244,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) dev_dbg(&dev->dev, "xen: msi already bound to pirq=%d\n", pirq); } - irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, + irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0, (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi", DOMID_SELF); @@ -326,7 +326,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) } ret = xen_bind_pirq_msi_to_irq(dev, msidesc, - map_irq.pirq, + map_irq.pirq, map_irq.index, (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi", domid); diff --git a/trunk/arch/x86/platform/efi/efi.c b/trunk/arch/x86/platform/efi/efi.c index e4a86a677ce1..5f2ecaf3f9d8 100644 --- a/trunk/arch/x86/platform/efi/efi.c +++ b/trunk/arch/x86/platform/efi/efi.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -52,13 +51,6 @@ #define EFI_DEBUG 1 -/* - * There's some additional metadata associated with each - * variable. Intel's reference implementation is 60 bytes - bump that - * to account for potential alignment constraints - */ -#define VAR_METADATA_SIZE 64 - struct efi __read_mostly efi = { .mps = EFI_INVALID_TABLE_ADDR, .acpi = EFI_INVALID_TABLE_ADDR, @@ -77,13 +69,6 @@ struct efi_memory_map memmap; static struct efi efi_phys __initdata; static efi_system_table_t efi_systab __initdata; -static u64 efi_var_store_size; -static u64 efi_var_remaining_size; -static u64 efi_var_max_var_size; -static u64 boot_used_size; -static u64 boot_var_size; -static u64 active_size; - unsigned long x86_efi_facility; /* @@ -113,15 +98,6 @@ static int __init setup_add_efi_memmap(char *arg) } early_param("add_efi_memmap", setup_add_efi_memmap); -static bool efi_no_storage_paranoia; - -static int __init setup_storage_paranoia(char *arg) -{ - efi_no_storage_paranoia = true; - return 0; -} -early_param("efi_no_storage_paranoia", setup_storage_paranoia); - static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) { @@ -186,53 +162,8 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor) { - efi_status_t status; - static bool finished = false; - static u64 var_size; - - status = efi_call_virt3(get_next_variable, - name_size, name, vendor); - - if (status == EFI_NOT_FOUND) { - finished = true; - if (var_size < boot_used_size) { - boot_var_size = boot_used_size - var_size; - active_size += boot_var_size; - } else { - printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n"); - } - } - - if (boot_used_size && !finished) { - unsigned long size; - u32 attr; - efi_status_t s; - void *tmp; - - s = virt_efi_get_variable(name, vendor, &attr, &size, NULL); - - if (s != EFI_BUFFER_TOO_SMALL || !size) - return status; - - tmp = kmalloc(size, GFP_ATOMIC); - - if (!tmp) - return status; - - s = virt_efi_get_variable(name, vendor, &attr, &size, tmp); - - if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) { - var_size += size; - var_size += ucs2_strsize(name, 1024); - active_size += size; - active_size += VAR_METADATA_SIZE; - active_size += ucs2_strsize(name, 1024); - } - - kfree(tmp); - } - - return status; + return efi_call_virt3(get_next_variable, + name_size, name, vendor); } static efi_status_t virt_efi_set_variable(efi_char16_t *name, @@ -241,34 +172,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, unsigned long data_size, void *data) { - efi_status_t status; - u32 orig_attr = 0; - unsigned long orig_size = 0; - - status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size, - NULL); - - if (status != EFI_BUFFER_TOO_SMALL) - orig_size = 0; - - status = efi_call_virt5(set_variable, - name, vendor, attr, - data_size, data); - - if (status == EFI_SUCCESS) { - if (orig_size) { - active_size -= orig_size; - active_size -= ucs2_strsize(name, 1024); - active_size -= VAR_METADATA_SIZE; - } - if (data_size) { - active_size += data_size; - active_size += ucs2_strsize(name, 1024); - active_size += VAR_METADATA_SIZE; - } - } - - return status; + return efi_call_virt5(set_variable, + name, vendor, attr, + data_size, data); } static efi_status_t virt_efi_query_variable_info(u32 attr, @@ -776,9 +682,6 @@ void __init efi_init(void) char vendor[100] = "unknown"; int i = 0; void *tmp; - struct setup_data *data; - struct efi_var_bootdata *efi_var_data; - u64 pa_data; #ifdef CONFIG_X86_32 if (boot_params.efi_info.efi_systab_hi || @@ -796,22 +699,6 @@ void __init efi_init(void) if (efi_systab_init(efi_phys.systab)) return; - pa_data = boot_params.hdr.setup_data; - while (pa_data) { - data = early_ioremap(pa_data, sizeof(*efi_var_data)); - if (data->type == SETUP_EFI_VARS) { - efi_var_data = (struct efi_var_bootdata *)data; - - efi_var_store_size = efi_var_data->store_size; - efi_var_remaining_size = efi_var_data->remaining_size; - efi_var_max_var_size = efi_var_data->max_var_size; - } - pa_data = data->next; - early_iounmap(data, sizeof(*efi_var_data)); - } - - boot_used_size = efi_var_store_size - efi_var_remaining_size; - set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); /* @@ -1112,48 +999,3 @@ u64 efi_mem_attributes(unsigned long phys_addr) } return 0; } - -/* - * Some firmware has serious problems when using more than 50% of the EFI - * variable store, i.e. it triggers bugs that can brick machines. Ensure that - * we never use more than this safe limit. - * - * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable - * store. - */ -efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) -{ - efi_status_t status; - u64 storage_size, remaining_size, max_size; - - status = efi.query_variable_info(attributes, &storage_size, - &remaining_size, &max_size); - if (status != EFI_SUCCESS) - return status; - - if (!max_size && remaining_size > size) - printk_once(KERN_ERR FW_BUG "Broken EFI implementation" - " is returning MaxVariableSize=0\n"); - /* - * Some firmware implementations refuse to boot if there's insufficient - * space in the variable store. We account for that by refusing the - * write if permitting it would reduce the available space to under - * 50%. However, some firmware won't reclaim variable space until - * after the used (not merely the actively used) space drops below - * a threshold. We can approximate that case with the value calculated - * above. If both the firmware and our calculations indicate that the - * available space would drop below 50%, refuse the write. - */ - - if (!storage_size || size > remaining_size || - (max_size && size > max_size)) - return EFI_OUT_OF_RESOURCES; - - if (!efi_no_storage_paranoia && - ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && - (remaining_size - size < storage_size / 2))) - return EFI_OUT_OF_RESOURCES; - - return EFI_SUCCESS; -} -EXPORT_SYMBOL_GPL(efi_query_variable_store); diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index ddbd54a9b845..c8e1c7b95c3b 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -1307,55 +1306,6 @@ static const struct machine_ops xen_machine_ops __initconst = { .emergency_restart = xen_emergency_restart, }; -static void __init xen_boot_params_init_edd(void) -{ -#if IS_ENABLED(CONFIG_EDD) - struct xen_platform_op op; - struct edd_info *edd_info; - u32 *mbr_signature; - unsigned nr; - int ret; - - edd_info = boot_params.eddbuf; - mbr_signature = boot_params.edd_mbr_sig_buffer; - - op.cmd = XENPF_firmware_info; - - op.u.firmware_info.type = XEN_FW_DISK_INFO; - for (nr = 0; nr < EDDMAXNR; nr++) { - struct edd_info *info = edd_info + nr; - - op.u.firmware_info.index = nr; - info->params.length = sizeof(info->params); - set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, - &info->params); - ret = HYPERVISOR_dom0_op(&op); - if (ret) - break; - -#define C(x) info->x = op.u.firmware_info.u.disk_info.x - C(device); - C(version); - C(interface_support); - C(legacy_max_cylinder); - C(legacy_max_head); - C(legacy_sectors_per_track); -#undef C - } - boot_params.eddbuf_entries = nr; - - op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; - for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { - op.u.firmware_info.index = nr; - ret = HYPERVISOR_dom0_op(&op); - if (ret) - break; - mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; - } - boot_params.edd_mbr_sig_buf_entries = nr; -#endif -} - /* * Set up the GDT and segment registers for -fstack-protector. Until * we do this, we have to be careful not to call any stack-protected @@ -1558,8 +1508,6 @@ asmlinkage void __init xen_start_kernel(void) /* Avoid searching for BIOS MP tables */ x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.mpparse.get_smp_config = x86_init_uint_noop; - - xen_boot_params_init_edd(); } #ifdef CONFIG_PCI /* PCI BIOS service won't work from a PV guest. */ @@ -1641,11 +1589,8 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self, switch (action) { case CPU_UP_PREPARE: xen_vcpu_setup(cpu); - if (xen_have_vector_callback) { + if (xen_have_vector_callback) xen_init_lock_cpu(cpu); - if (xen_feature(XENFEAT_hvm_safe_pvclock)) - xen_setup_timer(cpu); - } break; default: break; diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index e006c18d288a..6afbb2ca9a0a 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1748,18 +1748,14 @@ static void *m2v(phys_addr_t maddr) } /* Set the page permissions on an identity-mapped pages */ -static void set_page_prot_flags(void *addr, pgprot_t prot, unsigned long flags) +static void set_page_prot(void *addr, pgprot_t prot) { unsigned long pfn = __pa(addr) >> PAGE_SHIFT; pte_t pte = pfn_pte(pfn, prot); - if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, flags)) + if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0)) BUG(); } -static void set_page_prot(void *addr, pgprot_t prot) -{ - return set_page_prot_flags(addr, prot, UVMF_NONE); -} #ifdef CONFIG_X86_32 static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) { @@ -1843,12 +1839,12 @@ static void __init check_pt_base(unsigned long *pt_base, unsigned long *pt_end, unsigned long addr) { if (*pt_base == PFN_DOWN(__pa(addr))) { - set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); + set_page_prot((void *)addr, PAGE_KERNEL); clear_page((void *)addr); (*pt_base)++; } if (*pt_end == PFN_DOWN(__pa(addr))) { - set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); + set_page_prot((void *)addr, PAGE_KERNEL); clear_page((void *)addr); (*pt_end)--; } @@ -2200,7 +2196,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { .lazy_mode = { .enter = paravirt_enter_lazy_mmu, .leave = xen_leave_lazy_mmu, - .flush = paravirt_flush_lazy_mmu, }, .set_fixmap = xen_set_fixmap, diff --git a/trunk/arch/x86/xen/smp.c b/trunk/arch/x86/xen/smp.c index 0d466d7c7175..09ea61d2e02f 100644 --- a/trunk/arch/x86/xen/smp.c +++ b/trunk/arch/x86/xen/smp.c @@ -144,13 +144,6 @@ static int xen_smp_intr_init(unsigned int cpu) goto fail; per_cpu(xen_callfuncsingle_irq, cpu) = rc; - /* - * The IRQ worker on PVHVM goes through the native path and uses the - * IPI mechanism. - */ - if (xen_hvm_domain()) - return 0; - callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, cpu, @@ -174,9 +167,6 @@ static int xen_smp_intr_init(unsigned int cpu) if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0) unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); - if (xen_hvm_domain()) - return rc; - if (per_cpu(xen_irq_work, cpu) >= 0) unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); @@ -428,7 +418,7 @@ static int xen_cpu_disable(void) static void xen_cpu_die(unsigned int cpu) { - while (xen_pv_domain() && HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { + while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { current->state = TASK_UNINTERRUPTIBLE; schedule_timeout(HZ/10); } @@ -436,8 +426,7 @@ static void xen_cpu_die(unsigned int cpu) unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); - if (!xen_hvm_domain()) - unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); xen_uninit_lock_cpu(cpu); xen_teardown_timer(cpu); } @@ -668,7 +657,11 @@ static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) static void xen_hvm_cpu_die(unsigned int cpu) { - xen_cpu_die(cpu); + unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); + unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); native_cpu_die(cpu); } diff --git a/trunk/arch/x86/xen/spinlock.c b/trunk/arch/x86/xen/spinlock.c index 8b54603ce816..f7a080ef0354 100644 --- a/trunk/arch/x86/xen/spinlock.c +++ b/trunk/arch/x86/xen/spinlock.c @@ -364,16 +364,6 @@ void __cpuinit xen_init_lock_cpu(int cpu) int irq; const char *name; - WARN(per_cpu(lock_kicker_irq, cpu) > 0, "spinlock on CPU%d exists on IRQ%d!\n", - cpu, per_cpu(lock_kicker_irq, cpu)); - - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) - return; - name = kasprintf(GFP_KERNEL, "spinlock%d", cpu); irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR, cpu, @@ -392,26 +382,11 @@ void __cpuinit xen_init_lock_cpu(int cpu) void xen_uninit_lock_cpu(int cpu) { - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) - return; - unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL); - per_cpu(lock_kicker_irq, cpu) = -1; } void __init xen_init_spinlocks(void) { - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) - return; - BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); pv_lock_ops.spin_is_locked = xen_spin_is_locked; diff --git a/trunk/arch/x86/xen/time.c b/trunk/arch/x86/xen/time.c index 3d88bfdf9e1c..0296a9522501 100644 --- a/trunk/arch/x86/xen/time.c +++ b/trunk/arch/x86/xen/time.c @@ -377,7 +377,7 @@ static const struct clock_event_device xen_vcpuop_clockevent = { static const struct clock_event_device *xen_clockevent = &xen_timerop_clockevent; -static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events) = { .irq = -1 }; +static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events); static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) { @@ -401,9 +401,6 @@ void xen_setup_timer(int cpu) struct clock_event_device *evt; int irq; - evt = &per_cpu(xen_clock_events, cpu); - WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu); - printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); name = kasprintf(GFP_KERNEL, "timer%d", cpu); @@ -416,6 +413,7 @@ void xen_setup_timer(int cpu) IRQF_FORCE_RESUME, name, NULL); + evt = &per_cpu(xen_clock_events, cpu); memcpy(evt, xen_clockevent, sizeof(*evt)); evt->cpumask = cpumask_of(cpu); @@ -428,7 +426,6 @@ void xen_teardown_timer(int cpu) BUG_ON(cpu == 0); evt = &per_cpu(xen_clock_events, cpu); unbind_from_irqhandler(evt->irq, NULL); - evt->irq = -1; } void xen_setup_cpu_clockevents(void) @@ -500,11 +497,7 @@ static void xen_hvm_setup_cpu_clockevents(void) { int cpu = smp_processor_id(); xen_setup_runstate_info(cpu); - /* - * xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence - * doing it xen_hvm_cpu_notify (which gets called by smp_init during - * early bootup and also during CPU hotplug events). - */ + xen_setup_timer(cpu); xen_setup_cpu_clockevents(); } diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 7c288358a745..074b758efc42 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -39,7 +39,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap); EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); -EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); EXPORT_TRACEPOINT_SYMBOL_GPL(block_unplug); DEFINE_IDA(blk_queue_ida); diff --git a/trunk/block/blk-sysfs.c b/trunk/block/blk-sysfs.c index 5efc5a647183..6206a934eb8c 100644 --- a/trunk/block/blk-sysfs.c +++ b/trunk/block/blk-sysfs.c @@ -229,8 +229,6 @@ queue_store_##name(struct request_queue *q, const char *page, size_t count) \ unsigned long val; \ ssize_t ret; \ ret = queue_var_store(&val, page, count); \ - if (ret < 0) \ - return ret; \ if (neg) \ val = !val; \ \ diff --git a/trunk/block/partition-generic.c b/trunk/block/partition-generic.c index 789cdea05893..ae95ee6a58aa 100644 --- a/trunk/block/partition-generic.c +++ b/trunk/block/partition-generic.c @@ -257,6 +257,7 @@ void delete_partition(struct gendisk *disk, int partno) hd_struct_put(part); } +EXPORT_SYMBOL(delete_partition); static ssize_t whole_disk_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/trunk/crypto/algif_hash.c b/trunk/crypto/algif_hash.c index 0262210cad38..ef5356cd280a 100644 --- a/trunk/crypto/algif_hash.c +++ b/trunk/crypto/algif_hash.c @@ -161,8 +161,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock, else if (len < ds) msg->msg_flags |= MSG_TRUNC; - msg->msg_namelen = 0; - lock_sock(sk); if (ctx->more) { ctx->more = 0; diff --git a/trunk/crypto/algif_skcipher.c b/trunk/crypto/algif_skcipher.c index a1c4f0a55583..6a6dfc062d2a 100644 --- a/trunk/crypto/algif_skcipher.c +++ b/trunk/crypto/algif_skcipher.c @@ -432,7 +432,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, long copied = 0; lock_sock(sk); - msg->msg_namelen = 0; for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; iovlen--, iov++) { unsigned long seglen = iov->iov_len; diff --git a/trunk/crypto/gcm.c b/trunk/crypto/gcm.c index 13ccbda34ff9..137ad1ec5438 100644 --- a/trunk/crypto/gcm.c +++ b/trunk/crypto/gcm.c @@ -44,7 +44,6 @@ struct crypto_rfc4543_ctx { struct crypto_rfc4543_req_ctx { u8 auth_tag[16]; - u8 assocbuf[32]; struct scatterlist cipher[1]; struct scatterlist payload[2]; struct scatterlist assoc[2]; @@ -1134,19 +1133,9 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2); assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); - if (req->assoc->length == req->assoclen) { - sg_init_table(assoc, 2); - sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, - req->assoc->offset); - } else { - BUG_ON(req->assoclen > sizeof(rctx->assocbuf)); - - scatterwalk_map_and_copy(rctx->assocbuf, req->assoc, 0, - req->assoclen, 0); - - sg_init_table(assoc, 2); - sg_set_buf(assoc, rctx->assocbuf, req->assoclen); - } + sg_init_table(assoc, 2); + sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, + req->assoc->offset); scatterwalk_crypto_chain(assoc, payload, 0, 2); aead_request_set_tfm(subreq, ctx->child); diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 4bf68c8d4797..92ed9692c47e 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -396,7 +396,7 @@ config ACPI_CUSTOM_METHOD config ACPI_BGRT bool "Boottime Graphics Resource Table support" - depends on EFI && X86 + depends on EFI help This driver adds support for exposing the ACPI Boottime Graphics Resource Table, which allows the operating system to obtain diff --git a/trunk/drivers/acpi/acpi_i2c.c b/trunk/drivers/acpi/acpi_i2c.c index a82c7626aa9b..82045e3f5cac 100644 --- a/trunk/drivers/acpi/acpi_i2c.c +++ b/trunk/drivers/acpi/acpi_i2c.c @@ -90,7 +90,7 @@ void acpi_i2c_register_devices(struct i2c_adapter *adapter) acpi_handle handle; acpi_status status; - handle = ACPI_HANDLE(adapter->dev.parent); + handle = ACPI_HANDLE(&adapter->dev); if (!handle) return; diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index ac8688b89705..5ff173066127 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -65,12 +65,44 @@ static struct acpi_scan_handler pci_root_handler = { .detach = acpi_pci_root_remove, }; -/* Lock to protect both acpi_pci_roots lists */ +/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ static DEFINE_MUTEX(acpi_pci_root_lock); static LIST_HEAD(acpi_pci_roots); +static LIST_HEAD(acpi_pci_drivers); static DEFINE_MUTEX(osc_lock); +int acpi_pci_register_driver(struct acpi_pci_driver *driver) +{ + int n = 0; + struct acpi_pci_root *root; + + mutex_lock(&acpi_pci_root_lock); + list_add_tail(&driver->node, &acpi_pci_drivers); + if (driver->add) + list_for_each_entry(root, &acpi_pci_roots, node) { + driver->add(root); + n++; + } + mutex_unlock(&acpi_pci_root_lock); + + return n; +} +EXPORT_SYMBOL(acpi_pci_register_driver); + +void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) +{ + struct acpi_pci_root *root; + + mutex_lock(&acpi_pci_root_lock); + list_del(&driver->node); + if (driver->remove) + list_for_each_entry(root, &acpi_pci_roots, node) + driver->remove(root); + mutex_unlock(&acpi_pci_root_lock); +} +EXPORT_SYMBOL(acpi_pci_unregister_driver); + /** * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge * @handle - the ACPI CA node in question. @@ -381,7 +413,9 @@ static int acpi_pci_root_add(struct acpi_device *device, acpi_status status; int result; struct acpi_pci_root *root; + struct acpi_pci_driver *driver; u32 flags, base_flags; + bool is_osc_granted = false; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) @@ -442,30 +476,6 @@ static int acpi_pci_root_add(struct acpi_device *device, flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; acpi_pci_osc_support(root, flags); - /* - * TBD: Need PCI interface for enumeration/configuration of roots. - */ - - mutex_lock(&acpi_pci_root_lock); - list_add_tail(&root->node, &acpi_pci_roots); - mutex_unlock(&acpi_pci_root_lock); - - /* - * Scan the Root Bridge - * -------------------- - * Must do this prior to any attempt to bind the root device, as the - * PCI namespace does not get created until this call is made (and - * thus the root bridge's pci_dev does not exist). - */ - root->bus = pci_acpi_scan_root(root); - if (!root->bus) { - printk(KERN_ERR PREFIX - "Bus %04x:%02x not present in PCI namespace\n", - root->segment, (unsigned int)root->secondary.start); - result = -ENODEV; - goto out_del_root; - } - /* Indicate support for various _OSC capabilities. */ if (pci_ext_cfg_avail()) flags |= OSC_EXT_PCI_CONFIG_SUPPORT; @@ -484,7 +494,6 @@ static int acpi_pci_root_add(struct acpi_device *device, flags = base_flags; } } - if (!pcie_ports_disabled && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL @@ -505,28 +514,54 @@ static int acpi_pci_root_add(struct acpi_device *device, status = acpi_pci_osc_control_set(device->handle, &flags, OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); if (ACPI_SUCCESS(status)) { + is_osc_granted = true; dev_info(&device->dev, "ACPI _OSC control (0x%02x) granted\n", flags); - if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { - /* - * We have ASPM control, but the FADT indicates - * that it's unsupported. Clear it. - */ - pcie_clear_aspm(root->bus); - } } else { + is_osc_granted = false; dev_info(&device->dev, "ACPI _OSC request failed (%s), " "returned control mask: 0x%02x\n", acpi_format_exception(status), flags); - pr_info("ACPI _OSC control for PCIe not granted, " - "disabling ASPM\n"); - pcie_no_aspm(); } } else { dev_info(&device->dev, - "Unable to request _OSC control " - "(_OSC support mask: 0x%02x)\n", flags); + "Unable to request _OSC control " + "(_OSC support mask: 0x%02x)\n", flags); + } + + /* + * TBD: Need PCI interface for enumeration/configuration of roots. + */ + + mutex_lock(&acpi_pci_root_lock); + list_add_tail(&root->node, &acpi_pci_roots); + mutex_unlock(&acpi_pci_root_lock); + + /* + * Scan the Root Bridge + * -------------------- + * Must do this prior to any attempt to bind the root device, as the + * PCI namespace does not get created until this call is made (and + * thus the root bridge's pci_dev does not exist). + */ + root->bus = pci_acpi_scan_root(root); + if (!root->bus) { + printk(KERN_ERR PREFIX + "Bus %04x:%02x not present in PCI namespace\n", + root->segment, (unsigned int)root->secondary.start); + result = -ENODEV; + goto out_del_root; + } + + /* ASPM setting */ + if (is_osc_granted) { + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) + pcie_clear_aspm(root->bus); + } else { + pr_info("ACPI _OSC control for PCIe not granted, " + "disabling ASPM\n"); + pcie_no_aspm(); } pci_acpi_add_bus_pm_notifier(device, root->bus); @@ -538,6 +573,12 @@ static int acpi_pci_root_add(struct acpi_device *device, pci_assign_unassigned_bus_resources(root->bus); } + mutex_lock(&acpi_pci_root_lock); + list_for_each_entry(driver, &acpi_pci_drivers, node) + if (driver->add) + driver->add(root); + mutex_unlock(&acpi_pci_root_lock); + /* need to after hot-added ioapic is registered */ if (system_state != SYSTEM_BOOTING) pci_enable_bridges(root->bus); @@ -558,9 +599,16 @@ static int acpi_pci_root_add(struct acpi_device *device, static void acpi_pci_root_remove(struct acpi_device *device) { struct acpi_pci_root *root = acpi_driver_data(device); + struct acpi_pci_driver *driver; pci_stop_root_bus(root->bus); + mutex_lock(&acpi_pci_root_lock); + list_for_each_entry_reverse(driver, &acpi_pci_drivers, node) + if (driver->remove) + driver->remove(root); + mutex_unlock(&acpi_pci_root_lock); + device_set_run_wake(root->bus->bridge, false); pci_acpi_remove_bus_pm_notifier(device); diff --git a/trunk/drivers/acpi/pci_slot.c b/trunk/drivers/acpi/pci_slot.c index 033d1179bdb5..cd1434eb1de8 100644 --- a/trunk/drivers/acpi/pci_slot.c +++ b/trunk/drivers/acpi/pci_slot.c @@ -9,9 +9,6 @@ * Copyright (C) 2007-2008 Hewlett-Packard Development Company, L.P. * Alex Chiang * - * Copyright (C) 2013 Huawei Tech. Co., Ltd. - * Jiang Liu - * * 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. @@ -31,9 +28,10 @@ #include #include #include -#include #include #include +#include +#include #include static bool debug; @@ -63,12 +61,20 @@ ACPI_MODULE_NAME("pci_slot"); #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ struct acpi_pci_slot { + acpi_handle root_handle; /* handle of the root bridge */ struct pci_slot *pci_slot; /* corresponding pci_slot */ struct list_head list; /* node in the list of slots */ }; +static int acpi_pci_slot_add(struct acpi_pci_root *root); +static void acpi_pci_slot_remove(struct acpi_pci_root *root); + static LIST_HEAD(slot_list); static DEFINE_MUTEX(slot_list_lock); +static struct acpi_pci_driver acpi_pci_slot_driver = { + .add = acpi_pci_slot_add, + .remove = acpi_pci_slot_remove, +}; static int check_slot(acpi_handle handle, unsigned long long *sun) @@ -107,8 +113,21 @@ check_slot(acpi_handle handle, unsigned long long *sun) return device; } +struct callback_args { + acpi_walk_callback user_function; /* only for walk_p2p_bridge */ + struct pci_bus *pci_bus; + acpi_handle root_handle; +}; + /* - * Check whether handle has an associated slot and create PCI slot if it has. + * register_slot + * + * Called once for each SxFy object in the namespace. Don't worry about + * calling pci_create_slot multiple times for the same pci_bus:device, + * since each subsequent call simply bumps the refcount on the pci_slot. + * + * The number of calls to pci_destroy_slot from unregister_slot is + * symmetrical. */ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) @@ -118,22 +137,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) char name[SLOT_NAME_SIZE]; struct acpi_pci_slot *slot; struct pci_slot *pci_slot; - struct pci_bus *pci_bus = context; + struct callback_args *parent_context = context; + struct pci_bus *pci_bus = parent_context->pci_bus; device = check_slot(handle, &sun); if (device < 0) return AE_OK; - /* - * There may be multiple PCI functions associated with the same slot. - * Check whether PCI slot has already been created for this PCI device. - */ - list_for_each_entry(slot, &slot_list, list) { - pci_slot = slot->pci_slot; - if (pci_slot->bus == pci_bus && pci_slot->number == device) - return AE_OK; - } - slot = kmalloc(sizeof(*slot), GFP_KERNEL); if (!slot) { err("%s: cannot allocate memory\n", __func__); @@ -148,8 +158,12 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } + slot->root_handle = parent_context->root_handle; slot->pci_slot = pci_slot; + INIT_LIST_HEAD(&slot->list); + mutex_lock(&slot_list_lock); list_add(&slot->list, &slot_list); + mutex_unlock(&slot_list_lock); get_device(&pci_bus->dev); @@ -159,24 +173,131 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle) +/* + * walk_p2p_bridge - discover and walk p2p bridges + * @handle: points to an acpi_pci_root + * @context: p2p_bridge_context pointer + * + * Note that when we call ourselves recursively, we pass a different + * value of pci_bus in the child_context. + */ +static acpi_status +walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) { - mutex_lock(&slot_list_lock); - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, - register_slot, NULL, bus, NULL); - mutex_unlock(&slot_list_lock); + int device, function; + unsigned long long adr; + acpi_status status; + acpi_handle dummy_handle; + acpi_walk_callback user_function; + + struct pci_dev *dev; + struct pci_bus *pci_bus; + struct callback_args child_context; + struct callback_args *parent_context = context; + + pci_bus = parent_context->pci_bus; + user_function = parent_context->user_function; + + status = acpi_get_handle(handle, "_ADR", &dummy_handle); + if (ACPI_FAILURE(status)) + return AE_OK; + + status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); + if (ACPI_FAILURE(status)) + return AE_OK; + + device = (adr >> 16) & 0xffff; + function = adr & 0xffff; + + dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function)); + if (!dev || !dev->subordinate) + goto out; + + child_context.pci_bus = dev->subordinate; + child_context.user_function = user_function; + child_context.root_handle = parent_context->root_handle; + + dbg("p2p bridge walk, pci_bus = %x\n", dev->subordinate->number); + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + user_function, NULL, &child_context, NULL); + if (ACPI_FAILURE(status)) + goto out; + + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + walk_p2p_bridge, NULL, &child_context, NULL); +out: + pci_dev_put(dev); + return AE_OK; +} + +/* + * walk_root_bridge - generic root bridge walker + * @root: poiner of an acpi_pci_root + * @user_function: user callback for slot objects + * + * Call user_function for all objects underneath this root bridge. + * Walk p2p bridges underneath us and call user_function on those too. + */ +static int +walk_root_bridge(struct acpi_pci_root *root, acpi_walk_callback user_function) +{ + acpi_status status; + acpi_handle handle = root->device->handle; + struct pci_bus *pci_bus = root->bus; + struct callback_args context; + + context.pci_bus = pci_bus; + context.user_function = user_function; + context.root_handle = handle; + + dbg("root bridge walk, pci_bus = %x\n", pci_bus->number); + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + user_function, NULL, &context, NULL); + if (ACPI_FAILURE(status)) + return status; + + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + walk_p2p_bridge, NULL, &context, NULL); + if (ACPI_FAILURE(status)) + err("%s: walk_p2p_bridge failure - %d\n", __func__, status); + + return status; } -void acpi_pci_slot_remove(struct pci_bus *bus) +/* + * acpi_pci_slot_add + * @handle: points to an acpi_pci_root + */ +static int +acpi_pci_slot_add(struct acpi_pci_root *root) +{ + acpi_status status; + + status = walk_root_bridge(root, register_slot); + if (ACPI_FAILURE(status)) + err("%s: register_slot failure - %d\n", __func__, status); + + return status; +} + +/* + * acpi_pci_slot_remove + * @handle: points to an acpi_pci_root + */ +static void +acpi_pci_slot_remove(struct acpi_pci_root *root) { struct acpi_pci_slot *slot, *tmp; + struct pci_bus *pbus; + acpi_handle handle = root->device->handle; mutex_lock(&slot_list_lock); list_for_each_entry_safe(slot, tmp, &slot_list, list) { - if (slot->pci_slot->bus == bus) { + if (slot->root_handle == handle) { list_del(&slot->list); + pbus = slot->pci_slot->bus; pci_destroy_slot(slot->pci_slot); - put_device(&bus->dev); + put_device(&pbus->dev); kfree(slot); } } @@ -211,4 +332,5 @@ static struct dmi_system_id acpi_pci_slot_dmi_table[] __initdata = { void __init acpi_pci_slot_init(void) { dmi_check_system(acpi_pci_slot_dmi_table); + acpi_pci_register_driver(&acpi_pci_slot_driver); } diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index ee255c60bdac..fc95308e9a11 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -66,8 +66,7 @@ module_param(latency_factor, uint, 0644); static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); -static DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], - acpi_cstate); +static struct acpi_processor_cx *acpi_cstate[CPUIDLE_STATE_MAX]; static int disabled_by_idle_boot_param(void) { @@ -723,7 +722,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); + struct acpi_processor_cx *cx = acpi_cstate[index]; pr = __this_cpu_read(processors); @@ -746,7 +745,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, */ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) { - struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); + struct acpi_processor_cx *cx = acpi_cstate[index]; ACPI_FLUSH_CPU_CACHE(); @@ -776,7 +775,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); + struct acpi_processor_cx *cx = acpi_cstate[index]; pr = __this_cpu_read(processors); @@ -834,7 +833,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); + struct acpi_processor_cx *cx = acpi_cstate[index]; pr = __this_cpu_read(processors); @@ -961,7 +960,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) continue; #endif - per_cpu(acpi_cstate[count], dev->cpu) = cx; + acpi_cstate[count] = cx; count++; if (count == CPUIDLE_STATE_MAX) diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index f54d1985e594..5e7e991717d7 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -1790,6 +1790,7 @@ int __init acpi_scan_init(void) acpi_platform_init(); acpi_csrt_init(); acpi_container_init(); + acpi_pci_slot_init(); mutex_lock(&acpi_scan_lock); /* diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 251e57d38942..6a67b07de494 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -415,17 +415,17 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* Marvell */ { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9123), + { PCI_DEVICE(0x1b4b, 0x9123), .class = PCI_CLASS_STORAGE_SATA_AHCI, .class_mask = 0xffffff, .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9125), + { PCI_DEVICE(0x1b4b, 0x9125), .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a), + { PCI_DEVICE(0x1b4b, 0x917a), .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192), + { PCI_DEVICE(0x1b4b, 0x9192), .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3), + { PCI_DEVICE(0x1b4b, 0x91a3), .driver_data = board_ahci_yes_fbs }, /* Promise */ diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 2f48123d74c4..ffdd32d22602 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -150,7 +150,6 @@ enum piix_controller_ids { tolapai_sata, piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */ ich8_sata_snb, - ich8_2port_sata_snb, }; struct piix_map_db { @@ -305,7 +304,7 @@ static const struct pci_device_id piix_pci_tbl[] = { /* SATA Controller IDE (Lynx Point) */ { 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, /* SATA Controller IDE (Lynx Point) */ - { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb }, + { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Lynx Point) */ { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Lynx Point-LP) */ @@ -440,7 +439,6 @@ static const struct piix_map_db *piix_map_db_table[] = { [ich8m_apple_sata] = &ich8m_apple_map_db, [tolapai_sata] = &tolapai_map_db, [ich8_sata_snb] = &ich8_map_db, - [ich8_2port_sata_snb] = &ich8_2port_map_db, }; static struct pci_bits piix_enable_bits[] = { @@ -1244,16 +1242,6 @@ static struct ata_port_info piix_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &piix_sata_ops, }, - - [ich8_2port_sata_snb] = - { - .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR - | PIIX_FLAG_PIO16, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - .port_ops = &piix_sata_ops, - }, }; #define AHCI_PCI_BAR 5 diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 63c743baf920..497adea1f0d6 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -2329,7 +2329,7 @@ int ata_dev_configure(struct ata_device *dev) * from SATA Settings page of Identify Device Data Log. */ if (ata_id_has_devslp(dev->id)) { - u8 *sata_setting = ap->sector_buf; + u8 sata_setting[ATA_SECT_SIZE]; int i, j; dev->flags |= ATA_DFLAG_DEVSLP; @@ -2439,9 +2439,6 @@ int ata_dev_configure(struct ata_device *dev) dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, dev->max_sectors); - if (dev->horkage & ATA_HORKAGE_MAX_SEC_LBA48) - dev->max_sectors = ATA_MAX_SECTORS_LBA48; - if (ap->ops->dev_config) ap->ops->dev_config(dev); @@ -4103,7 +4100,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Weird ATAPI devices */ { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, { "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA }, - { "Slimtype DVD A DS8A8SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 }, /* Devices we expect to fail diagnostics */ diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index ff44787e5a45..318b41358187 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -532,8 +532,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) struct scsi_sense_hdr sshdr; scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sshdr); - if (sshdr.sense_key == RECOVERED_ERROR && - sshdr.asc == 0 && sshdr.ascq == 0x1d) + if (sshdr.sense_key == 0 && + sshdr.asc == 0 && sshdr.ascq == 0) cmd_result &= ~SAM_STAT_CHECK_CONDITION; } @@ -618,8 +618,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) struct scsi_sense_hdr sshdr; scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sshdr); - if (sshdr.sense_key == RECOVERED_ERROR && - sshdr.asc == 0 && sshdr.ascq == 0x1d) + if (sshdr.sense_key == 0 && + sshdr.asc == 0 && sshdr.ascq == 0) cmd_result &= ~SAM_STAT_CHECK_CONDITION; } diff --git a/trunk/drivers/base/power/qos.c b/trunk/drivers/base/power/qos.c index 71671c42ef45..5f74587ef258 100644 --- a/trunk/drivers/base/power/qos.c +++ b/trunk/drivers/base/power/qos.c @@ -46,7 +46,6 @@ #include "power.h" static DEFINE_MUTEX(dev_pm_qos_mtx); -static DEFINE_MUTEX(dev_pm_qos_sysfs_mtx); static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); @@ -217,17 +216,12 @@ void dev_pm_qos_constraints_destroy(struct device *dev) struct pm_qos_constraints *c; struct pm_qos_flags *f; - mutex_lock(&dev_pm_qos_sysfs_mtx); + mutex_lock(&dev_pm_qos_mtx); /* * If the device's PM QoS resume latency limit or PM QoS flags have been * exposed to user space, they have to be hidden at this point. */ - pm_qos_sysfs_remove_latency(dev); - pm_qos_sysfs_remove_flags(dev); - - mutex_lock(&dev_pm_qos_mtx); - __dev_pm_qos_hide_latency_limit(dev); __dev_pm_qos_hide_flags(dev); @@ -260,8 +254,6 @@ void dev_pm_qos_constraints_destroy(struct device *dev) out: mutex_unlock(&dev_pm_qos_mtx); - - mutex_unlock(&dev_pm_qos_sysfs_mtx); } /** @@ -566,14 +558,6 @@ static void __dev_pm_qos_drop_user_request(struct device *dev, kfree(req); } -static void dev_pm_qos_drop_user_request(struct device *dev, - enum dev_pm_qos_req_type type) -{ - mutex_lock(&dev_pm_qos_mtx); - __dev_pm_qos_drop_user_request(dev, type); - mutex_unlock(&dev_pm_qos_mtx); -} - /** * dev_pm_qos_expose_latency_limit - Expose PM QoS latency limit to user space. * @dev: Device whose PM QoS latency limit is to be exposed to user space. @@ -597,8 +581,6 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) return ret; } - mutex_lock(&dev_pm_qos_sysfs_mtx); - mutex_lock(&dev_pm_qos_mtx); if (IS_ERR_OR_NULL(dev->power.qos)) @@ -609,27 +591,26 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (ret < 0) { __dev_pm_qos_remove_request(req); kfree(req); - mutex_unlock(&dev_pm_qos_mtx); goto out; } - dev->power.qos->latency_req = req; - - mutex_unlock(&dev_pm_qos_mtx); + dev->power.qos->latency_req = req; ret = pm_qos_sysfs_add_latency(dev); if (ret) - dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); out: - mutex_unlock(&dev_pm_qos_sysfs_mtx); + mutex_unlock(&dev_pm_qos_mtx); return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); static void __dev_pm_qos_hide_latency_limit(struct device *dev) { - if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) + if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) { + pm_qos_sysfs_remove_latency(dev); __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + } } /** @@ -638,15 +619,9 @@ static void __dev_pm_qos_hide_latency_limit(struct device *dev) */ void dev_pm_qos_hide_latency_limit(struct device *dev) { - mutex_lock(&dev_pm_qos_sysfs_mtx); - - pm_qos_sysfs_remove_latency(dev); - mutex_lock(&dev_pm_qos_mtx); __dev_pm_qos_hide_latency_limit(dev); mutex_unlock(&dev_pm_qos_mtx); - - mutex_unlock(&dev_pm_qos_sysfs_mtx); } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); @@ -674,8 +649,6 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) } pm_runtime_get_sync(dev); - mutex_lock(&dev_pm_qos_sysfs_mtx); - mutex_lock(&dev_pm_qos_mtx); if (IS_ERR_OR_NULL(dev->power.qos)) @@ -686,19 +659,16 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) if (ret < 0) { __dev_pm_qos_remove_request(req); kfree(req); - mutex_unlock(&dev_pm_qos_mtx); goto out; } - dev->power.qos->flags_req = req; - - mutex_unlock(&dev_pm_qos_mtx); + dev->power.qos->flags_req = req; ret = pm_qos_sysfs_add_flags(dev); if (ret) - dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); out: - mutex_unlock(&dev_pm_qos_sysfs_mtx); + mutex_unlock(&dev_pm_qos_mtx); pm_runtime_put(dev); return ret; } @@ -706,8 +676,10 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags); static void __dev_pm_qos_hide_flags(struct device *dev) { - if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) + if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) { + pm_qos_sysfs_remove_flags(dev); __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + } } /** @@ -717,15 +689,9 @@ static void __dev_pm_qos_hide_flags(struct device *dev) void dev_pm_qos_hide_flags(struct device *dev) { pm_runtime_get_sync(dev); - mutex_lock(&dev_pm_qos_sysfs_mtx); - - pm_qos_sysfs_remove_flags(dev); - mutex_lock(&dev_pm_qos_mtx); __dev_pm_qos_hide_flags(dev); mutex_unlock(&dev_pm_qos_mtx); - - mutex_unlock(&dev_pm_qos_sysfs_mtx); pm_runtime_put(dev); } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags); diff --git a/trunk/drivers/base/regmap/regcache-rbtree.c b/trunk/drivers/base/regmap/regcache-rbtree.c index 79f4fca9877a..e6732cf7c06e 100644 --- a/trunk/drivers/base/regmap/regcache-rbtree.c +++ b/trunk/drivers/base/regmap/regcache-rbtree.c @@ -398,7 +398,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, base = 0; if (max < rbnode->base_reg + rbnode->blklen) - end = max - rbnode->base_reg + 1; + end = rbnode->base_reg + rbnode->blklen - max; else end = rbnode->blklen; diff --git a/trunk/drivers/base/regmap/regmap.c b/trunk/drivers/base/regmap/regmap.c index 58cfb3232428..3d2367501fd0 100644 --- a/trunk/drivers/base/regmap/regmap.c +++ b/trunk/drivers/base/regmap/regmap.c @@ -710,12 +710,12 @@ struct regmap *regmap_init(struct device *dev, } } - regmap_debugfs_init(map, config->name); - ret = regcache_init(map, config); if (ret != 0) goto err_range; + regmap_debugfs_init(map, config->name); + /* Add a devres resource for dev_get_regmap() */ m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); if (!m) { @@ -1036,8 +1036,6 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, kfree(async->work_buf); kfree(async); } - - return ret; } trace_regmap_hw_write_start(map->dev, reg, diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 92b6d7c51e39..25ef5c014fca 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -51,9 +51,8 @@ new_skb(ulong len) { struct sk_buff *skb; - skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC); + skb = alloc_skb(len, GFP_ATOMIC); if (skb) { - skb_reserve(skb, MAX_HEADER); skb_reset_mac_header(skb); skb_reset_network_header(skb); skb->protocol = __constant_htons(ETH_P_AOE); diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index dfe758382eaf..fe5f6403417f 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -922,11 +922,6 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, lo->lo_flags |= LO_FLAGS_PARTSCAN; if (lo->lo_flags & LO_FLAGS_PARTSCAN) ioctl_by_bdev(bdev, BLKRRPART, 0); - - /* Grab the block_device to prevent its destruction after we - * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). - */ - bdgrab(bdev); return 0; out_clr: @@ -1036,10 +1031,8 @@ static int loop_clr_fd(struct loop_device *lo) memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); - if (bdev) { - bdput(bdev); + if (bdev) invalidate_bdev(bdev); - } set_capacity(lo->lo_disk, 0); loop_sysfs_exit(lo); if (bdev) { @@ -1051,12 +1044,29 @@ static int loop_clr_fd(struct loop_device *lo) lo->lo_state = Lo_unbound; /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); - if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) - ioctl_by_bdev(bdev, BLKRRPART, 0); lo->lo_flags = 0; if (!part_shift) lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; mutex_unlock(&lo->lo_ctl_mutex); + + /* + * Remove all partitions, since BLKRRPART won't remove user + * added partitions when max_part=0 + */ + if (bdev) { + struct disk_part_iter piter; + struct hd_struct *part; + + mutex_lock_nested(&bdev->bd_mutex, 1); + invalidate_partition(bdev->bd_disk, 0); + disk_part_iter_init(&piter, bdev->bd_disk, + DISK_PITER_INCL_EMPTY); + while ((part = disk_part_iter_next(&piter))) + delete_partition(bdev->bd_disk, part->partno); + disk_part_iter_exit(&piter); + mutex_unlock(&bdev->bd_mutex); + } + /* * Need not hold lo_ctl_mutex to fput backing file. * Calling fput holding lo_ctl_mutex triggers a circular diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index 32c678028e53..92250af84e7d 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -81,17 +81,12 @@ /* Device instance number, incremented each time a device is probed. */ static int instance; -struct list_head online_list; -struct list_head removing_list; -spinlock_t dev_lock; - /* * Global variable used to hold the major block device number * allocated in mtip_init(). */ static int mtip_major; static struct dentry *dfs_parent; -static struct dentry *dfs_device_status; static u32 cpu_use[NR_CPUS]; @@ -248,31 +243,40 @@ static inline void release_slot(struct mtip_port *port, int tag) /* * Reset the HBA (without sleeping) * + * Just like hba_reset, except does not call sleep, so can be + * run from interrupt/tasklet context. + * * @dd Pointer to the driver data structure. * * return value * 0 The reset was successful. * -1 The HBA Reset bit did not clear. */ -static int mtip_hba_reset(struct driver_data *dd) +static int hba_reset_nosleep(struct driver_data *dd) { unsigned long timeout; + /* Chip quirk: quiesce any chip function */ + mdelay(10); + /* Set the reset bit */ writel(HOST_RESET, dd->mmio + HOST_CTL); /* Flush */ readl(dd->mmio + HOST_CTL); - /* Spin for up to 2 seconds, waiting for reset acknowledgement */ - timeout = jiffies + msecs_to_jiffies(2000); - do { - mdelay(10); - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) - return -1; + /* + * Wait 10ms then spin for up to 1 second + * waiting for reset acknowledgement + */ + timeout = jiffies + msecs_to_jiffies(1000); + mdelay(10); + while ((readl(dd->mmio + HOST_CTL) & HOST_RESET) + && time_before(jiffies, timeout)) + mdelay(1); - } while ((readl(dd->mmio + HOST_CTL) & HOST_RESET) - && time_before(jiffies, timeout)); + if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) + return -1; if (readl(dd->mmio + HOST_CTL) & HOST_RESET) return -1; @@ -477,7 +481,7 @@ static void mtip_restart_port(struct mtip_port *port) dev_warn(&port->dd->pdev->dev, "PxCMD.CR not clear, escalating reset\n"); - if (mtip_hba_reset(port->dd)) + if (hba_reset_nosleep(port->dd)) dev_err(&port->dd->pdev->dev, "HBA reset escalation failed.\n"); @@ -523,26 +527,6 @@ static void mtip_restart_port(struct mtip_port *port) } -static int mtip_device_reset(struct driver_data *dd) -{ - int rv = 0; - - if (mtip_check_surprise_removal(dd->pdev)) - return 0; - - if (mtip_hba_reset(dd) < 0) - rv = -EFAULT; - - mdelay(1); - mtip_init_port(dd->port); - mtip_start_port(dd->port); - - /* Enable interrupts on the HBA. */ - writel(readl(dd->mmio + HOST_CTL) | HOST_IRQ_EN, - dd->mmio + HOST_CTL); - return rv; -} - /* * Helper function for tag logging */ @@ -648,7 +632,7 @@ static void mtip_timeout_function(unsigned long int data) if (cmdto_cnt) { print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { - mtip_device_reset(port->dd); + mtip_restart_port(port); wake_up_interruptible(&port->svc_wait); } clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); @@ -1299,11 +1283,11 @@ static int mtip_exec_internal_command(struct mtip_port *port, int rv = 0, ready2go = 1; struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL]; unsigned long to; - struct driver_data *dd = port->dd; /* Make sure the buffer is 8 byte aligned. This is asic specific. */ if (buffer & 0x00000007) { - dev_err(&dd->pdev->dev, "SG buffer is not 8 byte aligned\n"); + dev_err(&port->dd->pdev->dev, + "SG buffer is not 8 byte aligned\n"); return -EFAULT; } @@ -1316,21 +1300,23 @@ static int mtip_exec_internal_command(struct mtip_port *port, mdelay(100); } while (time_before(jiffies, to)); if (!ready2go) { - dev_warn(&dd->pdev->dev, + dev_warn(&port->dd->pdev->dev, "Internal cmd active. new cmd [%02X]\n", fis->command); return -EBUSY; } set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); port->ic_pause_timer = 0; - clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); - clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); + if (fis->command == ATA_CMD_SEC_ERASE_UNIT) + clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); + else if (fis->command == ATA_CMD_DOWNLOAD_MICRO) + clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); if (atomic == GFP_KERNEL) { if (fis->command != ATA_CMD_STANDBYNOW1) { /* wait for io to complete if non atomic */ if (mtip_quiesce_io(port, 5000) < 0) { - dev_warn(&dd->pdev->dev, + dev_warn(&port->dd->pdev->dev, "Failed to quiesce IO\n"); release_slot(port, MTIP_TAG_INTERNAL); clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); @@ -1375,84 +1361,58 @@ static int mtip_exec_internal_command(struct mtip_port *port, /* Issue the command to the hardware */ mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL); + /* Poll if atomic, wait_for_completion otherwise */ if (atomic == GFP_KERNEL) { /* Wait for the command to complete or timeout. */ - if (wait_for_completion_interruptible_timeout( + if (wait_for_completion_timeout( &wait, - msecs_to_jiffies(timeout)) <= 0) { - if (rv == -ERESTARTSYS) { /* interrupted */ - dev_err(&dd->pdev->dev, - "Internal command [%02X] was interrupted after %lu ms\n", - fis->command, timeout); - rv = -EINTR; - goto exec_ic_exit; - } else if (rv == 0) /* timeout */ - dev_err(&dd->pdev->dev, - "Internal command did not complete [%02X] within timeout of %lu ms\n", - fis->command, timeout); - else - dev_err(&dd->pdev->dev, - "Internal command [%02X] wait returned code [%d] after %lu ms - unhandled\n", - fis->command, rv, timeout); - - if (mtip_check_surprise_removal(dd->pdev) || + msecs_to_jiffies(timeout)) == 0) { + dev_err(&port->dd->pdev->dev, + "Internal command did not complete [%d] " + "within timeout of %lu ms\n", + atomic, timeout); + if (mtip_check_surprise_removal(port->dd->pdev) || test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag)) { - dev_err(&dd->pdev->dev, - "Internal command [%02X] wait returned due to SR\n", - fis->command); + &port->dd->dd_flag)) { rv = -ENXIO; goto exec_ic_exit; } - mtip_device_reset(dd); /* recover from timeout issue */ rv = -EAGAIN; - goto exec_ic_exit; } } else { - u32 hba_stat, port_stat; - /* Spin for checking if command still outstanding */ timeout = jiffies + msecs_to_jiffies(timeout); while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) && time_before(jiffies, timeout)) { - if (mtip_check_surprise_removal(dd->pdev)) { + if (mtip_check_surprise_removal(port->dd->pdev)) { rv = -ENXIO; goto exec_ic_exit; } if ((fis->command != ATA_CMD_STANDBYNOW1) && test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag)) { + &port->dd->dd_flag)) { rv = -ENXIO; goto exec_ic_exit; } - port_stat = readl(port->mmio + PORT_IRQ_STAT); - if (!port_stat) - continue; - - if (port_stat & PORT_IRQ_ERR) { - dev_err(&dd->pdev->dev, - "Internal command [%02X] failed\n", - fis->command); - mtip_device_reset(dd); - rv = -EIO; - goto exec_ic_exit; - } else { - writel(port_stat, port->mmio + PORT_IRQ_STAT); - hba_stat = readl(dd->mmio + HOST_IRQ_STAT); - if (hba_stat) - writel(hba_stat, - dd->mmio + HOST_IRQ_STAT); + if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) { + atomic_inc(&int_cmd->active); /* error */ + break; } - break; } } + if (atomic_read(&int_cmd->active) > 1) { + dev_err(&port->dd->pdev->dev, + "Internal command [%02X] failed\n", fis->command); + rv = -EIO; + } if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) { rv = -ENXIO; - if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { - mtip_device_reset(dd); + if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, + &port->dd->dd_flag)) { + mtip_restart_port(port); rv = -EAGAIN; } } @@ -1764,8 +1724,7 @@ static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, * -EINVAL Invalid parameters passed in, trim not supported * -EIO Error submitting trim request to hw */ -static int mtip_send_trim(struct driver_data *dd, unsigned int lba, - unsigned int len) +static int mtip_send_trim(struct driver_data *dd, unsigned int lba, unsigned int len) { int i, rv = 0; u64 tlba, tlen, sect_left; @@ -1851,6 +1810,45 @@ static bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors) return (bool) !!port->identify_valid; } +/* + * Reset the HBA. + * + * Resets the HBA by setting the HBA Reset bit in the Global + * HBA Control register. After setting the HBA Reset bit the + * function waits for 1 second before reading the HBA Reset + * bit to make sure it has cleared. If HBA Reset is not clear + * an error is returned. Cannot be used in non-blockable + * context. + * + * @dd Pointer to the driver data structure. + * + * return value + * 0 The reset was successful. + * -1 The HBA Reset bit did not clear. + */ +static int mtip_hba_reset(struct driver_data *dd) +{ + mtip_deinit_port(dd->port); + + /* Set the reset bit */ + writel(HOST_RESET, dd->mmio + HOST_CTL); + + /* Flush */ + readl(dd->mmio + HOST_CTL); + + /* Wait for reset to clear */ + ssleep(1); + + /* Check the bit has cleared */ + if (readl(dd->mmio + HOST_CTL) & HOST_RESET) { + dev_err(&dd->pdev->dev, + "Reset bit did not clear.\n"); + return -1; + } + + return 0; +} + /* * Display the identify command data. * @@ -2712,100 +2710,6 @@ static ssize_t mtip_hw_show_status(struct device *dev, static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); -/* debugsfs entries */ - -static ssize_t show_device_status(struct device_driver *drv, char *buf) -{ - int size = 0; - struct driver_data *dd, *tmp; - unsigned long flags; - char id_buf[42]; - u16 status = 0; - - spin_lock_irqsave(&dev_lock, flags); - size += sprintf(&buf[size], "Devices Present:\n"); - list_for_each_entry_safe(dd, tmp, &online_list, online_list) { - if (dd->pdev) { - if (dd->port && - dd->port->identify && - dd->port->identify_valid) { - strlcpy(id_buf, - (char *) (dd->port->identify + 10), 21); - status = *(dd->port->identify + 141); - } else { - memset(id_buf, 0, 42); - status = 0; - } - - if (dd->port && - test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) { - size += sprintf(&buf[size], - " device %s %s (ftl rebuild %d %%)\n", - dev_name(&dd->pdev->dev), - id_buf, - status); - } else { - size += sprintf(&buf[size], - " device %s %s\n", - dev_name(&dd->pdev->dev), - id_buf); - } - } - } - - size += sprintf(&buf[size], "Devices Being Removed:\n"); - list_for_each_entry_safe(dd, tmp, &removing_list, remove_list) { - if (dd->pdev) { - if (dd->port && - dd->port->identify && - dd->port->identify_valid) { - strlcpy(id_buf, - (char *) (dd->port->identify+10), 21); - status = *(dd->port->identify + 141); - } else { - memset(id_buf, 0, 42); - status = 0; - } - - if (dd->port && - test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) { - size += sprintf(&buf[size], - " device %s %s (ftl rebuild %d %%)\n", - dev_name(&dd->pdev->dev), - id_buf, - status); - } else { - size += sprintf(&buf[size], - " device %s %s\n", - dev_name(&dd->pdev->dev), - id_buf); - } - } - } - spin_unlock_irqrestore(&dev_lock, flags); - - return size; -} - -static ssize_t mtip_hw_read_device_status(struct file *f, char __user *ubuf, - size_t len, loff_t *offset) -{ - int size = *offset; - char buf[MTIP_DFS_MAX_BUF_SIZE]; - - if (!len || *offset) - return 0; - - size += show_device_status(NULL, buf); - - *offset = size <= len ? size : len; - size = copy_to_user(ubuf, buf, *offset); - if (size) - return -EFAULT; - - return *offset; -} - static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, size_t len, loff_t *offset) { @@ -2900,13 +2804,6 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, return *offset; } -static const struct file_operations mtip_device_status_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = mtip_hw_read_device_status, - .llseek = no_llseek, -}; - static const struct file_operations mtip_regs_fops = { .owner = THIS_MODULE, .open = simple_open, @@ -4264,7 +4161,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, const struct cpumask *node_mask; int cpu, i = 0, j = 0; int my_node = NUMA_NO_NODE; - unsigned long flags; /* Allocate memory for this devices private data. */ my_node = pcibus_to_node(pdev->bus); @@ -4322,9 +4218,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, dd->pdev = pdev; dd->numa_node = my_node; - INIT_LIST_HEAD(&dd->online_list); - INIT_LIST_HEAD(&dd->remove_list); - memset(dd->workq_name, 0, 32); snprintf(dd->workq_name, 31, "mtipq%d", dd->instance); @@ -4412,14 +4305,6 @@ static int mtip_pci_probe(struct pci_dev *pdev, instance++; if (rv != MTIP_FTL_REBUILD_MAGIC) set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); - else - rv = 0; /* device in rebuild state, return 0 from probe */ - - /* Add to online list even if in ftl rebuild */ - spin_lock_irqsave(&dev_lock, flags); - list_add(&dd->online_list, &online_list); - spin_unlock_irqrestore(&dev_lock, flags); - goto done; block_initialize_err: @@ -4453,15 +4338,9 @@ static void mtip_pci_remove(struct pci_dev *pdev) { struct driver_data *dd = pci_get_drvdata(pdev); int counter = 0; - unsigned long flags; set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); - spin_lock_irqsave(&dev_lock, flags); - list_del_init(&dd->online_list); - list_add(&dd->remove_list, &removing_list); - spin_unlock_irqrestore(&dev_lock, flags); - if (mtip_check_surprise_removal(pdev)) { while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { counter++; @@ -4487,10 +4366,6 @@ static void mtip_pci_remove(struct pci_dev *pdev) pci_disable_msi(pdev); - spin_lock_irqsave(&dev_lock, flags); - list_del_init(&dd->remove_list); - spin_unlock_irqrestore(&dev_lock, flags); - kfree(dd); pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); } @@ -4638,11 +4513,6 @@ static int __init mtip_init(void) pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); - spin_lock_init(&dev_lock); - - INIT_LIST_HEAD(&online_list); - INIT_LIST_HEAD(&removing_list); - /* Allocate a major block device number to use with this driver. */ error = register_blkdev(0, MTIP_DRV_NAME); if (error <= 0) { @@ -4652,18 +4522,11 @@ static int __init mtip_init(void) } mtip_major = error; - dfs_parent = debugfs_create_dir("rssd", NULL); - if (IS_ERR_OR_NULL(dfs_parent)) { - pr_warn("Error creating debugfs parent\n"); - dfs_parent = NULL; - } - if (dfs_parent) { - dfs_device_status = debugfs_create_file("device_status", - S_IRUGO, dfs_parent, NULL, - &mtip_device_status_fops); - if (IS_ERR_OR_NULL(dfs_device_status)) { - pr_err("Error creating device_status node\n"); - dfs_device_status = NULL; + if (!dfs_parent) { + dfs_parent = debugfs_create_dir("rssd", NULL); + if (IS_ERR_OR_NULL(dfs_parent)) { + pr_warn("Error creating debugfs parent\n"); + dfs_parent = NULL; } } diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index 8e8334c9dd0f..3bffff5f670c 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -129,9 +129,9 @@ enum { MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */ MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */ MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */ - MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | - (1 << MTIP_PF_EH_ACTIVE_BIT) | - (1 << MTIP_PF_SE_ACTIVE_BIT) | + MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ + (1 << MTIP_PF_EH_ACTIVE_BIT) | \ + (1 << MTIP_PF_SE_ACTIVE_BIT) | \ (1 << MTIP_PF_DM_ACTIVE_BIT)), MTIP_PF_SVC_THD_ACTIVE_BIT = 4, @@ -144,9 +144,9 @@ enum { MTIP_DDF_REMOVE_PENDING_BIT = 1, MTIP_DDF_OVER_TEMP_BIT = 2, MTIP_DDF_WRITE_PROTECT_BIT = 3, - MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | - (1 << MTIP_DDF_SEC_LOCK_BIT) | - (1 << MTIP_DDF_OVER_TEMP_BIT) | + MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ + (1 << MTIP_DDF_SEC_LOCK_BIT) | \ + (1 << MTIP_DDF_OVER_TEMP_BIT) | \ (1 << MTIP_DDF_WRITE_PROTECT_BIT)), MTIP_DDF_CLEANUP_BIT = 5, @@ -180,7 +180,7 @@ struct mtip_work { #define MTIP_TRIM_TIMEOUT_MS 240000 #define MTIP_MAX_TRIM_ENTRIES 8 -#define MTIP_MAX_TRIM_ENTRY_LEN 0xfff8 +#define MTIP_MAX_TRIM_ENTRY_LEN 0xfff8 struct mtip_trim_entry { u32 lba; /* starting lba of region */ @@ -501,10 +501,6 @@ struct driver_data { atomic_t irq_workers_active; int isr_binding; - - struct list_head online_list; /* linkage for online list */ - - struct list_head remove_list; /* linkage for removing list */ }; #endif diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index b7b7a88d9f68..f556f8a8b3f9 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -1742,10 +1742,9 @@ static int rbd_img_request_submit(struct rbd_img_request *img_request) struct rbd_device *rbd_dev = img_request->rbd_dev; struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; struct rbd_obj_request *obj_request; - struct rbd_obj_request *next_obj_request; dout("%s: img %p\n", __func__, img_request); - for_each_obj_request_safe(img_request, obj_request, next_obj_request) { + for_each_obj_request(img_request, obj_request) { int ret; obj_request->callback = rbd_img_obj_callback; diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index d784650d14f0..e3f9a99b8522 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -373,14 +373,26 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) struct hpet_dev *devp; unsigned long addr; + if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) + return -EINVAL; + devp = file->private_data; addr = devp->hd_hpets->hp_hpet_phys; if (addr & (PAGE_SIZE - 1)) return -ENOSYS; + vma->vm_flags |= VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - return vm_iomap_memory(vma, addr, PAGE_SIZE); + + if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, + PAGE_SIZE, vma->vm_page_prot)) { + printk(KERN_ERR "%s: io_remap_pfn_range failed\n", + __func__); + return -EAGAIN; + } + + return 0; #else return -ENOSYS; #endif diff --git a/trunk/drivers/char/hw_random/core.c b/trunk/drivers/char/hw_random/core.c index a0f7724852eb..69ae5972713c 100644 --- a/trunk/drivers/char/hw_random/core.c +++ b/trunk/drivers/char/hw_random/core.c @@ -380,15 +380,6 @@ void hwrng_unregister(struct hwrng *rng) } EXPORT_SYMBOL_GPL(hwrng_unregister); -static void __exit hwrng_exit(void) -{ - mutex_lock(&rng_mutex); - BUG_ON(current_rng); - kfree(rng_buffer); - mutex_unlock(&rng_mutex); -} - -module_exit(hwrng_exit); MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/virtio_console.c b/trunk/drivers/char/virtio_console.c index ce5f3fc25d6d..e905d5f53051 100644 --- a/trunk/drivers/char/virtio_console.c +++ b/trunk/drivers/char/virtio_console.c @@ -149,8 +149,7 @@ struct ports_device { spinlock_t ports_lock; /* To protect the vq operations for the control channel */ - spinlock_t c_ivq_lock; - spinlock_t c_ovq_lock; + spinlock_t cvq_lock; /* The current config space is stored here */ struct virtio_console_config config; @@ -570,14 +569,11 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, vq = portdev->c_ovq; sg_init_one(sg, &cpkt, sizeof(cpkt)); - - spin_lock(&portdev->c_ovq_lock); if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) == 0) { virtqueue_kick(vq); while (!virtqueue_get_buf(vq, &len)) cpu_relax(); } - spin_unlock(&portdev->c_ovq_lock); return 0; } @@ -1440,7 +1436,7 @@ static int add_port(struct ports_device *portdev, u32 id) * rproc_serial does not want the console port, only * the generic port implementation. */ - port->host_connected = true; + port->host_connected = port->guest_connected = true; else if (!use_multiport(port->portdev)) { /* * If we're not using multiport support, @@ -1713,23 +1709,23 @@ static void control_work_handler(struct work_struct *work) portdev = container_of(work, struct ports_device, control_work); vq = portdev->c_ivq; - spin_lock(&portdev->c_ivq_lock); + spin_lock(&portdev->cvq_lock); while ((buf = virtqueue_get_buf(vq, &len))) { - spin_unlock(&portdev->c_ivq_lock); + spin_unlock(&portdev->cvq_lock); buf->len = len; buf->offset = 0; handle_control_message(portdev, buf); - spin_lock(&portdev->c_ivq_lock); + spin_lock(&portdev->cvq_lock); if (add_inbuf(portdev->c_ivq, buf) < 0) { dev_warn(&portdev->vdev->dev, "Error adding buffer to queue\n"); free_buf(buf, false); } } - spin_unlock(&portdev->c_ivq_lock); + spin_unlock(&portdev->cvq_lock); } static void out_intr(struct virtqueue *vq) @@ -1756,23 +1752,13 @@ static void in_intr(struct virtqueue *vq) port->inbuf = get_inbuf(port); /* - * Normally the port should not accept data when the port is - * closed. For generic serial ports, the host won't (shouldn't) - * send data till the guest is connected. But this condition + * Don't queue up data when port is closed. This condition * can be reached when a console port is not yet connected (no - * tty is spawned) and the other side sends out data over the - * vring, or when a remote devices start sending data before - * the ports are opened. - * - * A generic serial port will discard data if not connected, - * while console ports and rproc-serial ports accepts data at - * any time. rproc-serial is initiated with guest_connected to - * false because port_fops_open expects this. Console ports are - * hooked up with an HVC console and is initialized with - * guest_connected to true. + * tty is spawned) and the host sends out data to console + * ports. For generic serial ports, the host won't + * (shouldn't) send data till the guest is connected. */ - - if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) + if (!port->guest_connected) discard_port_data(port); spin_unlock_irqrestore(&port->inbuf_lock, flags); @@ -2000,12 +1986,10 @@ static int virtcons_probe(struct virtio_device *vdev) if (multiport) { unsigned int nr_added_bufs; - spin_lock_init(&portdev->c_ivq_lock); - spin_lock_init(&portdev->c_ovq_lock); + spin_lock_init(&portdev->cvq_lock); INIT_WORK(&portdev->control_work, &control_work_handler); - nr_added_bufs = fill_queue(portdev->c_ivq, - &portdev->c_ivq_lock); + nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock); if (!nr_added_bufs) { dev_err(&vdev->dev, "Error allocating buffers for control queue\n"); @@ -2156,7 +2140,7 @@ static int virtcons_restore(struct virtio_device *vdev) return ret; if (use_multiport(portdev)) - fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); + fill_queue(portdev->c_ivq, &portdev->cvq_lock); list_for_each_entry(port, &portdev->ports, list) { port->in_vq = portdev->in_vqs[port->id]; diff --git a/trunk/drivers/clk/tegra/clk-tegra20.c b/trunk/drivers/clk/tegra/clk-tegra20.c index f873dcefe0de..1e2de7305362 100644 --- a/trunk/drivers/clk/tegra/clk-tegra20.c +++ b/trunk/drivers/clk/tegra/clk-tegra20.c @@ -703,7 +703,7 @@ static void tegra20_pll_init(void) clks[pll_a_out0] = clk; /* PLLE */ - clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base, + clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, NULL, 0, 100000000, &pll_e_params, 0, pll_e_freq_table, NULL); clk_register_clkdev(clk, "pll_e", NULL); diff --git a/trunk/drivers/cpufreq/cpufreq-cpu0.c b/trunk/drivers/cpufreq/cpufreq-cpu0.c index 37d23a0f8c56..4e5b7fb8927c 100644 --- a/trunk/drivers/cpufreq/cpufreq-cpu0.c +++ b/trunk/drivers/cpufreq/cpufreq-cpu0.c @@ -178,16 +178,10 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { static int cpu0_cpufreq_probe(struct platform_device *pdev) { - struct device_node *np, *parent; + struct device_node *np; int ret; - parent = of_find_node_by_path("/cpus"); - if (!parent) { - pr_err("failed to find OF /cpus\n"); - return -ENOENT; - } - - for_each_child_of_node(parent, np) { + for_each_child_of_node(of_find_node_by_path("/cpus"), np) { if (of_get_property(np, "operating-points", NULL)) break; } diff --git a/trunk/drivers/cpufreq/cpufreq_governor.h b/trunk/drivers/cpufreq/cpufreq_governor.h index cc4bd2f6838a..46bde01eee62 100644 --- a/trunk/drivers/cpufreq/cpufreq_governor.h +++ b/trunk/drivers/cpufreq/cpufreq_governor.h @@ -14,8 +14,8 @@ * published by the Free Software Foundation. */ -#ifndef _CPUFREQ_GOVERNOR_H -#define _CPUFREQ_GOVERNOR_H +#ifndef _CPUFREQ_GOVERNER_H +#define _CPUFREQ_GOVERNER_H #include #include @@ -175,4 +175,4 @@ bool need_load_eval(struct cpu_dbs_common_info *cdbs, unsigned int sampling_rate); int cpufreq_governor_dbs(struct dbs_data *dbs_data, struct cpufreq_policy *policy, unsigned int event); -#endif /* _CPUFREQ_GOVERNOR_H */ +#endif /* _CPUFREQ_GOVERNER_H */ diff --git a/trunk/drivers/cpufreq/intel_pstate.c b/trunk/drivers/cpufreq/intel_pstate.c index 6133ef5cf671..ad72922919ed 100644 --- a/trunk/drivers/cpufreq/intel_pstate.c +++ b/trunk/drivers/cpufreq/intel_pstate.c @@ -502,6 +502,7 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu) sample_time = cpu->pstate_policy->sample_rate_ms; delay = msecs_to_jiffies(sample_time); + delay -= jiffies % delay; mod_timer_pinned(&cpu->timer, jiffies + delay); } diff --git a/trunk/drivers/crypto/ux500/cryp/cryp_core.c b/trunk/drivers/crypto/ux500/cryp/cryp_core.c index 22c9063e0120..8bc5fef07e7a 100644 --- a/trunk/drivers/crypto/ux500/cryp/cryp_core.c +++ b/trunk/drivers/crypto/ux500/cryp/cryp_core.c @@ -1750,7 +1750,7 @@ static struct platform_driver cryp_driver = { .shutdown = ux500_cryp_shutdown, .driver = { .owner = THIS_MODULE, - .name = "cryp1", + .name = "cryp1" .pm = &ux500_cryp_pm, } }; diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig index aeaea32bcfda..80b69971cf28 100644 --- a/trunk/drivers/dma/Kconfig +++ b/trunk/drivers/dma/Kconfig @@ -83,7 +83,6 @@ config INTEL_IOP_ADMA config DW_DMAC tristate "Synopsys DesignWare AHB DMA support" - depends on GENERIC_HARDIRQS select DMA_ENGINE default y if CPU_AT32AP7000 help diff --git a/trunk/drivers/dma/at_hdmac.c b/trunk/drivers/dma/at_hdmac.c index 88cfc61329d2..6e13f262139a 100644 --- a/trunk/drivers/dma/at_hdmac.c +++ b/trunk/drivers/dma/at_hdmac.c @@ -310,6 +310,8 @@ static void atc_complete_all(struct at_dma_chan *atchan) dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n"); + BUG_ON(atc_chan_is_enabled(atchan)); + /* * Submit queued descriptors ASAP, i.e. before we go through * the completed ones. @@ -366,9 +368,6 @@ static void atc_advance_work(struct at_dma_chan *atchan) { dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n"); - if (atc_chan_is_enabled(atchan)) - return; - if (list_empty(&atchan->active_list) || list_is_singular(&atchan->active_list)) { atc_complete_all(atchan); @@ -1079,7 +1078,9 @@ static void atc_issue_pending(struct dma_chan *chan) return; spin_lock_irqsave(&atchan->lock, flags); - atc_advance_work(atchan); + if (!atc_chan_is_enabled(atchan)) { + atc_advance_work(atchan); + } spin_unlock_irqrestore(&atchan->lock, flags); } diff --git a/trunk/drivers/dma/omap-dma.c b/trunk/drivers/dma/omap-dma.c index 08b43bf37158..c4b4fd2acc42 100644 --- a/trunk/drivers/dma/omap-dma.c +++ b/trunk/drivers/dma/omap-dma.c @@ -276,20 +276,12 @@ static void omap_dma_issue_pending(struct dma_chan *chan) spin_lock_irqsave(&c->vc.lock, flags); if (vchan_issue_pending(&c->vc) && !c->desc) { - /* - * c->cyclic is used only by audio and in this case the DMA need - * to be started without delay. - */ - if (!c->cyclic) { - struct omap_dmadev *d = to_omap_dma_dev(chan->device); - spin_lock(&d->lock); - if (list_empty(&c->node)) - list_add_tail(&c->node, &d->pending); - spin_unlock(&d->lock); - tasklet_schedule(&d->task); - } else { - omap_dma_start_desc(c); - } + struct omap_dmadev *d = to_omap_dma_dev(chan->device); + spin_lock(&d->lock); + if (list_empty(&c->node)) + list_add_tail(&c->node, &d->pending); + spin_unlock(&d->lock); + tasklet_schedule(&d->task); } spin_unlock_irqrestore(&c->vc.lock, flags); } diff --git a/trunk/drivers/dma/pl330.c b/trunk/drivers/dma/pl330.c index 5dbc5946c4c3..718153122759 100644 --- a/trunk/drivers/dma/pl330.c +++ b/trunk/drivers/dma/pl330.c @@ -2882,7 +2882,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) { struct dma_pl330_platdata *pdat; struct dma_pl330_dmac *pdmac; - struct dma_pl330_chan *pch, *_p; + struct dma_pl330_chan *pch; struct pl330_info *pi; struct dma_device *pd; struct resource *res; @@ -2984,16 +2984,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) ret = dma_async_device_register(pd); if (ret) { dev_err(&adev->dev, "unable to register DMAC\n"); - goto probe_err3; - } - - if (adev->dev.of_node) { - ret = of_dma_controller_register(adev->dev.of_node, - of_dma_pl330_xlate, pdmac); - if (ret) { - dev_err(&adev->dev, - "unable to register DMA to the generic DT DMA helpers\n"); - } + goto probe_err2; } dev_info(&adev->dev, @@ -3004,21 +2995,16 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan, pi->pcfg.num_peri, pi->pcfg.num_events); - return 0; -probe_err3: - amba_set_drvdata(adev, NULL); - - /* Idle the DMAC */ - list_for_each_entry_safe(pch, _p, &pdmac->ddma.channels, - chan.device_node) { + ret = of_dma_controller_register(adev->dev.of_node, + of_dma_pl330_xlate, pdmac); + if (ret) { + dev_err(&adev->dev, + "unable to register DMA to the generic DT DMA helpers\n"); + goto probe_err2; + } - /* Remove the channel */ - list_del(&pch->chan.device_node); + return 0; - /* Flush the channel */ - pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0); - pl330_free_chan_resources(&pch->chan); - } probe_err2: pl330_del(pi); probe_err1: @@ -3037,10 +3023,8 @@ static int pl330_remove(struct amba_device *adev) if (!pdmac) return 0; - if (adev->dev.of_node) - of_dma_controller_free(adev->dev.of_node); + of_dma_controller_free(adev->dev.of_node); - dma_async_device_unregister(&pdmac->ddma); amba_set_drvdata(adev, NULL); /* Idle the DMAC */ diff --git a/trunk/drivers/eisa/eisa-bus.c b/trunk/drivers/eisa/eisa-bus.c index 272a3ec35957..806c77bfd434 100644 --- a/trunk/drivers/eisa/eisa-bus.c +++ b/trunk/drivers/eisa/eisa-bus.c @@ -275,18 +275,19 @@ static int __init eisa_request_resources(struct eisa_root_device *root, } if (slot) { + edev->res[i].name = NULL; edev->res[i].start = SLOT_ADDRESS(root, slot) + (i * 0x400); edev->res[i].end = edev->res[i].start + 0xff; edev->res[i].flags = IORESOURCE_IO; } else { + edev->res[i].name = NULL; edev->res[i].start = SLOT_ADDRESS(root, slot) + EISA_VENDOR_ID_OFFSET; edev->res[i].end = edev->res[i].start + 3; - edev->res[i].flags = IORESOURCE_IO | IORESOURCE_BUSY; + edev->res[i].flags = IORESOURCE_BUSY; } - dev_printk(KERN_DEBUG, &edev->dev, "%pR\n", &edev->res[i]); if (request_resource(root->res, &edev->res[i])) goto failed; } @@ -313,40 +314,41 @@ static int __init eisa_probe(struct eisa_root_device *root) { int i, c; struct eisa_device *edev; - char *enabled_str; - dev_info(root->dev, "Probing EISA bus %d\n", root->bus_nr); + printk(KERN_INFO "EISA: Probing bus %d at %s\n", + root->bus_nr, dev_name(root->dev)); /* First try to get hold of slot 0. If there is no device * here, simply fail, unless root->force_probe is set. */ edev = kzalloc(sizeof(*edev), GFP_KERNEL); if (!edev) { - dev_err(root->dev, "EISA: Couldn't allocate mainboard slot\n"); + printk(KERN_ERR "EISA: Couldn't allocate mainboard slot\n"); return -ENOMEM; } - if (eisa_init_device(root, edev, 0)) { + if (eisa_request_resources(root, edev, 0)) { + printk(KERN_WARNING \ + "EISA: Cannot allocate resource for mainboard\n"); kfree(edev); if (!root->force_probe) - return -ENODEV; + return -EBUSY; goto force_probe; } - if (eisa_request_resources(root, edev, 0)) { - dev_warn(root->dev, - "EISA: Cannot allocate resource for mainboard\n"); + if (eisa_init_device(root, edev, 0)) { + eisa_release_resources(edev); kfree(edev); if (!root->force_probe) - return -EBUSY; + return -ENODEV; goto force_probe; } - dev_info(&edev->dev, "EISA: Mainboard %s detected\n", edev->id.sig); + printk(KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig); if (eisa_register_device(edev)) { - dev_err(&edev->dev, "EISA: Failed to register %s\n", - edev->id.sig); + printk(KERN_ERR "EISA: Failed to register %s\n", + edev->id.sig); eisa_release_resources(edev); kfree(edev); } @@ -356,47 +358,55 @@ static int __init eisa_probe(struct eisa_root_device *root) for (c = 0, i = 1; i <= root->slots; i++) { edev = kzalloc(sizeof(*edev), GFP_KERNEL); if (!edev) { - dev_err(root->dev, "EISA: Out of memory for slot %d\n", - i); + printk(KERN_ERR "EISA: Out of memory for slot %d\n", i); continue; } - if (eisa_init_device(root, edev, i)) { + if (eisa_request_resources(root, edev, i)) { + printk(KERN_WARNING \ + "Cannot allocate resource for EISA slot %d\n", + i); kfree(edev); continue; } - if (eisa_request_resources(root, edev, i)) { - dev_warn(root->dev, - "Cannot allocate resource for EISA slot %d\n", - i); + if (eisa_init_device(root, edev, i)) { + eisa_release_resources(edev); kfree(edev); continue; } - - if (edev->state == (EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED)) - enabled_str = " (forced enabled)"; - else if (edev->state == EISA_CONFIG_FORCED) - enabled_str = " (forced disabled)"; - else if (edev->state == 0) - enabled_str = " (disabled)"; - else - enabled_str = ""; - - dev_info(&edev->dev, "EISA: slot %d: %s detected%s\n", i, - edev->id.sig, enabled_str); + + printk(KERN_INFO "EISA: slot %d : %s detected", + i, edev->id.sig); + + switch (edev->state) { + case EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED: + printk(" (forced enabled)"); + break; + + case EISA_CONFIG_FORCED: + printk(" (forced disabled)"); + break; + + case 0: + printk(" (disabled)"); + break; + } + + printk (".\n"); c++; if (eisa_register_device(edev)) { - dev_err(&edev->dev, "EISA: Failed to register %s\n", - edev->id.sig); + printk(KERN_ERR "EISA: Failed to register %s\n", + edev->id.sig); eisa_release_resources(edev); kfree(edev); } } - dev_info(root->dev, "EISA: Detected %d card%s\n", c, c == 1 ? "" : "s"); + printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s"); + return 0; } diff --git a/trunk/drivers/eisa/pci_eisa.c b/trunk/drivers/eisa/pci_eisa.c index a333bf3517de..cdae207028a7 100644 --- a/trunk/drivers/eisa/pci_eisa.c +++ b/trunk/drivers/eisa/pci_eisa.c @@ -19,72 +19,48 @@ /* There is only *one* pci_eisa device per machine, right ? */ static struct eisa_root_device pci_eisa_root; -static int __init pci_eisa_init(struct pci_dev *pdev) +static int __init pci_eisa_init(struct pci_dev *pdev, + const struct pci_device_id *ent) { - int rc, i; - struct resource *res, *bus_res = NULL; + int rc; if ((rc = pci_enable_device (pdev))) { - dev_err(&pdev->dev, "Could not enable device\n"); + printk (KERN_ERR "pci_eisa : Could not enable device %s\n", + pci_name(pdev)); return rc; } - /* - * The Intel 82375 PCI-EISA bridge is a subtractive-decode PCI - * device, so the resources available on EISA are the same as those - * available on the 82375 bus. This works the same as a PCI-PCI - * bridge in subtractive-decode mode (see pci_read_bridge_bases()). - * We assume other PCI-EISA bridges are similar. - * - * eisa_root_register() can only deal with a single io port resource, - * so we use the first valid io port resource. - */ - pci_bus_for_each_resource(pdev->bus, res, i) - if (res && (res->flags & IORESOURCE_IO)) { - bus_res = res; - break; - } - - if (!bus_res) { - dev_err(&pdev->dev, "No resources available\n"); - return -1; - } - pci_eisa_root.dev = &pdev->dev; - pci_eisa_root.res = bus_res; - pci_eisa_root.bus_base_addr = bus_res->start; + pci_eisa_root.res = pdev->bus->resource[0]; + pci_eisa_root.bus_base_addr = pdev->bus->resource[0]->start; pci_eisa_root.slots = EISA_MAX_SLOTS; pci_eisa_root.dma_mask = pdev->dma_mask; dev_set_drvdata(pci_eisa_root.dev, &pci_eisa_root); if (eisa_root_register (&pci_eisa_root)) { - dev_err(&pdev->dev, "Could not register EISA root\n"); + printk (KERN_ERR "pci_eisa : Could not register EISA root\n"); return -1; } return 0; } -/* - * We have to call pci_eisa_init_early() before pnpacpi_init()/isapnp_init(). - * Otherwise pnp resource will get enabled early and could prevent eisa - * to be initialized. - * Also need to make sure pci_eisa_init_early() is called after - * x86/pci_subsys_init(). - * So need to use subsys_initcall_sync with it. - */ -static int __init pci_eisa_init_early(void) -{ - struct pci_dev *dev = NULL; - int ret; +static struct pci_device_id pci_eisa_pci_tbl[] = { + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_BRIDGE_EISA << 8, 0xffff00, 0 }, + { 0, } +}; - for_each_pci_dev(dev) - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_EISA) { - ret = pci_eisa_init(dev); - if (ret) - return ret; - } +static struct pci_driver __refdata pci_eisa_driver = { + .name = "pci_eisa", + .id_table = pci_eisa_pci_tbl, + .probe = pci_eisa_init, +}; - return 0; +static int __init pci_eisa_init_module (void) +{ + return pci_register_driver (&pci_eisa_driver); } -subsys_initcall_sync(pci_eisa_init_early); + +device_initcall(pci_eisa_init_module); +MODULE_DEVICE_TABLE(pci, pci_eisa_pci_tbl); diff --git a/trunk/drivers/firmware/Kconfig b/trunk/drivers/firmware/Kconfig index 3e532002e4d1..42c759a4d047 100644 --- a/trunk/drivers/firmware/Kconfig +++ b/trunk/drivers/firmware/Kconfig @@ -39,7 +39,6 @@ config FIRMWARE_MEMMAP config EFI_VARS tristate "EFI Variable Support via sysfs" depends on EFI - select UCS2_STRING default n help If you say Y here, you are able to get EFI (Extensible Firmware diff --git a/trunk/drivers/firmware/efivars.c b/trunk/drivers/firmware/efivars.c index f4baa11d3644..7acafb80fd4c 100644 --- a/trunk/drivers/firmware/efivars.c +++ b/trunk/drivers/firmware/efivars.c @@ -80,7 +80,6 @@ #include #include #include -#include #include #include @@ -173,6 +172,51 @@ static void efivar_update_sysfs_entries(struct work_struct *); static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries); static bool efivar_wq_enabled = true; +/* Return the number of unicode characters in data */ +static unsigned long +utf16_strnlen(efi_char16_t *s, size_t maxlength) +{ + unsigned long length = 0; + + while (*s++ != 0 && length < maxlength) + length++; + return length; +} + +static inline unsigned long +utf16_strlen(efi_char16_t *s) +{ + return utf16_strnlen(s, ~0UL); +} + +/* + * Return the number of bytes is the length of this string + * Note: this is NOT the same as the number of unicode characters + */ +static inline unsigned long +utf16_strsize(efi_char16_t *data, unsigned long maxlength) +{ + return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t); +} + +static inline int +utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len) +{ + while (1) { + if (len == 0) + return 0; + if (*a < *b) + return -1; + if (*a > *b) + return 1; + if (*a == 0) /* implies *b == 0 */ + return 0; + a++; + b++; + len--; + } +} + static bool validate_device_path(struct efi_variable *var, int match, u8 *buffer, unsigned long len) @@ -224,7 +268,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, u16 filepathlength; int i, desclength = 0, namelen; - namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName)); + namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); /* Either "Boot" or "Driver" followed by four digits of hex */ for (i = match; i < match+4; i++) { @@ -247,7 +291,7 @@ validate_load_option(struct efi_variable *var, int match, u8 *buffer, * There's no stored length for the description, so it has to be * found by hand */ - desclength = ucs2_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; + desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; /* Each boot entry must have a descriptor */ if (!desclength) @@ -392,12 +436,24 @@ static efi_status_t check_var_size_locked(struct efivars *efivars, u32 attributes, unsigned long size) { + u64 storage_size, remaining_size, max_size; + efi_status_t status; const struct efivar_operations *fops = efivars->ops; - if (!efivars->ops->query_variable_store) + if (!efivars->ops->query_variable_info) return EFI_UNSUPPORTED; - return fops->query_variable_store(attributes, size); + status = fops->query_variable_info(attributes, &storage_size, + &remaining_size, &max_size); + + if (status != EFI_SUCCESS) + return status; + + if (!storage_size || size > remaining_size || size > max_size || + (remaining_size - size) < (storage_size / 2)) + return EFI_OUT_OF_RESOURCES; + + return status; } @@ -537,7 +593,7 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) spin_lock_irq(&efivars->lock); status = check_var_size_locked(efivars, new_var->Attributes, - new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024)); + new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED) status = efivars->ops->set_variable(new_var->VariableName, @@ -715,7 +771,7 @@ static ssize_t efivarfs_file_write(struct file *file, * QueryVariableInfo() isn't supported by the firmware. */ - varsize = datasize + ucs2_strsize(var->var.VariableName, 1024); + varsize = datasize + utf16_strsize(var->var.VariableName, 1024); status = check_var_size(efivars, attributes, varsize); if (status != EFI_SUCCESS) { @@ -1167,7 +1223,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) inode = NULL; - len = ucs2_strlen(entry->var.VariableName); + len = utf16_strlen(entry->var.VariableName); /* name, plus '-', plus GUID, plus NUL*/ name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC); @@ -1425,8 +1481,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, if (efi_guidcmp(entry->var.VendorGuid, vendor)) continue; - if (ucs2_strncmp(entry->var.VariableName, efi_name, - ucs2_strlen(efi_name))) { + if (utf16_strncmp(entry->var.VariableName, efi_name, + utf16_strlen(efi_name))) { /* * Check if an old format, * which doesn't support holding @@ -1438,8 +1494,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, for (i = 0; i < DUMP_NAME_LEN; i++) efi_name_old[i] = name_old[i]; - if (ucs2_strncmp(entry->var.VariableName, efi_name_old, - ucs2_strlen(efi_name_old))) + if (utf16_strncmp(entry->var.VariableName, efi_name_old, + utf16_strlen(efi_name_old))) continue; } @@ -1517,8 +1573,8 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, * Does this variable already exist? */ list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { - strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024); - strsize2 = ucs2_strsize(new_var->VariableName, 1024); + strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); + strsize2 = utf16_strsize(new_var->VariableName, 1024); if (strsize1 == strsize2 && !memcmp(&(search_efivar->var.VariableName), new_var->VariableName, strsize1) && @@ -1534,7 +1590,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, } status = check_var_size_locked(efivars, new_var->Attributes, - new_var->DataSize + ucs2_strsize(new_var->VariableName, 1024)); + new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); if (status && status != EFI_UNSUPPORTED) { spin_unlock_irq(&efivars->lock); @@ -1558,7 +1614,7 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, /* Create the entry in sysfs. Locking is not required here */ status = efivar_create_sysfs_entry(efivars, - ucs2_strsize(new_var->VariableName, + utf16_strsize(new_var->VariableName, 1024), new_var->VariableName, &new_var->VendorGuid); @@ -1588,8 +1644,8 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, * Does this variable already exist? */ list_for_each_entry_safe(search_efivar, n, &efivars->list, list) { - strsize1 = ucs2_strsize(search_efivar->var.VariableName, 1024); - strsize2 = ucs2_strsize(del_var->VariableName, 1024); + strsize1 = utf16_strsize(search_efivar->var.VariableName, 1024); + strsize2 = utf16_strsize(del_var->VariableName, 1024); if (strsize1 == strsize2 && !memcmp(&(search_efivar->var.VariableName), del_var->VariableName, strsize1) && @@ -1628,17 +1684,16 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, return count; } -static bool variable_is_present(struct efivars *efivars, - efi_char16_t *variable_name, - efi_guid_t *vendor) +static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor) { struct efivar_entry *entry, *n; + struct efivars *efivars = &__efivars; unsigned long strsize1, strsize2; bool found = false; - strsize1 = ucs2_strsize(variable_name, 1024); + strsize1 = utf16_strsize(variable_name, 1024); list_for_each_entry_safe(entry, n, &efivars->list, list) { - strsize2 = ucs2_strsize(entry->var.VariableName, 1024); + strsize2 = utf16_strsize(entry->var.VariableName, 1024); if (strsize1 == strsize2 && !memcmp(variable_name, &(entry->var.VariableName), strsize2) && @@ -1704,8 +1759,8 @@ static void efivar_update_sysfs_entries(struct work_struct *work) if (status != EFI_SUCCESS) { break; } else { - if (!variable_is_present(efivars, - variable_name, &vendor)) { + if (!variable_is_present(variable_name, + &vendor)) { found = true; break; } @@ -2009,8 +2064,7 @@ int register_efivars(struct efivars *efivars, * we'll ever see a different variable name, * and may end up looping here forever. */ - if (variable_is_present(efivars, variable_name, - &vendor_guid)) { + if (variable_is_present(variable_name, &vendor_guid)) { dup_variable_bug(variable_name, &vendor_guid, variable_name_size); status = EFI_NOT_FOUND; @@ -2077,7 +2131,7 @@ efivars_init(void) ops.get_variable = efi.get_variable; ops.set_variable = efi.set_variable; ops.get_next_variable = efi.get_next_variable; - ops.query_variable_store = efi_query_variable_store; + ops.query_variable_info = efi.query_variable_info; error = register_efivars(&__efivars, &ops, efi_kobj); if (error) diff --git a/trunk/drivers/gpio/gpio-ich.c b/trunk/drivers/gpio/gpio-ich.c index de3c317bd3e2..f9dbd503fc40 100644 --- a/trunk/drivers/gpio/gpio-ich.c +++ b/trunk/drivers/gpio/gpio-ich.c @@ -214,7 +214,7 @@ static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) * If it can't be trusted, assume that the pin can be used as a GPIO. */ if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) - return 0; + return 1; return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; } diff --git a/trunk/drivers/gpio/gpio-pca953x.c b/trunk/drivers/gpio/gpio-pca953x.c index 9391cf16e990..24059462c87f 100644 --- a/trunk/drivers/gpio/gpio-pca953x.c +++ b/trunk/drivers/gpio/gpio-pca953x.c @@ -575,7 +575,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, chip->gpio_chip.ngpio, irq_base, &pca953x_irq_simple_ops, - chip); + NULL); if (!chip->domain) return -ENODEV; diff --git a/trunk/drivers/gpio/gpio-pxa.c b/trunk/drivers/gpio/gpio-pxa.c index 8325f580c0f1..9cc108d2b770 100644 --- a/trunk/drivers/gpio/gpio-pxa.c +++ b/trunk/drivers/gpio/gpio-pxa.c @@ -642,12 +642,7 @@ static struct platform_driver pxa_gpio_driver = { .of_match_table = of_match_ptr(pxa_gpio_dt_ids), }, }; - -static int __init pxa_gpio_init(void) -{ - return platform_driver_register(&pxa_gpio_driver); -} -postcore_initcall(pxa_gpio_init); +module_platform_driver(pxa_gpio_driver); #ifdef CONFIG_PM static int pxa_gpio_suspend(void) diff --git a/trunk/drivers/gpio/gpio-stmpe.c b/trunk/drivers/gpio/gpio-stmpe.c index 3ce5bc38ac31..770476a9da87 100644 --- a/trunk/drivers/gpio/gpio-stmpe.c +++ b/trunk/drivers/gpio/gpio-stmpe.c @@ -307,15 +307,11 @@ static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = { .xlate = irq_domain_xlate_twocell, }; -static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio, - struct device_node *np) +static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) { - int base = 0; + int base = stmpe_gpio->irq_base; - if (!np) - base = stmpe_gpio->irq_base; - - stmpe_gpio->domain = irq_domain_add_simple(np, + stmpe_gpio->domain = irq_domain_add_simple(NULL, stmpe_gpio->chip.ngpio, base, &stmpe_gpio_irq_simple_ops, stmpe_gpio); if (!stmpe_gpio->domain) { @@ -350,9 +346,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev) stmpe_gpio->chip = template_chip; stmpe_gpio->chip.ngpio = stmpe->num_gpios; stmpe_gpio->chip.dev = &pdev->dev; -#ifdef CONFIG_OF - stmpe_gpio->chip.of_node = np; -#endif stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1; if (pdata) @@ -373,7 +366,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) goto out_free; if (irq >= 0) { - ret = stmpe_gpio_irq_init(stmpe_gpio, np); + ret = stmpe_gpio_irq_init(stmpe_gpio); if (ret) goto out_disable; diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index dd64a06dc5b4..792c3e3795ca 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -2326,6 +2326,7 @@ int drm_mode_addfb(struct drm_device *dev, fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); if (IS_ERR(fb)) { DRM_DEBUG_KMS("could not create framebuffer\n"); + drm_modeset_unlock_all(dev); return PTR_ERR(fb); } @@ -2505,6 +2506,7 @@ int drm_mode_addfb2(struct drm_device *dev, fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); if (IS_ERR(fb)) { DRM_DEBUG_KMS("could not create framebuffer\n"); + drm_modeset_unlock_all(dev); return PTR_ERR(fb); } diff --git a/trunk/drivers/gpu/drm/drm_fb_helper.c b/trunk/drivers/gpu/drm/drm_fb_helper.c index 892ff9f95975..59d6b9bf204b 100644 --- a/trunk/drivers/gpu/drm/drm_fb_helper.c +++ b/trunk/drivers/gpu/drm/drm_fb_helper.c @@ -1544,10 +1544,10 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) if (!fb_helper->fb) return 0; - mutex_lock(&fb_helper->dev->mode_config.mutex); + drm_modeset_lock_all(dev); if (!drm_fb_helper_is_bound(fb_helper)) { fb_helper->delayed_hotplug = true; - mutex_unlock(&fb_helper->dev->mode_config.mutex); + drm_modeset_unlock_all(dev); return 0; } DRM_DEBUG_KMS("\n"); @@ -1558,11 +1558,9 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, max_height); - mutex_unlock(&fb_helper->dev->mode_config.mutex); - - drm_modeset_lock_all(dev); drm_setup_crtcs(fb_helper); drm_modeset_unlock_all(dev); + drm_fb_helper_set_par(fb_helper->fbdev); return 0; diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 429e07d0b0f1..13fdcd10a605 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -123,7 +123,6 @@ int drm_open(struct inode *inode, struct file *filp) int retcode = 0; int need_setup = 0; struct address_space *old_mapping; - struct address_space *old_imapping; minor = idr_find(&drm_minors_idr, minor_id); if (!minor) @@ -138,7 +137,6 @@ int drm_open(struct inode *inode, struct file *filp) if (!dev->open_count++) need_setup = 1; mutex_lock(&dev->struct_mutex); - old_imapping = inode->i_mapping; old_mapping = dev->dev_mapping; if (old_mapping == NULL) dev->dev_mapping = &inode->i_data; @@ -161,8 +159,8 @@ int drm_open(struct inode *inode, struct file *filp) err_undo: mutex_lock(&dev->struct_mutex); - filp->f_mapping = old_imapping; - inode->i_mapping = old_imapping; + filp->f_mapping = old_mapping; + inode->i_mapping = old_mapping; iput(container_of(dev->dev_mapping, struct inode, i_data)); dev->dev_mapping = old_mapping; mutex_unlock(&dev->struct_mutex); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 9a48e1a2d417..3b11ab0fbc96 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -57,7 +57,7 @@ eb_create(struct drm_i915_gem_execbuffer2 *args) if (eb == NULL) { int size = args->buffer_count; int count = PAGE_SIZE / sizeof(struct hlist_head) / 2; - BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head)); + BUILD_BUG_ON(!is_power_of_2(PAGE_SIZE / sizeof(struct hlist_head))); while (count > 2*size) count >>= 1; eb = kzalloc(count*sizeof(struct hlist_head) + diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 1ce45a0a2d3e..32a3693905ec 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -45,9 +45,6 @@ struct intel_crt { struct intel_encoder base; - /* DPMS state is stored in the connector, which we need in the - * encoder's enable/disable callbacks */ - struct intel_connector *connector; bool force_hotplug_required; u32 adpa_reg; }; @@ -84,6 +81,29 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, return true; } +static void intel_disable_crt(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crt *crt = intel_encoder_to_crt(encoder); + u32 temp; + + temp = I915_READ(crt->adpa_reg); + temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; + temp &= ~ADPA_DAC_ENABLE; + I915_WRITE(crt->adpa_reg, temp); +} + +static void intel_enable_crt(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct intel_crt *crt = intel_encoder_to_crt(encoder); + u32 temp; + + temp = I915_READ(crt->adpa_reg); + temp |= ADPA_DAC_ENABLE; + I915_WRITE(crt->adpa_reg, temp); +} + /* Note: The caller is required to filter out dpms modes not supported by the * platform. */ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) @@ -115,19 +135,6 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) I915_WRITE(crt->adpa_reg, temp); } -static void intel_disable_crt(struct intel_encoder *encoder) -{ - intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF); -} - -static void intel_enable_crt(struct intel_encoder *encoder) -{ - struct intel_crt *crt = intel_encoder_to_crt(encoder); - - intel_crt_set_dpms(encoder, crt->connector->base.dpms); -} - - static void intel_crt_dpms(struct drm_connector *connector, int mode) { struct drm_device *dev = connector->dev; @@ -739,7 +746,6 @@ void intel_crt_init(struct drm_device *dev) } connector = &intel_connector->base; - crt->connector = intel_connector; drm_connector_init(dev, &intel_connector->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 8fc93f90a7cd..d7d4afe01341 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -2559,15 +2559,12 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) { struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); struct intel_dp *intel_dp = &intel_dig_port->dp; - struct drm_device *dev = intel_dp_to_dev(intel_dp); i2c_del_adapter(&intel_dp->adapter); drm_encoder_cleanup(encoder); if (is_edp(intel_dp)) { cancel_delayed_work_sync(&intel_dp->panel_vdd_work); - mutex_lock(&dev->mode_config.mutex); ironlake_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev->mode_config.mutex); } kfree(intel_dig_port); } diff --git a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c index 78d8e919509f..fe22bb780e1d 100644 --- a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -751,6 +751,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, int i; unsigned char misc = 0; unsigned char ext_vga[6]; + unsigned char ext_vga_index24; + unsigned char dac_index90 = 0; u8 bppshift; static unsigned char dacvalue[] = { @@ -801,6 +803,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, option2 = 0x0000b000; break; case G200_ER: + dac_index90 = 0; break; } @@ -849,8 +852,10 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_DAC(i, dacvalue[i]); } - if (mdev->type == G200_ER) - WREG_DAC(0x90, 0); + if (mdev->type == G200_ER) { + WREG_DAC(0x90, dac_index90); + } + if (option) pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option); @@ -947,6 +952,8 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, if (mdev->type == G200_WB) ext_vga[1] |= 0x88; + ext_vga_index24 = 0x05; + /* Set pixel clocks */ misc = 0x2d; WREG8(MGA_MISC_OUT, misc); @@ -958,7 +965,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, } if (mdev->type == G200_ER) - WREG_ECRT(0x24, 0x5); + WREG_ECRT(24, ext_vga_index24); if (mdev->type == G200_EV) { WREG_ECRT(6, 0); diff --git a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index 0e2c1a4f1659..e816f06637a7 100644 --- a/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/trunk/drivers/gpu/drm/nouveau/core/subdev/bios/base.c @@ -248,22 +248,6 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios) } } -static void -nouveau_bios_shadow_platform(struct nouveau_bios *bios) -{ - struct pci_dev *pdev = nv_device(bios)->pdev; - size_t size; - - void __iomem *rom = pci_platform_rom(pdev, &size); - if (rom && size) { - bios->data = kmalloc(size, GFP_KERNEL); - if (bios->data) { - memcpy_fromio(bios->data, rom, size); - bios->size = size; - } - } -} - static int nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) { @@ -304,7 +288,6 @@ nouveau_bios_shadow(struct nouveau_bios *bios) { "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL }, { "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL }, { "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL }, - { "PLATFORM", nouveau_bios_shadow_platform, true, 0, 0, NULL }, {} }; struct methods *mthd, *best; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c b/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c index 5eb3e0da7c6e..3b6dc883e150 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -391,7 +391,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_device *device = nv_device(drm->device); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); - struct nouveau_abi16_chan *chan = NULL, *temp; + struct nouveau_abi16_chan *chan, *temp; struct nouveau_abi16_ntfy *ntfy; struct nouveau_object *object; struct nv_dma_class args = {}; @@ -404,11 +404,10 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) if (unlikely(nv_device(abi16->device)->card_type >= NV_C0)) return nouveau_abi16_put(abi16, -EINVAL); - list_for_each_entry(temp, &abi16->channels, head) { - if (temp->chan->handle == (NVDRM_CHAN | info->channel)) { - chan = temp; + list_for_each_entry_safe(chan, temp, &abi16->channels, head) { + if (chan->chan->handle == (NVDRM_CHAN | info->channel)) break; - } + chan = NULL; } if (!chan) @@ -460,18 +459,17 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) { struct drm_nouveau_gpuobj_free *fini = data; struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); - struct nouveau_abi16_chan *chan = NULL, *temp; + struct nouveau_abi16_chan *chan, *temp; struct nouveau_abi16_ntfy *ntfy; int ret; if (unlikely(!abi16)) return -ENOMEM; - list_for_each_entry(temp, &abi16->channels, head) { - if (temp->chan->handle == (NVDRM_CHAN | fini->channel)) { - chan = temp; + list_for_each_entry_safe(chan, temp, &abi16->channels, head) { + if (chan->chan->handle == (NVDRM_CHAN | fini->channel)) break; - } + chan = NULL; } if (!chan) diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c index c95decf543e9..d1099365bfc1 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -71,26 +71,12 @@ module_param_named(modeset, nouveau_modeset, int, 0400); static struct drm_driver driver; -static int -nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) -{ - struct nouveau_drm *drm = - container_of(event, struct nouveau_drm, vblank[head]); - drm_handle_vblank(drm->dev, head); - return NVKM_EVENT_KEEP; -} - static int nouveau_drm_vblank_enable(struct drm_device *dev, int head) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); - - if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank))) - return -EIO; - WARN_ON_ONCE(drm->vblank[head].func); - drm->vblank[head].func = nouveau_drm_vblank_handler; - nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]); + nouveau_event_get(pdisp->vblank, head, &drm->vblank); return 0; } @@ -99,11 +85,16 @@ nouveau_drm_vblank_disable(struct drm_device *dev, int head) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); - if (drm->vblank[head].func) - nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]); - else - WARN_ON_ONCE(1); - drm->vblank[head].func = NULL; + nouveau_event_put(pdisp->vblank, head, &drm->vblank); +} + +static int +nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) +{ + struct nouveau_drm *drm = + container_of(event, struct nouveau_drm, vblank); + drm_handle_vblank(drm->dev, head); + return NVKM_EVENT_KEEP; } static u64 @@ -301,6 +292,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) dev->dev_private = drm; drm->dev = dev; + drm->vblank.func = nouveau_drm_vblank_handler; INIT_LIST_HEAD(&drm->clients); spin_lock_init(&drm->tile.lock); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h index 9c39bafbef2c..b25df374c901 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -113,7 +113,7 @@ struct nouveau_drm { struct nvbios vbios; struct nouveau_display *display; struct backlight_device *backlight; - struct nouveau_eventh vblank[4]; + struct nouveau_eventh vblank; /* power management */ struct nouveau_pm *pm; diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_display.c b/trunk/drivers/gpu/drm/nouveau/nv50_display.c index 1ddc03e51bf4..7f0e6c3f37d1 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_display.c @@ -479,7 +479,7 @@ nv50_display_flip_wait(void *data) { struct nv50_display_flip *flip = data; if (nouveau_bo_rd32(flip->disp->sync, flip->chan->addr / 4) == - flip->chan->data) + flip->chan->data); return true; usleep_range(1, 2); return false; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_bios.c b/trunk/drivers/gpu/drm/radeon/radeon_bios.c index fa3c56fba294..b8015913d382 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_bios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_bios.c @@ -99,29 +99,6 @@ static bool radeon_read_bios(struct radeon_device *rdev) return true; } -static bool radeon_read_platform_bios(struct radeon_device *rdev) -{ - uint8_t __iomem *bios; - size_t size; - - rdev->bios = NULL; - - bios = pci_platform_rom(rdev->pdev, &size); - if (!bios) { - return false; - } - - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { - return false; - } - rdev->bios = kmemdup(bios, size, GFP_KERNEL); - if (rdev->bios == NULL) { - return false; - } - - return true; -} - #ifdef CONFIG_ACPI /* ATRM is used to get the BIOS on the discrete cards in * dual-gpu systems. @@ -643,9 +620,6 @@ bool radeon_get_bios(struct radeon_device *rdev) if (r == false) { r = radeon_read_disabled_bios(rdev); } - if (r == false) { - r = radeon_read_platform_bios(rdev); - } if (r == false || rdev->bios == NULL) { DRM_ERROR("Unable to locate a BIOS ROM\n"); rdev->bios = NULL; diff --git a/trunk/drivers/gpu/drm/udl/udl_connector.c b/trunk/drivers/gpu/drm/udl/udl_connector.c index b44d548c56f8..fe5cdbcf2636 100644 --- a/trunk/drivers/gpu/drm/udl/udl_connector.c +++ b/trunk/drivers/gpu/drm/udl/udl_connector.c @@ -61,10 +61,6 @@ static int udl_get_modes(struct drm_connector *connector) int ret; edid = (struct edid *)udl_get_edid(udl); - if (!edid) { - drm_mode_connector_update_edid_property(connector, NULL); - return 0; - } /* * We only read the main block, but if the monitor reports extension diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index aa341d135867..512b01c04ea7 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -2077,6 +2077,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) }, { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MASTERKIT, USB_DEVICE_ID_MASTERKIT_MA901RADIO) }, { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, @@ -2243,18 +2244,6 @@ bool hid_ignore(struct hid_device *hdev) hdev->product <= USB_DEVICE_ID_VELLEMAN_K8061_LAST)) return true; break; - case USB_VENDOR_ID_ATMEL_V_USB: - /* Masterkit MA901 usb radio based on Atmel tiny85 chip and - * it has the same USB ID as many Atmel V-USB devices. This - * usb radio is handled by radio-ma901.c driver so we want - * ignore the hid. Check the name, bus, product and ignore - * if we have MA901 usb radio. - */ - if (hdev->product == USB_DEVICE_ID_ATMEL_V_USB && - hdev->bus == BUS_USB && - strncmp(hdev->name, "www.masterkit.ru MA901", 22) == 0) - return true; - break; } if (hdev->type == HID_TYPE_USBMOUSE && diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index 5309fd5eb0eb..c4388776f4e4 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -158,8 +158,6 @@ #define USB_VENDOR_ID_ATMEL 0x03eb #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c #define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118 -#define USB_VENDOR_ID_ATMEL_V_USB 0x16c0 -#define USB_DEVICE_ID_ATMEL_V_USB 0x05df #define USB_VENDOR_ID_AUREAL 0x0755 #define USB_DEVICE_ID_AUREAL_W01RN 0x2626 @@ -559,6 +557,9 @@ #define USB_VENDOR_ID_MADCATZ 0x0738 #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 +#define USB_VENDOR_ID_MASTERKIT 0x16c0 +#define USB_DEVICE_ID_MASTERKIT_MA901RADIO 0x05df + #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a diff --git a/trunk/drivers/hid/hid-magicmouse.c b/trunk/drivers/hid/hid-magicmouse.c index a8ce44296cfd..f7f113ba083e 100644 --- a/trunk/drivers/hid/hid-magicmouse.c +++ b/trunk/drivers/hid/hid-magicmouse.c @@ -462,21 +462,6 @@ static int magicmouse_input_mapping(struct hid_device *hdev, return 0; } -static void magicmouse_input_configured(struct hid_device *hdev, - struct hid_input *hi) - -{ - struct magicmouse_sc *msc = hid_get_drvdata(hdev); - - int ret = magicmouse_setup_input(msc->input, hdev); - if (ret) { - hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); - /* clean msc->input to notify probe() of the failure */ - msc->input = NULL; - } -} - - static int magicmouse_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -508,10 +493,15 @@ static int magicmouse_probe(struct hid_device *hdev, goto err_free; } - if (!msc->input) { - hid_err(hdev, "magicmouse input not registered\n"); - ret = -ENOMEM; - goto err_stop_hw; + /* We do this after hid-input is done parsing reports so that + * hid-input uses the most natural button and axis IDs. + */ + if (msc->input) { + ret = magicmouse_setup_input(msc->input, hdev); + if (ret) { + hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); + goto err_stop_hw; + } } if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) @@ -578,7 +568,6 @@ static struct hid_driver magicmouse_driver = { .remove = magicmouse_remove, .raw_event = magicmouse_raw_event, .input_mapping = magicmouse_input_mapping, - .input_configured = magicmouse_input_configured, }; module_hid_driver(magicmouse_driver); diff --git a/trunk/drivers/hwspinlock/hwspinlock_core.c b/trunk/drivers/hwspinlock/hwspinlock_core.c index 461a0d739d75..db713c0dfba4 100644 --- a/trunk/drivers/hwspinlock/hwspinlock_core.c +++ b/trunk/drivers/hwspinlock/hwspinlock_core.c @@ -416,8 +416,6 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock) ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "%s: can't power on device\n", __func__); - pm_runtime_put_noidle(dev); - module_put(dev->driver->owner); return ret; } diff --git a/trunk/drivers/i2c/busses/i2c-designware-platdrv.c b/trunk/drivers/i2c/busses/i2c-designware-platdrv.c index e3085c487ace..0ceb6e1b0f65 100644 --- a/trunk/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/trunk/drivers/i2c/busses/i2c-designware-platdrv.c @@ -182,6 +182,7 @@ static int dw_i2c_probe(struct platform_device *pdev) adap->algo = &i2c_dw_algo; adap->dev.parent = &pdev->dev; adap->dev.of_node = pdev->dev.of_node; + ACPI_HANDLE_SET(&adap->dev, ACPI_HANDLE(&pdev->dev)); r = i2c_add_numbered_adapter(adap); if (r) { diff --git a/trunk/drivers/idle/intel_idle.c b/trunk/drivers/idle/intel_idle.c index 1a38dd7dfe4e..5d6675013864 100644 --- a/trunk/drivers/idle/intel_idle.c +++ b/trunk/drivers/idle/intel_idle.c @@ -465,7 +465,6 @@ static const struct x86_cpu_id intel_idle_ids[] = { ICPU(0x3c, idle_cpu_hsw), ICPU(0x3f, idle_cpu_hsw), ICPU(0x45, idle_cpu_hsw), - ICPU(0x46, idle_cpu_hsw), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); diff --git a/trunk/drivers/infiniband/hw/qib/qib_sd7220.c b/trunk/drivers/infiniband/hw/qib/qib_sd7220.c index 911205d3d5a0..08a6c6d39e56 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_sd7220.c +++ b/trunk/drivers/infiniband/hw/qib/qib_sd7220.c @@ -44,7 +44,7 @@ #include "qib.h" #include "qib_7220.h" -#define SD7220_FW_NAME "qlogic/sd7220.fw" +#define SD7220_FW_NAME "intel/sd7220.fw" MODULE_FIRMWARE(SD7220_FW_NAME); /* diff --git a/trunk/drivers/input/tablet/wacom_wac.c b/trunk/drivers/input/tablet/wacom_wac.c index 0bfd8cf25200..1daa97913b7d 100644 --- a/trunk/drivers/input/tablet/wacom_wac.c +++ b/trunk/drivers/input/tablet/wacom_wac.c @@ -359,7 +359,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) case 0x802: /* Intuos4 General Pen */ case 0x804: /* Intuos4 Marker Pen */ case 0x40802: /* Intuos4 Classic Pen */ - case 0x18802: /* DTH2242 Grip Pen */ + case 0x18803: /* DTH2242 Grip Pen */ case 0x022: wacom->tool[idx] = BTN_TOOL_PEN; break; @@ -1912,7 +1912,7 @@ static const struct wacom_features wacom_features_0xBB = { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xBC = - { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40640, 25400, 2047, + { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0x26 = { "Wacom Intuos5 touch S", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, @@ -2144,7 +2144,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x44) }, { USB_DEVICE_WACOM(0x45) }, { USB_DEVICE_WACOM(0x59) }, - { USB_DEVICE_DETAILED(0x5D, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_WACOM(0x5D) }, { USB_DEVICE_WACOM(0xB0) }, { USB_DEVICE_WACOM(0xB1) }, { USB_DEVICE_WACOM(0xB2) }, @@ -2209,7 +2209,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_WACOM(0xF4) }, { USB_DEVICE_WACOM(0xF8) }, - { USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_WACOM(0xF6) }, { USB_DEVICE_WACOM(0xFA) }, { USB_DEVICE_LENOVO(0x6004) }, { } diff --git a/trunk/drivers/iommu/amd_iommu.c b/trunk/drivers/iommu/amd_iommu.c index 830183737b0f..b287ca33833d 100644 --- a/trunk/drivers/iommu/amd_iommu.c +++ b/trunk/drivers/iommu/amd_iommu.c @@ -173,7 +173,7 @@ static inline u16 get_device_id(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - return PCI_DEVID(pdev->bus->number, pdev->devfn); + return calc_devid(pdev->bus->number, pdev->devfn); } static struct iommu_dev_data *get_dev_data(struct device *dev) @@ -649,26 +649,26 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) case EVENT_TYPE_ILL_DEV: printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x " "address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), address, flags); dump_dte_entry(devid); break; case EVENT_TYPE_IO_FAULT: printk("IO_PAGE_FAULT device=%02x:%02x.%x " "domain=0x%04x address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), domid, address, flags); break; case EVENT_TYPE_DEV_TAB_ERR: printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x " "address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), address, flags); break; case EVENT_TYPE_PAGE_TAB_ERR: printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x " "domain=0x%04x address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), domid, address, flags); break; case EVENT_TYPE_ILL_CMD: @@ -682,13 +682,13 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) case EVENT_TYPE_IOTLB_INV_TO: printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x " "address=0x%016llx]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), address); break; case EVENT_TYPE_INV_DEV_REQ: printk("INVALID_DEVICE_REQUEST device=%02x:%02x.%x " "address=0x%016llx flags=0x%04x]\n", - PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), address, flags); break; default: diff --git a/trunk/drivers/iommu/amd_iommu_init.c b/trunk/drivers/iommu/amd_iommu_init.c index 2f46881256a2..e3c2d74b7684 100644 --- a/trunk/drivers/iommu/amd_iommu_init.c +++ b/trunk/drivers/iommu/amd_iommu_init.c @@ -406,7 +406,7 @@ static int __init find_last_devid_on_pci(int bus, int dev, int fn, int cap_ptr) u32 cap; cap = read_pci_config(bus, dev, fn, cap_ptr+MMIO_RANGE_OFFSET); - update_last_devid(PCI_DEVID(MMIO_GET_BUS(cap), MMIO_GET_LD(cap))); + update_last_devid(calc_devid(MMIO_GET_BUS(cap), MMIO_GET_LD(cap))); return 0; } @@ -423,7 +423,7 @@ static int __init find_last_devid_from_ivhd(struct ivhd_header *h) p += sizeof(*h); end += h->length; - find_last_devid_on_pci(PCI_BUS_NUM(h->devid), + find_last_devid_on_pci(PCI_BUS(h->devid), PCI_SLOT(h->devid), PCI_FUNC(h->devid), h->cap_ptr); @@ -784,10 +784,10 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_ALL\t\t\t first devid: %02x:%02x.%x" " last device %02x:%02x.%x flags: %02x\n", - PCI_BUS_NUM(iommu->first_device), + PCI_BUS(iommu->first_device), PCI_SLOT(iommu->first_device), PCI_FUNC(iommu->first_device), - PCI_BUS_NUM(iommu->last_device), + PCI_BUS(iommu->last_device), PCI_SLOT(iommu->last_device), PCI_FUNC(iommu->last_device), e->flags); @@ -801,7 +801,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_SELECT\t\t\t devid: %02x:%02x.%x " "flags: %02x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags); @@ -813,7 +813,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_SELECT_RANGE_START\t " "devid: %02x:%02x.%x flags: %02x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags); @@ -827,11 +827,11 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_ALIAS\t\t\t devid: %02x:%02x.%x " "flags: %02x devid_to: %02x:%02x.%x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags, - PCI_BUS_NUM(e->ext >> 8), + PCI_BUS(e->ext >> 8), PCI_SLOT(e->ext >> 8), PCI_FUNC(e->ext >> 8)); @@ -846,11 +846,11 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_ALIAS_RANGE\t\t " "devid: %02x:%02x.%x flags: %02x " "devid_to: %02x:%02x.%x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags, - PCI_BUS_NUM(e->ext >> 8), + PCI_BUS(e->ext >> 8), PCI_SLOT(e->ext >> 8), PCI_FUNC(e->ext >> 8)); @@ -864,7 +864,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_EXT_SELECT\t\t devid: %02x:%02x.%x " "flags: %02x ext: %08x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags, e->ext); @@ -877,7 +877,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_EXT_SELECT_RANGE\t devid: " "%02x:%02x.%x flags: %02x ext: %08x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid), e->flags, e->ext); @@ -890,7 +890,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, case IVHD_DEV_RANGE_END: DUMP_printk(" DEV_RANGE_END\t\t devid: %02x:%02x.%x\n", - PCI_BUS_NUM(e->devid), + PCI_BUS(e->devid), PCI_SLOT(e->devid), PCI_FUNC(e->devid)); @@ -924,7 +924,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, DUMP_printk(" DEV_SPECIAL(%s[%d])\t\tdevid: %02x:%02x.%x\n", var, (int)handle, - PCI_BUS_NUM(devid), + PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid)); @@ -1086,7 +1086,7 @@ static int __init init_iommu_all(struct acpi_table_header *table) DUMP_printk("device: %02x:%02x.%01x cap: %04x " "seg: %d flags: %01x info %04x\n", - PCI_BUS_NUM(h->devid), PCI_SLOT(h->devid), + PCI_BUS(h->devid), PCI_SLOT(h->devid), PCI_FUNC(h->devid), h->cap_ptr, h->pci_seg, h->flags, h->info); DUMP_printk(" mmio-addr: %016llx\n", @@ -1116,7 +1116,7 @@ static int iommu_init_pci(struct amd_iommu *iommu) int cap_ptr = iommu->cap_ptr; u32 range, misc, low, high; - iommu->dev = pci_get_bus_and_slot(PCI_BUS_NUM(iommu->devid), + iommu->dev = pci_get_bus_and_slot(PCI_BUS(iommu->devid), iommu->devid & 0xff); if (!iommu->dev) return -ENODEV; @@ -1128,9 +1128,9 @@ static int iommu_init_pci(struct amd_iommu *iommu) pci_read_config_dword(iommu->dev, cap_ptr + MMIO_MISC_OFFSET, &misc); - iommu->first_device = PCI_DEVID(MMIO_GET_BUS(range), + iommu->first_device = calc_devid(MMIO_GET_BUS(range), MMIO_GET_FD(range)); - iommu->last_device = PCI_DEVID(MMIO_GET_BUS(range), + iommu->last_device = calc_devid(MMIO_GET_BUS(range), MMIO_GET_LD(range)); if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB))) @@ -1388,8 +1388,8 @@ static int __init init_unity_map_range(struct ivmd_header *m) DUMP_printk("%s devid_start: %02x:%02x.%x devid_end: %02x:%02x.%x" " range_start: %016llx range_end: %016llx flags: %x\n", s, - PCI_BUS_NUM(e->devid_start), PCI_SLOT(e->devid_start), - PCI_FUNC(e->devid_start), PCI_BUS_NUM(e->devid_end), + PCI_BUS(e->devid_start), PCI_SLOT(e->devid_start), + PCI_FUNC(e->devid_start), PCI_BUS(e->devid_end), PCI_SLOT(e->devid_end), PCI_FUNC(e->devid_end), e->address_start, e->address_end, m->flags); diff --git a/trunk/drivers/iommu/amd_iommu_types.h b/trunk/drivers/iommu/amd_iommu_types.h index ec36cf63e0ca..e38ab438bb34 100644 --- a/trunk/drivers/iommu/amd_iommu_types.h +++ b/trunk/drivers/iommu/amd_iommu_types.h @@ -24,7 +24,6 @@ #include #include #include -#include /* * Maximum number of IOMMUs supported @@ -316,6 +315,9 @@ #define MAX_DOMAIN_ID 65536 +/* FIXME: move this macro to */ +#define PCI_BUS(x) (((x) >> 8) & 0xff) + /* Protection domain flags */ #define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */ #define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops @@ -701,6 +703,13 @@ extern int amd_iommu_max_glx_val; */ extern void iommu_flush_all_caches(struct amd_iommu *iommu); +/* takes bus and device/function and returns the device id + * FIXME: should that be in generic PCI code? */ +static inline u16 calc_devid(u8 bus, u8 devfn) +{ + return (((u16)bus) << 8) | devfn; +} + static inline int get_ioapic_devid(int id) { struct devid_map *entry; diff --git a/trunk/drivers/irqchip/irq-gic.c b/trunk/drivers/irqchip/irq-gic.c index fc6aebf1e4b2..a32e0d5aa45f 100644 --- a/trunk/drivers/irqchip/irq-gic.c +++ b/trunk/drivers/irqchip/irq-gic.c @@ -236,8 +236,7 @@ static int gic_retrigger(struct irq_data *d) if (gic_arch_extn.irq_retrigger) return gic_arch_extn.irq_retrigger(d); - /* the genirq layer expects 0 if we can't retrigger in hardware */ - return 0; + return -ENXIO; } #ifdef CONFIG_SMP diff --git a/trunk/drivers/md/dm-cache-target.c b/trunk/drivers/md/dm-cache-target.c index 10744091e6ca..66120bd46d15 100644 --- a/trunk/drivers/md/dm-cache-target.c +++ b/trunk/drivers/md/dm-cache-target.c @@ -6,7 +6,6 @@ #include "dm.h" #include "dm-bio-prison.h" -#include "dm-bio-record.h" #include "dm-cache-metadata.h" #include @@ -202,15 +201,10 @@ struct per_bio_data { unsigned req_nr:2; struct dm_deferred_entry *all_io_entry; - /* - * writethrough fields. These MUST remain at the end of this - * structure and the 'cache' member must be the first as it - * is used to determine the offsetof the writethrough fields. - */ + /* writethrough fields */ struct cache *cache; dm_cblock_t cblock; bio_end_io_t *saved_bi_end_io; - struct dm_bio_details bio_details; }; struct dm_cache_migration { @@ -519,28 +513,16 @@ static void save_stats(struct cache *cache) /*---------------------------------------------------------------- * Per bio data *--------------------------------------------------------------*/ - -/* - * If using writeback, leave out struct per_bio_data's writethrough fields. - */ -#define PB_DATA_SIZE_WB (offsetof(struct per_bio_data, cache)) -#define PB_DATA_SIZE_WT (sizeof(struct per_bio_data)) - -static size_t get_per_bio_data_size(struct cache *cache) -{ - return cache->features.write_through ? PB_DATA_SIZE_WT : PB_DATA_SIZE_WB; -} - -static struct per_bio_data *get_per_bio_data(struct bio *bio, size_t data_size) +static struct per_bio_data *get_per_bio_data(struct bio *bio) { - struct per_bio_data *pb = dm_per_bio_data(bio, data_size); + struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); BUG_ON(!pb); return pb; } -static struct per_bio_data *init_per_bio_data(struct bio *bio, size_t data_size) +static struct per_bio_data *init_per_bio_data(struct bio *bio) { - struct per_bio_data *pb = get_per_bio_data(bio, data_size); + struct per_bio_data *pb = get_per_bio_data(bio); pb->tick = false; pb->req_nr = dm_bio_get_target_bio_nr(bio); @@ -574,8 +556,7 @@ static void remap_to_cache(struct cache *cache, struct bio *bio, static void check_if_tick_bio_needed(struct cache *cache, struct bio *bio) { unsigned long flags; - size_t pb_data_size = get_per_bio_data_size(cache); - struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); + struct per_bio_data *pb = get_per_bio_data(bio); spin_lock_irqsave(&cache->lock, flags); if (cache->need_tick_bio && @@ -654,7 +635,7 @@ static void defer_writethrough_bio(struct cache *cache, struct bio *bio) static void writethrough_endio(struct bio *bio, int err) { - struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT); + struct per_bio_data *pb = get_per_bio_data(bio); bio->bi_end_io = pb->saved_bi_end_io; if (err) { @@ -662,7 +643,6 @@ static void writethrough_endio(struct bio *bio, int err) return; } - dm_bio_restore(&pb->bio_details, bio); remap_to_cache(pb->cache, bio, pb->cblock); /* @@ -682,12 +662,11 @@ static void writethrough_endio(struct bio *bio, int err) static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio, dm_oblock_t oblock, dm_cblock_t cblock) { - struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT); + struct per_bio_data *pb = get_per_bio_data(bio); pb->cache = cache; pb->cblock = cblock; pb->saved_bi_end_io = bio->bi_end_io; - dm_bio_record(&pb->bio_details, bio); bio->bi_end_io = writethrough_endio; remap_to_origin_clear_discard(pb->cache, bio, oblock); @@ -1056,8 +1035,7 @@ static void defer_bio(struct cache *cache, struct bio *bio) static void process_flush_bio(struct cache *cache, struct bio *bio) { - size_t pb_data_size = get_per_bio_data_size(cache); - struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); + struct per_bio_data *pb = get_per_bio_data(bio); BUG_ON(bio->bi_size); if (!pb->req_nr) @@ -1129,8 +1107,7 @@ static void process_bio(struct cache *cache, struct prealloc *structs, dm_oblock_t block = get_bio_block(cache, bio); struct dm_bio_prison_cell *cell_prealloc, *old_ocell, *new_ocell; struct policy_result lookup_result; - size_t pb_data_size = get_per_bio_data_size(cache); - struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); + struct per_bio_data *pb = get_per_bio_data(bio); bool discarded_block = is_discarded_oblock(cache, block); bool can_migrate = discarded_block || spare_migration_bandwidth(cache); @@ -1904,6 +1881,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) cache->ti = ca->ti; ti->private = cache; + ti->per_bio_data_size = sizeof(struct per_bio_data); ti->num_flush_bios = 2; ti->flush_supported = true; @@ -1912,7 +1890,6 @@ static int cache_create(struct cache_args *ca, struct cache **result) ti->discard_zeroes_data_unsupported = true; memcpy(&cache->features, &ca->features, sizeof(cache->features)); - ti->per_bio_data_size = get_per_bio_data_size(cache); cache->callbacks.congested_fn = cache_is_congested; dm_table_add_target_callbacks(ti->table, &cache->callbacks); @@ -2115,7 +2092,6 @@ static int cache_map(struct dm_target *ti, struct bio *bio) int r; dm_oblock_t block = get_bio_block(cache, bio); - size_t pb_data_size = get_per_bio_data_size(cache); bool can_migrate = false; bool discarded_block; struct dm_bio_prison_cell *cell; @@ -2132,7 +2108,7 @@ static int cache_map(struct dm_target *ti, struct bio *bio) return DM_MAPIO_REMAPPED; } - pb = init_per_bio_data(bio, pb_data_size); + pb = init_per_bio_data(bio); if (bio->bi_rw & (REQ_FLUSH | REQ_FUA | REQ_DISCARD)) { defer_bio(cache, bio); @@ -2217,8 +2193,7 @@ static int cache_end_io(struct dm_target *ti, struct bio *bio, int error) { struct cache *cache = ti->private; unsigned long flags; - size_t pb_data_size = get_per_bio_data_size(cache); - struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); + struct per_bio_data *pb = get_per_bio_data(bio); if (pb->tick) { policy_tick(cache->policy); diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 9a0bdad9ad8f..7e469260fe5e 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -611,7 +611,6 @@ static void dec_pending(struct dm_io *io, int error) queue_io(md, bio); } else { /* done with normal IO or empty flush */ - trace_block_bio_complete(md->queue, bio, io_error); bio_endio(bio, io_error); } } diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index f4e87bfc7567..24909eb13fec 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -184,8 +184,6 @@ static void return_io(struct bio *return_bi) return_bi = bi->bi_next; bi->bi_next = NULL; bi->bi_size = 0; - trace_block_bio_complete(bdev_get_queue(bi->bi_bdev), - bi, 0); bio_endio(bi, 0); bi = return_bi; } @@ -3916,8 +3914,6 @@ static void raid5_align_endio(struct bio *bi, int error) rdev_dec_pending(rdev, conf->mddev); if (!error && uptodate) { - trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev), - raid_bi, 0); bio_endio(raid_bi, 0); if (atomic_dec_and_test(&conf->active_aligned_reads)) wake_up(&conf->wait_for_stripe); @@ -4386,8 +4382,6 @@ static void make_request(struct mddev *mddev, struct bio * bi) if ( rw == WRITE ) md_write_end(mddev); - trace_block_bio_complete(bdev_get_queue(bi->bi_bdev), - bi, 0); bio_endio(bi, 0); } } @@ -4764,11 +4758,8 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio) handled++; } remaining = raid5_dec_bi_active_stripes(raid_bio); - if (remaining == 0) { - trace_block_bio_complete(bdev_get_queue(raid_bio->bi_bdev), - raid_bio, 0); + if (remaining == 0) bio_endio(raid_bio, 0); - } if (atomic_dec_and_test(&conf->active_aligned_reads)) wake_up(&conf->wait_for_stripe); return handled; diff --git a/trunk/drivers/media/dvb-frontends/mb86a20s.c b/trunk/drivers/media/dvb-frontends/mb86a20s.c index 4faaf8053f26..f19cd7367040 100644 --- a/trunk/drivers/media/dvb-frontends/mb86a20s.c +++ b/trunk/drivers/media/dvb-frontends/mb86a20s.c @@ -610,7 +610,7 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer, __func__, 'A' + layer, segment * isdbt_rate[m][f][i]/1000, rate, rate); - state->estimated_rate[layer] = rate; + state->estimated_rate[i] = rate; } diff --git a/trunk/drivers/media/pci/cx25821/cx25821-video.c b/trunk/drivers/media/pci/cx25821/cx25821-video.c index 31ce7698acb9..d4de021dc844 100644 --- a/trunk/drivers/media/pci/cx25821/cx25821-video.c +++ b/trunk/drivers/media/pci/cx25821/cx25821-video.c @@ -461,7 +461,7 @@ int cx25821_video_register(struct cx25821_dev *dev) spin_lock_init(&dev->slock); - for (i = 0; i < VID_CHANNEL_NUM; ++i) { + for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) { cx25821_init_controls(dev, i); cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, diff --git a/trunk/drivers/media/platform/Kconfig b/trunk/drivers/media/platform/Kconfig index a0639e779973..05d7b6333461 100644 --- a/trunk/drivers/media/platform/Kconfig +++ b/trunk/drivers/media/platform/Kconfig @@ -204,7 +204,7 @@ config VIDEO_SAMSUNG_EXYNOS_GSC config VIDEO_SH_VEU tristate "SuperH VEU mem2mem video processing driver" - depends on VIDEO_DEV && VIDEO_V4L2 && GENERIC_HARDIRQS + depends on VIDEO_DEV && VIDEO_V4L2 select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV help diff --git a/trunk/drivers/media/radio/radio-ma901.c b/trunk/drivers/media/radio/radio-ma901.c index 348dafc0318a..c61f590029ad 100644 --- a/trunk/drivers/media/radio/radio-ma901.c +++ b/trunk/drivers/media/radio/radio-ma901.c @@ -347,20 +347,9 @@ static void usb_ma901radio_release(struct v4l2_device *v4l2_dev) static int usb_ma901radio_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *dev = interface_to_usbdev(intf); struct ma901radio_device *radio; int retval = 0; - /* Masterkit MA901 usb radio has the same USB ID as many others - * Atmel V-USB devices. Let's make additional checks to be sure - * that this is our device. - */ - - if (dev->product && dev->manufacturer && - (strncmp(dev->product, "MA901", 5) != 0 - || strncmp(dev->manufacturer, "www.masterkit.ru", 16) != 0)) - return -ENODEV; - radio = kzalloc(sizeof(struct ma901radio_device), GFP_KERNEL); if (!radio) { dev_err(&intf->dev, "kzalloc for ma901radio_device failed\n"); diff --git a/trunk/drivers/misc/vmw_vmci/Kconfig b/trunk/drivers/misc/vmw_vmci/Kconfig index ea98f7e9ccd1..39c2ecadb273 100644 --- a/trunk/drivers/misc/vmw_vmci/Kconfig +++ b/trunk/drivers/misc/vmw_vmci/Kconfig @@ -4,7 +4,7 @@ config VMWARE_VMCI tristate "VMware VMCI Driver" - depends on X86 && PCI && NET + depends on X86 && PCI help This is VMware's Virtual Machine Communication Interface. It enables high-speed communication between host and guest in a virtual diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index dc571ebc1aa0..92ab30ab00dc 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -1123,6 +1123,33 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file, } #endif +static inline unsigned long get_vm_size(struct vm_area_struct *vma) +{ + return vma->vm_end - vma->vm_start; +} + +static inline resource_size_t get_vm_offset(struct vm_area_struct *vma) +{ + return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT; +} + +/* + * Set a new vm offset. + * + * Verify that the incoming offset really works as a page offset, + * and that the offset and size fit in a resource_size_t. + */ +static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off) +{ + pgoff_t pgoff = off >> PAGE_SHIFT; + if (off != (resource_size_t) pgoff << PAGE_SHIFT) + return -EINVAL; + if (off + get_vm_size(vma) - 1 < off) + return -EINVAL; + vma->vm_pgoff = pgoff; + return 0; +} + /* * set up a mapping for shared memory segments */ @@ -1132,17 +1159,45 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma) struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; struct map_info *map = mtd->priv; + resource_size_t start, off; + unsigned long len, vma_len; /* This is broken because it assumes the MTD device is map-based and that mtd->priv is a valid struct map_info. It should be replaced with something that uses the mtd_get_unmapped_area() operation properly. */ if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { + off = get_vm_offset(vma); + start = map->phys; + len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); + start &= PAGE_MASK; + vma_len = get_vm_size(vma); + + /* Overflow in off+len? */ + if (vma_len + off < off) + return -EINVAL; + /* Does it fit in the mapping? */ + if (vma_len + off > len) + return -EINVAL; + + off += start; + /* Did that overflow? */ + if (off < start) + return -EINVAL; + if (set_vm_offset(vma, off) < 0) + return -EINVAL; + vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; + #ifdef pgprot_noncached - if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory)) + if (file->f_flags & O_DSYNC || off >= __pa(high_memory)) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); #endif - return vm_iomap_memory(vma, map->phys, map->size); + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) + return -EAGAIN; + + return 0; } return -ENOSYS; #else diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index dbbea0eec134..6bbd90e1123c 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -846,10 +846,8 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, if (bond->dev->flags & IFF_ALLMULTI) dev_set_allmulti(old_active->dev, -1); - netif_addr_lock_bh(bond->dev); netdev_for_each_mc_addr(ha, bond->dev) dev_mc_del(old_active->dev, ha->addr); - netif_addr_unlock_bh(bond->dev); } if (new_active) { @@ -860,10 +858,8 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, if (bond->dev->flags & IFF_ALLMULTI) dev_set_allmulti(new_active->dev, 1); - netif_addr_lock_bh(bond->dev); netdev_for_each_mc_addr(ha, bond->dev) dev_mc_add(new_active->dev, ha->addr); - netif_addr_unlock_bh(bond->dev); } } @@ -1905,29 +1901,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) bond_destroy_slave_symlinks(bond_dev, slave_dev); err_detach: - if (!USES_PRIMARY(bond->params.mode)) { - netif_addr_lock_bh(bond_dev); - bond_mc_list_flush(bond_dev, slave_dev); - netif_addr_unlock_bh(bond_dev); - } - bond_del_vlans_from_slave(bond, slave_dev); write_lock_bh(&bond->lock); bond_detach_slave(bond, new_slave); - if (bond->primary_slave == new_slave) - bond->primary_slave = NULL; write_unlock_bh(&bond->lock); - if (bond->curr_active_slave == new_slave) { - read_lock(&bond->lock); - write_lock_bh(&bond->curr_slave_lock); - bond_change_active_slave(bond, NULL); - bond_select_active_slave(bond); - write_unlock_bh(&bond->curr_slave_lock); - read_unlock(&bond->lock); - } - slave_disable_netpoll(new_slave); err_close: - slave_dev->priv_flags &= ~IFF_BONDING; dev_close(slave_dev); err_unset_master: @@ -1998,11 +1976,12 @@ static int __bond_release_one(struct net_device *bond_dev, return -EINVAL; } - write_unlock_bh(&bond->lock); /* unregister rx_handler early so bond_handle_frame wouldn't be called * for this slave anymore. */ netdev_rx_handler_unregister(slave_dev); + write_unlock_bh(&bond->lock); + synchronize_net(); write_lock_bh(&bond->lock); if (!all && !bond->params.fail_over_mac) { @@ -3190,20 +3169,11 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) { struct slave *slave = bond_slave_get_rtnl(slave_dev); - struct bonding *bond; - struct net_device *bond_dev; + struct bonding *bond = slave->bond; + struct net_device *bond_dev = slave->bond->dev; u32 old_speed; u8 old_duplex; - /* A netdev event can be generated while enslaving a device - * before netdev_rx_handler_register is called in which case - * slave will be NULL - */ - if (!slave) - return NOTIFY_DONE; - bond_dev = slave->bond->dev; - bond = slave->bond; - switch (event) { case NETDEV_UNREGISTER: if (bond->setup_by_slave) @@ -3317,22 +3287,20 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb, int count) */ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) { - const struct ethhdr *data; - const struct iphdr *iph; - const struct ipv6hdr *ipv6h; + struct ethhdr *data = (struct ethhdr *)skb->data; + struct iphdr *iph; + struct ipv6hdr *ipv6h; u32 v6hash; - const __be32 *s, *d; + __be32 *s, *d; if (skb->protocol == htons(ETH_P_IP) && - pskb_network_may_pull(skb, sizeof(*iph))) { + skb_network_header_len(skb) >= sizeof(*iph)) { iph = ip_hdr(skb); - data = (struct ethhdr *)skb->data; return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ (data->h_dest[5] ^ data->h_source[5])) % count; } else if (skb->protocol == htons(ETH_P_IPV6) && - pskb_network_may_pull(skb, sizeof(*ipv6h))) { + skb_network_header_len(skb) >= sizeof(*ipv6h)) { ipv6h = ipv6_hdr(skb); - data = (struct ethhdr *)skb->data; s = &ipv6h->saddr.s6_addr32[0]; d = &ipv6h->daddr.s6_addr32[0]; v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]); @@ -3351,36 +3319,33 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) { u32 layer4_xor = 0; - const struct iphdr *iph; - const struct ipv6hdr *ipv6h; - const __be32 *s, *d; - const __be16 *l4 = NULL; - __be16 _l4[2]; - int noff = skb_network_offset(skb); - int poff; + struct iphdr *iph; + struct ipv6hdr *ipv6h; + __be32 *s, *d; + __be16 *layer4hdr; if (skb->protocol == htons(ETH_P_IP) && - pskb_may_pull(skb, noff + sizeof(*iph))) { + skb_network_header_len(skb) >= sizeof(*iph)) { iph = ip_hdr(skb); - poff = proto_ports_offset(iph->protocol); - - if (!ip_is_fragment(iph) && poff >= 0) { - l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff, - sizeof(_l4), &_l4); - if (l4) - layer4_xor = ntohs(l4[0] ^ l4[1]); + if (!ip_is_fragment(iph) && + (iph->protocol == IPPROTO_TCP || + iph->protocol == IPPROTO_UDP) && + (skb_headlen(skb) - skb_network_offset(skb) >= + iph->ihl * sizeof(u32) + sizeof(*layer4hdr) * 2)) { + layer4hdr = (__be16 *)((u32 *)iph + iph->ihl); + layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1)); } return (layer4_xor ^ ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count; } else if (skb->protocol == htons(ETH_P_IPV6) && - pskb_may_pull(skb, noff + sizeof(*ipv6h))) { + skb_network_header_len(skb) >= sizeof(*ipv6h)) { ipv6h = ipv6_hdr(skb); - poff = proto_ports_offset(ipv6h->nexthdr); - if (poff >= 0) { - l4 = skb_header_pointer(skb, noff + sizeof(*ipv6h) + poff, - sizeof(_l4), &_l4); - if (l4) - layer4_xor = ntohs(l4[0] ^ l4[1]); + if ((ipv6h->nexthdr == IPPROTO_TCP || + ipv6h->nexthdr == IPPROTO_UDP) && + (skb_headlen(skb) - skb_network_offset(skb) >= + sizeof(*ipv6h) + sizeof(*layer4hdr) * 2)) { + layer4hdr = (__be16 *)(ipv6h + 1); + layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1)); } s = &ipv6h->saddr.s6_addr32[0]; d = &ipv6h->daddr.s6_addr32[0]; @@ -4882,18 +4847,9 @@ static int __net_init bond_net_init(struct net *net) static void __net_exit bond_net_exit(struct net *net) { struct bond_net *bn = net_generic(net, bond_net_id); - struct bonding *bond, *tmp_bond; - LIST_HEAD(list); bond_destroy_sysfs(bn); bond_destroy_proc_dir(bn); - - /* Kill off any bonds created after unregistering bond rtnl ops */ - rtnl_lock(); - list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list) - unregister_netdevice_queue(bond->dev, &list); - unregister_netdevice_many(&list); - rtnl_unlock(); } static struct pernet_operations bond_net_ops = { diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index ea7a388f4843..db103e03ba05 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -527,7 +527,7 @@ static ssize_t bonding_store_arp_interval(struct device *d, goto out; } if (new_value < 0) { - pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n", + pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n", bond->dev->name, new_value, INT_MAX); ret = -EINVAL; goto out; @@ -542,15 +542,14 @@ static ssize_t bonding_store_arp_interval(struct device *d, pr_info("%s: Setting ARP monitoring interval to %d.\n", bond->dev->name, new_value); bond->params.arp_interval = new_value; - if (new_value) { - if (bond->params.miimon) { - pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", - bond->dev->name, bond->dev->name); - bond->params.miimon = 0; - } - if (!bond->params.arp_targets[0]) - pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", - bond->dev->name); + if (bond->params.miimon) { + pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", + bond->dev->name, bond->dev->name); + bond->params.miimon = 0; + } + if (!bond->params.arp_targets[0]) { + pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", + bond->dev->name); } if (bond->dev->flags & IFF_UP) { /* If the interface is up, we may need to fire off @@ -558,13 +557,10 @@ static ssize_t bonding_store_arp_interval(struct device *d, * timer will get fired off when the open function * is called. */ - if (!new_value) { - cancel_delayed_work_sync(&bond->arp_work); - } else { - cancel_delayed_work_sync(&bond->mii_work); - queue_delayed_work(bond->wq, &bond->arp_work, 0); - } + cancel_delayed_work_sync(&bond->mii_work); + queue_delayed_work(bond->wq, &bond->arp_work, 0); } + out: rtnl_unlock(); return ret; @@ -706,7 +702,7 @@ static ssize_t bonding_store_downdelay(struct device *d, } if (new_value < 0) { pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 0, INT_MAX); + bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; } else { @@ -761,8 +757,8 @@ static ssize_t bonding_store_updelay(struct device *d, goto out; } if (new_value < 0) { - pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 0, INT_MAX); + pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", + bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; } else { @@ -972,37 +968,37 @@ static ssize_t bonding_store_miimon(struct device *d, } if (new_value < 0) { pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 0, INT_MAX); + bond->dev->name, new_value, 1, INT_MAX); ret = -EINVAL; goto out; - } - pr_info("%s: Setting MII monitoring interval to %d.\n", - bond->dev->name, new_value); - bond->params.miimon = new_value; - if (bond->params.updelay) - pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", - bond->dev->name, - bond->params.updelay * bond->params.miimon); - if (bond->params.downdelay) - pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", - bond->dev->name, - bond->params.downdelay * bond->params.miimon); - if (new_value && bond->params.arp_interval) { - pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", - bond->dev->name); - bond->params.arp_interval = 0; - if (bond->params.arp_validate) - bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; - } - if (bond->dev->flags & IFF_UP) { - /* If the interface is up, we may need to fire off - * the MII timer. If the interface is down, the - * timer will get fired off when the open function - * is called. - */ - if (!new_value) { - cancel_delayed_work_sync(&bond->mii_work); - } else { + } else { + pr_info("%s: Setting MII monitoring interval to %d.\n", + bond->dev->name, new_value); + bond->params.miimon = new_value; + if (bond->params.updelay) + pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", + bond->dev->name, + bond->params.updelay * bond->params.miimon); + if (bond->params.downdelay) + pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", + bond->dev->name, + bond->params.downdelay * bond->params.miimon); + if (bond->params.arp_interval) { + pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", + bond->dev->name); + bond->params.arp_interval = 0; + if (bond->params.arp_validate) { + bond->params.arp_validate = + BOND_ARP_VALIDATE_NONE; + } + } + + if (bond->dev->flags & IFF_UP) { + /* If the interface is up, we may need to fire off + * the MII timer. If the interface is down, the + * timer will get fired off when the open function + * is called. + */ cancel_delayed_work_sync(&bond->arp_work); queue_delayed_work(bond->wq, &bond->mii_work, 0); } diff --git a/trunk/drivers/net/can/mcp251x.c b/trunk/drivers/net/can/mcp251x.c index 9aa0c64c33c8..f32b9fc6a983 100644 --- a/trunk/drivers/net/can/mcp251x.c +++ b/trunk/drivers/net/can/mcp251x.c @@ -929,7 +929,6 @@ static int mcp251x_open(struct net_device *net) struct mcp251x_priv *priv = netdev_priv(net); struct spi_device *spi = priv->spi; struct mcp251x_platform_data *pdata = spi->dev.platform_data; - unsigned long flags; int ret; ret = open_candev(net); @@ -946,14 +945,9 @@ static int mcp251x_open(struct net_device *net) priv->tx_skb = NULL; priv->tx_len = 0; - flags = IRQF_ONESHOT; - if (pdata->irq_flags) - flags |= pdata->irq_flags; - else - flags |= IRQF_TRIGGER_FALLING; - ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist, - flags, DEVICE_NAME, priv); + pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING, + DEVICE_NAME, priv); if (ret) { dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq); if (pdata->transceiver_enable) diff --git a/trunk/drivers/net/can/sja1000/Kconfig b/trunk/drivers/net/can/sja1000/Kconfig index ff2ba86cd4a4..b39ca5b3ea7f 100644 --- a/trunk/drivers/net/can/sja1000/Kconfig +++ b/trunk/drivers/net/can/sja1000/Kconfig @@ -46,7 +46,6 @@ config CAN_EMS_PCI config CAN_PEAK_PCMCIA tristate "PEAK PCAN-PC Card" depends on PCMCIA - depends on HAS_IOPORT ---help--- This driver is for the PCAN-PC Card PCMCIA adapter (1 or 2 channels) from PEAK-System (http://www.peak-system.com). To compile this diff --git a/trunk/drivers/net/can/sja1000/plx_pci.c b/trunk/drivers/net/can/sja1000/plx_pci.c index 3c18d7d000ed..a042cdc260dc 100644 --- a/trunk/drivers/net/can/sja1000/plx_pci.c +++ b/trunk/drivers/net/can/sja1000/plx_pci.c @@ -348,7 +348,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) */ if ((priv->read_reg(priv, REG_CR) & REG_CR_BASICCAN_INITIAL_MASK) == REG_CR_BASICCAN_INITIAL && - (priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_BASICCAN_INITIAL) && + (priv->read_reg(priv, REG_SR) == REG_SR_BASICCAN_INITIAL) && (priv->read_reg(priv, REG_IR) == REG_IR_BASICCAN_INITIAL)) flag = 1; @@ -360,7 +360,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) * See states on p. 23 of the Datasheet. */ if (priv->read_reg(priv, REG_MOD) == REG_MOD_PELICAN_INITIAL && - priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_PELICAN_INITIAL && + priv->read_reg(priv, REG_SR) == REG_SR_PELICAN_INITIAL && priv->read_reg(priv, REG_IR) == REG_IR_PELICAN_INITIAL) return flag; diff --git a/trunk/drivers/net/can/sja1000/sja1000.c b/trunk/drivers/net/can/sja1000/sja1000.c index e4df307eaa90..daf4013a8fc7 100644 --- a/trunk/drivers/net/can/sja1000/sja1000.c +++ b/trunk/drivers/net/can/sja1000/sja1000.c @@ -92,7 +92,7 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val) */ spin_lock_irqsave(&priv->cmdreg_lock, flags); priv->write_reg(priv, REG_CMR, val); - priv->read_reg(priv, SJA1000_REG_SR); + priv->read_reg(priv, REG_SR); spin_unlock_irqrestore(&priv->cmdreg_lock, flags); } @@ -502,7 +502,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) { n++; - status = priv->read_reg(priv, SJA1000_REG_SR); + status = priv->read_reg(priv, REG_SR); /* check for absent controller due to hw unplug */ if (status == 0xFF && sja1000_is_absent(priv)) return IRQ_NONE; @@ -530,7 +530,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) /* receive interrupt */ while (status & SR_RBS) { sja1000_rx(dev); - status = priv->read_reg(priv, SJA1000_REG_SR); + status = priv->read_reg(priv, REG_SR); /* check for absent controller */ if (status == 0xFF && sja1000_is_absent(priv)) return IRQ_NONE; diff --git a/trunk/drivers/net/can/sja1000/sja1000.h b/trunk/drivers/net/can/sja1000/sja1000.h index aa48e053da27..afa99847a510 100644 --- a/trunk/drivers/net/can/sja1000/sja1000.h +++ b/trunk/drivers/net/can/sja1000/sja1000.h @@ -56,7 +56,7 @@ /* SJA1000 registers - manual section 6.4 (Pelican Mode) */ #define REG_MOD 0x00 #define REG_CMR 0x01 -#define SJA1000_REG_SR 0x02 +#define REG_SR 0x02 #define REG_IR 0x03 #define REG_IER 0x04 #define REG_ALC 0x0B diff --git a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c index 8e0c4a001939..6433b81256cd 100644 --- a/trunk/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/trunk/drivers/net/can/sja1000/sja1000_of_platform.c @@ -96,8 +96,8 @@ static int sja1000_ofp_probe(struct platform_device *ofdev) struct net_device *dev; struct sja1000_priv *priv; struct resource res; - u32 prop; - int err, irq, res_size; + const u32 *prop; + int err, irq, res_size, prop_size; void __iomem *base; err = of_address_to_resource(np, 0, &res); @@ -138,27 +138,27 @@ static int sja1000_ofp_probe(struct platform_device *ofdev) priv->read_reg = sja1000_ofp_read_reg; priv->write_reg = sja1000_ofp_write_reg; - err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop); - if (!err) - priv->can.clock.freq = prop / 2; + prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->can.clock.freq = *prop / 2; else priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ - err = of_property_read_u32(np, "nxp,tx-output-mode", &prop); - if (!err) - priv->ocr |= prop & OCR_MODE_MASK; + prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->ocr |= *prop & OCR_MODE_MASK; else priv->ocr |= OCR_MODE_NORMAL; /* default */ - err = of_property_read_u32(np, "nxp,tx-output-config", &prop); - if (!err) - priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; + prop = of_get_property(np, "nxp,tx-output-config", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; else priv->ocr |= OCR_TX0_PULLDOWN; /* default */ - err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop); - if (!err && prop) { - u32 divider = priv->can.clock.freq * 2 / prop; + prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); + if (prop && (prop_size == sizeof(u32)) && *prop) { + u32 divider = priv->can.clock.freq * 2 / *prop; if (divider > 1) priv->cdr |= divider / 2 - 1; @@ -168,7 +168,8 @@ static int sja1000_ofp_probe(struct platform_device *ofdev) priv->cdr |= CDR_CLK_OFF; /* default */ } - if (!of_property_read_bool(np, "nxp,no-comparator-bypass")) + prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); + if (!prop) priv->cdr |= CDR_CBP; /* default */ priv->irq_flags = IRQF_SHARED; diff --git a/trunk/drivers/net/ethernet/8390/ax88796.c b/trunk/drivers/net/ethernet/8390/ax88796.c index e1d26433d619..cab306a9888e 100644 --- a/trunk/drivers/net/ethernet/8390/ax88796.c +++ b/trunk/drivers/net/ethernet/8390/ax88796.c @@ -828,7 +828,7 @@ static int ax_probe(struct platform_device *pdev) struct ei_device *ei_local; struct ax_device *ax; struct resource *irq, *mem, *mem2; - unsigned long mem_size, mem2_size = 0; + resource_size_t mem_size, mem2_size = 0; int ret = 0; dev = ax__alloc_ei_netdev(sizeof(struct ax_device)); diff --git a/trunk/drivers/net/ethernet/atheros/atl1e/atl1e.h b/trunk/drivers/net/ethernet/atheros/atl1e/atl1e.h index b5fd934585e9..829b5ad71d0d 100644 --- a/trunk/drivers/net/ethernet/atheros/atl1e/atl1e.h +++ b/trunk/drivers/net/ethernet/atheros/atl1e/atl1e.h @@ -186,7 +186,7 @@ struct atl1e_tpd_desc { /* how about 0x2000 */ #define MAX_TX_BUF_LEN 0x2000 #define MAX_TX_BUF_SHIFT 13 -#define MAX_TSO_SEG_SIZE 0x3c00 +/*#define MAX_TX_BUF_LEN 0x3000 */ /* rrs word 1 bit 0:31 */ #define RRS_RX_CSUM_MASK 0xFFFF @@ -438,6 +438,7 @@ struct atl1e_adapter { struct atl1e_hw hw; struct atl1e_hw_stats hw_stats; + bool have_msi; u32 wol; u16 link_speed; u16 link_duplex; diff --git a/trunk/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/trunk/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index ac25f05ff68f..92f4734f860d 100644 --- a/trunk/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/trunk/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -1849,19 +1849,34 @@ static void atl1e_free_irq(struct atl1e_adapter *adapter) struct net_device *netdev = adapter->netdev; free_irq(adapter->pdev->irq, netdev); + + if (adapter->have_msi) + pci_disable_msi(adapter->pdev); } static int atl1e_request_irq(struct atl1e_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; + int flags = 0; int err = 0; - err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, netdev->name, - netdev); + adapter->have_msi = true; + err = pci_enable_msi(pdev); + if (err) { + netdev_dbg(netdev, + "Unable to allocate MSI interrupt Error: %d\n", err); + adapter->have_msi = false; + } + + if (!adapter->have_msi) + flags |= IRQF_SHARED; + err = request_irq(pdev->irq, atl1e_intr, flags, netdev->name, netdev); if (err) { netdev_dbg(adapter->netdev, "Unable to allocate interrupt Error: %d\n", err); + if (adapter->have_msi) + pci_disable_msi(pdev); return err; } netdev_dbg(netdev, "atl1e_request_irq OK\n"); @@ -2329,7 +2344,6 @@ static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) INIT_WORK(&adapter->reset_task, atl1e_reset_task); INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task); - netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE); err = register_netdev(netdev); if (err) { netdev_err(netdev, "register netdevice failed\n"); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 57619dd4a92b..4046f97378c2 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2614,9 +2614,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } - /* initialize FW coalescing state machines in RAM */ - bnx2x_update_coalesce(bp); - /* setup the leading queue */ rc = bnx2x_setup_leading(bp); if (rc) { @@ -4583,11 +4580,11 @@ static void storm_memset_hc_disable(struct bnx2x *bp, u8 port, u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(fw_sb_id, sb_index); - u8 flags = REG_RD8(bp, addr); + u16 flags = REG_RD16(bp, addr); /* clear and set */ flags &= ~HC_INDEX_DATA_HC_ENABLED; flags |= enable_flag; - REG_WR8(bp, addr, flags); + REG_WR16(bp, addr, flags); DP(NETIF_MSG_IFUP, "port %x fw_sb_id %d sb_index %d disable %d\n", port, fw_sb_id, sb_index, disable); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 0283f343b0d1..77ebae0ac64a 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -13437,7 +13437,13 @@ static void bnx2x_check_kr2_wa(struct link_params *params, { struct bnx2x *bp = params->bp; u16 base_page, next_page, not_kr2_device, lane; - int sigdet; + int sigdet = bnx2x_warpcore_get_sigdet(phy, params); + + if (!sigdet) { + if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) + bnx2x_kr2_recovery(params, vars, phy); + return; + } /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery * since some switches tend to reinit the AN process and clear the @@ -13448,16 +13454,6 @@ static void bnx2x_check_kr2_wa(struct link_params *params, vars->check_kr2_recovery_cnt--; return; } - - sigdet = bnx2x_warpcore_get_sigdet(phy, params); - if (!sigdet) { - if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { - bnx2x_kr2_recovery(params, vars, phy); - DP(NETIF_MSG_LINK, "No sigdet\n"); - } - return; - } - lane = bnx2x_get_warpcore_lane(phy, params); CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, MDIO_AER_BLOCK_AER_REG, lane); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c50696b396f1..e81a747ea8ce 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -4947,7 +4947,7 @@ static void bnx2x_after_function_update(struct bnx2x *bp) q); } - if (!NO_FCOE(bp) && CNIC_ENABLED(bp)) { + if (!NO_FCOE(bp)) { fp = &bp->fp[FCOE_IDX(bp)]; queue_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; @@ -9878,10 +9878,6 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp) REG_RD(bp, NIG_REG_NIG_INT_STS_CLR_0); } } - if (!CHIP_IS_E1x(bp)) - /* block FW from writing to host */ - REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0); - /* wait until BRB is empty */ tmp_reg = REG_RD(bp, BRB1_REG_NUM_OF_FULL_BLOCKS); while (timer_count) { @@ -13358,7 +13354,6 @@ static int bnx2x_unregister_cnic(struct net_device *dev) RCU_INIT_POINTER(bp->cnic_ops, NULL); mutex_unlock(&bp->cnic_mutex); synchronize_rcu(); - bp->cnic_enabled = false; kfree(bp->cnic_kwq); bp->cnic_kwq = NULL; diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index 17a972734ba7..67d2663b3974 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -14604,11 +14604,8 @@ static void tg3_read_vpd(struct tg3 *tp) if (j + len > block_end) goto partno; - if (len >= sizeof(tp->fw_ver)) - len = sizeof(tp->fw_ver) - 1; - memset(tp->fw_ver, 0, sizeof(tp->fw_ver)); - snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len, - &vpd_data[j]); + memcpy(tp->fw_ver, &vpd_data[j], len); + strncat(tp->fw_ver, " bc ", vpdlen - len - 1); } partno: diff --git a/trunk/drivers/net/ethernet/calxeda/xgmac.c b/trunk/drivers/net/ethernet/calxeda/xgmac.c index b0ebc9f6d55e..a170065b5973 100644 --- a/trunk/drivers/net/ethernet/calxeda/xgmac.c +++ b/trunk/drivers/net/ethernet/calxeda/xgmac.c @@ -163,7 +163,6 @@ #define XGMAC_FLOW_CTRL_FCB_BPA 0x00000001 /* Flow Control Busy ... */ /* XGMAC_INT_STAT reg */ -#define XGMAC_INT_STAT_PMTIM 0x00800000 /* PMT Interrupt Mask */ #define XGMAC_INT_STAT_PMT 0x0080 /* PMT Interrupt Status */ #define XGMAC_INT_STAT_LPI 0x0040 /* LPI Interrupt Status */ @@ -961,9 +960,6 @@ static int xgmac_hw_init(struct net_device *dev) writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA); - /* Mask power mgt interrupt */ - writel(XGMAC_INT_STAT_PMTIM, ioaddr + XGMAC_INT_STAT); - /* XGMAC requires AXI bus init. This is a 'magic number' for now */ writel(0x0077000E, ioaddr + XGMAC_DMA_AXI_BUS); @@ -1145,9 +1141,6 @@ static int xgmac_rx(struct xgmac_priv *priv, int limit) struct sk_buff *skb; int frame_len; - if (!dma_ring_cnt(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ)) - break; - entry = priv->rx_tail; p = priv->dma_rx + entry; if (desc_get_owner(p)) @@ -1832,7 +1825,7 @@ static void xgmac_pmt(void __iomem *ioaddr, unsigned long mode) unsigned int pmt = 0; if (mode & WAKE_MAGIC) - pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT_EN; + pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT; if (mode & WAKE_UCAST) pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_GLBL_UNICAST; diff --git a/trunk/drivers/net/ethernet/davicom/dm9000.c b/trunk/drivers/net/ethernet/davicom/dm9000.c index 9eada8e86078..8cdf02503d13 100644 --- a/trunk/drivers/net/ethernet/davicom/dm9000.c +++ b/trunk/drivers/net/ethernet/davicom/dm9000.c @@ -257,107 +257,6 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count) tmp = readl(reg); } -/* - * Sleep, either by using msleep() or if we are suspending, then - * use mdelay() to sleep. - */ -static void dm9000_msleep(board_info_t *db, unsigned int ms) -{ - if (db->in_suspend) - mdelay(ms); - else - msleep(ms); -} - -/* Read a word from phyxcer */ -static int -dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) -{ - board_info_t *db = netdev_priv(dev); - unsigned long flags; - unsigned int reg_save; - int ret; - - mutex_lock(&db->addr_lock); - - spin_lock_irqsave(&db->lock, flags); - - /* Save previous register address */ - reg_save = readb(db->io_addr); - - /* Fill the phyxcer register into REG_0C */ - iow(db, DM9000_EPAR, DM9000_PHY | reg); - - /* Issue phyxcer read command */ - iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); - - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - - dm9000_msleep(db, 1); /* Wait read complete */ - - spin_lock_irqsave(&db->lock, flags); - reg_save = readb(db->io_addr); - - iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ - - /* The read data keeps on REG_0D & REG_0E */ - ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); - - /* restore the previous address */ - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - - mutex_unlock(&db->addr_lock); - - dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); - return ret; -} - -/* Write a word to phyxcer */ -static void -dm9000_phy_write(struct net_device *dev, - int phyaddr_unused, int reg, int value) -{ - board_info_t *db = netdev_priv(dev); - unsigned long flags; - unsigned long reg_save; - - dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); - mutex_lock(&db->addr_lock); - - spin_lock_irqsave(&db->lock, flags); - - /* Save previous register address */ - reg_save = readb(db->io_addr); - - /* Fill the phyxcer register into REG_0C */ - iow(db, DM9000_EPAR, DM9000_PHY | reg); - - /* Fill the written data into REG_0D & REG_0E */ - iow(db, DM9000_EPDRL, value); - iow(db, DM9000_EPDRH, value >> 8); - - /* Issue phyxcer write command */ - iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); - - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - - dm9000_msleep(db, 1); /* Wait write complete */ - - spin_lock_irqsave(&db->lock, flags); - reg_save = readb(db->io_addr); - - iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ - - /* restore the previous address */ - writeb(reg_save, db->io_addr); - - spin_unlock_irqrestore(&db->lock, flags); - mutex_unlock(&db->addr_lock); -} - /* dm9000_set_io * * select the specified set of io routines to use with the @@ -896,9 +795,6 @@ dm9000_init_dm9000(struct net_device *dev) iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ - dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */ - dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */ - ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0; /* if wol is needed, then always set NCR_WAKEEN otherwise we end @@ -1305,6 +1201,109 @@ dm9000_open(struct net_device *dev) return 0; } +/* + * Sleep, either by using msleep() or if we are suspending, then + * use mdelay() to sleep. + */ +static void dm9000_msleep(board_info_t *db, unsigned int ms) +{ + if (db->in_suspend) + mdelay(ms); + else + msleep(ms); +} + +/* + * Read a word from phyxcer + */ +static int +dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) +{ + board_info_t *db = netdev_priv(dev); + unsigned long flags; + unsigned int reg_save; + int ret; + + mutex_lock(&db->addr_lock); + + spin_lock_irqsave(&db->lock,flags); + + /* Save previous register address */ + reg_save = readb(db->io_addr); + + /* Fill the phyxcer register into REG_0C */ + iow(db, DM9000_EPAR, DM9000_PHY | reg); + + iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); /* Issue phyxcer read command */ + + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock,flags); + + dm9000_msleep(db, 1); /* Wait read complete */ + + spin_lock_irqsave(&db->lock,flags); + reg_save = readb(db->io_addr); + + iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ + + /* The read data keeps on REG_0D & REG_0E */ + ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); + + /* restore the previous address */ + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock,flags); + + mutex_unlock(&db->addr_lock); + + dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); + return ret; +} + +/* + * Write a word to phyxcer + */ +static void +dm9000_phy_write(struct net_device *dev, + int phyaddr_unused, int reg, int value) +{ + board_info_t *db = netdev_priv(dev); + unsigned long flags; + unsigned long reg_save; + + dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); + mutex_lock(&db->addr_lock); + + spin_lock_irqsave(&db->lock,flags); + + /* Save previous register address */ + reg_save = readb(db->io_addr); + + /* Fill the phyxcer register into REG_0C */ + iow(db, DM9000_EPAR, DM9000_PHY | reg); + + /* Fill the written data into REG_0D & REG_0E */ + iow(db, DM9000_EPDRL, value); + iow(db, DM9000_EPDRH, value >> 8); + + iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); /* Issue phyxcer write command */ + + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock, flags); + + dm9000_msleep(db, 1); /* Wait write complete */ + + spin_lock_irqsave(&db->lock,flags); + reg_save = readb(db->io_addr); + + iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ + + /* restore the previous address */ + writeb(reg_save, db->io_addr); + + spin_unlock_irqrestore(&db->lock, flags); + mutex_unlock(&db->addr_lock); +} + static void dm9000_shutdown(struct net_device *dev) { @@ -1503,12 +1502,7 @@ dm9000_probe(struct platform_device *pdev) db->flags |= DM9000_PLATF_SIMPLE_PHY; #endif - /* Fixing bug on dm9000_probe, takeover dm9000_reset(db), - * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo - * while probe stage. - */ - - iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST); + dm9000_reset(db); /* try multiple times, DM9000 sometimes gets the read wrong */ for (i = 0; i < 8; i++) { diff --git a/trunk/drivers/net/ethernet/davicom/dm9000.h b/trunk/drivers/net/ethernet/davicom/dm9000.h index 9ce058adabab..55688bd1a3ef 100644 --- a/trunk/drivers/net/ethernet/davicom/dm9000.h +++ b/trunk/drivers/net/ethernet/davicom/dm9000.h @@ -69,9 +69,7 @@ #define NCR_WAKEEN (1<<6) #define NCR_FCOL (1<<4) #define NCR_FDX (1<<3) - -#define NCR_RESERVED (3<<1) -#define NCR_MAC_LBK (1<<1) +#define NCR_LBK (3<<1) #define NCR_RST (1<<0) #define NSR_SPEED (1<<7) @@ -169,12 +167,5 @@ #define ISR_LNKCHNG (1<<5) #define ISR_UNDERRUN (1<<4) -/* Davicom MII registers. - */ - -#define MII_DM_DSPCR 0x1b /* DSP Control Register */ - -#define DSPCR_INIT_PARAM 0xE100 /* DSP init parameter */ - #endif /* _DM9000X_H_ */ diff --git a/trunk/drivers/net/ethernet/emulex/benet/be_main.c b/trunk/drivers/net/ethernet/emulex/benet/be_main.c index 2886c9b63f90..08e54f3d288b 100644 --- a/trunk/drivers/net/ethernet/emulex/benet/be_main.c +++ b/trunk/drivers/net/ethernet/emulex/benet/be_main.c @@ -759,9 +759,8 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, if (vlan_tx_tag_present(skb)) { vlan_tag = be_get_tx_vlan_tag(adapter, skb); - skb = __vlan_put_tag(skb, vlan_tag); - if (skb) - skb->vlan_tci = 0; + __vlan_put_tag(skb, vlan_tag); + skb->vlan_tci = 0; } return skb; diff --git a/trunk/drivers/net/ethernet/freescale/fec.c b/trunk/drivers/net/ethernet/freescale/fec.c index 73195f643c9c..911d0253dbb2 100644 --- a/trunk/drivers/net/ethernet/freescale/fec.c +++ b/trunk/drivers/net/ethernet/freescale/fec.c @@ -345,53 +345,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } -/* Init RX & TX buffer descriptors - */ -static void fec_enet_bd_init(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - struct bufdesc *bdp; - unsigned int i; - - /* Initialize the receive buffer descriptors. */ - bdp = fep->rx_bd_base; - for (i = 0; i < RX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - if (bdp->cbd_bufaddr) - bdp->cbd_sc = BD_ENET_RX_EMPTY; - else - bdp->cbd_sc = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } - - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - - fep->cur_rx = fep->rx_bd_base; - - /* ...and the same for transmit */ - bdp = fep->tx_bd_base; - fep->cur_tx = bdp; - for (i = 0; i < TX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) { - dev_kfree_skb_any(fep->tx_skbuff[i]); - fep->tx_skbuff[i] = NULL; - } - bdp->cbd_bufaddr = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } - - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - fep->dirty_tx = bdp; -} - /* This function is called to start or restart the FEC during a link * change. This only happens when switching between half and full * duplex. @@ -435,8 +388,6 @@ fec_restart(struct net_device *ndev, int duplex) /* Set maximum receive buffer size. */ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); - fec_enet_bd_init(ndev); - /* Set receive and transmit descriptor base. */ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); if (fep->bufdesc_ex) @@ -446,6 +397,7 @@ fec_restart(struct net_device *ndev, int duplex) writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); + fep->cur_rx = fep->rx_bd_base; for (i = 0; i <= TX_RING_MOD_MASK; i++) { if (fep->tx_skbuff[i]) { @@ -1002,7 +954,6 @@ static void fec_enet_adjust_link(struct net_device *ndev) } else { if (fep->link) { fec_stop(ndev); - fep->link = phy_dev->link; status_change = 1; } } @@ -1646,6 +1597,8 @@ static int fec_enet_init(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); struct bufdesc *cbd_base; + struct bufdesc *bdp; + unsigned int i; /* Allocate memory for buffer descriptors. */ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, @@ -1655,7 +1608,6 @@ static int fec_enet_init(struct net_device *ndev) return -ENOMEM; } - memset(cbd_base, 0, PAGE_SIZE); spin_lock_init(&fep->hw_lock); fep->netdev = ndev; @@ -1679,6 +1631,35 @@ static int fec_enet_init(struct net_device *ndev) writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK); netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT); + /* Initialize the receive buffer descriptors. */ + bdp = fep->rx_bd_base; + for (i = 0; i < RX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + + /* ...and the same for transmit */ + bdp = fep->tx_bd_base; + fep->cur_tx = bdp; + for (i = 0; i < TX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + bdp->cbd_bufaddr = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + fep->dirty_tx = bdp; + fec_restart(ndev, 0); return 0; diff --git a/trunk/drivers/net/ethernet/intel/e100.c b/trunk/drivers/net/ethernet/intel/e100.c index d2bea3f07c73..ec800b093e7e 100644 --- a/trunk/drivers/net/ethernet/intel/e100.c +++ b/trunk/drivers/net/ethernet/intel/e100.c @@ -870,7 +870,7 @@ static int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr) } static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, - int (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *)) + void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *)) { struct cb *cb; unsigned long flags; @@ -888,13 +888,10 @@ static int e100_exec_cb(struct nic *nic, struct sk_buff *skb, nic->cbs_avail--; cb->skb = skb; - err = cb_prepare(nic, cb, skb); - if (err) - goto err_unlock; - if (unlikely(!nic->cbs_avail)) err = -ENOSPC; + cb_prepare(nic, cb, skb); /* Order is important otherwise we'll be in a race with h/w: * set S-bit in current first, then clear S-bit in previous. */ @@ -1094,7 +1091,7 @@ static void e100_get_defaults(struct nic *nic) nic->mii.mdio_write = mdio_write; } -static int e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) +static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) { struct config *config = &cb->u.config; u8 *c = (u8 *)config; @@ -1184,7 +1181,6 @@ static int e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) netif_printk(nic, hw, KERN_DEBUG, nic->netdev, "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); - return 0; } /************************************************************************* @@ -1335,7 +1331,7 @@ static const struct firmware *e100_request_firmware(struct nic *nic) return fw; } -static int e100_setup_ucode(struct nic *nic, struct cb *cb, +static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) { const struct firmware *fw = (void *)skb; @@ -1362,7 +1358,6 @@ static int e100_setup_ucode(struct nic *nic, struct cb *cb, cb->u.ucode[min_size] |= cpu_to_le32((BUNDLESMALL) ? 0xFFFF : 0xFF80); cb->command = cpu_to_le16(cb_ucode | cb_el); - return 0; } static inline int e100_load_ucode_wait(struct nic *nic) @@ -1405,20 +1400,18 @@ static inline int e100_load_ucode_wait(struct nic *nic) return err; } -static int e100_setup_iaaddr(struct nic *nic, struct cb *cb, +static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, struct sk_buff *skb) { cb->command = cpu_to_le16(cb_iaaddr); memcpy(cb->u.iaaddr, nic->netdev->dev_addr, ETH_ALEN); - return 0; } -static int e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb) +static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb) { cb->command = cpu_to_le16(cb_dump); cb->u.dump_buffer_addr = cpu_to_le32(nic->dma_addr + offsetof(struct mem, dump_buf)); - return 0; } static int e100_phy_check_without_mii(struct nic *nic) @@ -1588,7 +1581,7 @@ static int e100_hw_init(struct nic *nic) return 0; } -static int e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) +static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) { struct net_device *netdev = nic->netdev; struct netdev_hw_addr *ha; @@ -1603,7 +1596,6 @@ static int e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb) memcpy(&cb->u.multi.addr[i++ * ETH_ALEN], &ha->addr, ETH_ALEN); } - return 0; } static void e100_set_multicast_list(struct net_device *netdev) @@ -1764,18 +1756,11 @@ static void e100_watchdog(unsigned long data) round_jiffies(jiffies + E100_WATCHDOG_PERIOD)); } -static int e100_xmit_prepare(struct nic *nic, struct cb *cb, +static void e100_xmit_prepare(struct nic *nic, struct cb *cb, struct sk_buff *skb) { - dma_addr_t dma_addr; cb->command = nic->tx_command; - dma_addr = pci_map_single(nic->pdev, - skb->data, skb->len, PCI_DMA_TODEVICE); - /* If we can't map the skb, have the upper layer try later */ - if (pci_dma_mapping_error(nic->pdev, dma_addr)) - return -ENOMEM; - /* * Use the last 4 bytes of the SKB payload packet as the CRC, used for * testing, ie sending frames with bad CRC. @@ -1792,10 +1777,11 @@ static int e100_xmit_prepare(struct nic *nic, struct cb *cb, cb->u.tcb.tcb_byte_count = 0; cb->u.tcb.threshold = nic->tx_threshold; cb->u.tcb.tbd_count = 1; - cb->u.tcb.tbd.buf_addr = cpu_to_le32(dma_addr); + cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev, + skb->data, skb->len, PCI_DMA_TODEVICE)); + /* check for mapping failure? */ cb->u.tcb.tbd.size = cpu_to_le16(skb->len); skb_tx_timestamp(skb); - return 0; } static netdev_tx_t e100_xmit_frame(struct sk_buff *skb, diff --git a/trunk/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/trunk/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index ffd287196bf8..43462d596a4e 100644 --- a/trunk/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -1053,10 +1053,6 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) txdr->buffer_info[i].dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(&pdev->dev, txdr->buffer_info[i].dma)) { - ret_val = 4; - goto err_nomem; - } tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma); tx_desc->lower.data = cpu_to_le32(skb->len); tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP | @@ -1073,7 +1069,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_buffer), GFP_KERNEL); if (!rxdr->buffer_info) { - ret_val = 5; + ret_val = 4; goto err_nomem; } @@ -1081,7 +1077,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma, GFP_KERNEL); if (!rxdr->desc) { - ret_val = 6; + ret_val = 5; goto err_nomem; } memset(rxdr->desc, 0, rxdr->size); @@ -1105,7 +1101,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL); if (!skb) { - ret_val = 7; + ret_val = 6; goto err_nomem; } skb_reserve(skb, NET_IP_ALIGN); @@ -1114,10 +1110,6 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->buffer_info[i].dma = dma_map_single(&pdev->dev, skb->data, E1000_RXBUFFER_2048, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, rxdr->buffer_info[i].dma)) { - ret_val = 8; - goto err_nomem; - } rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma); memset(skb->data, 0x00, skb->len); } diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 7e615e2bf7e6..948b86ffa4f0 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -848,16 +848,11 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring, } } - if (!buffer_info->dma) { + if (!buffer_info->dma) buffer_info->dma = dma_map_page(&pdev->dev, buffer_info->page, 0, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { - adapter->alloc_rx_buff_failed++; - break; - } - } rx_desc = E1000_RX_DESC_EXT(*rx_ring, i); rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma); diff --git a/trunk/drivers/net/ethernet/intel/igb/igb.h b/trunk/drivers/net/ethernet/intel/igb/igb.h index ab577a763a20..25151401c2ab 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb.h +++ b/trunk/drivers/net/ethernet/intel/igb/igb.h @@ -284,10 +284,18 @@ struct igb_q_vector { enum e1000_ring_flags_t { IGB_RING_FLAG_RX_SCTP_CSUM, IGB_RING_FLAG_RX_LB_VLAN_BSWAP, + IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, IGB_RING_FLAG_TX_CTX_IDX, IGB_RING_FLAG_TX_DETECT_HANG }; +#define ring_uses_build_skb(ring) \ + test_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags) +#define set_ring_build_skb_enabled(ring) \ + set_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags) +#define clear_ring_build_skb_enabled(ring) \ + clear_bit(IGB_RING_FLAG_RX_BUILD_SKB_ENABLED, &(ring)->flags) + #define IGB_TXD_DCMD (E1000_ADVTXD_DCMD_EOP | E1000_ADVTXD_DCMD_RS) #define IGB_RX_DESC(R, i) \ diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_main.c b/trunk/drivers/net/ethernet/intel/igb/igb_main.c index 64f75291e3a5..8496adfc6a68 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_main.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_main.c @@ -3350,6 +3350,20 @@ void igb_configure_rx_ring(struct igb_adapter *adapter, wr32(E1000_RXDCTL(reg_idx), rxdctl); } +static void igb_set_rx_buffer_len(struct igb_adapter *adapter, + struct igb_ring *rx_ring) +{ +#define IGB_MAX_BUILD_SKB_SIZE \ + (SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) - \ + (NET_SKB_PAD + NET_IP_ALIGN + IGB_TS_HDR_LEN)) + + /* set build_skb flag */ + if (adapter->max_frame_size <= IGB_MAX_BUILD_SKB_SIZE) + set_ring_build_skb_enabled(rx_ring); + else + clear_ring_build_skb_enabled(rx_ring); +} + /** * igb_configure_rx - Configure receive Unit after Reset * @adapter: board private structure @@ -3369,8 +3383,11 @@ static void igb_configure_rx(struct igb_adapter *adapter) /* Setup the HW Rx Head and Tail Descriptor Pointers and * the Base and Length of the Rx Descriptor Ring */ - for (i = 0; i < adapter->num_rx_queues; i++) - igb_configure_rx_ring(adapter, adapter->rx_ring[i]); + for (i = 0; i < adapter->num_rx_queues; i++) { + struct igb_ring *rx_ring = adapter->rx_ring[i]; + igb_set_rx_buffer_len(adapter, rx_ring); + igb_configure_rx_ring(adapter, rx_ring); + } } /** @@ -6186,6 +6203,78 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring, return igb_can_reuse_rx_page(rx_buffer, page, truesize); } +static struct sk_buff *igb_build_rx_buffer(struct igb_ring *rx_ring, + union e1000_adv_rx_desc *rx_desc) +{ + struct igb_rx_buffer *rx_buffer; + struct sk_buff *skb; + struct page *page; + void *page_addr; + unsigned int size = le16_to_cpu(rx_desc->wb.upper.length); +#if (PAGE_SIZE < 8192) + unsigned int truesize = IGB_RX_BUFSZ; +#else + unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) + + SKB_DATA_ALIGN(NET_SKB_PAD + + NET_IP_ALIGN + + size); +#endif + + /* If we spanned a buffer we have a huge mess so test for it */ + BUG_ON(unlikely(!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP))); + + rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; + page = rx_buffer->page; + prefetchw(page); + + page_addr = page_address(page) + rx_buffer->page_offset; + + /* prefetch first cache line of first page */ + prefetch(page_addr + NET_SKB_PAD + NET_IP_ALIGN); +#if L1_CACHE_BYTES < 128 + prefetch(page_addr + L1_CACHE_BYTES + NET_SKB_PAD + NET_IP_ALIGN); +#endif + + /* build an skb to around the page buffer */ + skb = build_skb(page_addr, truesize); + if (unlikely(!skb)) { + rx_ring->rx_stats.alloc_failed++; + return NULL; + } + + /* we are reusing so sync this buffer for CPU use */ + dma_sync_single_range_for_cpu(rx_ring->dev, + rx_buffer->dma, + rx_buffer->page_offset, + IGB_RX_BUFSZ, + DMA_FROM_DEVICE); + + /* update pointers within the skb to store the data */ + skb_reserve(skb, NET_IP_ALIGN + NET_SKB_PAD); + __skb_put(skb, size); + + /* pull timestamp out of packet data */ + if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { + igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb); + __skb_pull(skb, IGB_TS_HDR_LEN); + } + + if (igb_can_reuse_rx_page(rx_buffer, page, truesize)) { + /* hand second half of page back to the ring */ + igb_reuse_rx_page(rx_ring, rx_buffer); + } else { + /* we are not reusing the buffer so unmap it */ + dma_unmap_page(rx_ring->dev, rx_buffer->dma, + PAGE_SIZE, DMA_FROM_DEVICE); + } + + /* clear contents of buffer_info */ + rx_buffer->dma = 0; + rx_buffer->page = NULL; + + return skb; +} + static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring, union e1000_adv_rx_desc *rx_desc, struct sk_buff *skb) @@ -6601,7 +6690,10 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) rmb(); /* retrieve a buffer from the ring */ - skb = igb_fetch_rx_buffer(rx_ring, rx_desc, skb); + if (ring_uses_build_skb(rx_ring)) + skb = igb_build_rx_buffer(rx_ring, rx_desc); + else + skb = igb_fetch_rx_buffer(rx_ring, rx_desc, skb); /* exit if we failed to retrieve a buffer */ if (!skb) @@ -6688,6 +6780,14 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring, return true; } +static inline unsigned int igb_rx_offset(struct igb_ring *rx_ring) +{ + if (ring_uses_build_skb(rx_ring)) + return NET_SKB_PAD + NET_IP_ALIGN; + else + return 0; +} + /** * igb_alloc_rx_buffers - Replace used receive buffers; packet split * @adapter: address of board private structure @@ -6714,7 +6814,9 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count) * Refresh the desc even if buffer_addrs didn't change * because each write-back erases this info. */ - rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + bi->page_offset); + rx_desc->read.pkt_addr = cpu_to_le64(bi->dma + + bi->page_offset + + igb_rx_offset(rx_ring)); rx_desc++; bi++; diff --git a/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c index b5f94abe3cff..ea4808373435 100644 --- a/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -2159,10 +2159,6 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count) skb->data, adapter->rx_buffer_len, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { - adapter->alloc_rx_buff_failed++; - break; - } rx_desc = IXGB_RX_DESC(*rx_ring, i); rx_desc->buff_addr = cpu_to_le64(buffer_info->dma); @@ -2172,8 +2168,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count) rx_desc->status = 0; - if (++i == rx_ring->count) - i = 0; + if (++i == rx_ring->count) i = 0; buffer_info = &rx_ring->buffer_info[i]; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 79f4a26ea6cc..db5611ae407e 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7922,19 +7922,12 @@ static int __init ixgbe_init_module(void) ixgbe_dbg_init(); #endif /* CONFIG_DEBUG_FS */ - ret = pci_register_driver(&ixgbe_driver); - if (ret) { -#ifdef CONFIG_DEBUG_FS - ixgbe_dbg_exit(); -#endif /* CONFIG_DEBUG_FS */ - return ret; - } - #ifdef CONFIG_IXGBE_DCA dca_register_notify(&dca_notifier); #endif - return 0; + ret = pci_register_driver(&ixgbe_driver); + return ret; } module_init(ixgbe_init_module); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 97e33669c0b9..d44b4d21268c 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -1049,12 +1049,6 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) return -EINVAL; if (vlan || qos) { - if (adapter->vfinfo[vf].pf_vlan) - err = ixgbe_set_vf_vlan(adapter, false, - adapter->vfinfo[vf].pf_vlan, - vf); - if (err) - goto out; err = ixgbe_set_vf_vlan(adapter, true, vlan, vf); if (err) goto out; diff --git a/trunk/drivers/net/ethernet/marvell/Kconfig b/trunk/drivers/net/ethernet/marvell/Kconfig index 434e33c527df..edfba9370922 100644 --- a/trunk/drivers/net/ethernet/marvell/Kconfig +++ b/trunk/drivers/net/ethernet/marvell/Kconfig @@ -33,7 +33,6 @@ config MV643XX_ETH config MVMDIO tristate "Marvell MDIO interface support" - select PHYLIB ---help--- This driver supports the MDIO interface found in the network interface units of the Marvell EBU SoCs (Kirkwood, Orion5x, @@ -46,6 +45,7 @@ config MVMDIO config MVNETA tristate "Marvell Armada 370/XP network interface support" depends on MACH_ARMADA_370_XP + select PHYLIB select MVMDIO ---help--- This driver supports the network interface units in the diff --git a/trunk/drivers/net/ethernet/marvell/mvneta.c b/trunk/drivers/net/ethernet/marvell/mvneta.c index a47a097c21e1..cd345b8969bc 100644 --- a/trunk/drivers/net/ethernet/marvell/mvneta.c +++ b/trunk/drivers/net/ethernet/marvell/mvneta.c @@ -374,6 +374,7 @@ static int rxq_number = 8; static int txq_number = 8; static int rxq_def; +static int txq_def; #define MVNETA_DRIVER_NAME "mvneta" #define MVNETA_DRIVER_VERSION "1.0" @@ -1474,8 +1475,7 @@ static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb, static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) { struct mvneta_port *pp = netdev_priv(dev); - u16 txq_id = skb_get_queue_mapping(skb); - struct mvneta_tx_queue *txq = &pp->txqs[txq_id]; + struct mvneta_tx_queue *txq = &pp->txqs[txq_def]; struct mvneta_tx_desc *tx_desc; struct netdev_queue *nq; int frags = 0; @@ -1485,7 +1485,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) goto out; frags = skb_shinfo(skb)->nr_frags + 1; - nq = netdev_get_tx_queue(dev, txq_id); + nq = netdev_get_tx_queue(dev, txq_def); /* Get a descriptor for the first part of the packet */ tx_desc = mvneta_txq_next_desc_get(txq); @@ -2689,7 +2689,7 @@ static int mvneta_probe(struct platform_device *pdev) return -EINVAL; } - dev = alloc_etherdev_mqs(sizeof(struct mvneta_port), txq_number, rxq_number); + dev = alloc_etherdev_mq(sizeof(struct mvneta_port), 8); if (!dev) return -ENOMEM; @@ -2771,17 +2771,16 @@ static int mvneta_probe(struct platform_device *pdev) netif_napi_add(dev, &pp->napi, mvneta_poll, pp->weight); - dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; - dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM; - dev->vlan_features |= NETIF_F_SG | NETIF_F_IP_CSUM; - dev->priv_flags |= IFF_UNICAST_FLT; - err = register_netdev(dev); if (err < 0) { dev_err(&pdev->dev, "failed to register\n"); goto err_deinit; } + dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM; + dev->priv_flags |= IFF_UNICAST_FLT; + netdev_info(dev, "mac: %pM\n", dev->dev_addr); platform_set_drvdata(pdev, pp->dev); @@ -2844,3 +2843,4 @@ module_param(rxq_number, int, S_IRUGO); module_param(txq_number, int, S_IRUGO); module_param(rxq_def, int, S_IRUGO); +module_param(txq_def, int, S_IRUGO); diff --git a/trunk/drivers/net/ethernet/marvell/sky2.c b/trunk/drivers/net/ethernet/marvell/sky2.c index 6a0e671fcecd..fc07ca35721b 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.c +++ b/trunk/drivers/net/ethernet/marvell/sky2.c @@ -1067,7 +1067,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space) sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp); sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2); - tp = space - 8192/8; + tp = space - 2048/8; sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp); sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4); } else { diff --git a/trunk/drivers/net/ethernet/marvell/sky2.h b/trunk/drivers/net/ethernet/marvell/sky2.h index ec6dcd80152b..615ac63ea860 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.h +++ b/trunk/drivers/net/ethernet/marvell/sky2.h @@ -2074,7 +2074,7 @@ enum { GM_IS_RX_FF_OR = 1<<1, /* Receive FIFO Overrun */ GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */ -#define GMAC_DEF_MSK (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR) +#define GMAC_DEF_MSK GM_IS_TX_FF_UR }; /* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 30d78f806dc3..f278b10ef714 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -411,8 +411,8 @@ static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) static void mlx4_en_u64_to_mac(unsigned char dst_mac[ETH_ALEN + 2], u64 src_mac) { - int i; - for (i = ETH_ALEN - 1; i >= 0; --i) { + unsigned int i; + for (i = ETH_ALEN - 1; i; --i) { dst_mac[i] = src_mac & 0xff; src_mac >>= 8; } diff --git a/trunk/drivers/net/ethernet/micrel/ks8851.c b/trunk/drivers/net/ethernet/micrel/ks8851.c index 8fb481252e2c..33bcb63d56a2 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851.c @@ -528,7 +528,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) for (; rxfc != 0; rxfc--) { rxh = ks8851_rdreg32(ks, KS_RXFHSR); rxstat = rxh & 0xffff; - rxlen = (rxh >> 16) & 0xfff; + rxlen = rxh >> 16; netif_dbg(ks, rx_status, ks->netdev, "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen); diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index edd63f1230f3..cd5ae8813cb3 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -1500,12 +1500,6 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode) } } while ((adapter->ahw->linkup && ahw->has_link_events) != 1); - /* Make sure carrier is off and queue is stopped during loopback */ - if (netif_running(netdev)) { - netif_carrier_off(netdev); - netif_stop_queue(netdev); - } - ret = qlcnic_do_lb_test(adapter, mode); qlcnic_83xx_clear_lb_mode(adapter, mode); @@ -2786,7 +2780,6 @@ static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter, void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data) { struct qlcnic_cmd_args cmd; - struct net_device *netdev = adapter->netdev; int ret = 0; qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS); @@ -2796,7 +2789,7 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data) data = qlcnic_83xx_fill_stats(adapter, &cmd, data, QLC_83XX_STAT_TX, &ret); if (ret) { - netdev_err(netdev, "Error getting Tx stats\n"); + dev_info(&adapter->pdev->dev, "Error getting MAC stats\n"); goto out; } /* Get MAC stats */ @@ -2806,7 +2799,8 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data) data = qlcnic_83xx_fill_stats(adapter, &cmd, data, QLC_83XX_STAT_MAC, &ret); if (ret) { - netdev_err(netdev, "Error getting MAC stats\n"); + dev_info(&adapter->pdev->dev, + "Error getting Rx stats\n"); goto out; } /* Get Rx stats */ @@ -2816,7 +2810,8 @@ void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data) data = qlcnic_83xx_fill_stats(adapter, &cmd, data, QLC_83XX_STAT_RX, &ret); if (ret) - netdev_err(netdev, "Error getting Rx stats\n"); + dev_info(&adapter->pdev->dev, + "Error getting Tx stats\n"); out: qlcnic_free_mbx_args(&cmd); } diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 5fa847fe388a..0e630061bff3 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -358,7 +358,8 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter, memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN); } opcode = TX_ETHER_PKT; - if (skb_is_gso(skb)) { + if ((adapter->netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && + skb_shinfo(skb)->gso_size > 0) { hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); first_desc->total_hdr_length = hdr_len; diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 5ef328af61d0..987fb6f8adc3 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -200,10 +200,10 @@ static ssize_t qlcnic_store_beacon(struct device *dev, } err = qlcnic_config_led(adapter, b_state, b_rate); - if (!err) { + if (!err) err = len; + else ahw->beacon_state = b_state; - } if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) qlcnic_diag_free_res(adapter->netdev, max_sds_rings); diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge.h b/trunk/drivers/net/ethernet/qlogic/qlge/qlge.h index 7e8d68263963..a131d7b5d2fe 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge.h +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge.h @@ -18,7 +18,7 @@ */ #define DRV_NAME "qlge" #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION "v1.00.00.32" +#define DRV_VERSION "v1.00.00.31" #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c index 0780e039b271..6f316ab23257 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c @@ -379,13 +379,13 @@ static int ql_get_settings(struct net_device *ndev, ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->advertising = ADVERTISED_10000baseT_Full; + ecmd->autoneg = AUTONEG_ENABLE; ecmd->transceiver = XCVR_EXTERNAL; if ((qdev->link_status & STS_LINK_TYPE_MASK) == STS_LINK_TYPE_10GBASET) { ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); ecmd->port = PORT_TP; - ecmd->autoneg = AUTONEG_ENABLE; } else { ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 8033555e53c2..b13ab544a7eb 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1434,13 +1434,11 @@ static int ql_map_send(struct ql_adapter *qdev, } /* Categorizing receive firmware frame errors */ -static void ql_categorize_rx_err(struct ql_adapter *qdev, u8 rx_err, - struct rx_ring *rx_ring) +static void ql_categorize_rx_err(struct ql_adapter *qdev, u8 rx_err) { struct nic_stats *stats = &qdev->nic_stats; stats->rx_err_count++; - rx_ring->rx_errors++; switch (rx_err & IB_MAC_IOCB_RSP_ERR_MASK) { case IB_MAC_IOCB_RSP_ERR_CODE_ERR: @@ -1476,12 +1474,6 @@ static void ql_process_mac_rx_gro_page(struct ql_adapter *qdev, struct bq_desc *lbq_desc = ql_get_curr_lchunk(qdev, rx_ring); struct napi_struct *napi = &rx_ring->napi; - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - put_page(lbq_desc->p.pg_chunk.page); - return; - } napi->dev = qdev->ndev; skb = napi_get_frags(napi); @@ -1537,12 +1529,6 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, addr = lbq_desc->p.pg_chunk.va; prefetch(addr); - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - goto err_out; - } - /* The max framesize filter on this chip is set higher than * MTU since FCoE uses 2k frames. */ @@ -1628,13 +1614,6 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, memcpy(skb_put(new_skb, length), skb->data, length); skb = new_skb; - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - dev_kfree_skb_any(skb); - return; - } - /* loopback self test for ethtool */ if (test_bit(QL_SELFTEST, &qdev->flags)) { ql_check_lb_frame(qdev, skb); @@ -1940,13 +1919,6 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, return; } - /* Frame error, so drop the packet. */ - if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { - ql_categorize_rx_err(qdev, ib_mac_rsp->flags2, rx_ring); - dev_kfree_skb_any(skb); - return; - } - /* The max framesize filter on this chip is set higher than * MTU since FCoE uses 2k frames. */ @@ -2028,6 +2000,12 @@ static unsigned long ql_process_mac_rx_intr(struct ql_adapter *qdev, QL_DUMP_IB_MAC_RSP(ib_mac_rsp); + /* Frame error, so drop the packet. */ + if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) { + ql_categorize_rx_err(qdev, ib_mac_rsp->flags2); + return (unsigned long)length; + } + if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) { /* The data and headers are split into * separate buffers. diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index 4ecbe64a758d..28fb50a1e9c3 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -3818,30 +3818,6 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) } } -static void rtl_speed_down(struct rtl8169_private *tp) -{ - u32 adv; - int lpa; - - rtl_writephy(tp, 0x1f, 0x0000); - lpa = rtl_readphy(tp, MII_LPA); - - if (lpa & (LPA_10HALF | LPA_10FULL)) - adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; - else if (lpa & (LPA_100HALF | LPA_100FULL)) - adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; - else - adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | - (tp->mii.supports_gmii ? - ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full : 0); - - rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL, - adv); -} - static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3872,7 +3848,9 @@ static bool rtl_wol_pll_power_down(struct rtl8169_private *tp) if (!(__rtl8169_get_wol(tp) & WAKE_ANY)) return false; - rtl_speed_down(tp); + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, MII_BMCR, 0x0000); + rtl_wol_suspend_quirk(tp); return true; diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.c b/trunk/drivers/net/ethernet/renesas/sh_eth.c index 6ed333fe5c04..bf5e3cf97c4d 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.c +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.c @@ -1216,7 +1216,10 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (felic_stat & ECSR_LCHNG) { /* Link Changed */ if (mdp->cd->no_psr || mdp->no_ether_link) { - goto ignore_link; + if (mdp->link == PHY_DOWN) + link_stat = 0; + else + link_stat = PHY_ST_LINK; } else { link_stat = (sh_eth_read(ndev, PSR)); if (mdp->ether_link_active_low) @@ -1239,7 +1242,6 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) } } -ignore_link: if (intr_status & EESR_TWB) { /* Write buck end. unused write back interrupt */ if (intr_status & EESR_TABT) /* Transmit Abort int */ @@ -1324,18 +1326,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_cpu_data *cd = mdp->cd; irqreturn_t ret = IRQ_NONE; - unsigned long intr_status; + u32 intr_status = 0; spin_lock(&mdp->lock); - /* Get interrupt status */ + /* Get interrpt stat */ intr_status = sh_eth_read(ndev, EESR); - /* Mask it with the interrupt mask, forcing ECI interrupt to be always - * enabled since it's the one that comes thru regardless of the mask, - * and we need to fully handle it in sh_eth_error() in order to quench - * it as it doesn't get cleared by just writing 1 to the ECI bit... - */ - intr_status &= sh_eth_read(ndev, EESIPR) | DMAC_M_ECI; /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | @@ -1377,7 +1373,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) struct phy_device *phydev = mdp->phydev; int new_state = 0; - if (phydev->link) { + if (phydev->link != PHY_DOWN) { if (phydev->duplex != mdp->duplex) { new_state = 1; mdp->duplex = phydev->duplex; @@ -1391,21 +1387,17 @@ static void sh_eth_adjust_link(struct net_device *ndev) if (mdp->cd->set_rate) mdp->cd->set_rate(ndev); } - if (!mdp->link) { + if (mdp->link == PHY_DOWN) { sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR); new_state = 1; mdp->link = phydev->link; - if (mdp->cd->no_psr || mdp->no_ether_link) - sh_eth_rcv_snd_enable(ndev); } } else if (mdp->link) { new_state = 1; - mdp->link = 0; + mdp->link = PHY_DOWN; mdp->speed = 0; mdp->duplex = -1; - if (mdp->cd->no_psr || mdp->no_ether_link) - sh_eth_rcv_snd_disable(ndev); } if (new_state && netif_msg_link(mdp)) @@ -1422,7 +1414,7 @@ static int sh_eth_phy_init(struct net_device *ndev) snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, mdp->mii_bus->id , mdp->phy_id); - mdp->link = 0; + mdp->link = PHY_DOWN; mdp->speed = 0; mdp->duplex = -1; diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.h b/trunk/drivers/net/ethernet/renesas/sh_eth.h index 828be4515008..e6655678458e 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.h +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.h @@ -723,7 +723,7 @@ struct sh_eth_private { u32 phy_id; /* PHY ID */ struct mii_bus *mii_bus; /* MDIO bus control */ struct phy_device *phydev; /* PHY device control */ - int link; + enum phy_state link; phy_interface_t phy_interface; int msg_enable; int speed; diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index 50617c5a0bdb..0c74a702d461 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/mmc_core.c @@ -149,7 +149,6 @@ void dwmac_mmc_intr_all_mask(void __iomem *ioaddr) { writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_INTR_MASK); writel(MMC_DEFAULT_MASK, ioaddr + MMC_TX_INTR_MASK); - writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_IPC_INTR_MASK); } /* This reads the MAC core counters (if actaully supported). diff --git a/trunk/drivers/net/ethernet/ti/cpsw.c b/trunk/drivers/net/ethernet/ti/cpsw.c index 4781d3d8e182..df32a090d08e 100644 --- a/trunk/drivers/net/ethernet/ti/cpsw.c +++ b/trunk/drivers/net/ethernet/ti/cpsw.c @@ -436,7 +436,7 @@ void cpsw_tx_handler(void *token, int len, int status) * queue is stopped then start the queue as we have free desc for tx */ if (unlikely(netif_queue_stopped(ndev))) - netif_wake_queue(ndev); + netif_start_queue(ndev); cpts_tx_timestamp(priv->cpts, skb); priv->stats.tx_packets++; priv->stats.tx_bytes += len; @@ -1380,7 +1380,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); if (data->dual_emac) { - if (of_property_read_u32(slave_node, "dual_emac_res_vlan", + if (of_property_read_u32(node, "dual_emac_res_vlan", &prop)) { pr_err("Missing dual_emac_res_vlan in DT.\n"); slave_data->dual_emac_res_vlan = i+1; diff --git a/trunk/drivers/net/ethernet/ti/davinci_emac.c b/trunk/drivers/net/ethernet/ti/davinci_emac.c index 72300bc9e378..ae1b77aa199f 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_emac.c +++ b/trunk/drivers/net/ethernet/ti/davinci_emac.c @@ -1053,7 +1053,7 @@ static void emac_tx_handler(void *token, int len, int status) * queue is stopped then start the queue as we have free desc for tx */ if (unlikely(netif_queue_stopped(ndev))) - netif_wake_queue(ndev); + netif_start_queue(ndev); ndev->stats.tx_packets++; ndev->stats.tx_bytes += len; dev_kfree_skb_any(skb); diff --git a/trunk/drivers/net/hyperv/netvsc.c b/trunk/drivers/net/hyperv/netvsc.c index f5f0f09e4cc5..1cd77483da50 100644 --- a/trunk/drivers/net/hyperv/netvsc.c +++ b/trunk/drivers/net/hyperv/netvsc.c @@ -470,10 +470,8 @@ static void netvsc_send_completion(struct hv_device *device, packet->trans_id; /* Notify the layer above us */ - if (nvsc_packet) - nvsc_packet->completion.send.send_completion( - nvsc_packet->completion.send. - send_completion_ctx); + nvsc_packet->completion.send.send_completion( + nvsc_packet->completion.send.send_completion_ctx); num_outstanding_sends = atomic_dec_return(&net_device->num_outstanding_sends); @@ -500,7 +498,6 @@ int netvsc_send(struct hv_device *device, int ret = 0; struct nvsp_message sendMessage; struct net_device *ndev; - u64 req_id; net_device = get_outbound_net_device(device); if (!net_device) @@ -521,24 +518,20 @@ int netvsc_send(struct hv_device *device, 0xFFFFFFFF; sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0; - if (packet->completion.send.send_completion) - req_id = (u64)packet; - else - req_id = 0; - if (packet->page_buf_cnt) { ret = vmbus_sendpacket_pagebuffer(device->channel, packet->page_buf, packet->page_buf_cnt, &sendMessage, sizeof(struct nvsp_message), - req_id); + (unsigned long)packet); } else { ret = vmbus_sendpacket(device->channel, &sendMessage, sizeof(struct nvsp_message), - req_id, + (unsigned long)packet, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + } if (ret == 0) { diff --git a/trunk/drivers/net/hyperv/netvsc_drv.c b/trunk/drivers/net/hyperv/netvsc_drv.c index 8341b62e5521..5f85205cd12b 100644 --- a/trunk/drivers/net/hyperv/netvsc_drv.c +++ b/trunk/drivers/net/hyperv/netvsc_drv.c @@ -241,11 +241,13 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, if (status == 1) { netif_carrier_on(net); + netif_wake_queue(net); ndev_ctx = netdev_priv(net); schedule_delayed_work(&ndev_ctx->dwork, 0); schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); } else { netif_carrier_off(net); + netif_tx_disable(net); } } diff --git a/trunk/drivers/net/hyperv/rndis_filter.c b/trunk/drivers/net/hyperv/rndis_filter.c index 0775f0aefd1e..2b657d4d63a8 100644 --- a/trunk/drivers/net/hyperv/rndis_filter.c +++ b/trunk/drivers/net/hyperv/rndis_filter.c @@ -61,6 +61,9 @@ struct rndis_request { static void rndis_filter_send_completion(void *ctx); +static void rndis_filter_send_request_completion(void *ctx); + + static struct rndis_device *get_rndis_device(void) { @@ -238,7 +241,10 @@ static int rndis_filter_send_request(struct rndis_device *dev, packet->page_buf[0].len; } - packet->completion.send.send_completion = NULL; + packet->completion.send.send_completion_ctx = req;/* packet; */ + packet->completion.send.send_completion = + rndis_filter_send_request_completion; + packet->completion.send.send_completion_tid = (unsigned long)dev; ret = netvsc_send(dev->net_dev->dev, packet); return ret; @@ -993,3 +999,9 @@ static void rndis_filter_send_completion(void *ctx) /* Pass it back to the original handler */ filter_pkt->completion(filter_pkt->completion_ctx); } + + +static void rndis_filter_send_request_completion(void *ctx) +{ + /* Noop */ +} diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 729ed533bb33..b7c457adc0dc 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -1594,7 +1594,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (tun->flags & TUN_TAP_MQ && (tun->numqueues + tun->numdisabled > 1)) - return -EBUSY; + return err; } else { char *name; diff --git a/trunk/drivers/net/usb/cdc_mbim.c b/trunk/drivers/net/usb/cdc_mbim.c index 6bd91676d2cb..16c842997291 100644 --- a/trunk/drivers/net/usb/cdc_mbim.c +++ b/trunk/drivers/net/usb/cdc_mbim.c @@ -134,7 +134,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb goto error; if (skb) { - if (skb->len <= ETH_HLEN) + if (skb->len <= sizeof(ETH_HLEN)) goto error; /* mapping VLANs to MBIM sessions: diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index 2a3579f67910..968d5d50751d 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -53,96 +52,6 @@ struct qmi_wwan_state { struct usb_interface *data; }; -/* default ethernet address used by the modem */ -static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; - -/* Make up an ethernet header if the packet doesn't have one. - * - * A firmware bug common among several devices cause them to send raw - * IP packets under some circumstances. There is no way for the - * driver/host to know when this will happen. And even when the bug - * hits, some packets will still arrive with an intact header. - * - * The supported devices are only capably of sending IPv4, IPv6 and - * ARP packets on a point-to-point link. Any packet with an ethernet - * header will have either our address or a broadcast/multicast - * address as destination. ARP packets will always have a header. - * - * This means that this function will reliably add the appropriate - * header iff necessary, provided our hardware address does not start - * with 4 or 6. - * - * Another common firmware bug results in all packets being addressed - * to 00:a0:c6:00:00:00 despite the host address being different. - * This function will also fixup such packets. - */ -static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -{ - __be16 proto; - - /* usbnet rx_complete guarantees that skb->len is at least - * hard_header_len, so we can inspect the dest address without - * checking skb->len - */ - switch (skb->data[0] & 0xf0) { - case 0x40: - proto = htons(ETH_P_IP); - break; - case 0x60: - proto = htons(ETH_P_IPV6); - break; - case 0x00: - if (is_multicast_ether_addr(skb->data)) - return 1; - /* possibly bogus destination - rewrite just in case */ - skb_reset_mac_header(skb); - goto fix_dest; - default: - /* pass along other packets without modifications */ - return 1; - } - if (skb_headroom(skb) < ETH_HLEN) - return 0; - skb_push(skb, ETH_HLEN); - skb_reset_mac_header(skb); - eth_hdr(skb)->h_proto = proto; - memset(eth_hdr(skb)->h_source, 0, ETH_ALEN); -fix_dest: - memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN); - return 1; -} - -/* very simplistic detection of IPv4 or IPv6 headers */ -static bool possibly_iphdr(const char *data) -{ - return (data[0] & 0xd0) == 0x40; -} - -/* disallow addresses which may be confused with IP headers */ -static int qmi_wwan_mac_addr(struct net_device *dev, void *p) -{ - int ret; - struct sockaddr *addr = p; - - ret = eth_prepare_mac_addr_change(dev, p); - if (ret < 0) - return ret; - if (possibly_iphdr(addr->sa_data)) - return -EADDRNOTAVAIL; - eth_commit_mac_addr_change(dev, p); - return 0; -} - -static const struct net_device_ops qmi_wwan_netdev_ops = { - .ndo_open = usbnet_open, - .ndo_stop = usbnet_stop, - .ndo_start_xmit = usbnet_start_xmit, - .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_change_mtu = usbnet_change_mtu, - .ndo_set_mac_address = qmi_wwan_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - /* using a counter to merge subdriver requests with our own into a combined state */ static int qmi_wwan_manage_power(struct usbnet *dev, int on) { @@ -320,18 +229,6 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) usb_driver_release_interface(driver, info->data); } - /* Never use the same address on both ends of the link, even - * if the buggy firmware told us to. - */ - if (!compare_ether_addr(dev->net->dev_addr, default_modem_addr)) - eth_hw_addr_random(dev->net); - - /* make MAC addr easily distinguishable from an IP header */ - if (possibly_iphdr(dev->net->dev_addr)) { - dev->net->dev_addr[0] |= 0x02; /* set local assignment bit */ - dev->net->dev_addr[0] &= 0xbf; /* clear "IP" bit */ - } - dev->net->netdev_ops = &qmi_wwan_netdev_ops; err: return status; } @@ -410,7 +307,6 @@ static const struct driver_info qmi_wwan_info = { .bind = qmi_wwan_bind, .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, - .rx_fixup = qmi_wwan_rx_fixup, }; #define HUAWEI_VENDOR_ID 0x12D1 diff --git a/trunk/drivers/net/usb/smsc75xx.c b/trunk/drivers/net/usb/smsc75xx.c index 1a15ec14c386..9abe51710f22 100644 --- a/trunk/drivers/net/usb/smsc75xx.c +++ b/trunk/drivers/net/usb/smsc75xx.c @@ -914,12 +914,8 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) { struct usbnet *dev = netdev_priv(netdev); - int ret; - - if (new_mtu > MAX_SINGLE_PACKET_SIZE) - return -EINVAL; - ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); + int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu); if (ret < 0) { netdev_warn(dev->net, "Failed to set mac rx frame length\n"); return ret; @@ -1328,7 +1324,7 @@ static int smsc75xx_reset(struct usbnet *dev) netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x\n", buf); - ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN); + ret = smsc75xx_set_rx_max_frame_length(dev, 1514); if (ret < 0) { netdev_warn(dev->net, "Failed to set max rx frame length\n"); return ret; @@ -2138,8 +2134,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) dev->net->stats.rx_frame_errors++; } else { - /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */ - if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) { + /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ + if (unlikely(size > (ETH_FRAME_LEN + 12))) { netif_dbg(dev, rx_err, dev->net, "size err rx_cmd_a=0x%08x\n", rx_cmd_a); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h index bdee2ed67219..28fd99203f64 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h @@ -519,7 +519,7 @@ static const u32 ar9580_1p0_mac_core[][2] = { {0x00008258, 0x00000000}, {0x0000825c, 0x40000000}, {0x00008260, 0x00080922}, - {0x00008264, 0x9d400010}, + {0x00008264, 0x9bc00010}, {0x00008268, 0xffffffff}, {0x0000826c, 0x0000ffff}, {0x00008270, 0x00000000}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index 73fe8d6db566..467b60014b7b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c @@ -143,14 +143,14 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) u32 sz, i; struct channel_detector *cd; - cd = kmalloc(sizeof(*cd), GFP_ATOMIC); + cd = kmalloc(sizeof(*cd), GFP_KERNEL); if (cd == NULL) goto fail; INIT_LIST_HEAD(&cd->head); cd->freq = freq; sz = sizeof(cd->detectors) * dpd->num_radar_types; - cd->detectors = kzalloc(sz, GFP_ATOMIC); + cd->detectors = kzalloc(sz, GFP_KERNEL); if (cd->detectors == NULL) goto fail; diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c b/trunk/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c index 5e48c5515b8c..91b8dceeadb1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c @@ -218,7 +218,7 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) { struct pulse_elem *p = pool_get_pulse_elem(); if (p == NULL) { - p = kmalloc(sizeof(*p), GFP_ATOMIC); + p = kmalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) { DFS_POOL_STAT_INC(pulse_alloc_error); return false; @@ -299,7 +299,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde, ps.deadline_ts = ps.first_ts + ps.dur; new_ps = pool_get_pseq_elem(); if (new_ps == NULL) { - new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC); + new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL); if (new_ps == NULL) { DFS_POOL_STAT_INC(pseq_alloc_error); return false; 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 a47f5e05fc04..716058b67557 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -796,7 +796,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) * required version. */ if (priv->fw_version_major != MAJOR_VERSION_REQ || - priv->fw_version_minor < MINOR_VERSION_REQ) { + priv->fw_version_minor != MINOR_VERSION_REQ) { dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", MAJOR_VERSION_REQ, MINOR_VERSION_REQ); return -EINVAL; diff --git a/trunk/drivers/net/wireless/ath/ath9k/link.c b/trunk/drivers/net/wireless/ath/ath9k/link.c index 7fdac6c7b3ea..39c84ecf6a42 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/link.c +++ b/trunk/drivers/net/wireless/ath/ath9k/link.c @@ -170,8 +170,7 @@ void ath_rx_poll(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; - if (!test_bit(SC_OP_INVALID, &sc->sc_flags)) - ieee80211_queue_work(sc->hw, &sc->hw_check_work); + ieee80211_queue_work(sc->hw, &sc->hw_check_work); } /* diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 988372d218a4..6e66f9c6782b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -280,10 +280,6 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) if (r) { ath_err(common, "Unable to reset channel, reset status %d\n", r); - - ath9k_hw_enable_interrupts(ah); - ath9k_queue_reset(sc, RESET_TYPE_BB_HANG); - goto out; } diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index 122146943bf2..38bc5a7997ff 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -1487,12 +1487,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_dma_ops *ops; struct b43_dmaring *ring; struct b43_dmadesc_meta *meta; - static const struct b43_txstatus fake; /* filled with 0 */ - const struct b43_txstatus *txstat; int slot, firstused; bool frame_succeed; - int skip; - static u8 err_out1, err_out2; ring = parse_cookie(dev, status->cookie, &slot); if (unlikely(!ring)) @@ -1505,36 +1501,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, firstused = ring->current_slot - ring->used_slots + 1; if (firstused < 0) firstused = ring->nr_slots + firstused; - - skip = 0; if (unlikely(slot != firstused)) { /* This possibly is a firmware bug and will result in - * malfunction, memory leaks and/or stall of DMA functionality. - */ - if (slot == next_slot(ring, next_slot(ring, firstused))) { - /* If a single header/data pair was missed, skip over - * the first two slots in an attempt to recover. - */ - slot = firstused; - skip = 2; - if (!err_out1) { - /* Report the error once. */ - b43dbg(dev->wl, - "Skip on DMA ring %d slot %d.\n", - ring->index, slot); - err_out1 = 1; - } - } else { - /* More than a single header/data pair were missed. - * Report this error once. - */ - if (!err_out2) - b43dbg(dev->wl, - "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n", - ring->index, firstused, slot); - err_out2 = 1; - return; - } + * malfunction, memory leaks and/or stall of DMA functionality. */ + b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. " + "Expected %d, but got %d\n", + ring->index, firstused, slot); + return; } ops = ring->ops; @@ -1549,13 +1522,11 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, slot, firstused, ring->index); break; } - if (meta->skb) { struct b43_private_tx_info *priv_info = - b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); + b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); - unmap_descbuffer(ring, meta->dmaaddr, - meta->skb->len, 1); + unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); kfree(priv_info->bouncebuffer); priv_info->bouncebuffer = NULL; } else { @@ -1567,9 +1538,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, struct ieee80211_tx_info *info; if (unlikely(!meta->skb)) { - /* This is a scatter-gather fragment of a frame, - * so the skb pointer must not be NULL. - */ + /* This is a scatter-gather fragment of a frame, so + * the skb pointer must not be NULL. */ b43dbg(dev->wl, "TX status unexpected NULL skb " "at slot %d (first=%d) on ring %d\n", slot, firstused, ring->index); @@ -1580,18 +1550,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, /* * Call back to inform the ieee80211 subsystem about - * the status of the transmission. When skipping over - * a missed TX status report, use a status structure - * filled with zeros to indicate that the frame was not - * sent (frame_count 0) and not acknowledged + * the status of the transmission. */ - if (unlikely(skip)) - txstat = &fake; - else - txstat = status; - - frame_succeed = b43_fill_txstatus_report(dev, info, - txstat); + frame_succeed = b43_fill_txstatus_report(dev, info, status); #ifdef CONFIG_B43_DEBUG if (frame_succeed) ring->nr_succeed_tx_packets++; @@ -1619,14 +1580,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, /* Everything unmapped and free'd. So it's not used anymore. */ ring->used_slots--; - if (meta->is_last_fragment && !skip) { + if (meta->is_last_fragment) { /* This is the last scatter-gather * fragment of the frame. We are done. */ break; } slot = next_slot(ring, slot); - if (skip > 0) - --skip; } if (ring->stopped) { B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME); diff --git a/trunk/drivers/net/wireless/b43/phy_n.c b/trunk/drivers/net/wireless/b43/phy_n.c index b70f220bc4b3..3c35382ee6c2 100644 --- a/trunk/drivers/net/wireless/b43/phy_n.c +++ b/trunk/drivers/net/wireless/b43/phy_n.c @@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) u16 clip_off[2] = { 0xFFFF, 0xFFFF }; u8 vcm_final = 0; - s32 offset[4]; + s8 offset[4]; s32 results[8][4] = { }; s32 results_min[4] = { }; s32 poll_results[4] = { }; @@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) } for (i = 0; i < 4; i += 2) { s32 curr; - s32 mind = 0x100000; + s32 mind = 40; s32 minpoll = 249; u8 minvcm = 0; if (2 * core != i) @@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) u8 regs_save_radio[2]; u16 regs_save_phy[2]; - s32 offset[4]; + s8 offset[4]; u8 core; u8 rail; @@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) } for (i = 0; i < 4; i++) { - s32 mind = 0x100000; + s32 mind = 40; u8 minvcm = 0; s32 minpoll = 249; s32 curr; @@ -5165,8 +5165,7 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid) #endif #ifdef CONFIG_B43_SSB case B43_BUS_SSB: - ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco, - avoid); + /* FIXME */ break; #endif } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 35fc68be158d..4469321c0eb3 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3317,15 +3317,15 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) goto err; } + /* External image takes precedence if specified */ if (brcmf_sdbrcm_download_code_file(bus)) { brcmf_err("dongle image file download failed\n"); goto err; } - if (brcmf_sdbrcm_download_nvram(bus)) { + /* External nvram takes precedence if specified */ + if (brcmf_sdbrcm_download_nvram(bus)) brcmf_err("dongle nvram file download failed\n"); - goto err; - } /* Take arm out of reset */ if (brcmf_sdbrcm_download_state(bus, false)) { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 78da3eff75e8..2af9c0f0798d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -1891,10 +1891,8 @@ static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, const u8 *mac_addr, struct key_params *params) { - struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_wsec_key key; s32 err = 0; - u8 keybuf[8]; memset(&key, 0, sizeof(key)); key.index = (u32) key_idx; @@ -1918,9 +1916,8 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, brcmf_dbg(CONN, "Setting the key index %d\n", key.index); memcpy(key.data, params->key, key.len); - if ((ifp->vif->mode != WL_MODE_AP) && - (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { - brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); + if (params->cipher == WLAN_CIPHER_SUITE_TKIP) { + u8 keybuf[8]; memcpy(keybuf, &key.data[24], sizeof(keybuf)); memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); memcpy(&key.data[16], keybuf, sizeof(keybuf)); @@ -2016,7 +2013,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, break; case WLAN_CIPHER_SUITE_TKIP: if (ifp->vif->mode != WL_MODE_AP) { - brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); + brcmf_dbg(CONN, "Swapping key\n"); memcpy(keybuf, &key.data[24], sizeof(keybuf)); memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); memcpy(&key.data[16], keybuf, sizeof(keybuf)); @@ -2121,7 +2118,8 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, err = -EAGAIN; goto done; } - if (wsec & WEP_ENABLED) { + switch (wsec & ~SES_OW_ENABLED) { + case WEP_ENABLED: sec = &profile->sec; if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { params.cipher = WLAN_CIPHER_SUITE_WEP40; @@ -2130,13 +2128,16 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, params.cipher = WLAN_CIPHER_SUITE_WEP104; brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); } - } else if (wsec & TKIP_ENABLED) { + break; + case TKIP_ENABLED: params.cipher = WLAN_CIPHER_SUITE_TKIP; brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); - } else if (wsec & AES_ENABLED) { + break; + case AES_ENABLED: params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); - } else { + break; + default: brcmf_err("Invalid algo (0x%x)\n", wsec); err = -EINVAL; goto done; @@ -3823,9 +3824,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); - s32 err; + s32 err = -EPERM; struct brcmf_fil_bss_enable_le bss_enable; - struct brcmf_join_params join_params; brcmf_dbg(TRACE, "Enter\n"); @@ -3833,21 +3833,16 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) /* Due to most likely deauths outstanding we sleep */ /* first to make sure they get processed by fw. */ msleep(400); - - memset(&join_params, 0, sizeof(join_params)); - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, - &join_params, sizeof(join_params)); - if (err < 0) - brcmf_err("SET SSID error (%d)\n", err); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); - if (err < 0) - brcmf_err("BRCMF_C_UP error %d\n", err); err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); - if (err < 0) + if (err < 0) { brcmf_err("setting AP mode failed %d\n", err); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0); - if (err < 0) - brcmf_err("setting INFRA mode failed %d\n", err); + goto exit; + } + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); + if (err < 0) { + brcmf_err("BRCMF_C_UP error %d\n", err); + goto exit; + } } else { bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx); bss_enable.enable = cpu_to_le32(0); @@ -3860,6 +3855,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); +exit: return err; } @@ -4126,6 +4122,10 @@ static const struct ieee80211_iface_limit brcmf_iface_limits[] = { BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_DEVICE) + }, { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | @@ -4183,7 +4183,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO); + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_DEVICE); wiphy->iface_combinations = brcmf_iface_combos; wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index e2340b231aa1..c6451c61407a 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -274,130 +274,6 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br) } } -/** - * This function frees the WL per-device resources. - * - * This function frees resources owned by the WL device pointed to - * by the wl parameter. - * - * precondition: can both be called locked and unlocked - * - */ -static void brcms_free(struct brcms_info *wl) -{ - struct brcms_timer *t, *next; - - /* free ucode data */ - if (wl->fw.fw_cnt) - brcms_ucode_data_free(&wl->ucode); - if (wl->irq) - free_irq(wl->irq, wl); - - /* kill dpc */ - tasklet_kill(&wl->tasklet); - - if (wl->pub) { - brcms_debugfs_detach(wl->pub); - brcms_c_module_unregister(wl->pub, "linux", wl); - } - - /* free common resources */ - if (wl->wlc) { - brcms_c_detach(wl->wlc); - wl->wlc = NULL; - wl->pub = NULL; - } - - /* virtual interface deletion is deferred so we cannot spinwait */ - - /* wait for all pending callbacks to complete */ - while (atomic_read(&wl->callbacks) > 0) - schedule(); - - /* free timers */ - for (t = wl->timers; t; t = next) { - next = t->next; -#ifdef DEBUG - kfree(t->name); -#endif - kfree(t); - } -} - -/* -* called from both kernel as from this kernel module (error flow on attach) -* precondition: perimeter lock is not acquired. -*/ -static void brcms_remove(struct bcma_device *pdev) -{ - struct ieee80211_hw *hw = bcma_get_drvdata(pdev); - struct brcms_info *wl = hw->priv; - - if (wl->wlc) { - wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); - wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); - ieee80211_unregister_hw(hw); - } - - brcms_free(wl); - - bcma_set_drvdata(pdev, NULL); - ieee80211_free_hw(hw); -} - -/* - * Precondition: Since this function is called in brcms_pci_probe() context, - * no locking is required. - */ -static void brcms_release_fw(struct brcms_info *wl) -{ - int i; - for (i = 0; i < MAX_FW_IMAGES; i++) { - release_firmware(wl->fw.fw_bin[i]); - release_firmware(wl->fw.fw_hdr[i]); - } -} - -/* - * Precondition: Since this function is called in brcms_pci_probe() context, - * no locking is required. - */ -static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) -{ - int status; - struct device *device = &pdev->dev; - char fw_name[100]; - int i; - - memset(&wl->fw, 0, sizeof(struct brcms_firmware)); - for (i = 0; i < MAX_FW_IMAGES; i++) { - if (brcms_firmwares[i] == NULL) - break; - sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], - UCODE_LOADER_API_VER); - status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); - if (status) { - wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); - return status; - } - sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], - UCODE_LOADER_API_VER); - status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); - if (status) { - wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", - KBUILD_MODNAME, fw_name); - return status; - } - wl->fw.hdr_num_entries[i] = - wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); - } - wl->fw.fw_cnt = i; - status = brcms_ucode_data_init(wl, &wl->ucode); - brcms_release_fw(wl); - return status; -} - static void brcms_ops_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) @@ -430,14 +306,6 @@ static int brcms_ops_start(struct ieee80211_hw *hw) if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); - if (!wl->ucode.bcm43xx_bomminor) { - err = brcms_request_fw(wl, wl->wlc->hw->d11core); - if (err) { - brcms_remove(wl->wlc->hw->d11core); - return -ENOENT; - } - } - spin_lock_bh(&wl->lock); /* avoid acknowledging frames before a non-monitor device is added */ wl->mute_tx = true; @@ -925,6 +793,128 @@ void brcms_dpc(unsigned long data) wake_up(&wl->tx_flush_wq); } +/* + * Precondition: Since this function is called in brcms_pci_probe() context, + * no locking is required. + */ +static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev) +{ + int status; + struct device *device = &pdev->dev; + char fw_name[100]; + int i; + + memset(&wl->fw, 0, sizeof(struct brcms_firmware)); + for (i = 0; i < MAX_FW_IMAGES; i++) { + if (brcms_firmwares[i] == NULL) + break; + sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); + if (status) { + wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); + return status; + } + sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); + if (status) { + wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", + KBUILD_MODNAME, fw_name); + return status; + } + wl->fw.hdr_num_entries[i] = + wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); + } + wl->fw.fw_cnt = i; + return brcms_ucode_data_init(wl, &wl->ucode); +} + +/* + * Precondition: Since this function is called in brcms_pci_probe() context, + * no locking is required. + */ +static void brcms_release_fw(struct brcms_info *wl) +{ + int i; + for (i = 0; i < MAX_FW_IMAGES; i++) { + release_firmware(wl->fw.fw_bin[i]); + release_firmware(wl->fw.fw_hdr[i]); + } +} + +/** + * This function frees the WL per-device resources. + * + * This function frees resources owned by the WL device pointed to + * by the wl parameter. + * + * precondition: can both be called locked and unlocked + * + */ +static void brcms_free(struct brcms_info *wl) +{ + struct brcms_timer *t, *next; + + /* free ucode data */ + if (wl->fw.fw_cnt) + brcms_ucode_data_free(&wl->ucode); + if (wl->irq) + free_irq(wl->irq, wl); + + /* kill dpc */ + tasklet_kill(&wl->tasklet); + + if (wl->pub) { + brcms_debugfs_detach(wl->pub); + brcms_c_module_unregister(wl->pub, "linux", wl); + } + + /* free common resources */ + if (wl->wlc) { + brcms_c_detach(wl->wlc); + wl->wlc = NULL; + wl->pub = NULL; + } + + /* virtual interface deletion is deferred so we cannot spinwait */ + + /* wait for all pending callbacks to complete */ + while (atomic_read(&wl->callbacks) > 0) + schedule(); + + /* free timers */ + for (t = wl->timers; t; t = next) { + next = t->next; +#ifdef DEBUG + kfree(t->name); +#endif + kfree(t); + } +} + +/* +* called from both kernel as from this kernel module (error flow on attach) +* precondition: perimeter lock is not acquired. +*/ +static void brcms_remove(struct bcma_device *pdev) +{ + struct ieee80211_hw *hw = bcma_get_drvdata(pdev); + struct brcms_info *wl = hw->priv; + + if (wl->wlc) { + wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); + wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); + ieee80211_unregister_hw(hw); + } + + brcms_free(wl); + + bcma_set_drvdata(pdev, NULL); + ieee80211_free_hw(hw); +} + static irqreturn_t brcms_isr(int irq, void *dev_id) { struct brcms_info *wl; @@ -1057,8 +1047,18 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) spin_lock_init(&wl->lock); spin_lock_init(&wl->isr_lock); + /* prepare ucode */ + if (brcms_request_fw(wl, pdev) < 0) { + wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " + "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); + brcms_release_fw(wl); + brcms_remove(pdev); + return NULL; + } + /* common load-time initialization */ wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); + brcms_release_fw(wl); if (!wl->wlc) { wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", KBUILD_MODNAME, err); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c index 18d37645e2cd..21a824232478 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c @@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, gain0_15 = ((biq1 & 0xf) << 12) | ((tia & 0xf) << 8) | ((lna2 & 0x3) << 6) | - ((lna2 & - 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); + ((lna2 & 0x3) << 4) | + ((lna1 & 0x3) << 2) | + ((lna1 & 0x3) << 0); mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); @@ -1156,6 +1157,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, } mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); + mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); + mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3); } @@ -1328,6 +1331,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples) return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; } +static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain, + u16 tia_gain, u16 lna2_gain) +{ + u32 i_thresh_l, q_thresh_l; + u32 i_thresh_h, q_thresh_h; + struct lcnphy_iq_est iq_est_h, iq_est_l; + + wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain, + lna2_gain, 0); + + wlc_lcnphy_rx_gain_override_enable(pi, true); + wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0); + udelay(500); + write_radio_reg(pi, RADIO_2064_REG112, 0); + if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l)) + return false; + + wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0); + udelay(500); + write_radio_reg(pi, RADIO_2064_REG112, 0); + if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h)) + return false; + + i_thresh_l = (iq_est_l.i_pwr << 1); + i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr; + + q_thresh_l = (iq_est_l.q_pwr << 1); + q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr; + if ((iq_est_h.i_pwr > i_thresh_l) && + (iq_est_h.i_pwr < i_thresh_h) && + (iq_est_h.q_pwr > q_thresh_l) && + (iq_est_h.q_pwr < q_thresh_h)) + return true; + + return false; +} + static bool wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, const struct lcnphy_rx_iqcomp *iqcomp, @@ -1342,8 +1382,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, rfoverride3_old, rfoverride3val_old, rfoverride4_old, rfoverride4val_old, afectrlovr_old, afectrlovrval_old; - int tia_gain; - u32 received_power, rx_pwr_threshold; + int tia_gain, lna2_gain, biq1_gain; + bool set_gain; u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; u16 values_to_save[11]; s16 *ptr; @@ -1368,126 +1408,134 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, goto cal_done; } - if (module == 1) { + WARN_ON(module != 1); + tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + for (i = 0; i < 11; i++) + values_to_save[i] = + read_radio_reg(pi, rxiq_cal_rf_reg[i]); + Core1TxControl_old = read_phy_reg(pi, 0x631); + + or_phy_reg(pi, 0x631, 0x0015); + + RFOverride0_old = read_phy_reg(pi, 0x44c); + RFOverrideVal0_old = read_phy_reg(pi, 0x44d); + rfoverride2_old = read_phy_reg(pi, 0x4b0); + rfoverride2val_old = read_phy_reg(pi, 0x4b1); + rfoverride3_old = read_phy_reg(pi, 0x4f9); + rfoverride3val_old = read_phy_reg(pi, 0x4fa); + rfoverride4_old = read_phy_reg(pi, 0x938); + rfoverride4val_old = read_phy_reg(pi, 0x939); + afectrlovr_old = read_phy_reg(pi, 0x43b); + afectrlovrval_old = read_phy_reg(pi, 0x43c); + old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - for (i = 0; i < 11; i++) - values_to_save[i] = - read_radio_reg(pi, rxiq_cal_rf_reg[i]); - Core1TxControl_old = read_phy_reg(pi, 0x631); - - or_phy_reg(pi, 0x631, 0x0015); - - RFOverride0_old = read_phy_reg(pi, 0x44c); - RFOverrideVal0_old = read_phy_reg(pi, 0x44d); - rfoverride2_old = read_phy_reg(pi, 0x4b0); - rfoverride2val_old = read_phy_reg(pi, 0x4b1); - rfoverride3_old = read_phy_reg(pi, 0x4f9); - rfoverride3val_old = read_phy_reg(pi, 0x4fa); - rfoverride4_old = read_phy_reg(pi, 0x938); - rfoverride4val_old = read_phy_reg(pi, 0x939); - afectrlovr_old = read_phy_reg(pi, 0x43b); - afectrlovrval_old = read_phy_reg(pi, 0x43c); - old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - - tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); - if (tx_gain_override_old) { - wlc_lcnphy_get_tx_gain(pi, &old_gains); - tx_gain_index_old = pi_lcn->lcnphy_current_index; - } + tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); + if (tx_gain_override_old) { + wlc_lcnphy_get_tx_gain(pi, &old_gains); + tx_gain_index_old = pi_lcn->lcnphy_current_index; + } - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); - mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - write_radio_reg(pi, RADIO_2064_REG116, 0x06); - write_radio_reg(pi, RADIO_2064_REG12C, 0x07); - write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); - write_radio_reg(pi, RADIO_2064_REG098, 0x03); - write_radio_reg(pi, RADIO_2064_REG00B, 0x7); - mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); - write_radio_reg(pi, RADIO_2064_REG01D, 0x01); - write_radio_reg(pi, RADIO_2064_REG114, 0x01); - write_radio_reg(pi, RADIO_2064_REG02E, 0x10); - write_radio_reg(pi, RADIO_2064_REG12A, 0x08); - - mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); - mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); - mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); - - mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); - - wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0); - write_phy_reg(pi, 0x6da, 0xffff); - or_phy_reg(pi, 0x6db, 0x3); - wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); - wlc_lcnphy_rx_gain_override_enable(pi, true); - - tia_gain = 8; - rx_pwr_threshold = 950; - while (tia_gain > 0) { - tia_gain -= 1; - wlc_lcnphy_set_rx_gain_by_distribution(pi, - 0, 0, 2, 2, - (u16) - tia_gain, 1, 0); - udelay(500); + write_radio_reg(pi, RADIO_2064_REG116, 0x06); + write_radio_reg(pi, RADIO_2064_REG12C, 0x07); + write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); + write_radio_reg(pi, RADIO_2064_REG098, 0x03); + write_radio_reg(pi, RADIO_2064_REG00B, 0x7); + mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); + write_radio_reg(pi, RADIO_2064_REG01D, 0x01); + write_radio_reg(pi, RADIO_2064_REG114, 0x01); + write_radio_reg(pi, RADIO_2064_REG02E, 0x10); + write_radio_reg(pi, RADIO_2064_REG12A, 0x08); + + mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); + mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); - received_power = - wlc_lcnphy_measure_digital_power(pi, 2000); - if (received_power < rx_pwr_threshold) - break; + mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + + write_phy_reg(pi, 0x6da, 0xffff); + or_phy_reg(pi, 0x6db, 0x3); + + wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); + set_gain = false; + + lna2_gain = 3; + while ((lna2_gain >= 0) && !set_gain) { + tia_gain = 4; + + while ((tia_gain >= 0) && !set_gain) { + biq1_gain = 6; + + while ((biq1_gain >= 0) && !set_gain) { + set_gain = wlc_lcnphy_rx_iq_cal_gain(pi, + (u16) + biq1_gain, + (u16) + tia_gain, + (u16) + lna2_gain); + biq1_gain -= 1; + } + tia_gain -= 1; } - result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); + lna2_gain -= 1; + } - wlc_lcnphy_stop_tx_tone(pi); + if (set_gain) + result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024); + else + result = false; - write_phy_reg(pi, 0x631, Core1TxControl_old); + wlc_lcnphy_stop_tx_tone(pi); - write_phy_reg(pi, 0x44c, RFOverrideVal0_old); - write_phy_reg(pi, 0x44d, RFOverrideVal0_old); - write_phy_reg(pi, 0x4b0, rfoverride2_old); - write_phy_reg(pi, 0x4b1, rfoverride2val_old); - write_phy_reg(pi, 0x4f9, rfoverride3_old); - write_phy_reg(pi, 0x4fa, rfoverride3val_old); - write_phy_reg(pi, 0x938, rfoverride4_old); - write_phy_reg(pi, 0x939, rfoverride4val_old); - write_phy_reg(pi, 0x43b, afectrlovr_old); - write_phy_reg(pi, 0x43c, afectrlovrval_old); - write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); + write_phy_reg(pi, 0x631, Core1TxControl_old); + + write_phy_reg(pi, 0x44c, RFOverrideVal0_old); + write_phy_reg(pi, 0x44d, RFOverrideVal0_old); + write_phy_reg(pi, 0x4b0, rfoverride2_old); + write_phy_reg(pi, 0x4b1, rfoverride2val_old); + write_phy_reg(pi, 0x4f9, rfoverride3_old); + write_phy_reg(pi, 0x4fa, rfoverride3val_old); + write_phy_reg(pi, 0x938, rfoverride4_old); + write_phy_reg(pi, 0x939, rfoverride4val_old); + write_phy_reg(pi, 0x43b, afectrlovr_old); + write_phy_reg(pi, 0x43c, afectrlovrval_old); + write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); + write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); - wlc_lcnphy_clear_trsw_override(pi); + wlc_lcnphy_clear_trsw_override(pi); - mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); + mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); - for (i = 0; i < 11; i++) - write_radio_reg(pi, rxiq_cal_rf_reg[i], - values_to_save[i]); + for (i = 0; i < 11; i++) + write_radio_reg(pi, rxiq_cal_rf_reg[i], + values_to_save[i]); - if (tx_gain_override_old) - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); - else - wlc_lcnphy_disable_tx_gain_override(pi); + if (tx_gain_override_old) + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); + else + wlc_lcnphy_disable_tx_gain_override(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); - wlc_lcnphy_rx_gain_override_enable(pi, false); - } + wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); + wlc_lcnphy_rx_gain_override_enable(pi, false); cal_done: kfree(ptr); @@ -1781,6 +1829,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel) write_radio_reg(pi, RADIO_2064_REG038, 3); write_radio_reg(pi, RADIO_2064_REG091, 7); } + + if (!(pi->sh->boardflags & BFL_FEM)) { + u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc, + 0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0}; + + write_radio_reg(pi, RADIO_2064_REG02A, 0xf); + write_radio_reg(pi, RADIO_2064_REG091, 0x3); + write_radio_reg(pi, RADIO_2064_REG038, 0x3); + + write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]); + } } static int @@ -1975,6 +2034,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos) } else { mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); + mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2); + mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4); + mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0); + mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77); + mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1); + mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7); + mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1); + mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4); } } else { mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); @@ -2061,12 +2130,14 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi) (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); + mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0)); } static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) { struct phytbl_info tab; u32 rfseq, ind; + u8 tssi_sel; tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; @@ -2088,7 +2159,13 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); - wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); + if (pi->sh->boardflags & BFL_FEM) { + tssi_sel = 0x1; + wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); + } else { + tssi_sel = 0xe; + wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA); + } mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); @@ -2124,9 +2201,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); + mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel); mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); } else { + mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1); mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); } @@ -2173,6 +2251,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); + mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0); + mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0); + mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); + wlc_lcnphy_pwrctrl_rssiparams(pi); } @@ -2791,6 +2873,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) read_radio_reg(pi, RADIO_2064_REG007) & 1; u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; + u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi); + idleTssi = read_phy_reg(pi, 0x4ab); suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)); @@ -2808,6 +2892,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); wlc_lcnphy_tssi_setup(pi); + + mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0)); + mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6)); + + wlc_lcnphy_set_bbmult(pi, 0x0); + wlc_phy_do_dummy_tx(pi, true, OFF); idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) >> 0); @@ -2829,6 +2919,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); + wlc_lcnphy_set_bbmult(pi, SAVE_bbmult); wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); wlc_lcnphy_set_tx_gain(pi, &old_gains); wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); @@ -3042,6 +3133,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi) wlc_lcnphy_write_table(pi, &tab); tab.tbl_offset++; } + mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0); + mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0); + mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8); + mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4); + mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2); mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); @@ -3843,7 +3939,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) target_gains.pad_gain = 21; target_gains.dac_gain = 0; wlc_lcnphy_set_tx_gain(pi, &target_gains); - wlc_lcnphy_set_tx_pwr_by_index(pi, 16); if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { @@ -3854,6 +3949,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) lcnphy_recal ? LCNPHY_CAL_RECAL : LCNPHY_CAL_FULL), false); } else { + wlc_lcnphy_set_tx_pwr_by_index(pi, 16); wlc_lcnphy_tx_iqlo_soft_cal_full(pi); } @@ -4278,17 +4374,22 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi, if (CHSPEC_IS5G(pi->radio_chanspec)) pa_gain = 0x70; else - pa_gain = 0x70; + pa_gain = 0x60; if (pi->sh->boardflags & BFL_FEM) pa_gain = 0x10; + tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; tab.tbl_len = 1; tab.tbl_ptr = &val; for (j = 0; j < 128; j++) { - gm_gain = gain_table[j].gm; + if (pi->sh->boardflags & BFL_FEM) + gm_gain = gain_table[j].gm; + else + gm_gain = 15; + val = (((u32) pa_gain << 24) | (gain_table[j].pad << 16) | (gain_table[j].pga << 8) | gm_gain); @@ -4499,7 +4600,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi) write_phy_reg(pi, 0x4ea, 0x4688); - mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); + if (pi->sh->boardflags & BFL_FEM) + mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); + else + mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0); mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); @@ -4510,6 +4614,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi) wlc_lcnphy_rcal(pi); wlc_lcnphy_rc_cal(pi); + + if (!(pi->sh->boardflags & BFL_FEM)) { + write_radio_reg(pi, RADIO_2064_REG032, 0x6f); + write_radio_reg(pi, RADIO_2064_REG033, 0x19); + write_radio_reg(pi, RADIO_2064_REG039, 0xe); + } + } static void wlc_lcnphy_radio_init(struct brcms_phy *pi) @@ -4539,22 +4650,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) wlc_lcnphy_write_table(pi, &tab); } - tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; - tab.tbl_width = 16; - tab.tbl_ptr = &val; - tab.tbl_len = 1; - - val = 114; - tab.tbl_offset = 0; - wlc_lcnphy_write_table(pi, &tab); + if (!(pi->sh->boardflags & BFL_FEM)) { + tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; + tab.tbl_width = 16; + tab.tbl_ptr = &val; + tab.tbl_len = 1; - val = 130; - tab.tbl_offset = 1; - wlc_lcnphy_write_table(pi, &tab); + val = 150; + tab.tbl_offset = 0; + wlc_lcnphy_write_table(pi, &tab); - val = 6; - tab.tbl_offset = 8; - wlc_lcnphy_write_table(pi, &tab); + val = 220; + tab.tbl_offset = 1; + wlc_lcnphy_write_table(pi, &tab); + } if (CHSPEC_IS2G(pi->radio_chanspec)) { if (pi->sh->boardflags & BFL_FEM) @@ -4946,6 +5055,7 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec) wlc_lcnphy_load_tx_iir_filter(pi, true, 3); mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3); + wlc_lcnphy_tssi_setup(pi); } void wlc_phy_detach_lcnphy(struct brcms_phy *pi) @@ -4984,8 +5094,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) return false; - if ((pi->sh->boardflags & BFL_FEM) && - (LCNREV_IS(pi->pubpi.phy_rev, 1))) { + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { if (pi_lcn->lcnphy_tempsense_option == 3) { pi->hwpwrctrl = true; pi->hwpwrctrl_capable = true; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c index 622c01ca72c5..b7e95acc2084 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c @@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = { }; static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { - 0x000a, 0x0009, - 0x0006, - 0x0005, 0x000a, - 0x0009, - 0x0006, 0x0005, - 0x000a, - 0x0009, 0x0006, - 0x0005, - 0x000a, 0x0009, - 0x0006, - 0x0005, 0x000a, - 0x0009, - 0x0006, 0x0005, - 0x000a, - 0x0009, 0x0006, - 0x0005, - 0x000a, 0x0009, - 0x0006, - 0x0005, 0x000a, - 0x0009, - 0x0006, 0x0005, - 0x000a, - 0x0009, 0x0006, - 0x0005, - 0x000a, 0x0009, - 0x0006, - 0x0005, 0x000a, - 0x0009, - 0x0006, 0x0005, - 0x000a, - 0x0009, 0x0006, - 0x0005, + 0x0009, 0x000a, + 0x0005, + 0x0006, 0x0009, + 0x000a, + 0x0005, 0x0006, + 0x0009, + 0x000a, 0x0005, + 0x0006, + 0x0009, 0x000a, + 0x0005, + 0x0006, 0x0009, + 0x000a, + 0x0005, 0x0006, + 0x0009, + 0x000a, 0x0005, + 0x0006, + 0x0009, 0x000a, + 0x0005, + 0x0006, 0x0009, + 0x000a, + 0x0005, 0x0006, + 0x0009, + 0x000a, 0x0005, + 0x0006, + 0x0009, 0x000a, + 0x0005, + 0x0006, 0x0009, + 0x000a, + 0x0005, 0x0006, + 0x0009, + 0x000a, 0x0005, + 0x0006, }; static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-rs.c b/trunk/drivers/net/wireless/iwlegacy/4965-rs.c index 6c7493c2d698..e8324b5e5bfe 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-rs.c @@ -2152,7 +2152,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, int rate_idx; int i; u32 rate; - u8 use_green; + u8 use_green = il4965_rs_use_green(il, sta); u8 active_tbl = 0; u8 valid_tx_ant; struct il_station_priv *sta_priv; @@ -2160,7 +2160,6 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, if (!sta || !lq_sta) return; - use_green = il4965_rs_use_green(il, sta); sta_priv = (void *)sta->drv_priv; i = lq_sta->last_txrate_idx; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c b/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c index 44ca0e57f9f7..86ea5f4c3939 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -1261,15 +1261,6 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } - /* - * This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag - * in iwl_down but cancel the workers only later. - */ - if (!priv->ucode_loaded) { - IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id); - return -EIO; - } - /* * Synchronous commands from this op-mode must hold * the mutex, this ensures we don't try to send two diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c index a82b6b39d4ff..23be948cf162 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -1419,14 +1419,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (changes & BSS_CHANGED_IDLE && bss_conf->idle) { - /* - * If we go idle, then clearly no "passive-no-rx" - * workaround is needed any more, this is a reset. - */ - iwlagn_lift_passive_no_rx(priv); - } - if (unlikely(!iwl_is_ready(priv))) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); mutex_unlock(&priv->mutex); @@ -1458,6 +1450,16 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, priv->timestamp = bss_conf->sync_tsf; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { + /* + * If we disassociate while there are pending + * frames, just wake up the queues and let the + * frames "escape" ... This shouldn't really + * be happening to start with, but we should + * not get stuck in this case either since it + * can happen if userspace gets confused. + */ + iwlagn_lift_passive_no_rx(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; if (ctx->ctxid == IWL_RXON_CTX_BSS) diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c index d1a670d7b10c..6aec2df3bb27 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -1192,7 +1192,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, memset(&info->status, 0, sizeof(info->status)); if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && - ctx->vif && + iwl_is_associated_ctx(ctx) && ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) { /* block and stop all queues */ priv->passive_no_rx = true; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c index 1a4ac9236a44..736fe9bb140e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -367,8 +367,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return -EIO; } - priv->ucode_loaded = true; - if (ucode_type != IWL_UCODE_WOWLAN) { /* delay a bit to give rfkill time to run */ msleep(5); @@ -382,6 +380,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return ret; } + priv->ucode_loaded = true; + return 0; } diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c index 12c4f31ca8fb..17bedc50e753 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -475,10 +475,6 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, /* If platform's RF_KILL switch is NOT set to KILL */ hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans_pcie->status); - else - clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); if (hw_rfkill && !run_in_rfkill) return -ERFKILL; @@ -645,7 +641,6 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill; int err; @@ -661,10 +656,6 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_enable_rfkill_int(trans); hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans_pcie->status); - else - clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); return 0; @@ -703,10 +694,6 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, * op_mode. */ hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans_pcie->status); - else - clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); } } diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c index cb5c6792e3a8..8595c16f74de 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1264,7 +1264,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { int copy = 0; - if (!cmd->len[i]) + if (!cmd->len) continue; /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index 8aaf56ade4d9..a44023a7bd57 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -1892,8 +1892,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, } } - for (i = 0; i < min_t(u32, request->n_channels, - MWIFIEX_USER_SCAN_CHAN_MAX); i++) { + for (i = 0; i < request->n_channels; i++) { chan = request->channels[i]; priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; priv->user_scan_cfg->chan_list[i].radio_type = chan->band; diff --git a/trunk/drivers/net/wireless/mwifiex/pcie.c b/trunk/drivers/net/wireless/mwifiex/pcie.c index feb204613397..5c395e2e6a2b 100644 --- a/trunk/drivers/net/wireless/mwifiex/pcie.c +++ b/trunk/drivers/net/wireless/mwifiex/pcie.c @@ -1508,7 +1508,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) } memcpy(adapter->upld_buf, skb->data, min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); - skb_push(skb, INTF_HEADER_LEN); if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, PCI_DMA_FROMDEVICE)) return -1; diff --git a/trunk/drivers/net/wireless/mwifiex/scan.c b/trunk/drivers/net/wireless/mwifiex/scan.c index e7f6deaf715e..d215b4d3c51b 100644 --- a/trunk/drivers/net/wireless/mwifiex/scan.c +++ b/trunk/drivers/net/wireless/mwifiex/scan.c @@ -1393,10 +1393,8 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, queue_work(adapter->workqueue, &adapter->main_work); /* Perform internal scan synchronously */ - if (!priv->scan_request) { - dev_dbg(adapter->dev, "wait internal scan\n"); + if (!priv->scan_request) mwifiex_wait_queue_complete(adapter, cmd_node); - } } else { spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -1795,12 +1793,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, /* Need to indicate IOCTL complete */ if (adapter->curr_cmd->wait_q_enabled) { adapter->cmd_wait_q.status = 0; - if (!priv->scan_request) { - dev_dbg(adapter->dev, - "complete internal scan\n"); - mwifiex_complete_cmd(adapter, - adapter->curr_cmd); - } + mwifiex_complete_cmd(adapter, adapter->curr_cmd); } if (priv->report_scan_result) priv->report_scan_result = false; diff --git a/trunk/drivers/net/wireless/rt2x00/Kconfig b/trunk/drivers/net/wireless/rt2x00/Kconfig index 76cd47eb901e..2bf4efa33186 100644 --- a/trunk/drivers/net/wireless/rt2x00/Kconfig +++ b/trunk/drivers/net/wireless/rt2x00/Kconfig @@ -20,7 +20,6 @@ if RT2X00 config RT2400PCI tristate "Ralink rt2400 (PCI/PCMCIA) support" depends on PCI - select RT2X00_LIB_MMIO select RT2X00_LIB_PCI select EEPROM_93CX6 ---help--- @@ -32,7 +31,6 @@ config RT2400PCI config RT2500PCI tristate "Ralink rt2500 (PCI/PCMCIA) support" depends on PCI - select RT2X00_LIB_MMIO select RT2X00_LIB_PCI select EEPROM_93CX6 ---help--- @@ -45,7 +43,6 @@ config RT61PCI tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support" depends on PCI select RT2X00_LIB_PCI - select RT2X00_LIB_MMIO select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO select CRC_ITU_T @@ -60,7 +57,6 @@ config RT2800PCI tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" depends on PCI || SOC_RT288X || SOC_RT305X select RT2800_LIB - select RT2X00_LIB_MMIO select RT2X00_LIB_PCI if PCI select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X select RT2X00_LIB_FIRMWARE @@ -189,9 +185,6 @@ endif config RT2800_LIB tristate -config RT2X00_LIB_MMIO - tristate - config RT2X00_LIB_PCI tristate select RT2X00_LIB diff --git a/trunk/drivers/net/wireless/rt2x00/Makefile b/trunk/drivers/net/wireless/rt2x00/Makefile index f069d8bc5b67..349d5b8284a4 100644 --- a/trunk/drivers/net/wireless/rt2x00/Makefile +++ b/trunk/drivers/net/wireless/rt2x00/Makefile @@ -9,7 +9,6 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o -obj-$(CONFIG_RT2X00_LIB_MMIO) += rt2x00mmio.o obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o diff --git a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c index dcfb54e0c516..221beaaa83f1 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c @@ -34,7 +34,6 @@ #include #include "rt2x00.h" -#include "rt2x00mmio.h" #include "rt2x00pci.h" #include "rt2400pci.h" diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c index e1d2dc9ed28a..39edc59e8d03 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c @@ -34,7 +34,6 @@ #include #include "rt2x00.h" -#include "rt2x00mmio.h" #include "rt2x00pci.h" #include "rt2500pci.h" diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c index ba5a05625aaa..ded73da4de0b 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c @@ -41,7 +41,6 @@ #include #include "rt2x00.h" -#include "rt2x00mmio.h" #include "rt2x00pci.h" #include "rt2x00soc.h" #include "rt2800lib.h" diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.c deleted file mode 100644 index d84a680ba0c9..000000000000 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - Copyright (C) 2004 - 2009 Ivo van Doorn - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the - Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - Module: rt2x00mmio - Abstract: rt2x00 generic mmio device routines. - */ - -#include -#include -#include -#include - -#include "rt2x00.h" -#include "rt2x00mmio.h" - -/* - * Register access. - */ -int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const struct rt2x00_field32 field, - u32 *reg) -{ - unsigned int i; - - if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - return 0; - - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2x00pci_register_read(rt2x00dev, offset, reg); - if (!rt2x00_get_field32(*reg, field)) - return 1; - udelay(REGISTER_BUSY_DELAY); - } - - printk_once(KERN_ERR "%s() Indirect register access failed: " - "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg); - *reg = ~0; - - return 0; -} -EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); - -bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue = rt2x00dev->rx; - struct queue_entry *entry; - struct queue_entry_priv_pci *entry_priv; - struct skb_frame_desc *skbdesc; - int max_rx = 16; - - while (--max_rx) { - entry = rt2x00queue_get_entry(queue, Q_INDEX); - entry_priv = entry->priv_data; - - if (rt2x00dev->ops->lib->get_entry_state(entry)) - break; - - /* - * Fill in desc fields of the skb descriptor - */ - skbdesc = get_skb_frame_desc(entry->skb); - skbdesc->desc = entry_priv->desc; - skbdesc->desc_len = entry->queue->desc_size; - - /* - * DMA is already done, notify rt2x00lib that - * it finished successfully. - */ - rt2x00lib_dmastart(entry); - rt2x00lib_dmadone(entry); - - /* - * Send the frame to rt2x00lib for further processing. - */ - rt2x00lib_rxdone(entry, GFP_ATOMIC); - } - - return !max_rx; -} -EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); - -void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) -{ - unsigned int i; - - for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) - msleep(10); -} -EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); - -/* - * Device initialization handlers. - */ -static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) -{ - struct queue_entry_priv_pci *entry_priv; - void *addr; - dma_addr_t dma; - unsigned int i; - - /* - * Allocate DMA memory for descriptor and buffer. - */ - addr = dma_alloc_coherent(rt2x00dev->dev, - queue->limit * queue->desc_size, - &dma, GFP_KERNEL); - if (!addr) - return -ENOMEM; - - memset(addr, 0, queue->limit * queue->desc_size); - - /* - * Initialize all queue entries to contain valid addresses. - */ - for (i = 0; i < queue->limit; i++) { - entry_priv = queue->entries[i].priv_data; - entry_priv->desc = addr + i * queue->desc_size; - entry_priv->desc_dma = dma + i * queue->desc_size; - } - - return 0; -} - -static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) -{ - struct queue_entry_priv_pci *entry_priv = - queue->entries[0].priv_data; - - if (entry_priv->desc) - dma_free_coherent(rt2x00dev->dev, - queue->limit * queue->desc_size, - entry_priv->desc, entry_priv->desc_dma); - entry_priv->desc = NULL; -} - -int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - int status; - - /* - * Allocate DMA - */ - queue_for_each(rt2x00dev, queue) { - status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); - if (status) - goto exit; - } - - /* - * Register interrupt handler. - */ - status = request_irq(rt2x00dev->irq, - rt2x00dev->ops->lib->irq_handler, - IRQF_SHARED, rt2x00dev->name, rt2x00dev); - if (status) { - ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", - rt2x00dev->irq, status); - goto exit; - } - - return 0; - -exit: - queue_for_each(rt2x00dev, queue) - rt2x00pci_free_queue_dma(rt2x00dev, queue); - - return status; -} -EXPORT_SYMBOL_GPL(rt2x00pci_initialize); - -void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - - /* - * Free irq line. - */ - free_irq(rt2x00dev->irq, rt2x00dev); - - /* - * Free DMA - */ - queue_for_each(rt2x00dev, queue) - rt2x00pci_free_queue_dma(rt2x00dev, queue); -} -EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); - -/* - * rt2x00mmio module information. - */ -MODULE_AUTHOR(DRV_PROJECT); -MODULE_VERSION(DRV_VERSION); -MODULE_DESCRIPTION("rt2x00 mmio library"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.h b/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.h deleted file mode 100644 index 4ecaf60175bf..000000000000 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mmio.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (C) 2004 - 2009 Ivo van Doorn - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the - Free Software Foundation, Inc., - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - Module: rt2x00mmio - Abstract: Data structures for the rt2x00mmio module. - */ - -#ifndef RT2X00MMIO_H -#define RT2X00MMIO_H - -#include - -/* - * Register access. - */ -static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - u32 *value) -{ - *value = readl(rt2x00dev->csr.base + offset); -} - -static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - void *value, const u32 length) -{ - memcpy_fromio(value, rt2x00dev->csr.base + offset, length); -} - -static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - u32 value) -{ - writel(value, rt2x00dev->csr.base + offset); -} - -static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const void *value, - const u32 length) -{ - __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); -} - -/** - * rt2x00pci_regbusy_read - Read from register with busy check - * @rt2x00dev: Device pointer, see &struct rt2x00_dev. - * @offset: Register offset - * @field: Field to check if register is busy - * @reg: Pointer to where register contents should be stored - * - * This function will read the given register, and checks if the - * register is busy. If it is, it will sleep for a couple of - * microseconds before reading the register again. If the register - * is not read after a certain timeout, this function will return - * FALSE. - */ -int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, - const unsigned int offset, - const struct rt2x00_field32 field, - u32 *reg); - -/** - * struct queue_entry_priv_pci: Per entry PCI specific information - * - * @desc: Pointer to device descriptor - * @desc_dma: DMA pointer to &desc. - * @data: Pointer to device's entry memory. - * @data_dma: DMA pointer to &data. - */ -struct queue_entry_priv_pci { - __le32 *desc; - dma_addr_t desc_dma; -}; - -/** - * rt2x00pci_rxdone - Handle RX done events - * @rt2x00dev: Device pointer, see &struct rt2x00_dev. - * - * Returns true if there are still rx frames pending and false if all - * pending rx frames were processed. - */ -bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); - -/** - * rt2x00pci_flush_queue - Flush data queue - * @queue: Data queue to stop - * @drop: True to drop all pending frames. - * - * This will wait for a maximum of 100ms, waiting for the queues - * to become empty. - */ -void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); - -/* - * Device initialization handlers. - */ -int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); -void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); - -#endif /* RT2X00MMIO_H */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c index e87865e33113..a0c8caef3b0a 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -32,6 +32,182 @@ #include "rt2x00.h" #include "rt2x00pci.h" +/* + * Register access. + */ +int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const struct rt2x00_field32 field, + u32 *reg) +{ + unsigned int i; + + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + return 0; + + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2x00pci_register_read(rt2x00dev, offset, reg); + if (!rt2x00_get_field32(*reg, field)) + return 1; + udelay(REGISTER_BUSY_DELAY); + } + + ERROR(rt2x00dev, "Indirect register access failed: " + "offset=0x%.08x, value=0x%.08x\n", offset, *reg); + *reg = ~0; + + return 0; +} +EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); + +bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue = rt2x00dev->rx; + struct queue_entry *entry; + struct queue_entry_priv_pci *entry_priv; + struct skb_frame_desc *skbdesc; + int max_rx = 16; + + while (--max_rx) { + entry = rt2x00queue_get_entry(queue, Q_INDEX); + entry_priv = entry->priv_data; + + if (rt2x00dev->ops->lib->get_entry_state(entry)) + break; + + /* + * Fill in desc fields of the skb descriptor + */ + skbdesc = get_skb_frame_desc(entry->skb); + skbdesc->desc = entry_priv->desc; + skbdesc->desc_len = entry->queue->desc_size; + + /* + * DMA is already done, notify rt2x00lib that + * it finished successfully. + */ + rt2x00lib_dmastart(entry); + rt2x00lib_dmadone(entry); + + /* + * Send the frame to rt2x00lib for further processing. + */ + rt2x00lib_rxdone(entry, GFP_ATOMIC); + } + + return !max_rx; +} +EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); + +void rt2x00pci_flush_queue(struct data_queue *queue, bool drop) +{ + unsigned int i; + + for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) + msleep(10); +} +EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue); + +/* + * Device initialization handlers. + */ +static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue) +{ + struct queue_entry_priv_pci *entry_priv; + void *addr; + dma_addr_t dma; + unsigned int i; + + /* + * Allocate DMA memory for descriptor and buffer. + */ + addr = dma_alloc_coherent(rt2x00dev->dev, + queue->limit * queue->desc_size, + &dma, GFP_KERNEL); + if (!addr) + return -ENOMEM; + + memset(addr, 0, queue->limit * queue->desc_size); + + /* + * Initialize all queue entries to contain valid addresses. + */ + for (i = 0; i < queue->limit; i++) { + entry_priv = queue->entries[i].priv_data; + entry_priv->desc = addr + i * queue->desc_size; + entry_priv->desc_dma = dma + i * queue->desc_size; + } + + return 0; +} + +static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue) +{ + struct queue_entry_priv_pci *entry_priv = + queue->entries[0].priv_data; + + if (entry_priv->desc) + dma_free_coherent(rt2x00dev->dev, + queue->limit * queue->desc_size, + entry_priv->desc, entry_priv->desc_dma); + entry_priv->desc = NULL; +} + +int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + int status; + + /* + * Allocate DMA + */ + queue_for_each(rt2x00dev, queue) { + status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); + if (status) + goto exit; + } + + /* + * Register interrupt handler. + */ + status = request_irq(rt2x00dev->irq, + rt2x00dev->ops->lib->irq_handler, + IRQF_SHARED, rt2x00dev->name, rt2x00dev); + if (status) { + ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", + rt2x00dev->irq, status); + goto exit; + } + + return 0; + +exit: + queue_for_each(rt2x00dev, queue) + rt2x00pci_free_queue_dma(rt2x00dev, queue); + + return status; +} +EXPORT_SYMBOL_GPL(rt2x00pci_initialize); + +void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + + /* + * Free irq line. + */ + free_irq(rt2x00dev->irq, rt2x00dev); + + /* + * Free DMA + */ + queue_for_each(rt2x00dev, queue) + rt2x00pci_free_queue_dma(rt2x00dev, queue); +} +EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); + /* * PCI driver handlers. */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h index 60d90b20f8b9..e2c99f2b9a14 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -35,6 +35,94 @@ */ #define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops) +/* + * Register access. + */ +static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u32 *value) +{ + *value = readl(rt2x00dev->csr.base + offset); +} + +static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + void *value, const u32 length) +{ + memcpy_fromio(value, rt2x00dev->csr.base + offset, length); +} + +static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u32 value) +{ + writel(value, rt2x00dev->csr.base + offset); +} + +static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const void *value, + const u32 length) +{ + __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2); +} + +/** + * rt2x00pci_regbusy_read - Read from register with busy check + * @rt2x00dev: Device pointer, see &struct rt2x00_dev. + * @offset: Register offset + * @field: Field to check if register is busy + * @reg: Pointer to where register contents should be stored + * + * This function will read the given register, and checks if the + * register is busy. If it is, it will sleep for a couple of + * microseconds before reading the register again. If the register + * is not read after a certain timeout, this function will return + * FALSE. + */ +int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + const struct rt2x00_field32 field, + u32 *reg); + +/** + * struct queue_entry_priv_pci: Per entry PCI specific information + * + * @desc: Pointer to device descriptor + * @desc_dma: DMA pointer to &desc. + * @data: Pointer to device's entry memory. + * @data_dma: DMA pointer to &data. + */ +struct queue_entry_priv_pci { + __le32 *desc; + dma_addr_t desc_dma; +}; + +/** + * rt2x00pci_rxdone - Handle RX done events + * @rt2x00dev: Device pointer, see &struct rt2x00_dev. + * + * Returns true if there are still rx frames pending and false if all + * pending rx frames were processed. + */ +bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); + +/** + * rt2x00pci_flush_queue - Flush data queue + * @queue: Data queue to stop + * @drop: True to drop all pending frames. + * + * This will wait for a maximum of 100ms, waiting for the queues + * to become empty. + */ +void rt2x00pci_flush_queue(struct data_queue *queue, bool drop); + +/* + * Device initialization handlers. + */ +int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev); +void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev); + /* * PCI driver handlers. */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c index 9e3c8ff53e3f..f95792cfcf89 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c @@ -35,7 +35,6 @@ #include #include "rt2x00.h" -#include "rt2x00mmio.h" #include "rt2x00pci.h" #include "rt61pci.h" diff --git a/trunk/drivers/nfc/microread/mei.c b/trunk/drivers/nfc/microread/mei.c index ca33ae193935..eef38cfd812e 100644 --- a/trunk/drivers/nfc/microread/mei.c +++ b/trunk/drivers/nfc/microread/mei.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -32,6 +32,9 @@ #define MICROREAD_DRIVER_NAME "microread" +#define MICROREAD_UUID UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, 0x94, \ + 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c) + struct mei_nfc_hdr { u8 cmd; u8 status; @@ -45,7 +48,7 @@ struct mei_nfc_hdr { #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) struct microread_mei_phy { - struct mei_cl_device *device; + struct mei_device *mei_device; struct nfc_hci_dev *hdev; int powered; @@ -102,14 +105,14 @@ static int microread_mei_write(void *phy_id, struct sk_buff *skb) MEI_DUMP_SKB_OUT("mei frame sent", skb); - r = mei_cl_send(phy->device, skb->data, skb->len); + r = mei_send(phy->device, skb->data, skb->len); if (r > 0) r = 0; return r; } -static void microread_event_cb(struct mei_cl_device *device, u32 events, +static void microread_event_cb(struct mei_device *device, u32 events, void *context) { struct microread_mei_phy *phy = context; @@ -117,7 +120,7 @@ static void microread_event_cb(struct mei_cl_device *device, u32 events, if (phy->hard_fault != 0) return; - if (events & BIT(MEI_CL_EVENT_RX)) { + if (events & BIT(MEI_EVENT_RX)) { struct sk_buff *skb; int reply_size; @@ -125,7 +128,7 @@ static void microread_event_cb(struct mei_cl_device *device, u32 events, if (!skb) return; - reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); + reply_size = mei_recv(device, skb->data, MEI_NFC_MAX_READ); if (reply_size < MEI_NFC_HEADER_SIZE) { kfree(skb); return; @@ -146,8 +149,8 @@ static struct nfc_phy_ops mei_phy_ops = { .disable = microread_mei_disable, }; -static int microread_mei_probe(struct mei_cl_device *device, - const struct mei_cl_device_id *id) +static int microread_mei_probe(struct mei_device *device, + const struct mei_id *id) { struct microread_mei_phy *phy; int r; @@ -161,9 +164,9 @@ static int microread_mei_probe(struct mei_cl_device *device, } phy->device = device; - mei_cl_set_drvdata(device, phy); + mei_set_clientdata(device, phy); - r = mei_cl_register_event_cb(device, microread_event_cb, phy); + r = mei_register_event_cb(device, microread_event_cb, phy); if (r) { pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); goto err_out; @@ -183,9 +186,9 @@ static int microread_mei_probe(struct mei_cl_device *device, return r; } -static int microread_mei_remove(struct mei_cl_device *device) +static int microread_mei_remove(struct mei_device *device) { - struct microread_mei_phy *phy = mei_cl_get_drvdata(device); + struct microread_mei_phy *phy = mei_get_clientdata(device); pr_info("Removing microread\n"); @@ -199,15 +202,16 @@ static int microread_mei_remove(struct mei_cl_device *device) return 0; } -static struct mei_cl_device_id microread_mei_tbl[] = { - { MICROREAD_DRIVER_NAME }, +static struct mei_id microread_mei_tbl[] = { + { MICROREAD_DRIVER_NAME, MICROREAD_UUID }, /* required last entry */ { } }; + MODULE_DEVICE_TABLE(mei, microread_mei_tbl); -static struct mei_cl_driver microread_driver = { +static struct mei_driver microread_driver = { .id_table = microread_mei_tbl, .name = MICROREAD_DRIVER_NAME, @@ -221,7 +225,7 @@ static int microread_mei_init(void) pr_debug(DRIVER_DESC ": %s\n", __func__); - r = mei_cl_driver_register(µread_driver); + r = mei_driver_register(µread_driver); if (r) { pr_err(MICROREAD_DRIVER_NAME ": driver registration failed\n"); return r; @@ -232,7 +236,7 @@ static int microread_mei_init(void) static void microread_mei_exit(void) { - mei_cl_driver_unregister(µread_driver); + mei_driver_unregister(µread_driver); } module_init(microread_mei_init); diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index 748f8f3e9ff5..8647dc6f52d0 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -202,16 +202,20 @@ void pci_bus_add_devices(const struct pci_bus *bus) if (dev->is_added) continue; retval = pci_bus_add_device(dev); - if (retval) - dev_err(&dev->dev, "Error adding device (%d)\n", - retval); } list_for_each_entry(dev, &bus->devices, bus_list) { BUG_ON(!dev->is_added); + child = dev->subordinate; - if (child) - pci_bus_add_devices(child); + + if (!child) + continue; + pci_bus_add_devices(child); + + if (child->is_added) + continue; + child->is_added = 1; } } diff --git a/trunk/drivers/pci/hotplug/Kconfig b/trunk/drivers/pci/hotplug/Kconfig index 9fcb87f353d4..13e9e63a7266 100644 --- a/trunk/drivers/pci/hotplug/Kconfig +++ b/trunk/drivers/pci/hotplug/Kconfig @@ -52,12 +52,15 @@ config HOTPLUG_PCI_IBM When in doubt, say N. config HOTPLUG_PCI_ACPI - bool "ACPI PCI Hotplug driver" - depends on HOTPLUG_PCI=y && ((!ACPI_DOCK && ACPI) || (ACPI_DOCK)) + tristate "ACPI PCI Hotplug driver" + depends on (!ACPI_DOCK && ACPI) || (ACPI_DOCK) help Say Y here if you have a system that supports PCI Hotplug using ACPI. + To compile this driver as a module, choose M here: the + module will be called acpiphp. + When in doubt, say N. config HOTPLUG_PCI_ACPI_IBM diff --git a/trunk/drivers/pci/hotplug/acpiphp.h b/trunk/drivers/pci/hotplug/acpiphp.h index 6fdd49c6f0b9..b70ac00a117e 100644 --- a/trunk/drivers/pci/hotplug/acpiphp.h +++ b/trunk/drivers/pci/hotplug/acpiphp.h @@ -73,9 +73,8 @@ static inline const char *slot_name(struct slot *slot) */ struct acpiphp_bridge { struct list_head list; - struct list_head slots; - struct kref ref; acpi_handle handle; + struct acpiphp_slot *slots; /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ struct acpiphp_func *func; @@ -98,7 +97,7 @@ struct acpiphp_bridge { * PCI slot information for each *physical* PCI slot */ struct acpiphp_slot { - struct list_head node; + struct acpiphp_slot *next; struct acpiphp_bridge *bridge; /* parent */ struct list_head funcs; /* one slot may have different objects (i.e. for each function) */ @@ -120,6 +119,7 @@ struct acpiphp_slot { */ struct acpiphp_func { struct acpiphp_slot *slot; /* parent */ + struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ struct list_head sibling; struct notifier_block nb; @@ -146,6 +146,10 @@ struct acpiphp_attention_info #define ACPI_PCI_HOST_HID "PNP0A03" /* ACPI _STA method value (ignore bit 4; battery present) */ +#define ACPI_STA_PRESENT (0x00000001) +#define ACPI_STA_ENABLED (0x00000002) +#define ACPI_STA_SHOW_IN_UI (0x00000004) +#define ACPI_STA_FUNCTIONING (0x00000008) #define ACPI_STA_ALL (0x0000000f) /* bridge flags */ @@ -170,24 +174,25 @@ struct acpiphp_attention_info /* function prototypes */ /* acpiphp_core.c */ -int acpiphp_register_attention(struct acpiphp_attention_info*info); -int acpiphp_unregister_attention(struct acpiphp_attention_info *info); -int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); -void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); +extern int acpiphp_register_attention(struct acpiphp_attention_info*info); +extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info); +extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); +extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); /* acpiphp_glue.c */ +extern int acpiphp_glue_init (void); +extern void acpiphp_glue_exit (void); typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); -int acpiphp_enable_slot(struct acpiphp_slot *slot); -int acpiphp_disable_slot(struct acpiphp_slot *slot); -int acpiphp_eject_slot(struct acpiphp_slot *slot); -u8 acpiphp_get_power_status(struct acpiphp_slot *slot); -u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); -u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); -u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot); +extern int acpiphp_enable_slot (struct acpiphp_slot *slot); +extern int acpiphp_disable_slot (struct acpiphp_slot *slot); +extern int acpiphp_eject_slot (struct acpiphp_slot *slot); +extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot); +extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot); +extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); +extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); /* variables */ extern bool acpiphp_debug; -extern bool acpiphp_disabled; #endif /* _ACPIPHP_H */ diff --git a/trunk/drivers/pci/hotplug/acpiphp_core.c b/trunk/drivers/pci/hotplug/acpiphp_core.c index ca8127950fcd..c2fd3095701f 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_core.c +++ b/trunk/drivers/pci/hotplug/acpiphp_core.c @@ -37,7 +37,6 @@ #include #include -#include #include #include #include @@ -49,7 +48,6 @@ #define SLOT_NAME_SIZE 21 /* {_SUN} */ bool acpiphp_debug; -bool acpiphp_disabled; /* local variables */ static struct acpiphp_attention_info *attention_info; @@ -62,9 +60,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); -MODULE_PARM_DESC(disable, "disable acpiphp driver"); module_param_named(debug, acpiphp_debug, bool, 0644); -module_param_named(disable, acpiphp_disabled, bool, 0444); /* export the attention callback registration methods */ EXPORT_SYMBOL_GPL(acpiphp_register_attention); @@ -355,9 +351,27 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) } -void __init acpiphp_init(void) +static int __init acpiphp_init(void) { - info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", - acpiphp_disabled ? ", disabled by user; please report a bug" - : ""); + info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + + if (acpi_pci_disabled) + return 0; + + /* read all the ACPI info from the system */ + /* initialize internal data structure etc. */ + return acpiphp_glue_init(); +} + + +static void __exit acpiphp_exit(void) +{ + if (acpi_pci_disabled) + return; + + /* deallocate internal data structures etc. */ + acpiphp_glue_exit(); } + +module_init(acpiphp_init); +module_exit(acpiphp_exit); diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 96fed19c6d90..270fdbadc19c 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -54,7 +54,6 @@ #include "acpiphp.h" static LIST_HEAD(bridge_list); -static DEFINE_MUTEX(bridge_mutex); #define MY_NAME "acpiphp_glue" @@ -62,7 +61,6 @@ static void handle_hotplug_event_bridge (acpi_handle, u32, void *); static void acpiphp_sanitize_bus(struct pci_bus *bus); static void acpiphp_set_hpp_values(struct pci_bus *bus); static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); -static void free_bridge(struct kref *kref); /* callback routine to check for the existence of a pci dock device */ static acpi_status @@ -78,39 +76,6 @@ is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) } } -static inline void get_bridge(struct acpiphp_bridge *bridge) -{ - kref_get(&bridge->ref); -} - -static inline void put_bridge(struct acpiphp_bridge *bridge) -{ - kref_put(&bridge->ref, free_bridge); -} - -static void free_bridge(struct kref *kref) -{ - struct acpiphp_bridge *bridge; - struct acpiphp_slot *slot, *next; - struct acpiphp_func *func, *tmp; - - bridge = container_of(kref, struct acpiphp_bridge, ref); - - list_for_each_entry_safe(slot, next, &bridge->slots, node) { - list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { - kfree(func); - } - kfree(slot); - } - - /* Release reference acquired by acpiphp_bridge_handle_to_function() */ - if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) - put_bridge(bridge->func->slot->bridge); - put_device(&bridge->pci_bus->dev); - pci_dev_put(bridge->pci_dev); - kfree(bridge); -} - /* * the _DCK method can do funny things... and sometimes not * hah-hah funny. @@ -189,10 +154,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) acpi_handle tmp; acpi_status status = AE_OK; unsigned long long adr, sun; - int device, function, retval, found = 0; + int device, function, retval; struct pci_bus *pbus = bridge->pci_bus; struct pci_dev *pdev; - u32 val; if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) return AE_OK; @@ -206,7 +170,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) device = (adr >> 16) & 0xffff; function = adr & 0xffff; - pdev = bridge->pci_dev; + pdev = pbus->self; if (pdev && device_is_managed_by_native_pciehp(pdev)) return AE_OK; @@ -214,6 +178,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) if (!newfunc) return AE_NO_MEMORY; + INIT_LIST_HEAD(&newfunc->sibling); newfunc->handle = handle; newfunc->function = function; @@ -242,15 +207,14 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) } /* search for objects that share the same slot */ - list_for_each_entry(slot, &bridge->slots, node) + for (slot = bridge->slots; slot; slot = slot->next) if (slot->device == device) { if (slot->sun != sun) warn("sibling found, but _SUN doesn't match!\n"); - found = 1; break; } - if (!found) { + if (!slot) { slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); if (!slot) { kfree(newfunc); @@ -263,9 +227,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) INIT_LIST_HEAD(&slot->funcs); mutex_init(&slot->crit_sect); - mutex_lock(&bridge_mutex); - list_add_tail(&slot->node, &bridge->slots); - mutex_unlock(&bridge_mutex); + slot->next = bridge->slots; + bridge->slots = slot; + bridge->nr_slots++; dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", @@ -283,13 +247,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) } newfunc->slot = slot; - mutex_lock(&bridge_mutex); list_add_tail(&newfunc->sibling, &slot->funcs); - mutex_unlock(&bridge_mutex); - if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function), - &val, 60*1000)) + pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); + if (pdev) { slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); + pci_dev_put(pdev); + } if (is_dock_device(handle)) { /* we don't want to call this device's _EJ0 @@ -326,9 +290,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) err_exit: bridge->nr_slots--; - mutex_lock(&bridge_mutex); - list_del(&slot->node); - mutex_unlock(&bridge_mutex); + bridge->slots = slot->next; kfree(slot); kfree(newfunc); @@ -353,17 +315,13 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) acpi_status status; /* must be added to the list prior to calling register_slot */ - mutex_lock(&bridge_mutex); list_add(&bridge->list, &bridge_list); - mutex_unlock(&bridge_mutex); /* register all slot objects under this bridge */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, register_slot, NULL, bridge, NULL); if (ACPI_FAILURE(status)) { - mutex_lock(&bridge_mutex); list_del(&bridge->list); - mutex_unlock(&bridge_mutex); return; } @@ -393,46 +351,178 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle { struct acpiphp_bridge *bridge; struct acpiphp_slot *slot; - struct acpiphp_func *func = NULL; + struct acpiphp_func *func; - mutex_lock(&bridge_mutex); list_for_each_entry(bridge, &bridge_list, list) { - list_for_each_entry(slot, &bridge->slots, node) { + for (slot = bridge->slots; slot; slot = slot->next) { list_for_each_entry(func, &slot->funcs, sibling) { - if (func->handle == handle) { - get_bridge(func->slot->bridge); - mutex_unlock(&bridge_mutex); + if (func->handle == handle) return func; - } } } } - mutex_unlock(&bridge_mutex); return NULL; } +static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) +{ + acpi_handle dummy_handle; + struct acpiphp_func *func; + + if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, + "_EJ0", &dummy_handle))) { + bridge->flags |= BRIDGE_HAS_EJ0; + + dbg("found ejectable p2p bridge\n"); + + /* make link between PCI bridge and PCI function */ + func = acpiphp_bridge_handle_to_function(bridge->handle); + if (!func) + return; + bridge->func = func; + func->bridge = bridge; + } +} + + +/* allocate and initialize host bridge data structure */ +static void add_host_bridge(struct acpi_pci_root *root) +{ + struct acpiphp_bridge *bridge; + acpi_handle handle = root->device->handle; + + bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); + if (bridge == NULL) + return; + + bridge->handle = handle; + + bridge->pci_bus = root->bus; + + init_bridge_misc(bridge); +} + + +/* allocate and initialize PCI-to-PCI bridge data structure */ +static void add_p2p_bridge(acpi_handle *handle) +{ + struct acpiphp_bridge *bridge; + + bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); + if (bridge == NULL) { + err("out of memory\n"); + return; + } + + bridge->handle = handle; + config_p2p_bridge_flags(bridge); + + bridge->pci_dev = acpi_get_pci_dev(handle); + bridge->pci_bus = bridge->pci_dev->subordinate; + if (!bridge->pci_bus) { + err("This is not a PCI-to-PCI bridge!\n"); + goto err; + } + + /* + * Grab a ref to the subordinate PCI bus in case the bus is + * removed via PCI core logical hotplug. The ref pins the bus + * (which we access during module unload). + */ + get_device(&bridge->pci_bus->dev); + + init_bridge_misc(bridge); + return; + err: + pci_dev_put(bridge->pci_dev); + kfree(bridge); + return; +} + + +/* callback routine to find P2P bridges */ +static acpi_status +find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + acpi_status status; + struct pci_dev *dev; + + dev = acpi_get_pci_dev(handle); + if (!dev || !dev->subordinate) + goto out; + + /* check if this bridge has ejectable slots */ + if ((detect_ejectable_slots(handle) > 0)) { + dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); + add_p2p_bridge(handle); + } + + /* search P2P bridges under this p2p bridge */ + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + find_p2p_bridge, NULL, NULL, NULL); + if (ACPI_FAILURE(status)) + warn("find_p2p_bridge failed (error code = 0x%x)\n", status); + + out: + pci_dev_put(dev); + return AE_OK; +} + + +/* find hot-pluggable slots, and then find P2P bridge */ +static int add_bridge(struct acpi_pci_root *root) +{ + acpi_status status; + unsigned long long tmp; + acpi_handle dummy_handle; + acpi_handle handle = root->device->handle; + + /* if the bridge doesn't have _STA, we assume it is always there */ + status = acpi_get_handle(handle, "_STA", &dummy_handle); + if (ACPI_SUCCESS(status)) { + status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp); + if (ACPI_FAILURE(status)) { + dbg("%s: _STA evaluation failure\n", __func__); + return 0; + } + if ((tmp & ACPI_STA_FUNCTIONING) == 0) + /* don't register this object */ + return 0; + } + + /* check if this bridge has ejectable slots */ + if (detect_ejectable_slots(handle) > 0) { + dbg("found PCI host-bus bridge with hot-pluggable slots\n"); + add_host_bridge(root); + } + + /* search P2P bridges under this host bridge */ + status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + find_p2p_bridge, NULL, NULL, NULL); + + if (ACPI_FAILURE(status)) + warn("find_p2p_bridge failed (error code = 0x%x)\n", status); + + return 0; +} + static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) { struct acpiphp_bridge *bridge; - mutex_lock(&bridge_mutex); list_for_each_entry(bridge, &bridge_list, list) - if (bridge->handle == handle) { - get_bridge(bridge); - mutex_unlock(&bridge_mutex); + if (bridge->handle == handle) return bridge; - } - mutex_unlock(&bridge_mutex); return NULL; } static void cleanup_bridge(struct acpiphp_bridge *bridge) { - struct acpiphp_slot *slot; - struct acpiphp_func *func; + struct acpiphp_slot *slot, *next; + struct acpiphp_func *func, *tmp; acpi_status status; acpi_handle handle = bridge->handle; @@ -453,8 +543,10 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) err("failed to install interrupt notify handler\n"); } - list_for_each_entry(slot, &bridge->slots, node) { - list_for_each_entry(func, &slot->funcs, sibling) { + slot = bridge->slots; + while (slot) { + next = slot->next; + list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { if (is_dock_device(func->handle)) { unregister_hotplug_dock_device(func->handle); unregister_dock_notifier(&func->nb); @@ -466,13 +558,63 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) if (ACPI_FAILURE(status)) err("failed to remove notify handler\n"); } + list_del(&func->sibling); + kfree(func); } acpiphp_unregister_hotplug_slot(slot); + list_del(&slot->funcs); + kfree(slot); + slot = next; } - mutex_lock(&bridge_mutex); + /* + * Only P2P bridges have a pci_dev + */ + if (bridge->pci_dev) + put_device(&bridge->pci_bus->dev); + + pci_dev_put(bridge->pci_dev); list_del(&bridge->list); - mutex_unlock(&bridge_mutex); + kfree(bridge); +} + +static acpi_status +cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + struct acpiphp_bridge *bridge; + + /* cleanup p2p bridges under this P2P bridge + in a depth-first manner */ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, + cleanup_p2p_bridge, NULL, NULL, NULL); + + bridge = acpiphp_handle_to_bridge(handle); + if (bridge) + cleanup_bridge(bridge); + + return AE_OK; +} + +static void remove_bridge(struct acpi_pci_root *root) +{ + struct acpiphp_bridge *bridge; + acpi_handle handle = root->device->handle; + + /* cleanup p2p bridges under this host bridge + in a depth-first manner */ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + (u32)1, cleanup_p2p_bridge, NULL, NULL, NULL); + + /* + * On root bridges with hotplug slots directly underneath (ie, + * no p2p bridge between), we call cleanup_bridge(). + * + * The else clause cleans up root bridges that either had no + * hotplug slots at all, or had a p2p bridge underneath. + */ + bridge = acpiphp_handle_to_bridge(handle); + if (bridge) + cleanup_bridge(bridge); } static int power_on_slot(struct acpiphp_slot *slot) @@ -656,7 +798,6 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) } } } - /** * enable_device - enable, configure a slot * @slot: slot to be enabled @@ -669,7 +810,9 @@ static int __ref enable_device(struct acpiphp_slot *slot) struct pci_dev *dev; struct pci_bus *bus = slot->bridge->pci_bus; struct acpiphp_func *func; + int retval = 0; int num, max, pass; + acpi_status status; if (slot->flags & SLOT_ENABLED) goto err_exit; @@ -724,11 +867,23 @@ static int __ref enable_device(struct acpiphp_slot *slot) slot->flags &= (~SLOT_ENABLED); continue; } + + if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && + dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { + pci_dev_put(dev); + continue; + } + + status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); + if (ACPI_FAILURE(status)) + warn("find_p2p_bridge failed (error code = 0x%x)\n", + status); + pci_dev_put(dev); } err_exit: - return 0; + return retval; } /* return first device in slot, acquiring a reference on it */ @@ -757,6 +912,23 @@ static int disable_device(struct acpiphp_slot *slot) { struct acpiphp_func *func; struct pci_dev *pdev; + struct pci_bus *bus = slot->bridge->pci_bus; + + /* The slot will be enabled when func 0 is added, so check + func 0 before disable the slot. */ + pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); + if (!pdev) + goto err_exit; + pci_dev_put(pdev); + + list_for_each_entry(func, &slot->funcs, sibling) { + if (func->bridge) { + /* cleanup p2p bridges under this P2P bridge */ + cleanup_p2p_bridge(func->bridge->handle, + (u32)1, NULL, NULL); + func->bridge = NULL; + } + } /* * enable_device() enumerates all functions in this device via @@ -775,6 +947,7 @@ static int disable_device(struct acpiphp_slot *slot) slot->flags &= (~SLOT_ENABLED); +err_exit: return 0; } @@ -864,7 +1037,7 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) enabled = disabled = 0; - list_for_each_entry(slot, &bridge->slots, node) { + for (slot = bridge->slots; slot; slot = slot->next) { unsigned int status = get_slot_status(slot); if (slot->flags & SLOT_ENABLED) { if (status == ACPI_STA_ALL) @@ -909,11 +1082,11 @@ static void acpiphp_set_hpp_values(struct pci_bus *bus) */ static void acpiphp_sanitize_bus(struct pci_bus *bus) { - struct pci_dev *dev, *tmp; + struct pci_dev *dev; int i; unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; - list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { + list_for_each_entry(dev, &bus->devices, bus_list) { for (i=0; iresource[i]; if ((res->flags & type_mask) && !res->start && @@ -945,7 +1118,6 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) dbg("%s: re-enumerating slots under %s\n", __func__, objname); acpiphp_check_bridge(bridge); - put_bridge(bridge); } return AE_OK ; } @@ -1023,7 +1195,6 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ - put_bridge(bridge); } /** @@ -1037,8 +1208,6 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *context) { - struct acpiphp_bridge *bridge = context; - /* * Currently the code adds all hotplug events to the kacpid_wq * queue when it should add hotplug events to the kacpi_hotplug_wq. @@ -1047,7 +1216,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, * For now just re-add this work to the kacpi_hotplug_wq so we * don't deadlock on hotplug actions. */ - get_bridge(bridge); alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); } @@ -1102,7 +1270,6 @@ static void _handle_hotplug_event_func(struct work_struct *work) acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_func */ - put_bridge(func->slot->bridge); } /** @@ -1116,8 +1283,6 @@ static void _handle_hotplug_event_func(struct work_struct *work) static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context) { - struct acpiphp_func *func = context; - /* * Currently the code adds all hotplug events to the kacpid_wq * queue when it should add hotplug events to the kacpi_hotplug_wq. @@ -1126,69 +1291,33 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, * For now just re-add this work to the kacpi_hotplug_wq so we * don't deadlock on hotplug actions. */ - get_bridge(func->slot->bridge); alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); } -/* - * Create hotplug slots for the PCI bus. - * It should always return 0 to avoid skipping following notifiers. +static struct acpi_pci_driver acpi_pci_hp_driver = { + .add = add_bridge, + .remove = remove_bridge, +}; + +/** + * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures */ -void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) +int __init acpiphp_glue_init(void) { - acpi_handle dummy_handle; - struct acpiphp_bridge *bridge; - - if (acpiphp_disabled) - return; - - if (detect_ejectable_slots(handle) <= 0) - return; - - bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); - if (bridge == NULL) { - err("out of memory\n"); - return; - } - - INIT_LIST_HEAD(&bridge->slots); - kref_init(&bridge->ref); - bridge->handle = handle; - bridge->pci_dev = pci_dev_get(bus->self); - bridge->pci_bus = bus; + acpi_pci_register_driver(&acpi_pci_hp_driver); - /* - * Grab a ref to the subordinate PCI bus in case the bus is - * removed via PCI core logical hotplug. The ref pins the bus - * (which we access during module unload). - */ - get_device(&bus->dev); - - if (!pci_is_root_bus(bridge->pci_bus) && - ACPI_SUCCESS(acpi_get_handle(bridge->handle, - "_EJ0", &dummy_handle))) { - dbg("found ejectable p2p bridge\n"); - bridge->flags |= BRIDGE_HAS_EJ0; - bridge->func = acpiphp_bridge_handle_to_function(handle); - } - - init_bridge_misc(bridge); + return 0; } -/* Destroy hotplug slots associated with the PCI bus */ -void acpiphp_remove_slots(struct pci_bus *bus) -{ - struct acpiphp_bridge *bridge, *tmp; - - if (acpiphp_disabled) - return; - list_for_each_entry_safe(bridge, tmp, &bridge_list, list) - if (bridge->pci_bus == bus) { - cleanup_bridge(bridge); - put_bridge(bridge); - break; - } +/** + * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures + * + * This function frees all data allocated in acpiphp_glue_init(). + */ +void acpiphp_glue_exit(void) +{ + acpi_pci_unregister_driver(&acpi_pci_hp_driver); } /** @@ -1267,7 +1396,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) sta = get_slot_status(slot); - return (sta & ACPI_STA_DEVICE_UI) ? 0 : 1; + return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; } diff --git a/trunk/drivers/pci/hotplug/cpci_hotplug.h b/trunk/drivers/pci/hotplug/cpci_hotplug.h index 1356211431d0..9fff878cf026 100644 --- a/trunk/drivers/pci/hotplug/cpci_hotplug.h +++ b/trunk/drivers/pci/hotplug/cpci_hotplug.h @@ -75,36 +75,28 @@ static inline const char *slot_name(struct slot *slot) return hotplug_slot_name(slot->hotplug_slot); } -int cpci_hp_register_controller(struct cpci_hp_controller *controller); -int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); -int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); -int cpci_hp_unregister_bus(struct pci_bus *bus); -int cpci_hp_start(void); -int cpci_hp_stop(void); +extern int cpci_hp_register_controller(struct cpci_hp_controller *controller); +extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); +extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); +extern int cpci_hp_unregister_bus(struct pci_bus *bus); +extern int cpci_hp_start(void); +extern int cpci_hp_stop(void); /* * Internal function prototypes, these functions should not be used by * board/chassis drivers. */ -u8 cpci_get_attention_status(struct slot *slot); -u8 cpci_get_latch_status(struct slot *slot); -u8 cpci_get_adapter_status(struct slot *slot); -u16 cpci_get_hs_csr(struct slot * slot); -int cpci_set_attention_status(struct slot *slot, int status); -int cpci_check_and_clear_ins(struct slot * slot); -int cpci_check_ext(struct slot * slot); -int cpci_clear_ext(struct slot * slot); -int cpci_led_on(struct slot * slot); -int cpci_led_off(struct slot * slot); -int cpci_configure_slot(struct slot *slot); -int cpci_unconfigure_slot(struct slot *slot); - -#ifdef CONFIG_HOTPLUG_PCI_CPCI -int cpci_hotplug_init(int debug); -void cpci_hotplug_exit(void); -#else -static inline int cpci_hotplug_init(int debug) { return 0; } -static inline void cpci_hotplug_exit(void) { } -#endif +extern u8 cpci_get_attention_status(struct slot *slot); +extern u8 cpci_get_latch_status(struct slot *slot); +extern u8 cpci_get_adapter_status(struct slot *slot); +extern u16 cpci_get_hs_csr(struct slot * slot); +extern int cpci_set_attention_status(struct slot *slot, int status); +extern int cpci_check_and_clear_ins(struct slot * slot); +extern int cpci_check_ext(struct slot * slot); +extern int cpci_clear_ext(struct slot * slot); +extern int cpci_led_on(struct slot * slot); +extern int cpci_led_off(struct slot * slot); +extern int cpci_configure_slot(struct slot *slot); +extern int cpci_unconfigure_slot(struct slot *slot); #endif /* _CPCI_HOTPLUG_H */ diff --git a/trunk/drivers/pci/hotplug/cpqphp.h b/trunk/drivers/pci/hotplug/cpqphp.h index 516b87738b6e..d8ffc7366801 100644 --- a/trunk/drivers/pci/hotplug/cpqphp.h +++ b/trunk/drivers/pci/hotplug/cpqphp.h @@ -404,44 +404,50 @@ struct resource_lists { /* debugfs functions for the hotplug controller info */ -void cpqhp_initialize_debugfs(void); -void cpqhp_shutdown_debugfs(void); -void cpqhp_create_debugfs_files(struct controller *ctrl); -void cpqhp_remove_debugfs_files(struct controller *ctrl); +extern void cpqhp_initialize_debugfs(void); +extern void cpqhp_shutdown_debugfs(void); +extern void cpqhp_create_debugfs_files(struct controller *ctrl); +extern void cpqhp_remove_debugfs_files(struct controller *ctrl); /* controller functions */ -void cpqhp_pushbutton_thread(unsigned long event_pointer); -irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); -int cpqhp_find_available_resources(struct controller *ctrl, - void __iomem *rom_start); -int cpqhp_event_start_thread(void); -void cpqhp_event_stop_thread(void); -struct pci_func *cpqhp_slot_create(unsigned char busnumber); -struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, - unsigned char index); -int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); -int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); -int cpqhp_hardware_test(struct controller *ctrl, int test_num); +extern void cpqhp_pushbutton_thread(unsigned long event_pointer); +extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); +extern int cpqhp_find_available_resources(struct controller *ctrl, + void __iomem *rom_start); +extern int cpqhp_event_start_thread(void); +extern void cpqhp_event_stop_thread(void); +extern struct pci_func *cpqhp_slot_create(unsigned char busnumber); +extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, + unsigned char index); +extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); +extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); +extern int cpqhp_hardware_test(struct controller *ctrl, int test_num); /* resource functions */ -int cpqhp_resource_sort_and_combine (struct pci_resource **head); +extern int cpqhp_resource_sort_and_combine (struct pci_resource **head); /* pci functions */ -int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); -int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, - u8 slot); -int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug); -int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func); -int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func); -int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func); -int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot); -int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); -void cpqhp_destroy_board_resources(struct pci_func *func); -int cpqhp_return_board_resources(struct pci_func *func, - struct resource_lists *resources); -void cpqhp_destroy_resource_list(struct resource_lists *resources); -int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func); -int cpqhp_unconfigure_device(struct pci_func *func); +extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); +extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, + u8 slot); +extern int cpqhp_save_config(struct controller *ctrl, int busnumber, + int is_hot_plug); +extern int cpqhp_save_base_addr_length(struct controller *ctrl, + struct pci_func *func); +extern int cpqhp_save_used_resources(struct controller *ctrl, + struct pci_func *func); +extern int cpqhp_configure_board(struct controller *ctrl, + struct pci_func *func); +extern int cpqhp_save_slot_config(struct controller *ctrl, + struct pci_func *new_slot); +extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); +extern void cpqhp_destroy_board_resources(struct pci_func *func); +extern int cpqhp_return_board_resources (struct pci_func *func, + struct resource_lists *resources); +extern void cpqhp_destroy_resource_list(struct resource_lists *resources); +extern int cpqhp_configure_device(struct controller *ctrl, + struct pci_func *func); +extern int cpqhp_unconfigure_device(struct pci_func *func); /* Global variables */ extern int cpqhp_debug; diff --git a/trunk/drivers/pci/hotplug/cpqphp_nvram.h b/trunk/drivers/pci/hotplug/cpqphp_nvram.h index 34e4e54fcf15..e89c0702119d 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_nvram.h +++ b/trunk/drivers/pci/hotplug/cpqphp_nvram.h @@ -30,26 +30,26 @@ #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM -static inline void compaq_nvram_init(void __iomem *rom_start) +static inline void compaq_nvram_init (void __iomem *rom_start) { return; } -static inline int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) +static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) { return 0; } -static inline int compaq_nvram_store(void __iomem *rom_start) +static inline int compaq_nvram_store (void __iomem *rom_start) { return 0; } #else -void compaq_nvram_init(void __iomem *rom_start); -int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl); -int compaq_nvram_store(void __iomem *rom_start); +extern void compaq_nvram_init (void __iomem *rom_start); +extern int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl); +extern int compaq_nvram_store (void __iomem *rom_start); #endif diff --git a/trunk/drivers/pci/hotplug/ibmphp.h b/trunk/drivers/pci/hotplug/ibmphp.h index 8c5b25871d02..a8d391a4957d 100644 --- a/trunk/drivers/pci/hotplug/ibmphp.h +++ b/trunk/drivers/pci/hotplug/ibmphp.h @@ -275,17 +275,17 @@ extern struct list_head ibmphp_slot_head; * FUNCTION PROTOTYPES * ***********************************************************/ -void ibmphp_free_ebda_hpc_queue(void); -int ibmphp_access_ebda(void); -struct slot *ibmphp_get_slot_from_physical_num(u8); -int ibmphp_get_total_hp_slots(void); -void ibmphp_free_ibm_slot(struct slot *); -void ibmphp_free_bus_info_queue(void); -void ibmphp_free_ebda_pci_rsrc_queue(void); -struct bus_info *ibmphp_find_same_bus_num(u32); -int ibmphp_get_bus_index(u8); -u16 ibmphp_get_total_controllers(void); -int ibmphp_register_pci(void); +extern void ibmphp_free_ebda_hpc_queue (void); +extern int ibmphp_access_ebda (void); +extern struct slot *ibmphp_get_slot_from_physical_num (u8); +extern int ibmphp_get_total_hp_slots (void); +extern void ibmphp_free_ibm_slot (struct slot *); +extern void ibmphp_free_bus_info_queue (void); +extern void ibmphp_free_ebda_pci_rsrc_queue (void); +extern struct bus_info *ibmphp_find_same_bus_num (u32); +extern int ibmphp_get_bus_index (u8); +extern u16 ibmphp_get_total_controllers (void); +extern int ibmphp_register_pci (void); /* passed parameters */ #define MEM 0 @@ -381,24 +381,24 @@ struct res_needed { /* functions */ -int ibmphp_rsrc_init(void); -int ibmphp_add_resource(struct resource_node *); -int ibmphp_remove_resource(struct resource_node *); -int ibmphp_find_resource(struct bus_node *, u32, struct resource_node **, int); -int ibmphp_check_resource(struct resource_node *, u8); -int ibmphp_remove_bus(struct bus_node *, u8); -void ibmphp_free_resources(void); -int ibmphp_add_pfmem_from_mem(struct resource_node *); -struct bus_node *ibmphp_find_res_bus(u8); -void ibmphp_print_test(void); /* for debugging purposes */ +extern int ibmphp_rsrc_init (void); +extern int ibmphp_add_resource (struct resource_node *); +extern int ibmphp_remove_resource (struct resource_node *); +extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int); +extern int ibmphp_check_resource (struct resource_node *, u8); +extern int ibmphp_remove_bus (struct bus_node *, u8); +extern void ibmphp_free_resources (void); +extern int ibmphp_add_pfmem_from_mem (struct resource_node *); +extern struct bus_node *ibmphp_find_res_bus (u8); +extern void ibmphp_print_test (void); /* for debugging purposes */ -void ibmphp_hpc_initvars(void); -int ibmphp_hpc_readslot(struct slot *, u8, u8 *); -int ibmphp_hpc_writeslot(struct slot *, u8); -void ibmphp_lock_operations(void); -void ibmphp_unlock_operations(void); -int ibmphp_hpc_start_poll_thread(void); -void ibmphp_hpc_stop_poll_thread(void); +extern void ibmphp_hpc_initvars (void); +extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *); +extern int ibmphp_hpc_writeslot (struct slot *, u8); +extern void ibmphp_lock_operations (void); +extern void ibmphp_unlock_operations (void); +extern int ibmphp_hpc_start_poll_thread (void); +extern void ibmphp_hpc_stop_poll_thread (void); //---------------------------------------------------------------------------- @@ -749,11 +749,11 @@ struct controller { /* Functions */ -int ibmphp_init_devno(struct slot **); /* This function is called from EBDA, so we need it not be static */ -int ibmphp_do_disable_slot(struct slot *slot_cur); -int ibmphp_update_slot_info(struct slot *); /* This function is called from HPC, so we need it to not be be static */ -int ibmphp_configure_card(struct pci_func *, u8); -int ibmphp_unconfigure_card(struct slot **, int); +extern int ibmphp_init_devno (struct slot **); /* This function is called from EBDA, so we need it not be static */ +extern int ibmphp_do_disable_slot (struct slot *slot_cur); +extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */ +extern int ibmphp_configure_card (struct pci_func *, u8); +extern int ibmphp_unconfigure_card (struct slot **, int); extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; #endif //__IBMPHP_H diff --git a/trunk/drivers/pci/hotplug/pci_hotplug_core.c b/trunk/drivers/pci/hotplug/pci_hotplug_core.c index ec20f74c8981..202f4a969eb5 100644 --- a/trunk/drivers/pci/hotplug/pci_hotplug_core.c +++ b/trunk/drivers/pci/hotplug/pci_hotplug_core.c @@ -41,7 +41,6 @@ #include #include #include "../pci.h" -#include "cpci_hotplug.h" #define MY_NAME "pci_hotplug" @@ -64,6 +63,14 @@ static bool debug; static LIST_HEAD(pci_hotplug_slot_list); static DEFINE_MUTEX(pci_hp_mutex); +#ifdef CONFIG_HOTPLUG_PCI_CPCI +extern int cpci_hotplug_init(int debug); +extern void cpci_hotplug_exit(void); +#else +static inline int cpci_hotplug_init(int debug) { return 0; } +static inline void cpci_hotplug_exit(void) { } +#endif + /* Weee, fun with macros... */ #define GET_STATUS(name,type) \ static int get_##name (struct hotplug_slot *slot, type *value) \ @@ -517,11 +524,13 @@ int pci_hp_deregister(struct hotplug_slot *hotplug) * * Returns 0 if successful, anything else for an error. */ -int pci_hp_change_slot_info(struct hotplug_slot *hotplug, - struct hotplug_slot_info *info) +int __must_check pci_hp_change_slot_info(struct hotplug_slot *hotplug, + struct hotplug_slot_info *info) { + struct pci_slot *slot; if (!hotplug || !info) return -ENODEV; + slot = hotplug->pci_slot; memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 7fb326983ed6..2c113de94323 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -127,15 +127,15 @@ struct controller { #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) #define PSN(ctrl) ((ctrl)->slot_cap >> 19) -int pciehp_sysfs_enable_slot(struct slot *slot); -int pciehp_sysfs_disable_slot(struct slot *slot); -u8 pciehp_handle_attention_button(struct slot *p_slot); -u8 pciehp_handle_switch_change(struct slot *p_slot); -u8 pciehp_handle_presence_change(struct slot *p_slot); -u8 pciehp_handle_power_fault(struct slot *p_slot); -int pciehp_configure_device(struct slot *p_slot); -int pciehp_unconfigure_device(struct slot *p_slot); -void pciehp_queue_pushbutton_work(struct work_struct *work); +extern int pciehp_sysfs_enable_slot(struct slot *slot); +extern int pciehp_sysfs_disable_slot(struct slot *slot); +extern u8 pciehp_handle_attention_button(struct slot *p_slot); +extern u8 pciehp_handle_switch_change(struct slot *p_slot); +extern u8 pciehp_handle_presence_change(struct slot *p_slot); +extern u8 pciehp_handle_power_fault(struct slot *p_slot); +extern int pciehp_configure_device(struct slot *p_slot); +extern int pciehp_unconfigure_device(struct slot *p_slot); +extern void pciehp_queue_pushbutton_work(struct work_struct *work); struct controller *pcie_init(struct pcie_device *dev); int pcie_init_notification(struct controller *ctrl); int pciehp_enable_slot(struct slot *p_slot); @@ -166,8 +166,8 @@ static inline const char *slot_name(struct slot *slot) #include #include -void __init pciehp_acpi_slot_detection_init(void); -int pciehp_acpi_slot_detection_check(struct pci_dev *dev); +extern void __init pciehp_acpi_slot_detection_init(void); +extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); static inline void pciehp_firmware_init(void) { diff --git a/trunk/drivers/pci/hotplug/pciehp_acpi.c b/trunk/drivers/pci/hotplug/pciehp_acpi.c index ead7c534095e..24d709b7388c 100644 --- a/trunk/drivers/pci/hotplug/pciehp_acpi.c +++ b/trunk/drivers/pci/hotplug/pciehp_acpi.c @@ -90,7 +90,7 @@ static int __init dummy_probe(struct pcie_device *dev) slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) return -ENOMEM; - slot->number = (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19; + slot->number = slot_cap >> 19; list_for_each_entry(tmp, &dummy_slots, list) { if (tmp->number == slot->number) dup_slot_id++; diff --git a/trunk/drivers/pci/hotplug/rpadlpar.h b/trunk/drivers/pci/hotplug/rpadlpar.h index 81df93931ad0..4a0a59b82eae 100644 --- a/trunk/drivers/pci/hotplug/rpadlpar.h +++ b/trunk/drivers/pci/hotplug/rpadlpar.h @@ -15,10 +15,10 @@ #ifndef _RPADLPAR_IO_H_ #define _RPADLPAR_IO_H_ -int dlpar_sysfs_init(void); -void dlpar_sysfs_exit(void); +extern int dlpar_sysfs_init(void); +extern void dlpar_sysfs_exit(void); -int dlpar_add_slot(char *drc_name); -int dlpar_remove_slot(char *drc_name); +extern int dlpar_add_slot(char *drc_name); +extern int dlpar_remove_slot(char *drc_name); #endif diff --git a/trunk/drivers/pci/hotplug/rpaphp.h b/trunk/drivers/pci/hotplug/rpaphp.h index 3135856e5e1c..df5677440a08 100644 --- a/trunk/drivers/pci/hotplug/rpaphp.h +++ b/trunk/drivers/pci/hotplug/rpaphp.h @@ -86,18 +86,18 @@ extern struct list_head rpaphp_slot_head; /* function prototypes */ /* rpaphp_pci.c */ -int rpaphp_enable_slot(struct slot *slot); -int rpaphp_get_sensor_state(struct slot *slot, int *state); +extern int rpaphp_enable_slot(struct slot *slot); +extern int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ -int rpaphp_add_slot(struct device_node *dn); -int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, +extern int rpaphp_add_slot(struct device_node *dn); +extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, char **drc_name, char **drc_type, int *drc_power_domain); /* rpaphp_slot.c */ -void dealloc_slot_struct(struct slot *slot); -struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); -int rpaphp_register_slot(struct slot *slot); -int rpaphp_deregister_slot(struct slot *slot); +extern void dealloc_slot_struct(struct slot *slot); +extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); +extern int rpaphp_register_slot(struct slot *slot); +extern int rpaphp_deregister_slot(struct slot *slot); #endif /* _PPC64PHP_H */ diff --git a/trunk/drivers/pci/hotplug/s390_pci_hpc.c b/trunk/drivers/pci/hotplug/s390_pci_hpc.c index 46a7b738f61f..7db249a25016 100644 --- a/trunk/drivers/pci/hotplug/s390_pci_hpc.c +++ b/trunk/drivers/pci/hotplug/s390_pci_hpc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #define SLOT_NAME_SIZE 10 @@ -50,7 +49,6 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) return -EIO; rc = sclp_pci_configure(slot->zdev->fid); - zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, rc); if (!rc) { slot->zdev->state = ZPCI_FN_STATE_CONFIGURED; /* automatically scan the device after is was configured */ @@ -68,16 +66,16 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) if (!zpci_fn_configured(slot->zdev->state)) return -EIO; - rc = zpci_disable_device(slot->zdev); - if (rc) - return rc; /* TODO: we rely on the user to unbind/remove the device, is that plausible * or do we need to trigger that here? */ rc = sclp_pci_deconfigure(slot->zdev->fid); - zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, rc); - if (!rc) + if (!rc) { + /* Fixme: better call List-PCI to find the disabled FH + for the FID since the FH should be opaque... */ + slot->zdev->fh &= 0x7fffffff; slot->zdev->state = ZPCI_FN_STATE_STANDBY; + } return rc; } diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index e260f207a90e..b849f995075a 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -168,19 +168,19 @@ struct controller { #define WRONG_BUS_FREQUENCY 0x0000000D #define POWER_FAILURE 0x0000000E -int __must_check shpchp_create_ctrl_files(struct controller *ctrl); -void shpchp_remove_ctrl_files(struct controller *ctrl); -int shpchp_sysfs_enable_slot(struct slot *slot); -int shpchp_sysfs_disable_slot(struct slot *slot); -u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); -u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); -u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); -u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); -int shpchp_configure_device(struct slot *p_slot); -int shpchp_unconfigure_device(struct slot *p_slot); -void cleanup_slots(struct controller *ctrl); -void shpchp_queue_pushbutton_work(struct work_struct *work); -int shpc_init( struct controller *ctrl, struct pci_dev *pdev); +extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); +extern void shpchp_remove_ctrl_files(struct controller *ctrl); +extern int shpchp_sysfs_enable_slot(struct slot *slot); +extern int shpchp_sysfs_disable_slot(struct slot *slot); +extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); +extern int shpchp_configure_device(struct slot *p_slot); +extern int shpchp_unconfigure_device(struct slot *p_slot); +extern void cleanup_slots(struct controller *ctrl); +extern void shpchp_queue_pushbutton_work(struct work_struct *work); +extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); static inline const char *slot_name(struct slot *slot) { diff --git a/trunk/drivers/pci/hotplug/shpchp_sysfs.c b/trunk/drivers/pci/hotplug/shpchp_sysfs.c index e8c31fe20566..eeb23ceae4a8 100644 --- a/trunk/drivers/pci/hotplug/shpchp_sysfs.c +++ b/trunk/drivers/pci/hotplug/shpchp_sysfs.c @@ -85,7 +85,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); -int shpchp_create_ctrl_files (struct controller *ctrl) +int __must_check shpchp_create_ctrl_files (struct controller *ctrl) { return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); } diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index d40bed726769..00cc78c7aa04 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -22,12 +22,10 @@ #include #include "pci.h" +#include "msi.h" static int pci_msi_enable = 1; -#define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) - - /* Arch hooks */ #ifndef arch_msi_check_device @@ -113,26 +111,32 @@ void default_restore_msi_irqs(struct pci_dev *dev, int irq) } #endif -static void msi_set_enable(struct pci_dev *dev, int enable) +static void msi_set_enable(struct pci_dev *dev, int pos, int enable) { u16 control; - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); + BUG_ON(!pos); + + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); control &= ~PCI_MSI_FLAGS_ENABLE; if (enable) control |= PCI_MSI_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); } static void msix_set_enable(struct pci_dev *dev, int enable) { + int pos; u16 control; - pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); - control &= ~PCI_MSIX_FLAGS_ENABLE; - if (enable) - control |= PCI_MSIX_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + if (pos) { + pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); + control &= ~PCI_MSIX_FLAGS_ENABLE; + if (enable) + control |= PCI_MSIX_FLAGS_ENABLE; + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); + } } static inline __attribute_const__ u32 msi_mask(unsigned x) @@ -243,18 +247,18 @@ void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) msg->data = readl(base + PCI_MSIX_ENTRY_DATA); } else { struct pci_dev *dev = entry->dev; - int pos = dev->msi_cap; + int pos = entry->msi_attrib.pos; u16 data; - pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, - &msg->address_lo); + pci_read_config_dword(dev, msi_lower_address_reg(pos), + &msg->address_lo); if (entry->msi_attrib.is_64) { - pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, - &msg->address_hi); - pci_read_config_word(dev, pos + PCI_MSI_DATA_64, &data); + pci_read_config_dword(dev, msi_upper_address_reg(pos), + &msg->address_hi); + pci_read_config_word(dev, msi_data_reg(pos, 1), &data); } else { msg->address_hi = 0; - pci_read_config_word(dev, pos + PCI_MSI_DATA_32, &data); + pci_read_config_word(dev, msi_data_reg(pos, 0), &data); } msg->data = data; } @@ -298,24 +302,24 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) writel(msg->data, base + PCI_MSIX_ENTRY_DATA); } else { struct pci_dev *dev = entry->dev; - int pos = dev->msi_cap; + int pos = entry->msi_attrib.pos; u16 msgctl; - pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); + pci_read_config_word(dev, msi_control_reg(pos), &msgctl); msgctl &= ~PCI_MSI_FLAGS_QSIZE; msgctl |= entry->msi_attrib.multiple << 4; - pci_write_config_word(dev, pos + PCI_MSI_FLAGS, msgctl); + pci_write_config_word(dev, msi_control_reg(pos), msgctl); - pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, - msg->address_lo); + pci_write_config_dword(dev, msi_lower_address_reg(pos), + msg->address_lo); if (entry->msi_attrib.is_64) { - pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, - msg->address_hi); - pci_write_config_word(dev, pos + PCI_MSI_DATA_64, - msg->data); + pci_write_config_dword(dev, msi_upper_address_reg(pos), + msg->address_hi); + pci_write_config_word(dev, msi_data_reg(pos, 1), + msg->data); } else { - pci_write_config_word(dev, pos + PCI_MSI_DATA_32, - msg->data); + pci_write_config_word(dev, msi_data_reg(pos, 0), + msg->data); } } entry->msg = *msg; @@ -387,6 +391,7 @@ static void pci_intx_for_msi(struct pci_dev *dev, int enable) static void __pci_restore_msi_state(struct pci_dev *dev) { + int pos; u16 control; struct msi_desc *entry; @@ -394,20 +399,22 @@ static void __pci_restore_msi_state(struct pci_dev *dev) return; entry = irq_get_msi_desc(dev->irq); + pos = entry->msi_attrib.pos; pci_intx_for_msi(dev, 0); - msi_set_enable(dev, 0); + msi_set_enable(dev, pos, 0); arch_restore_msi_irqs(dev, dev->irq); - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); msi_mask_irq(entry, msi_capable_mask(control), entry->masked); control &= ~PCI_MSI_FLAGS_QSIZE; control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); } static void __pci_restore_msix_state(struct pci_dev *dev) { + int pos; struct msi_desc *entry; u16 control; @@ -415,12 +422,13 @@ static void __pci_restore_msix_state(struct pci_dev *dev) return; BUG_ON(list_empty(&dev->msi_list)); entry = list_first_entry(&dev->msi_list, struct msi_desc, list); - pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); + pos = entry->msi_attrib.pos; + pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); /* route the table */ pci_intx_for_msi(dev, 0); control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); list_for_each_entry(entry, &dev->msi_list, list) { arch_restore_msi_irqs(dev, entry->irq); @@ -428,7 +436,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) } control &= ~PCI_MSIX_FLAGS_MASKALL; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); } void pci_restore_msi_state(struct pci_dev *dev) @@ -476,12 +484,12 @@ static struct msi_attribute mode_attribute = __ATTR(mode, S_IRUGO, show_msi_mode, NULL); -static struct attribute *msi_irq_default_attrs[] = { +struct attribute *msi_irq_default_attrs[] = { &mode_attribute.attr, NULL }; -static void msi_kobj_release(struct kobject *kobj) +void msi_kobj_release(struct kobject *kobj) { struct msi_desc *entry = to_msi_desc(kobj); @@ -544,27 +552,27 @@ static int populate_msi_sysfs(struct pci_dev *pdev) static int msi_capability_init(struct pci_dev *dev, int nvec) { struct msi_desc *entry; - int ret; + int pos, ret; u16 control; unsigned mask; - msi_set_enable(dev, 0); /* Disable MSI during set up */ + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + msi_set_enable(dev, pos, 0); /* Disable MSI during set up */ - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); + pci_read_config_word(dev, msi_control_reg(pos), &control); /* MSI Entry Initialization */ entry = alloc_msi_entry(dev); if (!entry) return -ENOMEM; entry->msi_attrib.is_msix = 0; - entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); + entry->msi_attrib.is_64 = is_64bit_address(control); entry->msi_attrib.entry_nr = 0; - entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); + entry->msi_attrib.maskbit = is_mask_bit_support(control); entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ - entry->msi_attrib.pos = dev->msi_cap; + entry->msi_attrib.pos = pos; - entry->mask_pos = dev->msi_cap + (control & PCI_MSI_FLAGS_64BIT) ? - PCI_MSI_MASK_64 : PCI_MSI_MASK_32; + entry->mask_pos = msi_mask_reg(pos, entry->msi_attrib.is_64); /* All MSIs are unmasked by default, Mask them all */ if (entry->msi_attrib.maskbit) pci_read_config_dword(dev, entry->mask_pos, &entry->masked); @@ -590,30 +598,31 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) /* Set MSI enabled bits */ pci_intx_for_msi(dev, 0); - msi_set_enable(dev, 1); + msi_set_enable(dev, pos, 1); dev->msi_enabled = 1; dev->irq = entry->irq; return 0; } -static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries) +static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos, + unsigned nr_entries) { resource_size_t phys_addr; u32 table_offset; u8 bir; - pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, - &table_offset); - bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); - table_offset &= PCI_MSIX_TABLE_OFFSET; + pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); + table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; phys_addr = pci_resource_start(dev, bir) + table_offset; return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); } -static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, - struct msix_entry *entries, int nvec) +static int msix_setup_entries(struct pci_dev *dev, unsigned pos, + void __iomem *base, struct msix_entry *entries, + int nvec) { struct msi_desc *entry; int i; @@ -633,7 +642,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, entry->msi_attrib.is_64 = 1; entry->msi_attrib.entry_nr = entries[i].entry; entry->msi_attrib.default_irq = dev->irq; - entry->msi_attrib.pos = dev->msix_cap; + entry->msi_attrib.pos = pos; entry->mask_base = base; list_add_tail(&entry->list, &dev->msi_list); @@ -643,7 +652,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, } static void msix_program_entries(struct pci_dev *dev, - struct msix_entry *entries) + struct msix_entry *entries) { struct msi_desc *entry; int i = 0; @@ -673,22 +682,23 @@ static void msix_program_entries(struct pci_dev *dev, static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { - int ret; + int pos, ret; u16 control; void __iomem *base; - pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); /* Ensure MSI-X is disabled while it is set up */ control &= ~PCI_MSIX_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); /* Request & Map MSI-X table region */ - base = msix_map_region(dev, msix_table_size(control)); + base = msix_map_region(dev, pos, multi_msix_capable(control)); if (!base) return -ENOMEM; - ret = msix_setup_entries(dev, base, entries, nvec); + ret = msix_setup_entries(dev, pos, base, entries, nvec); if (ret) return ret; @@ -702,7 +712,7 @@ static int msix_capability_init(struct pci_dev *dev, * interrupts coming in before they're fully set up. */ control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); msix_program_entries(dev, entries); @@ -717,7 +727,7 @@ static int msix_capability_init(struct pci_dev *dev, dev->msix_enabled = 1; control &= ~PCI_MSIX_FLAGS_MASKALL; - pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); return 0; @@ -785,6 +795,9 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) if (ret) return ret; + if (!pci_find_capability(dev, type)) + return -EINVAL; + return 0; } @@ -803,13 +816,13 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) */ int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) { - int status, maxvec; + int status, pos, maxvec; u16 msgctl; - if (!dev->msi_cap) + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (!pos) return -EINVAL; - - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); if (nvec > maxvec) return maxvec; @@ -834,13 +847,14 @@ EXPORT_SYMBOL(pci_enable_msi_block); int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) { - int ret, nvec; + int ret, pos, nvec; u16 msgctl; - if (!dev->msi_cap) + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (!pos) return -EINVAL; - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); if (maxvec) @@ -862,19 +876,21 @@ void pci_msi_shutdown(struct pci_dev *dev) struct msi_desc *desc; u32 mask; u16 ctrl; + unsigned pos; if (!pci_msi_enable || !dev || !dev->msi_enabled) return; BUG_ON(list_empty(&dev->msi_list)); desc = list_first_entry(&dev->msi_list, struct msi_desc, list); + pos = desc->msi_attrib.pos; - msi_set_enable(dev, 0); + msi_set_enable(dev, pos, 0); pci_intx_for_msi(dev, 1); dev->msi_enabled = 0; /* Return the device with MSI unmasked as initial states */ - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &ctrl); + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl); mask = msi_capable_mask(ctrl); /* Keep cached state to be restored */ __msi_mask_irq(desc, mask, ~mask); @@ -901,13 +917,15 @@ EXPORT_SYMBOL(pci_disable_msi); */ int pci_msix_table_size(struct pci_dev *dev) { + int pos; u16 control; - if (!dev->msix_cap) + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + if (!pos) return 0; - pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); - return msix_table_size(control); + pci_read_config_word(dev, msi_control_reg(pos), &control); + return multi_msix_capable(control); } /** @@ -930,7 +948,7 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) int status, nr_entries; int i, j; - if (!entries || !dev->msix_cap) + if (!entries) return -EINVAL; status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); @@ -1030,17 +1048,15 @@ EXPORT_SYMBOL(pci_msi_enabled); void pci_msi_init_pci_dev(struct pci_dev *dev) { + int pos; INIT_LIST_HEAD(&dev->msi_list); /* Disable the msi hardware to avoid screaming interrupts * during boot. This is the power on reset default so * usually this should be a noop. */ - dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (dev->msi_cap) - msi_set_enable(dev, 0); - - dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (dev->msix_cap) - msix_set_enable(dev, 0); + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (pos) + msi_set_enable(dev, pos, 0); + msix_set_enable(dev, 0); } diff --git a/trunk/drivers/pci/msi.h b/trunk/drivers/pci/msi.h new file mode 100644 index 000000000000..65c42f80f23e --- /dev/null +++ b/trunk/drivers/pci/msi.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2003-2004 Intel + * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) + */ + +#ifndef MSI_H +#define MSI_H + +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) +#define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) +#define msi_data_reg(base, is64bit) \ + (base + ((is64bit == 1) ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32)) +#define msi_mask_reg(base, is64bit) \ + (base + ((is64bit == 1) ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32)) +#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) +#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) + +#define msix_table_offset_reg(base) (base + PCI_MSIX_TABLE) +#define msix_pba_offset_reg(base) (base + PCI_MSIX_PBA) +#define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) +#define multi_msix_capable(control) msix_table_size((control)) + +#endif /* MSI_H */ diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index e4b1fb2c0f5d..dee5dddaa292 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -53,15 +53,14 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) return; } - /* Clear PME Status if set. */ - if (pci_dev->pme_support) - pci_check_pme_status(pci_dev); + if (!pci_dev->pm_cap || !pci_dev->pme_support + || pci_check_pme_status(pci_dev)) { + if (pci_dev->pme_poll) + pci_dev->pme_poll = false; - if (pci_dev->pme_poll) - pci_dev->pme_poll = false; - - pci_wakeup_event(pci_dev); - pm_runtime_resume(&pci_dev->dev); + pci_wakeup_event(pci_dev); + pm_runtime_resume(&pci_dev->dev); + } if (pci_dev->subordinate) pci_pme_wakeup_bus(pci_dev->subordinate); @@ -288,32 +287,6 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { .run_wake = acpi_pci_run_wake, }; -void acpi_pci_add_bus(struct pci_bus *bus) -{ - acpi_handle handle = NULL; - - if (bus->bridge) - handle = ACPI_HANDLE(bus->bridge); - if (acpi_pci_disabled || handle == NULL) - return; - - acpi_pci_slot_enumerate(bus, handle); - acpiphp_enumerate_slots(bus, handle); -} - -void acpi_pci_remove_bus(struct pci_bus *bus) -{ - /* - * bus->bridge->acpi_node.handle has already been reset to NULL - * when acpi_pci_remove_bus() is called, so don't check ACPI handle. - */ - if (acpi_pci_disabled) - return; - - acpiphp_remove_slots(bus); - acpi_pci_slot_remove(bus); -} - /* ACPI bus type */ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) { @@ -388,11 +361,7 @@ static int __init acpi_pci_init(void) ret = register_acpi_bus_type(&acpi_pci_bus); if (ret) return 0; - pci_set_platform_pm(&acpi_pci_platform_pm); - acpi_pci_slot_init(); - acpiphp_init(); - return 0; } arch_initcall(acpi_pci_init); diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 79277fb36c6b..1fa1e482a999 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -390,10 +390,9 @@ static void pci_device_shutdown(struct device *dev) /* * Turn off Bus Master bit on the device to tell it to not - * continue to do DMA. Don't touch devices in D3cold or unknown states. + * continue to do DMA */ - if (pci_dev->current_state <= PCI_D3hot) - pci_clear_master(pci_dev); + pci_clear_master(pci_dev); } #ifdef CONFIG_PM diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index 5b4a9d9cd200..9c6e9bb674ec 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -897,7 +897,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, if (pci_resource_len(pdev, resno) == 0) return 0; - nr = vma_pages(vma); + nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; start = vma->vm_pgoff; size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; pci_start = (mmap_api == PCI_MMAP_PROCFS) ? diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index a899d8bb190d..b099e0025d2b 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -646,11 +646,15 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) error = platform_pci_set_power_state(dev, state); if (!error) pci_update_current_state(dev, state); - } else + /* Fall back to PCI_D0 if native PM is not supported */ + if (!dev->pm_cap) + dev->current_state = PCI_D0; + } else { error = -ENODEV; - - if (error && !dev->pm_cap) /* Fall back to PCI_D0 */ - dev->current_state = PCI_D0; + /* Fall back to PCI_D0 if native PM is not supported */ + if (!dev->pm_cap) + dev->current_state = PCI_D0; + } return error; } @@ -1571,7 +1575,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable) { u16 pmcsr; - if (!dev->pme_support) + if (!dev->pm_cap) return; pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); @@ -1920,7 +1924,6 @@ void pci_pm_init(struct pci_dev *dev) dev->wakeup_prepared = false; dev->pm_cap = 0; - dev->pme_support = 0; /* find PCI PM capability in list */ pm = pci_find_capability(dev, PCI_CAP_ID_PM); @@ -1972,6 +1975,8 @@ void pci_pm_init(struct pci_dev *dev) device_set_wakeup_capable(&dev->dev, true); /* Disable the PME# generation functionality */ pci_pme_active(dev, false); + } else { + dev->pme_support = 0; } } @@ -2614,7 +2619,7 @@ void pci_release_selected_regions(struct pci_dev *pdev, int bars) pci_release_region(pdev, i); } -static int __pci_request_selected_regions(struct pci_dev *pdev, int bars, +int __pci_request_selected_regions(struct pci_dev *pdev, int bars, const char *res_name, int excl) { int i; @@ -3694,7 +3699,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock); * RETURNS: Resource alignment if it is specified. * Zero if it is not specified. */ -static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) +resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) { int seg, bus, slot, func, align_order, count; resource_size_t align = 0; @@ -3807,7 +3812,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) } } -static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) +ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) { if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; @@ -3818,7 +3823,7 @@ static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) return count; } -static ssize_t pci_get_resource_alignment_param(char *buf, size_t size) +ssize_t pci_get_resource_alignment_param(char *buf, size_t size) { size_t count; spin_lock(&resource_alignment_lock); diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 68678ed76b0d..7346ee68f47d 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -8,25 +8,26 @@ /* Functions internal to the PCI core code */ -int pci_create_sysfs_dev_files(struct pci_dev *pdev); -void pci_remove_sysfs_dev_files(struct pci_dev *pdev); +extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); +extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); #if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI) static inline void pci_create_firmware_label_files(struct pci_dev *pdev) { return; } static inline void pci_remove_firmware_label_files(struct pci_dev *pdev) { return; } #else -void pci_create_firmware_label_files(struct pci_dev *pdev); -void pci_remove_firmware_label_files(struct pci_dev *pdev); +extern void pci_create_firmware_label_files(struct pci_dev *pdev); +extern void pci_remove_firmware_label_files(struct pci_dev *pdev); #endif -void pci_cleanup_rom(struct pci_dev *dev); +extern void pci_cleanup_rom(struct pci_dev *dev); #ifdef HAVE_PCI_MMAP enum pci_mmap_api { PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices//resource */ PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/ */ }; -int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai, - enum pci_mmap_api mmap_api); +extern int pci_mmap_fits(struct pci_dev *pdev, int resno, + struct vm_area_struct *vmai, + enum pci_mmap_api mmap_api); #endif int pci_probe_reset_function(struct pci_dev *dev); @@ -59,17 +60,17 @@ struct pci_platform_pm_ops { int (*run_wake)(struct pci_dev *dev, bool enable); }; -int pci_set_platform_pm(struct pci_platform_pm_ops *ops); -void pci_update_current_state(struct pci_dev *dev, pci_power_t state); -void pci_power_up(struct pci_dev *dev); -void pci_disable_enabled_device(struct pci_dev *dev); -int pci_finish_runtime_suspend(struct pci_dev *dev); -int __pci_pme_wakeup(struct pci_dev *dev, void *ign); -void pci_wakeup_bus(struct pci_bus *bus); -void pci_config_pm_runtime_get(struct pci_dev *dev); -void pci_config_pm_runtime_put(struct pci_dev *dev); -void pci_pm_init(struct pci_dev *dev); -void pci_allocate_cap_save_buffers(struct pci_dev *dev); +extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); +extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); +extern void pci_power_up(struct pci_dev *dev); +extern void pci_disable_enabled_device(struct pci_dev *dev); +extern int pci_finish_runtime_suspend(struct pci_dev *dev); +extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); +extern void pci_wakeup_bus(struct pci_bus *bus); +extern void pci_config_pm_runtime_get(struct pci_dev *dev); +extern void pci_config_pm_runtime_put(struct pci_dev *dev); +extern void pci_pm_init(struct pci_dev *dev); +extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); void pci_free_cap_save_buffers(struct pci_dev *dev); static inline void pci_wakeup_event(struct pci_dev *dev) @@ -95,7 +96,7 @@ struct pci_vpd { struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ }; -int pci_vpd_pci22_init(struct pci_dev *dev); +extern int pci_vpd_pci22_init(struct pci_dev *dev); static inline void pci_vpd_release(struct pci_dev *dev) { if (dev->vpd) @@ -104,9 +105,9 @@ static inline void pci_vpd_release(struct pci_dev *dev) /* PCI /proc functions */ #ifdef CONFIG_PROC_FS -int pci_proc_attach_device(struct pci_dev *dev); -int pci_proc_detach_device(struct pci_dev *dev); -int pci_proc_detach_bus(struct pci_bus *bus); +extern int pci_proc_attach_device(struct pci_dev *dev); +extern int pci_proc_detach_device(struct pci_dev *dev); +extern int pci_proc_detach_bus(struct pci_bus *bus); #else static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } @@ -117,8 +118,8 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } int pci_hp_add_bridge(struct pci_dev *dev); #ifdef HAVE_PCI_LEGACY -void pci_create_legacy_files(struct pci_bus *bus); -void pci_remove_legacy_files(struct pci_bus *bus); +extern void pci_create_legacy_files(struct pci_bus *bus); +extern void pci_remove_legacy_files(struct pci_bus *bus); #else static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } @@ -133,7 +134,7 @@ extern unsigned int pci_pm_d3_delay; #ifdef CONFIG_PCI_MSI void pci_no_msi(void); -void pci_msi_init_pci_dev(struct pci_dev *dev); +extern void pci_msi_init_pci_dev(struct pci_dev *dev); #else static inline void pci_no_msi(void) { } static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } @@ -197,11 +198,12 @@ enum pci_bar_type { bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, int crs_timeout); -int pci_setup_device(struct pci_dev *dev); -int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, - struct resource *res, unsigned int reg); -int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); -void pci_configure_ari(struct pci_dev *dev); +extern int pci_setup_device(struct pci_dev *dev); +extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, + struct resource *res, unsigned int reg); +extern int pci_resource_bar(struct pci_dev *dev, int resno, + enum pci_bar_type *type); +extern void pci_configure_ari(struct pci_dev *dev); /** * pci_ari_enabled - query ARI forwarding status @@ -215,7 +217,7 @@ static inline int pci_ari_enabled(struct pci_bus *bus) } void pci_reassigndev_resource_alignment(struct pci_dev *dev); -void pci_disable_bridge_window(struct pci_dev *dev); +extern void pci_disable_bridge_window(struct pci_dev *dev); /* Single Root I/O Virtualization */ struct pci_sriov { @@ -239,7 +241,7 @@ struct pci_sriov { }; #ifdef CONFIG_PCI_ATS -void pci_restore_ats_state(struct pci_dev *dev); +extern void pci_restore_ats_state(struct pci_dev *dev); #else static inline void pci_restore_ats_state(struct pci_dev *dev) { @@ -247,13 +249,14 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) #endif /* CONFIG_PCI_ATS */ #ifdef CONFIG_PCI_IOV -int pci_iov_init(struct pci_dev *dev); -void pci_iov_release(struct pci_dev *dev); -int pci_iov_resource_bar(struct pci_dev *dev, int resno, - enum pci_bar_type *type); -resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); -void pci_restore_iov_state(struct pci_dev *dev); -int pci_iov_bus_range(struct pci_bus *bus); +extern int pci_iov_init(struct pci_dev *dev); +extern void pci_iov_release(struct pci_dev *dev); +extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, + enum pci_bar_type *type); +extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, + int resno); +extern void pci_restore_iov_state(struct pci_dev *dev); +extern int pci_iov_bus_range(struct pci_bus *bus); #else static inline int pci_iov_init(struct pci_dev *dev) @@ -279,10 +282,10 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) #endif /* CONFIG_PCI_IOV */ -unsigned long pci_cardbus_resource_alignment(struct resource *); +extern unsigned long pci_cardbus_resource_alignment(struct resource *); static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, - struct resource *res) + struct resource *res) { #ifdef CONFIG_PCI_IOV int resno = res - dev->resource; @@ -295,7 +298,7 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, return resource_alignment(res); } -void pci_enable_acs(struct pci_dev *dev); +extern void pci_enable_acs(struct pci_dev *dev); struct pci_dev_reset_methods { u16 vendor; @@ -304,7 +307,7 @@ struct pci_dev_reset_methods { }; #ifdef CONFIG_PCI_QUIRKS -int pci_dev_specific_reset(struct pci_dev *dev, int probe); +extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); #else static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) { diff --git a/trunk/drivers/pci/pcie/Kconfig b/trunk/drivers/pci/pcie/Kconfig index 569f82fc9e22..fde4a32a0295 100644 --- a/trunk/drivers/pci/pcie/Kconfig +++ b/trunk/drivers/pci/pcie/Kconfig @@ -82,4 +82,4 @@ endchoice config PCIE_PME def_bool y - depends on PCIEPORTBUS && PM_RUNTIME + depends on PCIEPORTBUS && PM_RUNTIME && ACPI diff --git a/trunk/drivers/pci/pcie/aer/aer_inject.c b/trunk/drivers/pci/pcie/aer/aer_inject.c index 587e7e853107..4e24cb8a94ae 100644 --- a/trunk/drivers/pci/pcie/aer/aer_inject.c +++ b/trunk/drivers/pci/pcie/aer/aer_inject.c @@ -212,8 +212,8 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, return ops->read(bus, devfn, where, size, val); } -static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) +int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size, + u32 val) { u32 *sim; struct aer_error *err; @@ -334,13 +334,13 @@ static int aer_inject(struct aer_error_inj *einj) return -ENODEV; rpdev = pcie_find_root_port(dev); if (!rpdev) { - ret = -ENODEV; + ret = -ENOTTY; goto out_put; } pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos_cap_err) { - ret = -EPERM; + ret = -ENOTTY; goto out_put; } pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); @@ -350,7 +350,7 @@ static int aer_inject(struct aer_error_inj *einj) rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); if (!rp_pos_cap_err) { - ret = -EPERM; + ret = -ENOTTY; goto out_put; } diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.h b/trunk/drivers/pci/pcie/aer/aerdrv.h index d12c77cd6991..22f840f4dda1 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.h +++ b/trunk/drivers/pci/pcie/aer/aerdrv.h @@ -110,15 +110,15 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig, } extern struct bus_type pcie_port_bus_type; -void aer_do_secondary_bus_reset(struct pci_dev *dev); -int aer_init(struct pcie_device *dev); -void aer_isr(struct work_struct *work); -void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); -void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); -irqreturn_t aer_irq(int irq, void *context); +extern void aer_do_secondary_bus_reset(struct pci_dev *dev); +extern int aer_init(struct pcie_device *dev); +extern void aer_isr(struct work_struct *work); +extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); +extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); +extern irqreturn_t aer_irq(int irq, void *context); #ifdef CONFIG_ACPI_APEI -int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); +extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); #else static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) { diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index 8ec8b4f48560..564d97f94b6c 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -89,6 +89,8 @@ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev) return -ENOSPC; } +#define PCI_BUS(x) (((x) >> 8) & 0xff) + /** * is_error_source - check whether the device is source of reported error * @dev: pointer to pci_dev to be checked @@ -104,7 +106,7 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) * When bus id is equal to 0, it might be a bad id * reported by root port. */ - if (!nosourceid && (PCI_BUS_NUM(e_info->id) != 0)) { + if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { /* Device ID match? */ if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) return true; diff --git a/trunk/drivers/pci/pcie/pme.c b/trunk/drivers/pci/pcie/pme.c index 795db1f9d50c..9ca0dc9ffd84 100644 --- a/trunk/drivers/pci/pcie/pme.c +++ b/trunk/drivers/pci/pcie/pme.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include "../pci.h" diff --git a/trunk/drivers/pci/pcie/portdrv.h b/trunk/drivers/pci/pcie/portdrv.h index d2eb80aab569..eea2ca2375e6 100644 --- a/trunk/drivers/pci/pcie/portdrv.h +++ b/trunk/drivers/pci/pcie/portdrv.h @@ -21,18 +21,18 @@ #define get_descriptor_id(type, service) (((type - 4) << 4) | service) extern struct bus_type pcie_port_bus_type; -int pcie_port_device_register(struct pci_dev *dev); +extern int pcie_port_device_register(struct pci_dev *dev); #ifdef CONFIG_PM -int pcie_port_device_suspend(struct device *dev); -int pcie_port_device_resume(struct device *dev); +extern int pcie_port_device_suspend(struct device *dev); +extern int pcie_port_device_resume(struct device *dev); #endif -void pcie_port_device_remove(struct pci_dev *dev); -int __must_check pcie_port_bus_register(void); -void pcie_port_bus_unregister(void); +extern void pcie_port_device_remove(struct pci_dev *dev); +extern int __must_check pcie_port_bus_register(void); +extern void pcie_port_bus_unregister(void); struct pci_dev; -void pcie_clear_root_pme_status(struct pci_dev *dev); +extern void pcie_clear_root_pme_status(struct pci_dev *dev); #ifdef CONFIG_HOTPLUG_PCI_PCIE extern bool pciehp_msi_disabled; @@ -59,7 +59,7 @@ static inline bool pcie_pme_no_msi(void) return pcie_pme_msi_disabled; } -void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); +extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); #else /* !CONFIG_PCIE_PME */ static inline void pcie_pme_disable_msi(void) {} static inline bool pcie_pme_no_msi(void) { return false; } @@ -67,7 +67,7 @@ static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {} #endif /* !CONFIG_PCIE_PME */ #ifdef CONFIG_ACPI -int pcie_port_acpi_setup(struct pci_dev *port, int *mask); +extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask); static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) { diff --git a/trunk/drivers/pci/pcie/portdrv_acpi.c b/trunk/drivers/pci/pcie/portdrv_acpi.c index b4d2894ee3fc..a86b56e5f2f2 100644 --- a/trunk/drivers/pci/pcie/portdrv_acpi.c +++ b/trunk/drivers/pci/pcie/portdrv_acpi.c @@ -17,7 +17,6 @@ #include "aer/aerdrv.h" #include "../pci.h" -#include "portdrv.h" /** * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index 696caed5fdf5..08c243ab034e 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -184,6 +184,14 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { #define PCIE_PORTDRV_PM_OPS NULL #endif /* !PM */ +/* + * PCIe port runtime suspend is broken for some chipsets, so use a + * black list to disable runtime PM for these chipsets. + */ +static const struct pci_device_id port_runtime_pm_black_list[] = { + { /* end: all zeroes */ } +}; + /* * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed @@ -217,11 +225,16 @@ static int pcie_portdrv_probe(struct pci_dev *dev, * it by default. */ dev->d3cold_allowed = false; + if (!pci_match_id(port_runtime_pm_black_list, dev)) + pm_runtime_put_noidle(&dev->dev); + return 0; } static void pcie_portdrv_remove(struct pci_dev *dev) { + if (!pci_match_id(port_runtime_pm_black_list, dev)) + pm_runtime_get_noresume(&dev->dev); pcie_port_device_remove(dev); pci_disable_device(dev); } @@ -259,9 +272,11 @@ static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, enum pci_channel_state error) { struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; + int ret; + + /* can not fail */ + ret = device_for_each_child(&dev->dev, &data, error_detected_iter); - /* get true return value from &data */ - device_for_each_child(&dev->dev, &data, error_detected_iter); return data.result; } @@ -293,9 +308,10 @@ static int mmio_enabled_iter(struct device *device, void *data) static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) { pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; + int retval; /* get true return value from &status */ - device_for_each_child(&dev->dev, &status, mmio_enabled_iter); + retval = device_for_each_child(&dev->dev, &status, mmio_enabled_iter); return status; } @@ -327,6 +343,7 @@ static int slot_reset_iter(struct device *device, void *data) static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) { pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; + int retval; /* If fatal, restore cfg space for possible link reset at upstream */ if (dev->error_state == pci_channel_io_frozen) { @@ -337,7 +354,8 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) } /* get true return value from &status */ - device_for_each_child(&dev->dev, &status, slot_reset_iter); + retval = device_for_each_child(&dev->dev, &status, slot_reset_iter); + return status; } @@ -363,7 +381,9 @@ static int resume_iter(struct device *device, void *data) static void pcie_portdrv_err_resume(struct pci_dev *dev) { - device_for_each_child(&dev->dev, NULL, resume_iter); + int retval; + /* nothing to do with error value, if it ever happens */ + retval = device_for_each_child(&dev->dev, NULL, resume_iter); } /* diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index 43ece5d41d36..b494066ef32f 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -673,8 +673,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, ret = device_register(&child->dev); WARN_ON(ret < 0); - pcibios_add_bus(child); - /* Create legacy_io and legacy_mem files for this bus */ pci_create_legacy_files(child); @@ -1629,7 +1627,8 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) if (!bus->is_added) { dev_dbg(&bus->dev, "fixups for bus\n"); pcibios_fixup_bus(bus); - bus->is_added = 1; + if (pci_is_root_bus(bus)) + bus->is_added = 1; } for (pass=0; pass < 2; pass++) @@ -1662,14 +1661,6 @@ int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) return 0; } -void __weak pcibios_add_bus(struct pci_bus *bus) -{ -} - -void __weak pcibios_remove_bus(struct pci_bus *bus) -{ -} - struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources) { @@ -1724,8 +1715,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, if (error) goto class_dev_reg_err; - pcibios_add_bus(b); - /* Create legacy_io and legacy_mem files for this bus */ pci_create_legacy_files(b); diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 7d68aeebf56b..0369fb6fc1da 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -324,30 +324,29 @@ static void quirk_cs5536_vsa(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); -static void quirk_io_region(struct pci_dev *dev, int port, - unsigned size, int nr, const char *name) +static void quirk_io_region(struct pci_dev *dev, unsigned region, + unsigned size, int nr, const char *name) { - u16 region; - struct pci_bus_region bus_region; - struct resource *res = dev->resource + nr; - - pci_read_config_word(dev, port, ®ion); - region &= ~(size - 1); - - if (!region) - return; + region &= ~(size-1); + if (region) { + struct pci_bus_region bus_region; + struct resource *res = dev->resource + nr; - res->name = pci_name(dev); - res->flags = IORESOURCE_IO; + res->name = pci_name(dev); + res->start = region; + res->end = region + size - 1; + res->flags = IORESOURCE_IO; - /* Convert from PCI bus to resource space */ - bus_region.start = region; - bus_region.end = region + size - 1; - pcibios_bus_to_resource(dev, res, &bus_region); + /* Convert from PCI bus to resource space. */ + bus_region.start = res->start; + bus_region.end = res->end; + pcibios_bus_to_resource(dev, res, &bus_region); - if (!pci_claim_resource(dev, nr)) - dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); -} + if (pci_claim_resource(dev, nr) == 0) + dev_info(&dev->dev, "quirk: %pR claimed by %s\n", + res, name); + } +} /* * ATI Northbridge setups MCE the processor if you even @@ -375,8 +374,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_ */ static void quirk_ali7101_acpi(struct pci_dev *dev) { - quirk_io_region(dev, 0xE0, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); - quirk_io_region(dev, 0xE2, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); + u16 region; + + pci_read_config_word(dev, 0xE0, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); + pci_read_config_word(dev, 0xE2, ®ion); + quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi); @@ -439,10 +442,12 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int */ static void quirk_piix4_acpi(struct pci_dev *dev) { - u32 res_a; + u32 region, res_a; - quirk_io_region(dev, 0x40, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); - quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); + pci_read_config_dword(dev, 0x40, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); + pci_read_config_dword(dev, 0x90, ®ion); + quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); /* Device resource A has enables for some of the other ones */ pci_read_config_dword(dev, 0x5c, &res_a); @@ -486,6 +491,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, qui */ static void quirk_ich4_lpc_acpi(struct pci_dev *dev) { + u32 region; u8 enable; /* @@ -497,14 +503,22 @@ static void quirk_ich4_lpc_acpi(struct pci_dev *dev) */ pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); - if (enable & ICH4_ACPI_EN) - quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, - "ICH4 ACPI/GPIO/TCO"); + if (enable & ICH4_ACPI_EN) { + pci_read_config_dword(dev, ICH_PMBASE, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + if (region >= PCIBIOS_MIN_IO) + quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, + "ICH4 ACPI/GPIO/TCO"); + } pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); - if (enable & ICH4_GPIO_EN) - quirk_io_region(dev, ICH4_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, - "ICH4 GPIO"); + if (enable & ICH4_GPIO_EN) { + pci_read_config_dword(dev, ICH4_GPIOBASE, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + if (region >= PCIBIOS_MIN_IO) + quirk_io_region(dev, region, 64, + PCI_BRIDGE_RESOURCES + 1, "ICH4 GPIO"); + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi); @@ -519,17 +533,26 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, qui static void ich6_lpc_acpi_gpio(struct pci_dev *dev) { + u32 region; u8 enable; pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); - if (enable & ICH6_ACPI_EN) - quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, - "ICH6 ACPI/GPIO/TCO"); + if (enable & ICH6_ACPI_EN) { + pci_read_config_dword(dev, ICH_PMBASE, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + if (region >= PCIBIOS_MIN_IO) + quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, + "ICH6 ACPI/GPIO/TCO"); + } pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); - if (enable & ICH6_GPIO_EN) - quirk_io_region(dev, ICH6_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, - "ICH6 GPIO"); + if (enable & ICH6_GPIO_EN) { + pci_read_config_dword(dev, ICH6_GPIOBASE, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + if (region >= PCIBIOS_MIN_IO) + quirk_io_region(dev, region, 64, + PCI_BRIDGE_RESOURCES + 1, "ICH6 GPIO"); + } } static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) @@ -627,9 +650,13 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_1, qui */ static void quirk_vt82c586_acpi(struct pci_dev *dev) { - if (dev->revision & 0x10) - quirk_io_region(dev, 0x48, 256, PCI_BRIDGE_RESOURCES, - "vt82c586 ACPI"); + u32 region; + + if (dev->revision & 0x10) { + pci_read_config_dword(dev, 0x48, ®ion); + region &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI"); + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi); @@ -641,12 +668,18 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt */ static void quirk_vt82c686_acpi(struct pci_dev *dev) { + u16 hm; + u32 smb; + quirk_vt82c586_acpi(dev); - quirk_io_region(dev, 0x70, 128, PCI_BRIDGE_RESOURCES+1, - "vt82c686 HW-mon"); + pci_read_config_word(dev, 0x70, &hm); + hm &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon"); - quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+2, "vt82c686 SMB"); + pci_read_config_dword(dev, 0x90, &smb); + smb &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB"); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi); @@ -657,8 +690,15 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt */ static void quirk_vt8235_acpi(struct pci_dev *dev) { - quirk_io_region(dev, 0x88, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); - quirk_io_region(dev, 0xd0, 16, PCI_BRIDGE_RESOURCES+1, "vt8235 SMB"); + u16 pm, smb; + + pci_read_config_word(dev, 0x88, &pm); + pm &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); + + pci_read_config_word(dev, 0xd0, &smb); + smb &= PCI_BASE_ADDRESS_IO_MASK; + quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1, "vt8235 SMB"); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi); @@ -2554,14 +2594,6 @@ static void quirk_msi_intx_disable_ati_bug(struct pci_dev *dev) dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; pci_dev_put(p); } -static void quirk_msi_intx_disable_qca_bug(struct pci_dev *dev) -{ - /* AR816X/AR817X/E210X MSI is fixed at HW level from revision 0x18 */ - if (dev->revision < 0x18) { - dev_info(&dev->dev, "set MSI_INTX_DISABLE_BUG flag\n"); - dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; - } -} DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780, quirk_msi_intx_disable_bug); @@ -2611,16 +2643,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1073, quirk_msi_intx_disable_bug); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083, quirk_msi_intx_disable_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1090, - quirk_msi_intx_disable_qca_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1091, - quirk_msi_intx_disable_qca_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a0, - quirk_msi_intx_disable_qca_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a1, - quirk_msi_intx_disable_qca_bug); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0xe091, - quirk_msi_intx_disable_qca_bug); #endif /* CONFIG_PCI_MSI */ /* Allow manual resource allocation for PCI hotplug bridges diff --git a/trunk/drivers/pci/remove.c b/trunk/drivers/pci/remove.c index 8fc54b7327bc..cc875e6ed159 100644 --- a/trunk/drivers/pci/remove.c +++ b/trunk/drivers/pci/remove.c @@ -50,8 +50,10 @@ void pci_remove_bus(struct pci_bus *bus) list_del(&bus->node); pci_bus_release_busn_res(bus); up_write(&pci_bus_sem); + if (!bus->is_added) + return; + pci_remove_legacy_files(bus); - pcibios_remove_bus(bus); device_unregister(&bus->dev); } EXPORT_SYMBOL(pci_remove_bus); diff --git a/trunk/drivers/pci/rom.c b/trunk/drivers/pci/rom.c index c5d0a08a8747..b41ac7756a4b 100644 --- a/trunk/drivers/pci/rom.c +++ b/trunk/drivers/pci/rom.c @@ -100,6 +100,27 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) return min((size_t)(image - rom), size); } +static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size) +{ + struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; + loff_t start; + + /* assign the ROM an address if it doesn't have one */ + if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE)) + return 0; + start = pci_resource_start(pdev, PCI_ROM_RESOURCE); + *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); + + if (*size == 0) + return 0; + + /* Enable ROM space decodes */ + if (pci_enable_rom(pdev)) + return 0; + + return start; +} + /** * pci_map_rom - map a PCI ROM to kernel space * @pdev: pointer to pci device struct @@ -114,7 +135,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) { struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; - loff_t start; + loff_t start = 0; void __iomem *rom; /* @@ -133,21 +154,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) return (void __iomem *)(unsigned long) pci_resource_start(pdev, PCI_ROM_RESOURCE); } else { - /* assign the ROM an address if it doesn't have one */ - if (res->parent == NULL && - pci_assign_resource(pdev,PCI_ROM_RESOURCE)) - return NULL; - start = pci_resource_start(pdev, PCI_ROM_RESOURCE); - *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); - if (*size == 0) - return NULL; - - /* Enable ROM space decodes */ - if (pci_enable_rom(pdev)) - return NULL; + start = pci_find_rom(pdev, size); } } + /* + * Some devices may provide ROMs via a source other than the BAR + */ + if (!start && pdev->rom && pdev->romlen) { + *size = pdev->romlen; + return phys_to_virt(pdev->rom); + } + + if (!start) + return NULL; + rom = ioremap(start, *size); if (!rom) { /* restore enable if ioremap fails */ @@ -181,7 +202,8 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) return; - iounmap(rom); + if (!pdev->rom || !pdev->romlen) + iounmap(rom); /* Disable again before continuing, leave enabled if pci=rom */ if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW))) @@ -205,24 +227,7 @@ void pci_cleanup_rom(struct pci_dev *pdev) } } -/** - * pci_platform_rom - provides a pointer to any ROM image provided by the - * platform - * @pdev: pointer to pci device struct - * @size: pointer to receive size of pci window over ROM - */ -void __iomem *pci_platform_rom(struct pci_dev *pdev, size_t *size) -{ - if (pdev->rom && pdev->romlen) { - *size = pdev->romlen; - return phys_to_virt((phys_addr_t)pdev->rom); - } - - return NULL; -} - EXPORT_SYMBOL(pci_map_rom); EXPORT_SYMBOL(pci_unmap_rom); EXPORT_SYMBOL_GPL(pci_enable_rom); EXPORT_SYMBOL_GPL(pci_disable_rom); -EXPORT_SYMBOL(pci_platform_rom); diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index 16abaaa1f83c..7e8739e25b9e 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -1044,7 +1044,7 @@ static void pci_bus_size_cardbus(struct pci_bus *bus, ; } -static void __ref __pci_bus_size_bridges(struct pci_bus *bus, +void __ref __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head) { struct pci_dev *dev; @@ -1545,8 +1545,6 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) enable_all: retval = pci_reenable_device(bridge); - if (retval) - dev_err(&bridge->dev, "Error reenabling bridge (%d)\n", retval); pci_set_master(bridge); pci_enable_bridges(parent); } diff --git a/trunk/drivers/pci/setup-res.c b/trunk/drivers/pci/setup-res.c index 07f2eddc09ce..81b88bda7930 100644 --- a/trunk/drivers/pci/setup-res.c +++ b/trunk/drivers/pci/setup-res.c @@ -261,6 +261,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) { struct resource *res = dev->resource + resno; resource_size_t align, size; + struct pci_bus *bus; int ret; align = pci_resource_alignment(dev, res); @@ -270,6 +271,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) return -EINVAL; } + bus = dev->bus; size = resource_size(res); ret = _pci_assign_resource(dev, resno, size, align); diff --git a/trunk/drivers/pci/slot.c b/trunk/drivers/pci/slot.c index c1e9284a677b..ac6412fb8d6f 100644 --- a/trunk/drivers/pci/slot.c +++ b/trunk/drivers/pci/slot.c @@ -377,17 +377,14 @@ void pci_hp_create_module_link(struct pci_slot *pci_slot) { struct hotplug_slot *slot = pci_slot->hotplug; struct kobject *kobj = NULL; - int ret; + int no_warn; if (!slot || !slot->ops) return; kobj = kset_find_obj(module_kset, slot->ops->mod_name); if (!kobj) return; - ret = sysfs_create_link(&pci_slot->kobj, kobj, "module"); - if (ret) - dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n", - ret); + no_warn = sysfs_create_link(&pci_slot->kobj, kobj, "module"); kobject_put(kobj); } EXPORT_SYMBOL_GPL(pci_hp_create_module_link); diff --git a/trunk/drivers/platform/x86/hp-wmi.c b/trunk/drivers/platform/x86/hp-wmi.c index 1a779bbfb87d..45cacf79f3a7 100644 --- a/trunk/drivers/platform/x86/hp-wmi.c +++ b/trunk/drivers/platform/x86/hp-wmi.c @@ -134,6 +134,7 @@ static const struct key_entry hp_wmi_keymap[] = { { KE_KEY, 0x2142, { KEY_MEDIA } }, { KE_KEY, 0x213b, { KEY_INFO } }, { KE_KEY, 0x2169, { KEY_DIRECTION } }, + { KE_KEY, 0x216a, { KEY_SETUP } }, { KE_KEY, 0x231b, { KEY_HELP } }, { KE_END, 0 } }; @@ -924,6 +925,9 @@ static int __init hp_wmi_init(void) err = hp_wmi_input_setup(); if (err) return err; + + //Enable magic for hotkeys that run on the SMBus + ec_write(0xe6,0x6e); } if (bios_capable) { diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index edec135b1685..9a907567f41e 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -1964,6 +1964,9 @@ struct tp_nvram_state { /* kthread for the hotkey poller */ static struct task_struct *tpacpi_hotkey_task; +/* Acquired while the poller kthread is running, use to sync start/stop */ +static struct mutex hotkey_thread_mutex; + /* * Acquire mutex to write poller control variables as an * atomic block. @@ -2459,6 +2462,8 @@ static int hotkey_kthread(void *data) unsigned int poll_freq; bool was_frozen; + mutex_lock(&hotkey_thread_mutex); + if (tpacpi_lifecycle == TPACPI_LIFE_EXITING) goto exit; @@ -2518,6 +2523,7 @@ static int hotkey_kthread(void *data) } exit: + mutex_unlock(&hotkey_thread_mutex); return 0; } @@ -2527,6 +2533,9 @@ static void hotkey_poll_stop_sync(void) if (tpacpi_hotkey_task) { kthread_stop(tpacpi_hotkey_task); tpacpi_hotkey_task = NULL; + mutex_lock(&hotkey_thread_mutex); + /* at this point, the thread did exit */ + mutex_unlock(&hotkey_thread_mutex); } } @@ -3225,6 +3234,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) mutex_init(&hotkey_mutex); #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL + mutex_init(&hotkey_thread_mutex); mutex_init(&hotkey_thread_data_mutex); #endif diff --git a/trunk/drivers/remoteproc/Kconfig b/trunk/drivers/remoteproc/Kconfig index c6d77e20622c..cc1f7bf53fd0 100644 --- a/trunk/drivers/remoteproc/Kconfig +++ b/trunk/drivers/remoteproc/Kconfig @@ -4,7 +4,7 @@ menu "Remoteproc drivers" config REMOTEPROC tristate depends on HAS_DMA - select FW_LOADER + select FW_CONFIG select VIRTIO config OMAP_REMOTEPROC diff --git a/trunk/drivers/remoteproc/remoteproc_core.c b/trunk/drivers/remoteproc/remoteproc_core.c index 8edb4aed5d36..29387df4bfc9 100644 --- a/trunk/drivers/remoteproc/remoteproc_core.c +++ b/trunk/drivers/remoteproc/remoteproc_core.c @@ -217,7 +217,7 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i) * TODO: support predefined notifyids (via resource table) */ ret = idr_alloc(&rproc->notifyids, rvring, 0, 0, GFP_KERNEL); - if (ret < 0) { + if (ret) { dev_err(dev, "idr_alloc failed: %d\n", ret); dma_free_coherent(dev->parent, size, va, dma); return ret; @@ -366,12 +366,10 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc, /* it is now safe to add the virtio device */ ret = rproc_add_virtio_dev(rvdev, rsc->id); if (ret) - goto remove_rvdev; + goto free_rvdev; return 0; -remove_rvdev: - list_del(&rvdev->node); free_rvdev: kfree(rvdev); return ret; diff --git a/trunk/drivers/remoteproc/ste_modem_rproc.c b/trunk/drivers/remoteproc/ste_modem_rproc.c index fb95c4220052..a7743c069339 100644 --- a/trunk/drivers/remoteproc/ste_modem_rproc.c +++ b/trunk/drivers/remoteproc/ste_modem_rproc.c @@ -240,8 +240,6 @@ static int sproc_drv_remove(struct platform_device *pdev) /* Unregister as remoteproc device */ rproc_del(sproc->rproc); - dma_free_coherent(sproc->rproc->dev.parent, SPROC_FW_SIZE, - sproc->fw_addr, sproc->fw_dma_addr); rproc_put(sproc->rproc); mdev->drv_data = NULL; @@ -299,13 +297,10 @@ static int sproc_probe(struct platform_device *pdev) /* Register as a remoteproc device */ err = rproc_add(rproc); if (err) - goto free_mem; + goto free_rproc; return 0; -free_mem: - dma_free_coherent(rproc->dev.parent, SPROC_FW_SIZE, - sproc->fw_addr, sproc->fw_dma_addr); free_rproc: /* Reset device data upon error */ mdev->drv_data = NULL; diff --git a/trunk/drivers/rtc/rtc-at91rm9200.c b/trunk/drivers/rtc/rtc-at91rm9200.c index 434ebc3a99dc..0a9f27e094ea 100644 --- a/trunk/drivers/rtc/rtc-at91rm9200.c +++ b/trunk/drivers/rtc/rtc-at91rm9200.c @@ -44,6 +44,7 @@ static DECLARE_COMPLETION(at91_rtc_updated); static unsigned int at91_alarm_year = AT91_RTC_EPOCH; static void __iomem *at91_rtc_regs; static int irq; +static u32 at91_rtc_imr; /* * Decode time/date into rtc_time structure @@ -108,9 +109,11 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) cr = at91_rtc_read(AT91_RTC_CR); at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); + at91_rtc_imr |= AT91_RTC_ACKUPD; at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD); wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); + at91_rtc_imr &= ~AT91_RTC_ACKUPD; at91_rtc_write(AT91_RTC_TIMR, bin2bcd(tm->tm_sec) << 0 @@ -142,7 +145,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); tm->tm_year = at91_alarm_year - 1900; - alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) + alrm->enabled = (at91_rtc_imr & AT91_RTC_ALARM) ? 1 : 0; dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, @@ -168,6 +171,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) tm.tm_sec = alrm->time.tm_sec; at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); + at91_rtc_imr &= ~AT91_RTC_ALARM; at91_rtc_write(AT91_RTC_TIMALR, bin2bcd(tm.tm_sec) << 0 | bin2bcd(tm.tm_min) << 8 @@ -180,6 +184,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) if (alrm->enabled) { at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); + at91_rtc_imr |= AT91_RTC_ALARM; at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); } @@ -196,9 +201,12 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) if (enabled) { at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); + at91_rtc_imr |= AT91_RTC_ALARM; at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); - } else + } else { at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); + at91_rtc_imr &= ~AT91_RTC_ALARM; + } return 0; } @@ -207,12 +215,10 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) */ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) { - unsigned long imr = at91_rtc_read(AT91_RTC_IMR); - seq_printf(seq, "update_IRQ\t: %s\n", - (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); + (at91_rtc_imr & AT91_RTC_ACKUPD) ? "yes" : "no"); seq_printf(seq, "periodic_IRQ\t: %s\n", - (imr & AT91_RTC_SECEV) ? "yes" : "no"); + (at91_rtc_imr & AT91_RTC_SECEV) ? "yes" : "no"); return 0; } @@ -227,7 +233,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) unsigned int rtsr; unsigned long events = 0; - rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR); + rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_imr; if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr & AT91_RTC_ALARM) events |= (RTC_AF | RTC_IRQF); @@ -291,6 +297,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); + at91_rtc_imr = 0; ret = request_irq(irq, at91_rtc_interrupt, IRQF_SHARED, @@ -329,6 +336,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); + at91_rtc_imr = 0; free_irq(irq, pdev); rtc_device_unregister(rtc); @@ -341,31 +349,35 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) /* AT91RM9200 RTC Power management control */ -static u32 at91_rtc_imr; +static u32 at91_rtc_bkpimr; + static int at91_rtc_suspend(struct device *dev) { /* this IRQ is shared with DBGU and other hardware which isn't * necessarily doing PM like we are... */ - at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR) - & (AT91_RTC_ALARM|AT91_RTC_SECEV); - if (at91_rtc_imr) { - if (device_may_wakeup(dev)) + at91_rtc_bkpimr = at91_rtc_imr & (AT91_RTC_ALARM|AT91_RTC_SECEV); + if (at91_rtc_bkpimr) { + if (device_may_wakeup(dev)) { enable_irq_wake(irq); - else - at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr); - } + } else { + at91_rtc_write(AT91_RTC_IDR, at91_rtc_bkpimr); + at91_rtc_imr &= ~at91_rtc_bkpimr; + } +} return 0; } static int at91_rtc_resume(struct device *dev) { - if (at91_rtc_imr) { - if (device_may_wakeup(dev)) + if (at91_rtc_bkpimr) { + if (device_may_wakeup(dev)) { disable_irq_wake(irq); - else - at91_rtc_write(AT91_RTC_IER, at91_rtc_imr); + } else { + at91_rtc_imr |= at91_rtc_bkpimr; + at91_rtc_write(AT91_RTC_IER, at91_rtc_bkpimr); + } } return 0; } diff --git a/trunk/drivers/rtc/rtc-at91rm9200.h b/trunk/drivers/rtc/rtc-at91rm9200.h index da1945e5f714..5f940b6844cb 100644 --- a/trunk/drivers/rtc/rtc-at91rm9200.h +++ b/trunk/drivers/rtc/rtc-at91rm9200.h @@ -64,7 +64,6 @@ #define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */ #define AT91_RTC_IER 0x20 /* Interrupt Enable Register */ #define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */ -#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */ #define AT91_RTC_VER 0x2c /* Valid Entry Register */ #define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 82758cbb220b..f1b7fdc58a5f 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -246,7 +246,7 @@ static struct dentry *dasd_debugfs_setup(const char *name, static int dasd_state_known_to_basic(struct dasd_device *device) { struct dasd_block *block = device->block; - int rc = 0; + int rc; /* Allocate and register gendisk structure. */ if (block) { @@ -273,8 +273,7 @@ static int dasd_state_known_to_basic(struct dasd_device *device) DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created"); device->state = DASD_STATE_BASIC; - - return rc; + return 0; } /* @@ -283,7 +282,6 @@ static int dasd_state_known_to_basic(struct dasd_device *device) static int dasd_state_basic_to_known(struct dasd_device *device) { int rc; - if (device->block) { dasd_profile_exit(&device->block->profile); if (device->block->debugfs_dentry) @@ -334,10 +332,8 @@ static int dasd_state_basic_to_ready(struct dasd_device *device) if (block->base->discipline->do_analysis != NULL) rc = block->base->discipline->do_analysis(block); if (rc) { - if (rc != -EAGAIN) { + if (rc != -EAGAIN) device->state = DASD_STATE_UNFMT; - goto out; - } return rc; } dasd_setup_queue(block); @@ -345,16 +341,11 @@ static int dasd_state_basic_to_ready(struct dasd_device *device) block->blocks << block->s2b_shift); device->state = DASD_STATE_READY; rc = dasd_scan_partitions(block); - if (rc) { + if (rc) device->state = DASD_STATE_BASIC; - return rc; - } } else { device->state = DASD_STATE_READY; } -out: - if (device->discipline->basic_to_ready) - rc = device->discipline->basic_to_ready(device); return rc; } @@ -377,11 +368,6 @@ static int dasd_state_ready_to_basic(struct dasd_device *device) { int rc; - if (device->discipline->ready_to_basic) { - rc = device->discipline->ready_to_basic(device); - if (rc) - return rc; - } device->state = DASD_STATE_BASIC; if (device->block) { struct dasd_block *block = device->block; @@ -416,10 +402,16 @@ static int dasd_state_unfmt_to_basic(struct dasd_device *device) static int dasd_state_ready_to_online(struct dasd_device * device) { + int rc; struct gendisk *disk; struct disk_part_iter piter; struct hd_struct *part; + if (device->discipline->ready_to_online) { + rc = device->discipline->ready_to_online(device); + if (rc) + return rc; + } device->state = DASD_STATE_ONLINE; if (device->block) { dasd_schedule_block_bh(device->block); @@ -452,7 +444,6 @@ static int dasd_state_online_to_ready(struct dasd_device *device) if (rc) return rc; } - device->state = DASD_STATE_READY; if (device->block && !(device->features & DASD_FEATURE_USERAW)) { disk = device->block->bdev->bd_disk; @@ -2232,77 +2223,6 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) return rc; } -static inline int _wait_for_wakeup_queue(struct list_head *ccw_queue) -{ - struct dasd_ccw_req *cqr; - - list_for_each_entry(cqr, ccw_queue, blocklist) { - if (cqr->callback_data != DASD_SLEEPON_END_TAG) - return 0; - } - - return 1; -} - -static int _dasd_sleep_on_queue(struct list_head *ccw_queue, int interruptible) -{ - struct dasd_device *device; - int rc; - struct dasd_ccw_req *cqr, *n; - -retry: - list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) { - device = cqr->startdev; - if (cqr->status != DASD_CQR_FILLED) /*could be failed*/ - continue; - - if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags) && - !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) { - cqr->status = DASD_CQR_FAILED; - cqr->intrc = -EPERM; - continue; - } - /*Non-temporary stop condition will trigger fail fast*/ - if (device->stopped & ~DASD_STOPPED_PENDING && - test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && - !dasd_eer_enabled(device)) { - cqr->status = DASD_CQR_FAILED; - cqr->intrc = -EAGAIN; - continue; - } - - /*Don't try to start requests if device is stopped*/ - if (interruptible) { - rc = wait_event_interruptible( - generic_waitq, !device->stopped); - if (rc == -ERESTARTSYS) { - cqr->status = DASD_CQR_FAILED; - cqr->intrc = rc; - continue; - } - } else - wait_event(generic_waitq, !(device->stopped)); - - if (!cqr->callback) - cqr->callback = dasd_wakeup_cb; - cqr->callback_data = DASD_SLEEPON_START_TAG; - dasd_add_request_tail(cqr); - } - - wait_event(generic_waitq, _wait_for_wakeup_queue(ccw_queue)); - - rc = 0; - list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) { - if (__dasd_sleep_on_erp(cqr)) - rc = 1; - } - if (rc) - goto retry; - - - return 0; -} - /* * Queue a request to the tail of the device ccw_queue and wait for * it's completion. @@ -2312,15 +2232,6 @@ int dasd_sleep_on(struct dasd_ccw_req *cqr) return _dasd_sleep_on(cqr, 0); } -/* - * Start requests from a ccw_queue and wait for their completion. - */ -int dasd_sleep_on_queue(struct list_head *ccw_queue) -{ - return _dasd_sleep_on_queue(ccw_queue, 0); -} -EXPORT_SYMBOL(dasd_sleep_on_queue); - /* * Queue a request to the tail of the device ccw_queue and wait * interruptible for it's completion. @@ -2751,26 +2662,6 @@ static void _dasd_wake_block_flush_cb(struct dasd_ccw_req *cqr, void *data) wake_up(&dasd_flush_wq); } -/* - * Requeue a request back to the block request queue - * only works for block requests - */ -static int _dasd_requeue_request(struct dasd_ccw_req *cqr) -{ - struct dasd_block *block = cqr->block; - struct request *req; - unsigned long flags; - - if (!block) - return -EINVAL; - spin_lock_irqsave(&block->queue_lock, flags); - req = (struct request *) cqr->callback_data; - blk_requeue_request(block->request_queue, req); - spin_unlock_irqrestore(&block->queue_lock, flags); - - return 0; -} - /* * Go through all request on the dasd_block request queue, cancel them * on the respective dasd_device, and return them to the generic @@ -3489,11 +3380,10 @@ EXPORT_SYMBOL_GPL(dasd_generic_verify_path); int dasd_generic_pm_freeze(struct ccw_device *cdev) { - struct dasd_device *device = dasd_device_from_cdev(cdev); - struct list_head freeze_queue; struct dasd_ccw_req *cqr, *n; - struct dasd_ccw_req *refers; int rc; + struct list_head freeze_queue; + struct dasd_device *device = dasd_device_from_cdev(cdev); if (IS_ERR(device)) return PTR_ERR(device); @@ -3506,8 +3396,7 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev) /* disallow new I/O */ dasd_device_set_stop_bits(device, DASD_STOPPED_PM); - - /* clear active requests and requeue them to block layer if possible */ + /* clear active requests */ INIT_LIST_HEAD(&freeze_queue); spin_lock_irq(get_ccwdev_lock(cdev)); rc = 0; @@ -3527,6 +3416,7 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev) } list_move_tail(&cqr->devlist, &freeze_queue); } + spin_unlock_irq(get_ccwdev_lock(cdev)); list_for_each_entry_safe(cqr, n, &freeze_queue, devlist) { @@ -3534,38 +3424,12 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev) (cqr->status != DASD_CQR_CLEAR_PENDING)); if (cqr->status == DASD_CQR_CLEARED) cqr->status = DASD_CQR_QUEUED; - - /* requeue requests to blocklayer will only work for - block device requests */ - if (_dasd_requeue_request(cqr)) - continue; - - /* remove requests from device and block queue */ - list_del_init(&cqr->devlist); - while (cqr->refers != NULL) { - refers = cqr->refers; - /* remove the request from the block queue */ - list_del(&cqr->blocklist); - /* free the finished erp request */ - dasd_free_erp_request(cqr, cqr->memdev); - cqr = refers; - } - if (cqr->block) - list_del_init(&cqr->blocklist); - cqr->block->base->discipline->free_cp( - cqr, (struct request *) cqr->callback_data); } + /* move freeze_queue to start of the ccw_queue */ + spin_lock_irq(get_ccwdev_lock(cdev)); + list_splice_tail(&freeze_queue, &device->ccw_queue); + spin_unlock_irq(get_ccwdev_lock(cdev)); - /* - * if requests remain then they are internal request - * and go back to the device queue - */ - if (!list_empty(&freeze_queue)) { - /* move freeze_queue to start of the ccw_queue */ - spin_lock_irq(get_ccwdev_lock(cdev)); - list_splice_tail(&freeze_queue, &device->ccw_queue); - spin_unlock_irq(get_ccwdev_lock(cdev)); - } dasd_put_device(device); return rc; } diff --git a/trunk/drivers/s390/block/dasd_devmap.c b/trunk/drivers/s390/block/dasd_devmap.c index a71bb8aaca1d..c196827c228f 100644 --- a/trunk/drivers/s390/block/dasd_devmap.c +++ b/trunk/drivers/s390/block/dasd_devmap.c @@ -410,7 +410,8 @@ dasd_add_busid(const char *bus_id, int features) struct dasd_devmap *devmap, *new, *tmp; int hash; - new = kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); + new = (struct dasd_devmap *) + kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); if (!new) return ERR_PTR(-ENOMEM); spin_lock(&dasd_devmap_lock); diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index 6a44b27623ed..6999fd919e94 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -2022,7 +2022,7 @@ static int dasd_eckd_do_analysis(struct dasd_block *block) return dasd_eckd_end_analysis(block); } -static int dasd_eckd_basic_to_ready(struct dasd_device *device) +static int dasd_eckd_ready_to_online(struct dasd_device *device) { return dasd_alias_add_device(device); }; @@ -2031,11 +2031,6 @@ static int dasd_eckd_online_to_ready(struct dasd_device *device) { cancel_work_sync(&device->reload_device); cancel_work_sync(&device->kick_validate); - return 0; -}; - -static int dasd_eckd_ready_to_basic(struct dasd_device *device) -{ return dasd_alias_remove_device(device); }; @@ -2055,34 +2050,45 @@ dasd_eckd_fill_geometry(struct dasd_block *block, struct hd_geometry *geo) } static struct dasd_ccw_req * -dasd_eckd_build_format(struct dasd_device *base, - struct format_data_t *fdata) +dasd_eckd_format_device(struct dasd_device * device, + struct format_data_t * fdata) { - struct dasd_eckd_private *base_priv; - struct dasd_eckd_private *start_priv; - struct dasd_device *startdev; + struct dasd_eckd_private *private; struct dasd_ccw_req *fcp; struct eckd_count *ect; - struct ch_t address; struct ccw1 *ccw; void *data; int rpt; + struct ch_t address; int cplength, datasize; - int i, j; + int i; int intensity = 0; int r0_perm; - int nr_tracks; - - startdev = dasd_alias_get_start_dev(base); - if (!startdev) - startdev = base; - - start_priv = (struct dasd_eckd_private *) startdev->private; - base_priv = (struct dasd_eckd_private *) base->private; - rpt = recs_per_track(&base_priv->rdc_data, 0, fdata->blksize); + private = (struct dasd_eckd_private *) device->private; + rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize); + set_ch_t(&address, + fdata->start_unit / private->rdc_data.trk_per_cyl, + fdata->start_unit % private->rdc_data.trk_per_cyl); - nr_tracks = fdata->stop_unit - fdata->start_unit + 1; + /* Sanity checks. */ + if (fdata->start_unit >= + (private->real_cyl * private->rdc_data.trk_per_cyl)) { + dev_warn(&device->cdev->dev, "Start track number %d used in " + "formatting is too big\n", fdata->start_unit); + return ERR_PTR(-EINVAL); + } + if (fdata->start_unit > fdata->stop_unit) { + dev_warn(&device->cdev->dev, "Start track %d used in " + "formatting exceeds end track\n", fdata->start_unit); + return ERR_PTR(-EINVAL); + } + if (dasd_check_blocksize(fdata->blksize) != 0) { + dev_warn(&device->cdev->dev, + "The DASD cannot be formatted with block size %d\n", + fdata->blksize); + return ERR_PTR(-EINVAL); + } /* * fdata->intensity is a bit string that tells us what to do: @@ -2100,282 +2106,149 @@ dasd_eckd_build_format(struct dasd_device *base, r0_perm = 1; intensity = fdata->intensity; } - switch (intensity) { case 0x00: /* Normal format */ case 0x08: /* Normal format, use cdl. */ - cplength = 2 + (rpt*nr_tracks); - datasize = sizeof(struct PFX_eckd_data) + + cplength = 2 + rpt; + datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) + - rpt * nr_tracks * sizeof(struct eckd_count); + rpt * sizeof(struct eckd_count); break; case 0x01: /* Write record zero and format track. */ case 0x09: /* Write record zero and format track, use cdl. */ - cplength = 2 + rpt * nr_tracks; - datasize = sizeof(struct PFX_eckd_data) + + cplength = 3 + rpt; + datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) + sizeof(struct eckd_count) + - rpt * nr_tracks * sizeof(struct eckd_count); + rpt * sizeof(struct eckd_count); break; case 0x04: /* Invalidate track. */ case 0x0c: /* Invalidate track, use cdl. */ cplength = 3; - datasize = sizeof(struct PFX_eckd_data) + + datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) + sizeof(struct eckd_count); break; default: - dev_warn(&startdev->cdev->dev, - "An I/O control call used incorrect flags 0x%x\n", - fdata->intensity); + dev_warn(&device->cdev->dev, "An I/O control call used " + "incorrect flags 0x%x\n", fdata->intensity); return ERR_PTR(-EINVAL); } /* Allocate the format ccw request. */ - fcp = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, - datasize, startdev); + fcp = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize, device); if (IS_ERR(fcp)) return fcp; - start_priv->count++; data = fcp->data; ccw = fcp->cpaddr; switch (intensity & ~0x08) { case 0x00: /* Normal format. */ - prefix(ccw++, (struct PFX_eckd_data *) data, - fdata->start_unit, fdata->stop_unit, - DASD_ECKD_CCW_WRITE_CKD, base, startdev); + define_extent(ccw++, (struct DE_eckd_data *) data, + fdata->start_unit, fdata->start_unit, + DASD_ECKD_CCW_WRITE_CKD, device); /* grant subsystem permission to format R0 */ if (r0_perm) - ((struct PFX_eckd_data *)data) - ->define_extent.ga_extended |= 0x04; - data += sizeof(struct PFX_eckd_data); + ((struct DE_eckd_data *)data)->ga_extended |= 0x04; + data += sizeof(struct DE_eckd_data); ccw[-1].flags |= CCW_FLAG_CC; locate_record(ccw++, (struct LO_eckd_data *) data, - fdata->start_unit, 0, rpt*nr_tracks, - DASD_ECKD_CCW_WRITE_CKD, base, + fdata->start_unit, 0, rpt, + DASD_ECKD_CCW_WRITE_CKD, device, fdata->blksize); data += sizeof(struct LO_eckd_data); break; case 0x01: /* Write record zero + format track. */ - prefix(ccw++, (struct PFX_eckd_data *) data, - fdata->start_unit, fdata->stop_unit, - DASD_ECKD_CCW_WRITE_RECORD_ZERO, - base, startdev); - data += sizeof(struct PFX_eckd_data); + define_extent(ccw++, (struct DE_eckd_data *) data, + fdata->start_unit, fdata->start_unit, + DASD_ECKD_CCW_WRITE_RECORD_ZERO, + device); + data += sizeof(struct DE_eckd_data); ccw[-1].flags |= CCW_FLAG_CC; locate_record(ccw++, (struct LO_eckd_data *) data, - fdata->start_unit, 0, rpt * nr_tracks + 1, - DASD_ECKD_CCW_WRITE_RECORD_ZERO, base, - base->block->bp_block); + fdata->start_unit, 0, rpt + 1, + DASD_ECKD_CCW_WRITE_RECORD_ZERO, device, + device->block->bp_block); data += sizeof(struct LO_eckd_data); break; case 0x04: /* Invalidate track. */ - prefix(ccw++, (struct PFX_eckd_data *) data, - fdata->start_unit, fdata->stop_unit, - DASD_ECKD_CCW_WRITE_CKD, base, startdev); - data += sizeof(struct PFX_eckd_data); + define_extent(ccw++, (struct DE_eckd_data *) data, + fdata->start_unit, fdata->start_unit, + DASD_ECKD_CCW_WRITE_CKD, device); + data += sizeof(struct DE_eckd_data); ccw[-1].flags |= CCW_FLAG_CC; locate_record(ccw++, (struct LO_eckd_data *) data, fdata->start_unit, 0, 1, - DASD_ECKD_CCW_WRITE_CKD, base, 8); + DASD_ECKD_CCW_WRITE_CKD, device, 8); data += sizeof(struct LO_eckd_data); break; } - - for (j = 0; j < nr_tracks; j++) { - /* calculate cylinder and head for the current track */ - set_ch_t(&address, - (fdata->start_unit + j) / - base_priv->rdc_data.trk_per_cyl, - (fdata->start_unit + j) % - base_priv->rdc_data.trk_per_cyl); - if (intensity & 0x01) { /* write record zero */ - ect = (struct eckd_count *) data; - data += sizeof(struct eckd_count); - ect->cyl = address.cyl; - ect->head = address.head; - ect->record = 0; - ect->kl = 0; - ect->dl = 8; - ccw[-1].flags |= CCW_FLAG_CC; - ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO; - ccw->flags = CCW_FLAG_SLI; - ccw->count = 8; - ccw->cda = (__u32)(addr_t) ect; - ccw++; - } - if ((intensity & ~0x08) & 0x04) { /* erase track */ + if (intensity & 0x01) { /* write record zero */ + ect = (struct eckd_count *) data; + data += sizeof(struct eckd_count); + ect->cyl = address.cyl; + ect->head = address.head; + ect->record = 0; + ect->kl = 0; + ect->dl = 8; + ccw[-1].flags |= CCW_FLAG_CC; + ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO; + ccw->flags = CCW_FLAG_SLI; + ccw->count = 8; + ccw->cda = (__u32)(addr_t) ect; + ccw++; + } + if ((intensity & ~0x08) & 0x04) { /* erase track */ + ect = (struct eckd_count *) data; + data += sizeof(struct eckd_count); + ect->cyl = address.cyl; + ect->head = address.head; + ect->record = 1; + ect->kl = 0; + ect->dl = 0; + ccw[-1].flags |= CCW_FLAG_CC; + ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD; + ccw->flags = CCW_FLAG_SLI; + ccw->count = 8; + ccw->cda = (__u32)(addr_t) ect; + } else { /* write remaining records */ + for (i = 0; i < rpt; i++) { ect = (struct eckd_count *) data; data += sizeof(struct eckd_count); ect->cyl = address.cyl; ect->head = address.head; - ect->record = 1; + ect->record = i + 1; ect->kl = 0; - ect->dl = 0; + ect->dl = fdata->blksize; + /* Check for special tracks 0-1 when formatting CDL */ + if ((intensity & 0x08) && + fdata->start_unit == 0) { + if (i < 3) { + ect->kl = 4; + ect->dl = sizes_trk0[i] - 4; + } + } + if ((intensity & 0x08) && + fdata->start_unit == 1) { + ect->kl = 44; + ect->dl = LABEL_SIZE - 44; + } ccw[-1].flags |= CCW_FLAG_CC; ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD; ccw->flags = CCW_FLAG_SLI; ccw->count = 8; ccw->cda = (__u32)(addr_t) ect; - } else { /* write remaining records */ - for (i = 0; i < rpt; i++) { - ect = (struct eckd_count *) data; - data += sizeof(struct eckd_count); - ect->cyl = address.cyl; - ect->head = address.head; - ect->record = i + 1; - ect->kl = 0; - ect->dl = fdata->blksize; - /* - * Check for special tracks 0-1 - * when formatting CDL - */ - if ((intensity & 0x08) && - fdata->start_unit == 0) { - if (i < 3) { - ect->kl = 4; - ect->dl = sizes_trk0[i] - 4; - } - } - if ((intensity & 0x08) && - fdata->start_unit == 1) { - ect->kl = 44; - ect->dl = LABEL_SIZE - 44; - } - ccw[-1].flags |= CCW_FLAG_CC; - if (i != 0 || j == 0) - ccw->cmd_code = - DASD_ECKD_CCW_WRITE_CKD; - else - ccw->cmd_code = - DASD_ECKD_CCW_WRITE_CKD_MT; - ccw->flags = CCW_FLAG_SLI; - ccw->count = 8; - ccw->cda = (__u32)(addr_t) ect; - ccw++; - } + ccw++; } } - - fcp->startdev = startdev; - fcp->memdev = startdev; + fcp->startdev = device; + fcp->memdev = device; fcp->retries = 256; - fcp->expires = startdev->default_expires * HZ; fcp->buildclk = get_tod_clock(); fcp->status = DASD_CQR_FILLED; - return fcp; } -static int -dasd_eckd_format_device(struct dasd_device *base, - struct format_data_t *fdata) -{ - struct dasd_ccw_req *cqr, *n; - struct dasd_block *block; - struct dasd_eckd_private *private; - struct list_head format_queue; - struct dasd_device *device; - int old_stop, format_step; - int step, rc = 0; - - block = base->block; - private = (struct dasd_eckd_private *) base->private; - - /* Sanity checks. */ - if (fdata->start_unit >= - (private->real_cyl * private->rdc_data.trk_per_cyl)) { - dev_warn(&base->cdev->dev, - "Start track number %u used in formatting is too big\n", - fdata->start_unit); - return -EINVAL; - } - if (fdata->stop_unit >= - (private->real_cyl * private->rdc_data.trk_per_cyl)) { - dev_warn(&base->cdev->dev, - "Stop track number %u used in formatting is too big\n", - fdata->stop_unit); - return -EINVAL; - } - if (fdata->start_unit > fdata->stop_unit) { - dev_warn(&base->cdev->dev, - "Start track %u used in formatting exceeds end track\n", - fdata->start_unit); - return -EINVAL; - } - if (dasd_check_blocksize(fdata->blksize) != 0) { - dev_warn(&base->cdev->dev, - "The DASD cannot be formatted with block size %u\n", - fdata->blksize); - return -EINVAL; - } - - INIT_LIST_HEAD(&format_queue); - old_stop = fdata->stop_unit; - - while (fdata->start_unit <= 1) { - fdata->stop_unit = fdata->start_unit; - cqr = dasd_eckd_build_format(base, fdata); - list_add(&cqr->blocklist, &format_queue); - - fdata->stop_unit = old_stop; - fdata->start_unit++; - - if (fdata->start_unit > fdata->stop_unit) - goto sleep; - } - -retry: - format_step = 255 / recs_per_track(&private->rdc_data, 0, - fdata->blksize); - while (fdata->start_unit <= old_stop) { - step = fdata->stop_unit - fdata->start_unit + 1; - if (step > format_step) - fdata->stop_unit = fdata->start_unit + format_step - 1; - - cqr = dasd_eckd_build_format(base, fdata); - if (IS_ERR(cqr)) { - if (PTR_ERR(cqr) == -ENOMEM) { - /* - * not enough memory available - * go to out and start requests - * retry after first requests were finished - */ - fdata->stop_unit = old_stop; - goto sleep; - } else - return PTR_ERR(cqr); - } - list_add(&cqr->blocklist, &format_queue); - - fdata->start_unit = fdata->stop_unit + 1; - fdata->stop_unit = old_stop; - } - -sleep: - dasd_sleep_on_queue(&format_queue); - - list_for_each_entry_safe(cqr, n, &format_queue, blocklist) { - device = cqr->startdev; - private = (struct dasd_eckd_private *) device->private; - if (cqr->status == DASD_CQR_FAILED) - rc = -EIO; - list_del_init(&cqr->blocklist); - dasd_sfree_request(cqr, device); - private->count--; - } - - /* - * in case of ENOMEM we need to retry after - * first requests are finished - */ - if (fdata->start_unit <= fdata->stop_unit) - goto retry; - - return rc; -} - static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr) { cqr->status = DASD_CQR_FILLED; @@ -4432,9 +4305,8 @@ static struct dasd_discipline dasd_eckd_discipline = { .uncheck_device = dasd_eckd_uncheck_device, .do_analysis = dasd_eckd_do_analysis, .verify_path = dasd_eckd_verify_path, - .basic_to_ready = dasd_eckd_basic_to_ready, + .ready_to_online = dasd_eckd_ready_to_online, .online_to_ready = dasd_eckd_online_to_ready, - .ready_to_basic = dasd_eckd_ready_to_basic, .fill_geometry = dasd_eckd_fill_geometry, .start_IO = dasd_start_IO, .term_IO = dasd_term_IO, diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index 0785bd9bd5b6..899e3f5a56e5 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -300,11 +300,10 @@ struct dasd_discipline { * Last things to do when a device is set online, and first things * when it is set offline. */ - int (*basic_to_ready) (struct dasd_device *); + int (*ready_to_online) (struct dasd_device *); int (*online_to_ready) (struct dasd_device *); - int (*ready_to_basic) (struct dasd_device *); - /* (struct dasd_device *); + /* * Device operation functions. build_cp creates a ccw chain for * a block device request, start_io starts the request and * term_IO cancels it (e.g. in case of a timeout). format_device @@ -318,8 +317,8 @@ struct dasd_discipline { int (*start_IO) (struct dasd_ccw_req *); int (*term_IO) (struct dasd_ccw_req *); void (*handle_terminated_request) (struct dasd_ccw_req *); - int (*format_device) (struct dasd_device *, - struct format_data_t *); + struct dasd_ccw_req *(*format_device) (struct dasd_device *, + struct format_data_t *); int (*free_cp) (struct dasd_ccw_req *, struct request *); /* @@ -673,7 +672,6 @@ int dasd_term_IO(struct dasd_ccw_req *); void dasd_schedule_device_bh(struct dasd_device *); void dasd_schedule_block_bh(struct dasd_block *); int dasd_sleep_on(struct dasd_ccw_req *); -int dasd_sleep_on_queue(struct list_head *); int dasd_sleep_on_immediatly(struct dasd_ccw_req *); int dasd_sleep_on_interruptible(struct dasd_ccw_req *); void dasd_device_set_timer(struct dasd_device *, int); diff --git a/trunk/drivers/s390/block/dasd_ioctl.c b/trunk/drivers/s390/block/dasd_ioctl.c index 8be1b51e9311..03c0e0444553 100644 --- a/trunk/drivers/s390/block/dasd_ioctl.c +++ b/trunk/drivers/s390/block/dasd_ioctl.c @@ -143,12 +143,12 @@ static int dasd_ioctl_resume(struct dasd_block *block) /* * performs formatting of _device_ according to _fdata_ * Note: The discipline's format_function is assumed to deliver formatting - * commands to format multiple units of the device. In terms of the ECKD - * devices this means CCWs are generated to format multiple tracks. + * commands to format a single unit of the device. In terms of the ECKD + * devices this means CCWs are generated to format a single track. */ -static int -dasd_format(struct dasd_block *block, struct format_data_t *fdata) +static int dasd_format(struct dasd_block *block, struct format_data_t *fdata) { + struct dasd_ccw_req *cqr; struct dasd_device *base; int rc; @@ -157,8 +157,8 @@ dasd_format(struct dasd_block *block, struct format_data_t *fdata) return -EPERM; if (base->state != DASD_STATE_BASIC) { - pr_warn("%s: The DASD cannot be formatted while it is enabled\n", - dev_name(&base->cdev->dev)); + pr_warning("%s: The DASD cannot be formatted while it is " + "enabled\n", dev_name(&base->cdev->dev)); return -EBUSY; } @@ -178,10 +178,21 @@ dasd_format(struct dasd_block *block, struct format_data_t *fdata) bdput(bdev); } - rc = base->discipline->format_device(base, fdata); - if (rc) - return rc; - + while (fdata->start_unit <= fdata->stop_unit) { + cqr = base->discipline->format_device(base, fdata); + if (IS_ERR(cqr)) + return PTR_ERR(cqr); + rc = dasd_sleep_on_interruptible(cqr); + dasd_sfree_request(cqr, cqr->memdev); + if (rc) { + if (rc != -ERESTARTSYS) + pr_err("%s: Formatting unit %d failed with " + "rc=%d\n", dev_name(&base->cdev->dev), + fdata->start_unit, rc); + return rc; + } + fdata->start_unit++; + } return 0; } diff --git a/trunk/drivers/s390/block/scm_blk.c b/trunk/drivers/s390/block/scm_blk.c index b303cab76a7f..5ac9c935c151 100644 --- a/trunk/drivers/s390/block/scm_blk.c +++ b/trunk/drivers/s390/block/scm_blk.c @@ -307,7 +307,7 @@ static void scm_blk_handle_error(struct scm_request *scmrq) case EQC_WR_PROHIBIT: spin_lock_irqsave(&bdev->lock, flags); if (bdev->state != SCM_WR_PROHIBIT) - pr_info("%lx: Write access to the SCM increment is suspended\n", + pr_info("%lu: Write access to the SCM increment is suspended\n", (unsigned long) bdev->scmdev->address); bdev->state = SCM_WR_PROHIBIT; spin_unlock_irqrestore(&bdev->lock, flags); @@ -445,7 +445,7 @@ void scm_blk_set_available(struct scm_blk_dev *bdev) spin_lock_irqsave(&bdev->lock, flags); if (bdev->state == SCM_WR_PROHIBIT) - pr_info("%lx: Write access to the SCM increment is restored\n", + pr_info("%lu: Write access to the SCM increment is restored\n", (unsigned long) bdev->scmdev->address); bdev->state = SCM_OPER; spin_unlock_irqrestore(&bdev->lock, flags); @@ -463,15 +463,12 @@ static int __init scm_blk_init(void) goto out; scm_major = ret; - ret = scm_alloc_rqs(nr_requests); - if (ret) - goto out_free; + if (scm_alloc_rqs(nr_requests)) + goto out_unreg; scm_debug = debug_register("scm_log", 16, 1, 16); - if (!scm_debug) { - ret = -ENOMEM; + if (!scm_debug) goto out_free; - } debug_register_view(scm_debug, &debug_hex_ascii_view); debug_set_level(scm_debug, 2); @@ -486,6 +483,7 @@ static int __init scm_blk_init(void) debug_unregister(scm_debug); out_free: scm_free_rqs(); +out_unreg: unregister_blkdev(scm_major, "scm"); out: return ret; diff --git a/trunk/drivers/s390/block/scm_blk_cluster.c b/trunk/drivers/s390/block/scm_blk_cluster.c index c0d102e3a48b..f4bb61b0cea1 100644 --- a/trunk/drivers/s390/block/scm_blk_cluster.c +++ b/trunk/drivers/s390/block/scm_blk_cluster.c @@ -223,8 +223,6 @@ void scm_cluster_request_irq(struct scm_request *scmrq) bool scm_cluster_size_valid(void) { - if (write_cluster_size == 1 || write_cluster_size > 128) - return false; - - return !(write_cluster_size & (write_cluster_size - 1)); + return write_cluster_size == 0 || write_cluster_size == 32 || + write_cluster_size == 64 || write_cluster_size == 128; } diff --git a/trunk/drivers/s390/block/scm_drv.c b/trunk/drivers/s390/block/scm_drv.c index c98cf52d78d1..5f6180d6ff08 100644 --- a/trunk/drivers/s390/block/scm_drv.c +++ b/trunk/drivers/s390/block/scm_drv.c @@ -19,7 +19,7 @@ static void scm_notify(struct scm_device *scmdev, enum scm_event event) switch (event) { case SCM_CHANGE: - pr_info("%lx: The capabilities of the SCM increment changed\n", + pr_info("%lu: The capabilities of the SCM increment changed\n", (unsigned long) scmdev->address); SCM_LOG(2, "State changed"); SCM_LOG_STATE(2, scmdev); diff --git a/trunk/drivers/s390/char/con3215.c b/trunk/drivers/s390/char/con3215.c index eb5d22795c47..7b00fa634d40 100644 --- a/trunk/drivers/s390/char/con3215.c +++ b/trunk/drivers/s390/char/con3215.c @@ -502,7 +502,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length) raw3215_try_io(raw); raw->flags &= ~RAW3215_FLUSHING; #ifdef CONFIG_TN3215_CONSOLE - ccw_device_wait_idle(raw->cdev); + wait_cons_dev(); #endif /* Enough room freed up ? */ if (RAW3215_BUFFER_SIZE - raw->count >= length) @@ -858,7 +858,7 @@ static void con3215_flush(void) raw = raw3215[0]; /* console 3215 is the first one */ if (raw->port.flags & ASYNC_SUSPENDED) /* The console is still frozen for suspend. */ - if (ccw_device_force_console(raw->cdev)) + if (ccw_device_force_console()) /* Forcing didn't work, no panic message .. */ return; spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); diff --git a/trunk/drivers/s390/char/monreader.c b/trunk/drivers/s390/char/monreader.c index 0da3ae3cd63b..f4ff515db251 100644 --- a/trunk/drivers/s390/char/monreader.c +++ b/trunk/drivers/s390/char/monreader.c @@ -174,7 +174,8 @@ static void mon_free_mem(struct mon_private *monpriv) int i; for (i = 0; i < MON_MSGLIM; i++) - kfree(monpriv->msg_array[i]); + if (monpriv->msg_array[i]) + kfree(monpriv->msg_array[i]); kfree(monpriv); } diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index 24a08e8f19e1..4c9030a5b9f2 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -796,7 +796,7 @@ struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev) do { __raw3270_reset_device(rp); while (!raw3270_state_final(rp)) { - ccw_device_wait_idle(rp->cdev); + wait_cons_dev(); barrier(); } } while (rp->state != RAW3270_STATE_READY); @@ -810,7 +810,7 @@ raw3270_wait_cons_dev(struct raw3270 *rp) unsigned long flags; spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags); - ccw_device_wait_idle(rp->cdev); + wait_cons_dev(); spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); } @@ -1274,7 +1274,7 @@ void raw3270_pm_unfreeze(struct raw3270_view *view) rp = view->dev; if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) - ccw_device_force_console(rp->cdev); + ccw_device_force_console(); #endif } diff --git a/trunk/drivers/s390/char/sclp_cmd.c b/trunk/drivers/s390/char/sclp_cmd.c index 178836ec252b..cd798386b622 100644 --- a/trunk/drivers/s390/char/sclp_cmd.c +++ b/trunk/drivers/s390/char/sclp_cmd.c @@ -561,8 +561,6 @@ static void __init sclp_add_standby_memory(void) add_memory_merged(0); } -#define MEM_SCT_SIZE (1UL << SECTION_SIZE_BITS) - static void __init insert_increment(u16 rn, int standby, int assigned) { struct memory_increment *incr, *new_incr; @@ -575,7 +573,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) new_incr->rn = rn; new_incr->standby = standby; if (!standby) - new_incr->usecount = rzm > MEM_SCT_SIZE ? rzm/MEM_SCT_SIZE : 1; + new_incr->usecount = 1; last_rn = 0; prev = &sclp_mem_list; list_for_each_entry(incr, &sclp_mem_list, list) { diff --git a/trunk/drivers/s390/char/tty3270.c b/trunk/drivers/s390/char/tty3270.c index cee69dac3e18..b907dba24025 100644 --- a/trunk/drivers/s390/char/tty3270.c +++ b/trunk/drivers/s390/char/tty3270.c @@ -915,7 +915,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) int i, rc; /* Check if the tty3270 is already there. */ - view = raw3270_find_view(&tty3270_fn, tty->index + RAW3270_FIRSTMINOR); + view = raw3270_find_view(&tty3270_fn, tty->index); if (!IS_ERR(view)) { tp = container_of(view, struct tty3270, view); tty->driver_data = tp; @@ -927,16 +927,15 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) tp->inattr = TF_INPUT; return tty_port_install(&tp->port, driver, tty); } - if (tty3270_max_index < tty->index + 1) - tty3270_max_index = tty->index + 1; + if (tty3270_max_index < tty->index) + tty3270_max_index = tty->index; /* Allocate tty3270 structure on first open. */ tp = tty3270_alloc_view(); if (IS_ERR(tp)) return PTR_ERR(tp); - rc = raw3270_add_view(&tp->view, &tty3270_fn, - tty->index + RAW3270_FIRSTMINOR); + rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index); if (rc) { tty3270_free_view(tp); return rc; @@ -1847,12 +1846,12 @@ static const struct tty_operations tty3270_ops = { void tty3270_create_cb(int minor) { - tty_register_device(tty3270_driver, minor - RAW3270_FIRSTMINOR, NULL); + tty_register_device(tty3270_driver, minor, NULL); } void tty3270_destroy_cb(int minor) { - tty_unregister_device(tty3270_driver, minor - RAW3270_FIRSTMINOR); + tty_unregister_device(tty3270_driver, minor); } struct raw3270_notifier tty3270_notifier = @@ -1885,8 +1884,7 @@ static int __init tty3270_init(void) driver->driver_name = "tty3270"; driver->name = "3270/tty"; driver->major = IBM_TTY3270_MAJOR; - driver->minor_start = RAW3270_FIRSTMINOR; - driver->name_base = RAW3270_FIRSTMINOR; + driver->minor_start = 0; driver->type = TTY_DRIVER_TYPE_SYSTEM; driver->subtype = SYSTEM_TYPE_TTY; driver->init_termios = tty_std_termios; diff --git a/trunk/drivers/s390/char/zcore.c b/trunk/drivers/s390/char/zcore.c index 22820610022c..1d61a01576d2 100644 --- a/trunk/drivers/s390/char/zcore.c +++ b/trunk/drivers/s390/char/zcore.c @@ -127,7 +127,7 @@ static int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode) } if (mode == TO_USER) { if (copy_to_user((__force __user void*) dest + offs, buf, - count - offs)) + PAGE_SIZE)) return -EFAULT; } else memcpy(dest + offs, buf, count - offs); diff --git a/trunk/drivers/s390/cio/chp.c b/trunk/drivers/s390/cio/chp.c index 21fabc6d5a9c..50ad5fdd815d 100644 --- a/trunk/drivers/s390/cio/chp.c +++ b/trunk/drivers/s390/cio/chp.c @@ -376,26 +376,6 @@ static void chp_release(struct device *dev) kfree(cp); } -/** - * chp_update_desc - update channel-path description - * @chp - channel-path - * - * Update the channel-path description of the specified channel-path. - * Return zero on success, non-zero otherwise. - */ -int chp_update_desc(struct channel_path *chp) -{ - int rc; - - rc = chsc_determine_base_channel_path_desc(chp->chpid, &chp->desc); - if (rc) - return rc; - - rc = chsc_determine_fmt1_channel_path_desc(chp->chpid, &chp->desc_fmt1); - - return rc; -} - /** * chp_new - register a new channel-path * @chpid - channel-path ID @@ -423,7 +403,7 @@ int chp_new(struct chp_id chpid) mutex_init(&chp->lock); /* Obtain channel path description and fill it in. */ - ret = chp_update_desc(chp); + ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); if (ret) goto out_free; if ((chp->desc.flags & 0x80) == 0) { diff --git a/trunk/drivers/s390/cio/chp.h b/trunk/drivers/s390/cio/chp.h index 9284b785a06f..e1399dbee834 100644 --- a/trunk/drivers/s390/cio/chp.h +++ b/trunk/drivers/s390/cio/chp.h @@ -44,7 +44,6 @@ struct channel_path { struct mutex lock; /* Serialize access to below members. */ int state; struct channel_path_desc desc; - struct channel_path_desc_fmt1 desc_fmt1; /* Channel-measurement related stuff: */ int cmg; int shared; @@ -63,7 +62,6 @@ int chp_is_registered(struct chp_id chpid); void *chp_get_chp_desc(struct chp_id chpid); void chp_remove_cmg_attr(struct channel_path *chp); int chp_add_cmg_attr(struct channel_path *chp); -int chp_update_desc(struct channel_path *chp); int chp_new(struct chp_id chpid); void chp_cfg_schedule(struct chp_id chpid, int configure); void chp_cfg_cancel_deconfigure(struct chp_id chpid); diff --git a/trunk/drivers/s390/cio/chsc.c b/trunk/drivers/s390/cio/chsc.c index 8ea7d9b2c671..e16c553f6556 100644 --- a/trunk/drivers/s390/cio/chsc.c +++ b/trunk/drivers/s390/cio/chsc.c @@ -376,7 +376,7 @@ static void chsc_process_sei_chp_avail(struct chsc_sei_nt0_area *sei_area) continue; } mutex_lock(&chp->lock); - chp_update_desc(chp); + chsc_determine_base_channel_path_desc(chpid, &chp->desc); mutex_unlock(&chp->lock); } } @@ -631,8 +631,8 @@ int chsc_chp_vary(struct chp_id chpid, int on) * Redo PathVerification on the devices the chpid connects to */ if (on) { - /* Try to update the channel path description. */ - chp_update_desc(chp); + /* Try to update the channel path descritor. */ + chsc_determine_base_channel_path_desc(chpid, &chp->desc); for_each_subchannel_staged(s390_subchannel_vary_chpid_on, __s390_vary_chpid_on, &chpid); } else @@ -825,10 +825,9 @@ int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid, { struct chsc_response_struct *chsc_resp; struct chsc_scpd *scpd_area; - unsigned long flags; int ret; - spin_lock_irqsave(&chsc_page_lock, flags); + spin_lock_irq(&chsc_page_lock); scpd_area = chsc_page; ret = chsc_determine_channel_path_desc(chpid, 0, 0, 1, 0, scpd_area); if (ret) @@ -836,7 +835,7 @@ int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid, chsc_resp = (void *)&scpd_area->response; memcpy(desc, &chsc_resp->data, sizeof(*desc)); out: - spin_unlock_irqrestore(&chsc_page_lock, flags); + spin_unlock_irq(&chsc_page_lock); return ret; } diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index 935d80b4e9ce..986ef6a92a41 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -471,6 +471,15 @@ int cio_disable_subchannel(struct subchannel *sch) } EXPORT_SYMBOL_GPL(cio_disable_subchannel); +int cio_create_sch_lock(struct subchannel *sch) +{ + sch->lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL); + if (!sch->lock) + return -ENOMEM; + spin_lock_init(sch->lock); + return 0; +} + static int cio_check_devno_blacklisted(struct subchannel *sch) { if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) { @@ -527,19 +536,32 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) sprintf(dbf_txt, "valsch%x", schid.sch_no); CIO_TRACE_EVENT(4, dbf_txt); + /* Nuke all fields. */ + memset(sch, 0, sizeof(struct subchannel)); + + sch->schid = schid; + if (cio_is_console(schid)) { + sch->lock = cio_get_console_lock(); + } else { + err = cio_create_sch_lock(sch); + if (err) + goto out; + } + mutex_init(&sch->reg_mutex); + /* * The first subchannel that is not-operational (ccode==3) - * indicates that there aren't any more devices available. + * indicates that there aren't any more devices available. * If stsch gets an exception, it means the current subchannel set - * is not valid. + * is not valid. */ - ccode = stsch_err(schid, &sch->schib); + ccode = stsch_err (schid, &sch->schib); if (ccode) { err = (ccode == 3) ? -ENXIO : ccode; goto out; } + /* Copy subchannel type from path management control word. */ sch->st = sch->schib.pmcw.st; - sch->schid = schid; switch (sch->st) { case SUBCHANNEL_TYPE_IO: @@ -556,7 +578,11 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n", sch->schid.ssid, sch->schid.sch_no, sch->st); + return 0; out: + if (!cio_is_console(schid)) + kfree(sch->lock); + sch->lock = NULL; return err; } @@ -624,13 +650,15 @@ void __irq_entry do_IRQ(struct pt_regs *regs) } #ifdef CONFIG_CCW_CONSOLE -static struct subchannel *console_sch; +static struct subchannel console_subchannel; +static struct io_subchannel_private console_priv; +static int console_subchannel_in_use; /* * Use cio_tsch to update the subchannel status and call the interrupt handler - * if status had been pending. Called with the subchannel's lock held. + * if status had been pending. Called with the console_subchannel lock. */ -void cio_tsch(struct subchannel *sch) +static void cio_tsch(struct subchannel *sch) { struct irb *irb; int irq_context; @@ -647,7 +675,6 @@ void cio_tsch(struct subchannel *sch) local_bh_disable(); irq_enter(); } - kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL); if (sch->driver && sch->driver->irq) sch->driver->irq(sch); else @@ -658,90 +685,135 @@ void cio_tsch(struct subchannel *sch) } } -static int cio_test_for_console(struct subchannel_id schid, void *data) +void *cio_get_console_priv(void) { - struct schib schib; + return &console_priv; +} - if (stsch_err(schid, &schib) != 0) +/* + * busy wait for the next interrupt on the console + */ +void wait_cons_dev(void) +{ + if (!console_subchannel_in_use) + return; + + while (1) { + cio_tsch(&console_subchannel); + if (console_subchannel.schib.scsw.cmd.actl == 0) + break; + udelay_simple(100); + } +} + +static int +cio_test_for_console(struct subchannel_id schid, void *data) +{ + if (stsch_err(schid, &console_subchannel.schib) != 0) return -ENXIO; - if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && - (schib.pmcw.dev == console_devno)) { + if ((console_subchannel.schib.pmcw.st == SUBCHANNEL_TYPE_IO) && + console_subchannel.schib.pmcw.dnv && + (console_subchannel.schib.pmcw.dev == console_devno)) { console_irq = schid.sch_no; return 1; /* found */ } return 0; } -static int cio_get_console_sch_no(void) + +static int +cio_get_console_sch_no(void) { struct subchannel_id schid; - struct schib schib; - + init_subchannel_id(&schid); if (console_irq != -1) { /* VM provided us with the irq number of the console. */ schid.sch_no = console_irq; - if (stsch_err(schid, &schib) != 0 || - (schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv) + if (stsch_err(schid, &console_subchannel.schib) != 0 || + (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) || + !console_subchannel.schib.pmcw.dnv) return -1; - console_devno = schib.pmcw.dev; + console_devno = console_subchannel.schib.pmcw.dev; } else if (console_devno != -1) { /* At least the console device number is known. */ for_each_subchannel(cio_test_for_console, NULL); + if (console_irq == -1) + return -1; + } else { + /* unlike in 2.4, we cannot autoprobe here, since + * the channel subsystem is not fully initialized. + * With some luck, the HWC console can take over */ + return -1; } return console_irq; } -struct subchannel *cio_probe_console(void) +struct subchannel * +cio_probe_console(void) { - struct subchannel_id schid; - struct subchannel *sch; int sch_no, ret; + struct subchannel_id schid; + if (xchg(&console_subchannel_in_use, 1) != 0) + return ERR_PTR(-EBUSY); sch_no = cio_get_console_sch_no(); if (sch_no == -1) { + console_subchannel_in_use = 0; pr_warning("No CCW console was found\n"); return ERR_PTR(-ENODEV); } + memset(&console_subchannel, 0, sizeof(struct subchannel)); init_subchannel_id(&schid); schid.sch_no = sch_no; - sch = css_alloc_subchannel(schid); - if (IS_ERR(sch)) - return sch; + ret = cio_validate_subchannel(&console_subchannel, schid); + if (ret) { + console_subchannel_in_use = 0; + return ERR_PTR(-ENODEV); + } + /* + * enable console I/O-interrupt subclass + */ isc_register(CONSOLE_ISC); - sch->config.isc = CONSOLE_ISC; - sch->config.intparm = (u32)(addr_t)sch; - ret = cio_commit_config(sch); + console_subchannel.config.isc = CONSOLE_ISC; + console_subchannel.config.intparm = (u32)(addr_t)&console_subchannel; + ret = cio_commit_config(&console_subchannel); if (ret) { isc_unregister(CONSOLE_ISC); - put_device(&sch->dev); + console_subchannel_in_use = 0; return ERR_PTR(ret); } - console_sch = sch; - return sch; + return &console_subchannel; } -int cio_is_console(struct subchannel_id schid) +void +cio_release_console(void) { - if (!console_sch) - return 0; - return schid_equal(&schid, &console_sch->schid); + console_subchannel.config.intparm = 0; + cio_commit_config(&console_subchannel); + isc_unregister(CONSOLE_ISC); + console_subchannel_in_use = 0; } -void cio_register_early_subchannels(void) +/* Bah... hack to catch console special sausages. */ +int +cio_is_console(struct subchannel_id schid) { - int ret; - - if (!console_sch) - return; + if (!console_subchannel_in_use) + return 0; + return schid_equal(&schid, &console_subchannel.schid); +} - ret = css_register_subchannel(console_sch); - if (ret) - put_device(&console_sch->dev); +struct subchannel * +cio_get_console_subchannel(void) +{ + if (!console_subchannel_in_use) + return NULL; + return &console_subchannel; } -#endif /* CONFIG_CCW_CONSOLE */ +#endif static int __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) { diff --git a/trunk/drivers/s390/cio/cio.h b/trunk/drivers/s390/cio/cio.h index d62f5e7f3cf1..4a1ff5c2eb88 100644 --- a/trunk/drivers/s390/cio/cio.h +++ b/trunk/drivers/s390/cio/cio.h @@ -121,18 +121,23 @@ extern int cio_commit_config(struct subchannel *sch); int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key); int cio_tm_intrg(struct subchannel *sch); +int cio_create_sch_lock(struct subchannel *); void do_adapter_IO(u8 isc); void do_IRQ(struct pt_regs *); /* Use with care. */ #ifdef CONFIG_CCW_CONSOLE extern struct subchannel *cio_probe_console(void); +extern void cio_release_console(void); extern int cio_is_console(struct subchannel_id); -extern void cio_register_early_subchannels(void); -extern void cio_tsch(struct subchannel *sch); +extern struct subchannel *cio_get_console_subchannel(void); +extern spinlock_t * cio_get_console_lock(void); +extern void *cio_get_console_priv(void); #else #define cio_is_console(schid) 0 -static inline void cio_register_early_subchannels(void) {} +#define cio_get_console_subchannel() NULL +#define cio_get_console_lock() NULL +#define cio_get_console_priv() NULL #endif #endif diff --git a/trunk/drivers/s390/cio/css.c b/trunk/drivers/s390/cio/css.c index 1ebe5d3ddebb..a239237d43f3 100644 --- a/trunk/drivers/s390/cio/css.c +++ b/trunk/drivers/s390/cio/css.c @@ -137,53 +137,37 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), static void css_sch_todo(struct work_struct *work); -static int css_sch_create_locks(struct subchannel *sch) -{ - sch->lock = kmalloc(sizeof(*sch->lock), GFP_KERNEL); - if (!sch->lock) - return -ENOMEM; - - spin_lock_init(sch->lock); - mutex_init(&sch->reg_mutex); - - return 0; -} - -static void css_subchannel_release(struct device *dev) -{ - struct subchannel *sch = to_subchannel(dev); - - sch->config.intparm = 0; - cio_commit_config(sch); - kfree(sch->lock); - kfree(sch); -} - -struct subchannel *css_alloc_subchannel(struct subchannel_id schid) +static struct subchannel * +css_alloc_subchannel(struct subchannel_id schid) { struct subchannel *sch; int ret; - sch = kzalloc(sizeof(*sch), GFP_KERNEL | GFP_DMA); - if (!sch) + sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA); + if (sch == NULL) return ERR_PTR(-ENOMEM); - - ret = cio_validate_subchannel(sch, schid); - if (ret < 0) - goto err; - - ret = css_sch_create_locks(sch); - if (ret) - goto err; - + ret = cio_validate_subchannel (sch, schid); + if (ret < 0) { + kfree(sch); + return ERR_PTR(ret); + } INIT_WORK(&sch->todo_work, css_sch_todo); - sch->dev.release = &css_subchannel_release; - device_initialize(&sch->dev); return sch; +} + +static void +css_subchannel_release(struct device *dev) +{ + struct subchannel *sch; -err: - kfree(sch); - return ERR_PTR(ret); + sch = to_subchannel(dev); + if (!cio_is_console(sch->schid)) { + /* Reset intparm to zeroes. */ + sch->config.intparm = 0; + cio_commit_config(sch); + kfree(sch->lock); + kfree(sch); + } } static int css_sch_device_register(struct subchannel *sch) @@ -193,7 +177,7 @@ static int css_sch_device_register(struct subchannel *sch) mutex_lock(&sch->reg_mutex); dev_set_name(&sch->dev, "0.%x.%04x", sch->schid.ssid, sch->schid.sch_no); - ret = device_add(&sch->dev); + ret = device_register(&sch->dev); mutex_unlock(&sch->reg_mutex); return ret; } @@ -244,11 +228,16 @@ void css_update_ssd_info(struct subchannel *sch) { int ret; - ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info); - if (ret) + if (cio_is_console(sch->schid)) { + /* Console is initialized too early for functions requiring + * memory allocation. */ ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw); - - ssd_register_chpids(&sch->ssd_info); + } else { + ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info); + if (ret) + ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw); + ssd_register_chpids(&sch->ssd_info); + } } static ssize_t type_show(struct device *dev, struct device_attribute *attr, @@ -286,13 +275,14 @@ static const struct attribute_group *default_subch_attr_groups[] = { NULL, }; -int css_register_subchannel(struct subchannel *sch) +static int css_register_subchannel(struct subchannel *sch) { int ret; /* Initialize the subchannel structure */ sch->dev.parent = &channel_subsystems[0]->device; sch->dev.bus = &css_bus_type; + sch->dev.release = &css_subchannel_release; sch->dev.groups = default_subch_attr_groups; /* * We don't want to generate uevents for I/O subchannels that don't @@ -324,19 +314,23 @@ int css_register_subchannel(struct subchannel *sch) return ret; } -static int css_probe_device(struct subchannel_id schid) +int css_probe_device(struct subchannel_id schid) { - struct subchannel *sch; int ret; + struct subchannel *sch; - sch = css_alloc_subchannel(schid); - if (IS_ERR(sch)) - return PTR_ERR(sch); - + if (cio_is_console(schid)) + sch = cio_get_console_subchannel(); + else { + sch = css_alloc_subchannel(schid); + if (IS_ERR(sch)) + return PTR_ERR(sch); + } ret = css_register_subchannel(sch); - if (ret) - put_device(&sch->dev); - + if (ret) { + if (!cio_is_console(schid)) + put_device(&sch->dev); + } return ret; } @@ -776,7 +770,7 @@ static int __init setup_css(int nr) css->pseudo_subchannel->dev.release = css_subchannel_release; dev_set_name(&css->pseudo_subchannel->dev, "defunct"); mutex_init(&css->pseudo_subchannel->reg_mutex); - ret = css_sch_create_locks(css->pseudo_subchannel); + ret = cio_create_sch_lock(css->pseudo_subchannel); if (ret) { kfree(css->pseudo_subchannel); return ret; @@ -876,7 +870,8 @@ static struct notifier_block css_power_notifier = { /* * Now that the driver core is running, we can setup our channel subsystem. - * The struct subchannel's are created during probing. + * The struct subchannel's are created during probing (except for the + * static console subchannel). */ static int __init css_bus_init(void) { @@ -1055,8 +1050,6 @@ int css_complete_work(void) */ static int __init channel_subsystem_init_sync(void) { - /* Register subchannels which are already in use. */ - cio_register_early_subchannels(); /* Start initial subchannel evaluation. */ css_schedule_eval_all(); css_complete_work(); @@ -1072,8 +1065,9 @@ void channel_subsystem_reinit(void) chsc_enable_facility(CHSC_SDA_OC_MSS); chp_id_for_each(&chpid) { chp = chpid_to_chp(chpid); - if (chp) - chp_update_desc(chp); + if (!chp) + continue; + chsc_determine_base_channel_path_desc(chpid, &chp->desc); } } diff --git a/trunk/drivers/s390/cio/css.h b/trunk/drivers/s390/cio/css.h index b1de60335238..4af3dfe70ef5 100644 --- a/trunk/drivers/s390/cio/css.h +++ b/trunk/drivers/s390/cio/css.h @@ -101,8 +101,7 @@ extern int css_driver_register(struct css_driver *); extern void css_driver_unregister(struct css_driver *); extern void css_sch_device_unregister(struct subchannel *); -extern int css_register_subchannel(struct subchannel *); -extern struct subchannel *css_alloc_subchannel(struct subchannel_id); +extern int css_probe_device(struct subchannel_id); extern struct subchannel *get_subchannel_by_schid(struct subchannel_id); extern int css_init_done; extern int max_ssid; @@ -110,6 +109,7 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), int (*fn_unknown)(struct subchannel_id, void *), void *data); extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); +extern void css_reiterate_subchannels(void); void css_update_ssd_info(struct subchannel *sch); struct channel_subsystem { diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 1ab5f6c36d9b..c6767f5a58b2 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -44,10 +43,6 @@ static DEFINE_SPINLOCK(recovery_lock); static int recovery_phase; static const unsigned long recovery_delay[] = { 3, 30, 300 }; -static atomic_t ccw_device_init_count = ATOMIC_INIT(0); -static DECLARE_WAIT_QUEUE_HEAD(ccw_device_init_wq); -static struct bus_type ccw_bus_type; - /******************* bus type handling ***********************/ /* The Linux driver model distinguishes between a bus type and @@ -132,6 +127,8 @@ static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env) return ret; } +static struct bus_type ccw_bus_type; + static void io_subchannel_irq(struct subchannel *); static int io_subchannel_probe(struct subchannel *); static int io_subchannel_remove(struct subchannel *); @@ -140,6 +137,8 @@ static int io_subchannel_sch_event(struct subchannel *, int); static int io_subchannel_chp_event(struct subchannel *, struct chp_link *, int); static void recovery_func(unsigned long data); +wait_queue_head_t ccw_device_init_wq; +atomic_t ccw_device_init_count; static struct css_device_id io_subchannel_ids[] = { { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, }, @@ -192,7 +191,10 @@ int __init io_subchannel_init(void) { int ret; + init_waitqueue_head(&ccw_device_init_wq); + atomic_set(&ccw_device_init_count, 0); setup_timer(&recovery_timer, recovery_func, 0); + ret = bus_register(&ccw_bus_type); if (ret) return ret; @@ -1084,14 +1086,19 @@ static int io_subchannel_probe(struct subchannel *sch) dev_set_uevent_suppress(&sch->dev, 0); kobject_uevent(&sch->dev.kobj, KOBJ_ADD); cdev = sch_get_cdev(sch); - rc = ccw_device_register(cdev); - if (rc) { - /* Release online reference. */ - put_device(&cdev->dev); - goto out_schedule; - } - if (atomic_dec_and_test(&ccw_device_init_count)) - wake_up(&ccw_device_init_wq); + cdev->dev.groups = ccwdev_attr_groups; + device_initialize(&cdev->dev); + cdev->private->flags.initialized = 1; + ccw_device_register(cdev); + /* + * Check if the device is already online. If it is + * the reference count needs to be corrected since we + * didn't obtain a reference in ccw_device_set_online. + */ + if (cdev->private->state != DEV_STATE_NOT_OPER && + cdev->private->state != DEV_STATE_OFFLINE && + cdev->private->state != DEV_STATE_BOXED) + get_device(&cdev->dev); return 0; } io_subchannel_init_fields(sch); @@ -1573,102 +1580,88 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) } #ifdef CONFIG_CCW_CONSOLE +static struct ccw_device console_cdev; +static struct ccw_device_private console_private; +static int console_cdev_in_use; + +static DEFINE_SPINLOCK(ccw_console_lock); + +spinlock_t * cio_get_console_lock(void) +{ + return &ccw_console_lock; +} + static int ccw_device_console_enable(struct ccw_device *cdev, struct subchannel *sch) { + struct io_subchannel_private *io_priv = cio_get_console_priv(); int rc; + /* Attach subchannel private data. */ + memset(io_priv, 0, sizeof(*io_priv)); + set_io_private(sch, io_priv); io_subchannel_init_fields(sch); rc = cio_commit_config(sch); if (rc) return rc; sch->driver = &io_subchannel_driver; + /* Initialize the ccw_device structure. */ + cdev->dev.parent= &sch->dev; sch_set_cdev(sch, cdev); io_subchannel_recog(cdev, sch); /* Now wait for the async. recognition to come to an end. */ spin_lock_irq(cdev->ccwlock); while (!dev_fsm_final_state(cdev)) - ccw_device_wait_idle(cdev); - - /* Hold on to an extra reference while device is online. */ - get_device(&cdev->dev); - rc = ccw_device_online(cdev); - if (rc) + wait_cons_dev(); + rc = -EIO; + if (cdev->private->state != DEV_STATE_OFFLINE) goto out_unlock; - + ccw_device_online(cdev); while (!dev_fsm_final_state(cdev)) - ccw_device_wait_idle(cdev); - - if (cdev->private->state == DEV_STATE_ONLINE) - cdev->online = 1; - else - rc = -EIO; + wait_cons_dev(); + if (cdev->private->state != DEV_STATE_ONLINE) + goto out_unlock; + rc = 0; out_unlock: spin_unlock_irq(cdev->ccwlock); - if (rc) /* Give up online reference since onlining failed. */ - put_device(&cdev->dev); return rc; } -struct ccw_device *ccw_device_probe_console(void) +struct ccw_device * +ccw_device_probe_console(void) { - struct io_subchannel_private *io_priv; - struct ccw_device *cdev; struct subchannel *sch; int ret; + if (xchg(&console_cdev_in_use, 1) != 0) + return ERR_PTR(-EBUSY); sch = cio_probe_console(); - if (IS_ERR(sch)) - return ERR_CAST(sch); - - io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA); - if (!io_priv) { - put_device(&sch->dev); - return ERR_PTR(-ENOMEM); + if (IS_ERR(sch)) { + console_cdev_in_use = 0; + return (void *) sch; } - cdev = io_subchannel_create_ccwdev(sch); - if (IS_ERR(cdev)) { - put_device(&sch->dev); - kfree(io_priv); - return cdev; - } - set_io_private(sch, io_priv); - ret = ccw_device_console_enable(cdev, sch); + memset(&console_cdev, 0, sizeof(struct ccw_device)); + memset(&console_private, 0, sizeof(struct ccw_device_private)); + console_cdev.private = &console_private; + console_private.cdev = &console_cdev; + console_private.int_class = IRQIO_CIO; + ret = ccw_device_console_enable(&console_cdev, sch); if (ret) { - set_io_private(sch, NULL); - put_device(&sch->dev); - put_device(&cdev->dev); - kfree(io_priv); + cio_release_console(); + console_cdev_in_use = 0; return ERR_PTR(ret); } - return cdev; -} - -/** - * ccw_device_wait_idle() - busy wait for device to become idle - * @cdev: ccw device - * - * Poll until activity control is zero, that is, no function or data - * transfer is pending/active. - * Called with device lock being held. - */ -void ccw_device_wait_idle(struct ccw_device *cdev) -{ - struct subchannel *sch = to_subchannel(cdev->dev.parent); - - while (1) { - cio_tsch(sch); - if (sch->schib.scsw.cmd.actl == 0) - break; - udelay_simple(100); - } + console_cdev.online = 1; + return &console_cdev; } static int ccw_device_pm_restore(struct device *dev); -int ccw_device_force_console(struct ccw_device *cdev) +int ccw_device_force_console(void) { - return ccw_device_pm_restore(&cdev->dev); + if (!console_cdev_in_use) + return -ENODEV; + return ccw_device_pm_restore(&console_cdev.dev); } EXPORT_SYMBOL_GPL(ccw_device_force_console); #endif diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index 8d1d29873172..7d4ecb65db00 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -81,6 +81,8 @@ dev_fsm_final_state(struct ccw_device *cdev) cdev->private->state == DEV_STATE_BOXED); } +extern wait_queue_head_t ccw_device_init_wq; +extern atomic_t ccw_device_init_count; int __init io_subchannel_init(void); void io_subchannel_recog_done(struct ccw_device *cdev); diff --git a/trunk/drivers/s390/cio/device_ops.c b/trunk/drivers/s390/cio/device_ops.c index 4845d64f2842..c77b6e06bf64 100644 --- a/trunk/drivers/s390/cio/device_ops.c +++ b/trunk/drivers/s390/cio/device_ops.c @@ -704,9 +704,9 @@ EXPORT_SYMBOL(ccw_device_tm_start_timeout); int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask) { struct subchannel *sch = to_subchannel(cdev->dev.parent); - struct channel_path *chp; + struct channel_path_desc_fmt1 desc; struct chp_id chpid; - int mdc = 0, i; + int mdc = 0, ret, i; /* Adjust requested path mask to excluded varied off paths. */ if (mask) @@ -719,20 +719,14 @@ int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask) if (!(mask & (0x80 >> i))) continue; chpid.id = sch->schib.pmcw.chpid[i]; - chp = chpid_to_chp(chpid); - if (!chp) - continue; - - mutex_lock(&chp->lock); - if (!chp->desc_fmt1.f) { - mutex_unlock(&chp->lock); + ret = chsc_determine_fmt1_channel_path_desc(chpid, &desc); + if (ret) + return ret; + if (!desc.f) return 0; - } - if (!chp->desc_fmt1.r) + if (!desc.r) mdc = 1; - mdc = mdc ? min_t(int, mdc, chp->desc_fmt1.mdc) : - chp->desc_fmt1.mdc; - mutex_unlock(&chp->lock); + mdc = mdc ? min(mdc, (int)desc.mdc) : desc.mdc; } return mdc; diff --git a/trunk/drivers/s390/cio/idset.c b/trunk/drivers/s390/cio/idset.c index 5a999084a229..65d13e38803f 100644 --- a/trunk/drivers/s390/cio/idset.c +++ b/trunk/drivers/s390/cio/idset.c @@ -17,7 +17,7 @@ struct idset { static inline unsigned long bitmap_size(int num_ssid, int num_id) { - return BITS_TO_LONGS(num_ssid * num_id) * sizeof(unsigned long); + return __BITOPS_WORDS(num_ssid * num_id) * sizeof(unsigned long); } static struct idset *idset_new(int num_ssid, int num_id) diff --git a/trunk/drivers/s390/net/qeth_core.h b/trunk/drivers/s390/net/qeth_core.h index 6ccb7457746b..8c0622399fcd 100644 --- a/trunk/drivers/s390/net/qeth_core.h +++ b/trunk/drivers/s390/net/qeth_core.h @@ -769,7 +769,6 @@ struct qeth_card { unsigned long thread_start_mask; unsigned long thread_allowed_mask; unsigned long thread_running_mask; - struct task_struct *recovery_task; spinlock_t ip_lock; struct list_head ip_list; struct list_head *ip_tbd_list; @@ -863,8 +862,6 @@ extern struct qeth_card_list_struct qeth_core_card_list; extern struct kmem_cache *qeth_core_header_cache; extern struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS]; -void qeth_set_recovery_task(struct qeth_card *); -void qeth_clear_recovery_task(struct qeth_card *); void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int); int qeth_threads_running(struct qeth_card *, unsigned long); int qeth_wait_for_threads(struct qeth_card *, unsigned long); diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index 451f92020599..0d73a999983d 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -177,23 +177,6 @@ const char *qeth_get_cardname_short(struct qeth_card *card) return "n/a"; } -void qeth_set_recovery_task(struct qeth_card *card) -{ - card->recovery_task = current; -} -EXPORT_SYMBOL_GPL(qeth_set_recovery_task); - -void qeth_clear_recovery_task(struct qeth_card *card) -{ - card->recovery_task = NULL; -} -EXPORT_SYMBOL_GPL(qeth_clear_recovery_task); - -static bool qeth_is_recovery_task(const struct qeth_card *card) -{ - return card->recovery_task == current; -} - void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads, int clear_start_mask) { @@ -222,8 +205,6 @@ EXPORT_SYMBOL_GPL(qeth_threads_running); int qeth_wait_for_threads(struct qeth_card *card, unsigned long threads) { - if (qeth_is_recovery_task(card)) - return 0; return wait_event_interruptible(card->wait_q, qeth_threads_running(card, threads) == 0); } diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index 155b101bd730..d690166efeaf 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -1143,7 +1143,6 @@ static int qeth_l2_recover(void *ptr) QETH_CARD_TEXT(card, 2, "recover2"); dev_warn(&card->gdev->dev, "A recovery process has been started for the device\n"); - qeth_set_recovery_task(card); __qeth_l2_set_offline(card->gdev, 1); rc = __qeth_l2_set_online(card->gdev, 1); if (!rc) @@ -1154,7 +1153,6 @@ static int qeth_l2_recover(void *ptr) dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } - qeth_clear_recovery_task(card); qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); return 0; diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index 1f7edf1b26c3..8710337dab3e 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -3515,7 +3515,6 @@ static int qeth_l3_recover(void *ptr) QETH_CARD_TEXT(card, 2, "recover2"); dev_warn(&card->gdev->dev, "A recovery process has been started for the device\n"); - qeth_set_recovery_task(card); __qeth_l3_set_offline(card->gdev, 1); rc = __qeth_l3_set_online(card->gdev, 1); if (!rc) @@ -3526,7 +3525,6 @@ static int qeth_l3_recover(void *ptr) dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } - qeth_clear_recovery_task(card); qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); return 0; diff --git a/trunk/drivers/sbus/char/bbc_i2c.c b/trunk/drivers/sbus/char/bbc_i2c.c index c1441ed282eb..1a9d1e3ce64c 100644 --- a/trunk/drivers/sbus/char/bbc_i2c.c +++ b/trunk/drivers/sbus/char/bbc_i2c.c @@ -282,7 +282,7 @@ static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static void reset_one_i2c(struct bbc_i2c_bus *bp) +static void __init reset_one_i2c(struct bbc_i2c_bus *bp) { writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0); writeb(bp->own, bp->i2c_control_regs + 0x1); @@ -291,7 +291,7 @@ static void reset_one_i2c(struct bbc_i2c_bus *bp) writeb(I2C_PCF_IDLE, bp->i2c_control_regs + 0x0); } -static struct bbc_i2c_bus * attach_one_i2c(struct platform_device *op, int index) +static struct bbc_i2c_bus * __init attach_one_i2c(struct platform_device *op, int index) { struct bbc_i2c_bus *bp; struct device_node *dp; diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 90bc7bd00966..2daf4b0da434 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -940,7 +940,6 @@ static int bnx2fc_libfc_config(struct fc_lport *lport) fc_exch_init(lport); fc_rport_init(lport); fc_disc_init(lport); - fc_disc_config(lport, lport); return 0; } @@ -2134,7 +2133,6 @@ static int _bnx2fc_create(struct net_device *netdev, } ctlr = bnx2fc_to_ctlr(interface); - cdev = fcoe_ctlr_to_ctlr_dev(ctlr); interface->vlan_id = vlan_id; interface->timer_work_queue = @@ -2145,7 +2143,7 @@ static int _bnx2fc_create(struct net_device *netdev, goto ifput_err; } - lport = bnx2fc_if_create(interface, &cdev->dev, 0); + lport = bnx2fc_if_create(interface, &interface->hba->pcidev->dev, 0); if (!lport) { printk(KERN_ERR PFX "Failed to create interface (%s)\n", netdev->name); @@ -2161,6 +2159,8 @@ static int _bnx2fc_create(struct net_device *netdev, /* Make this master N_port */ ctlr->lp = lport; + cdev = fcoe_ctlr_to_ctlr_dev(ctlr); + if (link_state == BNX2FC_CREATE_LINK_UP) cdev->enabled = FCOE_CTLR_ENABLED; else diff --git a/trunk/drivers/scsi/fcoe/fcoe.c b/trunk/drivers/scsi/fcoe/fcoe.c index 9bfdc9a3f897..b5d92fc93c70 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.c +++ b/trunk/drivers/scsi/fcoe/fcoe.c @@ -490,6 +490,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) { struct net_device *netdev = fcoe->netdev; struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); + struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); rtnl_lock(); if (!fcoe->removed) @@ -500,6 +501,7 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) /* tear-down the FCoE controller */ fcoe_ctlr_destroy(fip); scsi_host_put(fip->lp->host); + fcoe_ctlr_device_delete(ctlr_dev); dev_put(netdev); module_put(THIS_MODULE); } @@ -2192,8 +2194,6 @@ static int fcoe_destroy(struct net_device *netdev) */ static void fcoe_destroy_work(struct work_struct *work) { - struct fcoe_ctlr_device *cdev; - struct fcoe_ctlr *ctlr; struct fcoe_port *port; struct fcoe_interface *fcoe; struct Scsi_Host *shost; @@ -2224,15 +2224,10 @@ static void fcoe_destroy_work(struct work_struct *work) mutex_lock(&fcoe_config_mutex); fcoe = port->priv; - ctlr = fcoe_to_ctlr(fcoe); - cdev = fcoe_ctlr_to_ctlr_dev(ctlr); - fcoe_if_destroy(port->lport); fcoe_interface_cleanup(fcoe); mutex_unlock(&fcoe_config_mutex); - - fcoe_ctlr_device_delete(cdev); } /** @@ -2340,9 +2335,7 @@ static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode, rc = -EIO; rtnl_unlock(); fcoe_interface_cleanup(fcoe); - mutex_unlock(&fcoe_config_mutex); - fcoe_ctlr_device_delete(ctlr_dev); - goto out; + goto out_nortnl; } /* Make this the "master" N_Port */ @@ -2382,8 +2375,8 @@ static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode, out_nodev: rtnl_unlock(); +out_nortnl: mutex_unlock(&fcoe_config_mutex); -out: return rc; } diff --git a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c index a76247201be5..08c3bc398da2 100644 --- a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c @@ -2814,47 +2814,6 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip) fc_lport_set_local_id(fip->lp, new_port_id); } -/** - * fcoe_ctlr_mode_set() - Set or reset the ctlr's mode - * @lport: The local port to be (re)configured - * @fip: The FCoE controller whose mode is changing - * @fip_mode: The new fip mode - * - * Note that the we shouldn't be changing the libfc discovery settings - * (fc_disc_config) while an lport is going through the libfc state - * machine. The mode can only be changed when a fcoe_ctlr device is - * disabled, so that should ensure that this routine is only called - * when nothing is happening. - */ -void fcoe_ctlr_mode_set(struct fc_lport *lport, struct fcoe_ctlr *fip, - enum fip_state fip_mode) -{ - void *priv; - - WARN_ON(lport->state != LPORT_ST_RESET && - lport->state != LPORT_ST_DISABLED); - - if (fip_mode == FIP_MODE_VN2VN) { - lport->rport_priv_size = sizeof(struct fcoe_rport); - lport->point_to_multipoint = 1; - lport->tt.disc_recv_req = fcoe_ctlr_disc_recv; - lport->tt.disc_start = fcoe_ctlr_disc_start; - lport->tt.disc_stop = fcoe_ctlr_disc_stop; - lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final; - priv = fip; - } else { - lport->rport_priv_size = 0; - lport->point_to_multipoint = 0; - lport->tt.disc_recv_req = NULL; - lport->tt.disc_start = NULL; - lport->tt.disc_stop = NULL; - lport->tt.disc_stop_final = NULL; - priv = lport; - } - - fc_disc_config(lport, priv); -} - /** * fcoe_libfc_config() - Sets up libfc related properties for local port * @lport: The local port to configure libfc for @@ -2874,9 +2833,21 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip, fc_exch_init(lport); fc_elsct_init(lport); fc_lport_init(lport); + if (fip->mode == FIP_MODE_VN2VN) + lport->rport_priv_size = sizeof(struct fcoe_rport); fc_rport_init(lport); - fc_disc_init(lport); - fcoe_ctlr_mode_set(lport, fip, fip->mode); + if (fip->mode == FIP_MODE_VN2VN) { + lport->point_to_multipoint = 1; + lport->tt.disc_recv_req = fcoe_ctlr_disc_recv; + lport->tt.disc_start = fcoe_ctlr_disc_start; + lport->tt.disc_stop = fcoe_ctlr_disc_stop; + lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final; + mutex_init(&lport->disc.disc_mutex); + INIT_LIST_HEAD(&lport->disc.rports); + lport->disc.priv = fip; + } else { + fc_disc_init(lport); + } return 0; } EXPORT_SYMBOL_GPL(fcoe_libfc_config); @@ -2904,7 +2875,6 @@ EXPORT_SYMBOL(fcoe_fcf_get_selected); void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev) { struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); - struct fc_lport *lport = ctlr->lp; mutex_lock(&ctlr->ctlr_mutex); switch (ctlr_dev->mode) { @@ -2918,7 +2888,5 @@ void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev) } mutex_unlock(&ctlr->ctlr_mutex); - - fcoe_ctlr_mode_set(lport, ctlr, ctlr->mode); } EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index d0fa4b6c551f..a044f593e8b9 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1899,8 +1899,8 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev) sdev->allow_restart = 1; blk_queue_rq_timeout(sdev->request_queue, 120 * HZ); } - spin_unlock_irqrestore(shost->host_lock, lock_flags); scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun); + spin_unlock_irqrestore(shost->host_lock, lock_flags); return 0; } diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 2197b57fb225..f328089a1060 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -5148,7 +5148,7 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) ipr_trace; } - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); + list_add_tail(&ipr_cmd->queue, &hrrq->hrrq_free_q); if (!ipr_is_naca_model(res)) res->needs_sync_complete = 1; @@ -9349,10 +9349,7 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - if (ioa_cfg->intr_flag == IPR_USE_MSIX) - rc = request_irq(ioa_cfg->vectors_info[0].vec, ipr_test_intr, 0, IPR_NAME, ioa_cfg); - else - rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg); + rc = request_irq(pdev->irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg); if (rc) { dev_err(&pdev->dev, "Can not assign irq %d\n", pdev->irq); return rc; @@ -9374,10 +9371,7 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - if (ioa_cfg->intr_flag == IPR_USE_MSIX) - free_irq(ioa_cfg->vectors_info[0].vec, ioa_cfg); - else - free_irq(pdev->irq, ioa_cfg); + free_irq(pdev->irq, ioa_cfg); LEAVE; @@ -9728,7 +9722,6 @@ static void __ipr_remove(struct pci_dev *pdev) spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); flush_work(&ioa_cfg->work_q); - INIT_LIST_HEAD(&ioa_cfg->used_res_q); spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); spin_lock(&ipr_driver_lock); diff --git a/trunk/drivers/scsi/libfc/fc_disc.c b/trunk/drivers/scsi/libfc/fc_disc.c index 880a9068ca12..8e561e6a557c 100644 --- a/trunk/drivers/scsi/libfc/fc_disc.c +++ b/trunk/drivers/scsi/libfc/fc_disc.c @@ -712,13 +712,12 @@ static void fc_disc_stop_final(struct fc_lport *lport) } /** - * fc_disc_config() - Configure the discovery layer for a local port - * @lport: The local port that needs the discovery layer to be configured - * @priv: Private data structre for users of the discovery layer + * fc_disc_init() - Initialize the discovery layer for a local port + * @lport: The local port that needs the discovery layer to be initialized */ -void fc_disc_config(struct fc_lport *lport, void *priv) +int fc_disc_init(struct fc_lport *lport) { - struct fc_disc *disc = &lport->disc; + struct fc_disc *disc; if (!lport->tt.disc_start) lport->tt.disc_start = fc_disc_start; @@ -733,21 +732,12 @@ void fc_disc_config(struct fc_lport *lport, void *priv) lport->tt.disc_recv_req = fc_disc_recv_req; disc = &lport->disc; - - disc->priv = priv; -} -EXPORT_SYMBOL(fc_disc_config); - -/** - * fc_disc_init() - Initialize the discovery layer for a local port - * @lport: The local port that needs the discovery layer to be initialized - */ -void fc_disc_init(struct fc_lport *lport) -{ - struct fc_disc *disc = &lport->disc; - INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout); mutex_init(&disc->disc_mutex); INIT_LIST_HEAD(&disc->rports); + + disc->priv = lport; + + return 0; } EXPORT_SYMBOL(fc_disc_init); diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index 55cbd0180159..aec2e0da5016 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -235,17 +235,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) linkrate = phy->linkrate; memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); - /* Handle vacant phy - rest of dr data is not valid so skip it */ - if (phy->phy_state == PHY_VACANT) { - memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - phy->attached_dev_type = NO_DEVICE; - if (!test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) { - phy->phy_id = phy_id; - goto skip; - } else - goto out; - } - phy->attached_dev_type = to_dev_type(dr); if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) goto out; @@ -283,7 +272,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) phy->phy->maximum_linkrate = dr->pmax_linkrate; phy->phy->negotiated_linkrate = phy->linkrate; - skip: if (new_phy) if (sas_phy_add(phy->phy)) { sas_phy_free(phy->phy); @@ -400,7 +388,7 @@ int sas_ex_phy_discover(struct domain_device *dev, int single) if (!disc_req) return -ENOMEM; - disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE); + disc_resp = alloc_smp_req(DISCOVER_RESP_SIZE); if (!disc_resp) { kfree(disc_req); return -ENOMEM; diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index d43faf34c1e2..74b67d98e952 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -438,12 +438,11 @@ lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, struct lpfc_rqe *temp_hrqe; struct lpfc_rqe *temp_drqe; struct lpfc_register doorbell; - int put_index; + int put_index = hq->host_index; /* sanity check on queue memory */ if (unlikely(!hq) || unlikely(!dq)) return -ENOMEM; - put_index = hq->host_index; temp_hrqe = hq->qe[hq->host_index].rqe; temp_drqe = dq->qe[dq->host_index].rqe; diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas.h b/trunk/drivers/scsi/megaraid/megaraid_sas.h index 684cc343cf09..408d2548a748 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas.h +++ b/trunk/drivers/scsi/megaraid/megaraid_sas.h @@ -1488,4 +1488,7 @@ struct megasas_mgmt_info { int max_index; }; +#define msi_control_reg(base) (base + PCI_MSI_FLAGS) +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) + #endif /*LSI_MEGARAID_SAS_H */ diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c index 7c90d57b867e..9d53540207ec 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3984,12 +3984,12 @@ static int megasas_probe_one(struct pci_dev *pdev, if (reset_devices) { pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); if (pos) { - pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS, + 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, - pos + PCI_MSIX_FLAGS, + msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); } diff --git a/trunk/drivers/scsi/mvsas/mv_init.c b/trunk/drivers/scsi/mvsas/mv_init.c index 74550922ad55..ce90d0546cdd 100644 --- a/trunk/drivers/scsi/mvsas/mv_init.c +++ b/trunk/drivers/scsi/mvsas/mv_init.c @@ -703,7 +703,7 @@ static struct pci_device_id mvs_pci_table[] = { { PCI_VDEVICE(TTI, 0x2744), chip_9480 }, { PCI_VDEVICE(TTI, 0x2760), chip_9480 }, { - .vendor = PCI_VENDOR_ID_MARVELL_EXT, + .vendor = 0x1b4b, .device = 0x9480, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, @@ -712,7 +712,7 @@ static struct pci_device_id mvs_pci_table[] = { .driver_data = chip_9480, }, { - .vendor = PCI_VENDOR_ID_MARVELL_EXT, + .vendor = 0x1b4b, .device = 0x9445, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, @@ -721,7 +721,7 @@ static struct pci_device_id mvs_pci_table[] = { .driver_data = chip_9445, }, { - .vendor = PCI_VENDOR_ID_MARVELL_EXT, + .vendor = 0x1b4b, .device = 0x9485, .subvendor = PCI_ANY_ID, .subdevice = 0x9480, diff --git a/trunk/drivers/scsi/mvumi.c b/trunk/drivers/scsi/mvumi.c index c3601b57a80c..4594ccaaf49b 100644 --- a/trunk/drivers/scsi/mvumi.c +++ b/trunk/drivers/scsi/mvumi.c @@ -49,8 +49,8 @@ MODULE_AUTHOR("jyli@marvell.com"); MODULE_DESCRIPTION("Marvell UMI Driver"); static DEFINE_PCI_DEVICE_TABLE(mvumi_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, PCI_DEVICE_ID_MARVELL_MV9143) }, - { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, PCI_DEVICE_ID_MARVELL_MV9580) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9143) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_2, PCI_DEVICE_ID_MARVELL_MV9580) }, { 0 } }; diff --git a/trunk/drivers/scsi/mvumi.h b/trunk/drivers/scsi/mvumi.h index 41f168702ac7..e360135fd1bd 100644 --- a/trunk/drivers/scsi/mvumi.h +++ b/trunk/drivers/scsi/mvumi.h @@ -32,6 +32,7 @@ #define VER_BUILD 1500 #define MV_DRIVER_NAME "mvumi" +#define PCI_VENDOR_ID_MARVELL_2 0x1b4b #define PCI_DEVICE_ID_MARVELL_MV9143 0x9143 #define PCI_DEVICE_ID_MARVELL_MV9580 0x9580 diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index b3db9dcc2619..1d82eef4e1eb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -1938,6 +1938,11 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) "Timer for the VP[%d] has stopped\n", vha->vp_idx); } + /* No pending activities shall be there on the vha now */ + if (ql2xextended_error_logging & ql_dbg_user) + msleep(random32()%10); /* Just to see if something falls on + * the net we have placed below */ + BUG_ON(atomic_read(&vha->vref_count)); qla2x00_free_fcports(vha); diff --git a/trunk/drivers/scsi/qla2xxx/qla_dbg.c b/trunk/drivers/scsi/qla2xxx/qla_dbg.c index fbc305f1c87c..1626de52e32a 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_dbg.c +++ b/trunk/drivers/scsi/qla2xxx/qla_dbg.c @@ -15,7 +15,6 @@ * | Mailbox commands | 0x115b | 0x111a-0x111b | * | | | 0x112c-0x112e | * | | | 0x113a | - * | | | 0x1155-0x1158 | * | Device Discovery | 0x2087 | 0x2020-0x2022, | * | | | 0x2016 | * | Queue Command and IO tracing | 0x3031 | 0x3006-0x300b | @@ -402,7 +401,7 @@ qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr, void *ring; } aq, *aqp; - if (!ha->tgt.atio_ring) + if (!ha->tgt.atio_q_length) return ptr; num_queues = 1; diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index 65c5ff75936b..c6509911772b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -863,6 +863,7 @@ typedef struct { #define MBX_1 BIT_1 #define MBX_0 BIT_0 +#define RNID_TYPE_SET_VERSION 0x9 #define RNID_TYPE_ASIC_TEMP 0xC /* diff --git a/trunk/drivers/scsi/qla2xxx/qla_gbl.h b/trunk/drivers/scsi/qla2xxx/qla_gbl.h index b310fa97b545..eb3ca21a7f17 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_gbl.h @@ -357,6 +357,9 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *, dma_addr_t, uint16_t , uint16_t *, extern int qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *); +extern int +qla2x00_set_driver_version(scsi_qla_host_t *, char *); + extern int qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *, uint16_t, uint16_t, uint16_t, uint16_t); diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index b59203393cb2..edf4d14a1335 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -619,6 +619,8 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) qla24xx_read_fcp_prio_cfg(vha); + qla2x00_set_driver_version(vha, QLA2XXX_VERSION); + return (rval); } @@ -1397,7 +1399,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) mq_size += ha->max_rsp_queues * (rsp->length * sizeof(response_t)); } - if (ha->tgt.atio_ring) + if (ha->tgt.atio_q_length) mq_size += ha->tgt.atio_q_length * sizeof(request_t); /* Allocate memory for Fibre Channel Event Buffer. */ if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha)) diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index 43345af56431..186dd59ce4fa 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -3866,6 +3866,64 @@ qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha) return rval; } +int +qla2x00_set_driver_version(scsi_qla_host_t *vha, char *version) +{ + int rval; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + int len; + uint16_t dwlen; + uint8_t *str; + dma_addr_t str_dma; + struct qla_hw_data *ha = vha->hw; + + if (!IS_FWI2_CAPABLE(ha) || IS_QLA82XX(ha)) + return QLA_FUNCTION_FAILED; + + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1155, + "Entered %s.\n", __func__); + + str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma); + if (!str) { + ql_log(ql_log_warn, vha, 0x1156, + "Failed to allocate driver version param.\n"); + return QLA_MEMORY_ALLOC_FAILED; + } + + memcpy(str, "\x7\x3\x11\x0", 4); + dwlen = str[0]; + len = dwlen * sizeof(uint32_t) - 4; + memset(str + 4, 0, len); + if (len > strlen(version)) + len = strlen(version); + memcpy(str + 4, version, len); + + mcp->mb[0] = MBC_SET_RNID_PARAMS; + mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen; + mcp->mb[2] = MSW(LSD(str_dma)); + mcp->mb[3] = LSW(LSD(str_dma)); + mcp->mb[6] = MSW(MSD(str_dma)); + mcp->mb[7] = LSW(MSD(str_dma)); + mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; + mcp->in_mb = MBX_0; + mcp->tov = MBX_TOV_SECONDS; + mcp->flags = 0; + rval = qla2x00_mailbox_command(vha, mcp); + + if (rval != QLA_SUCCESS) { + ql_dbg(ql_dbg_mbx, vha, 0x1157, + "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); + } else { + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1158, + "Done %s.\n", __func__); + } + + dma_pool_free(ha->s_dma_pool, str, str_dma); + + return rval; +} + static int qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index ec54036d1e12..2b6e478d9e33 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.04.00.13-k" +#define QLA2XXX_VERSION "8.04.00.08-k" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 4 diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index 2a32036a9404..86974471af68 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -4112,10 +4112,6 @@ static int st_probe(struct device *dev) tpnt->disk = disk; disk->private_data = &tpnt->driver; disk->queue = SDp->request_queue; - /* SCSI tape doesn't register this gendisk via add_disk(). Manually - * take queue reference that release_disk() expects. */ - if (!blk_get_queue(disk->queue)) - goto out_put_disk; tpnt->driver = &st_template; tpnt->device = SDp; @@ -4189,7 +4185,7 @@ static int st_probe(struct device *dev) idr_preload_end(); if (error < 0) { pr_warn("st: idr allocation failed: %d\n", error); - goto out_put_queue; + goto out_put_disk; } tpnt->index = error; sprintf(disk->disk_name, "st%d", tpnt->index); @@ -4215,8 +4211,6 @@ static int st_probe(struct device *dev) spin_lock(&st_index_lock); idr_remove(&st_index_idr, tpnt->index); spin_unlock(&st_index_lock); -out_put_queue: - blk_put_queue(disk->queue); out_put_disk: put_disk(disk); kfree(tpnt); diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index 2be0de920d67..f80eee74a311 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -55,7 +55,6 @@ comment "SPI Master Controller Drivers" config SPI_ALTERA tristate "Altera SPI Controller" - depends on GENERIC_HARDIRQS select SPI_BITBANG help This is the driver for the Altera SPI Controller. @@ -311,7 +310,7 @@ config SPI_PXA2XX_DMA config SPI_PXA2XX tristate "PXA2xx SSP SPI master" - depends on (ARCH_PXA || PCI || ACPI) && GENERIC_HARDIRQS + depends on ARCH_PXA || PCI || ACPI select PXA_SSP if ARCH_PXA help This enables using a PXA2xx or Sodaville SSP port as a SPI master diff --git a/trunk/drivers/spi/spi-bcm63xx.c b/trunk/drivers/spi/spi-bcm63xx.c index d7df435d962e..9578af782a77 100644 --- a/trunk/drivers/spi/spi-bcm63xx.c +++ b/trunk/drivers/spi/spi-bcm63xx.c @@ -152,6 +152,7 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, static int bcm63xx_spi_setup(struct spi_device *spi) { struct bcm63xx_spi *bs; + int ret; bs = spi_master_get_devdata(spi->master); @@ -489,7 +490,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) default: dev_err(dev, "unsupported MSG_CTL width: %d\n", bs->msg_ctl_width); - goto out_err; + goto out_clk_disable; } /* Initialize hardware */ diff --git a/trunk/drivers/spi/spi-mpc512x-psc.c b/trunk/drivers/spi/spi-mpc512x-psc.c index 3e490ee7f275..89480b281d74 100644 --- a/trunk/drivers/spi/spi-mpc512x-psc.c +++ b/trunk/drivers/spi/spi-mpc512x-psc.c @@ -164,7 +164,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, for (i = count; i > 0; i--) { data = tx_buf ? *tx_buf++ : 0; - if (len == EOFBYTE && t->cs_change) + if (len == EOFBYTE) setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); out_8(&fifo->txdata_8, data); len--; diff --git a/trunk/drivers/spi/spi-pxa2xx.c b/trunk/drivers/spi/spi-pxa2xx.c index 810413883c79..90b27a3508a6 100644 --- a/trunk/drivers/spi/spi-pxa2xx.c +++ b/trunk/drivers/spi/spi-pxa2xx.c @@ -1168,6 +1168,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) master->dev.parent = &pdev->dev; master->dev.of_node = pdev->dev.of_node; + ACPI_HANDLE_SET(&master->dev, ACPI_HANDLE(&pdev->dev)); /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; diff --git a/trunk/drivers/spi/spi-s3c64xx.c b/trunk/drivers/spi/spi-s3c64xx.c index 4188b2faac5c..e862ab8853aa 100644 --- a/trunk/drivers/spi/spi-s3c64xx.c +++ b/trunk/drivers/spi/spi-s3c64xx.c @@ -994,30 +994,25 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data) { struct s3c64xx_spi_driver_data *sdd = data; struct spi_master *spi = sdd->master; - unsigned int val, clr = 0; + unsigned int val; - val = readl(sdd->regs + S3C64XX_SPI_STATUS); + val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); - if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { - clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; + val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | + S3C64XX_SPI_PND_RX_UNDERRUN_CLR | + S3C64XX_SPI_PND_TX_OVERRUN_CLR | + S3C64XX_SPI_PND_TX_UNDERRUN_CLR; + + writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); + + if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) dev_err(&spi->dev, "RX overrun\n"); - } - if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { - clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; + if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) dev_err(&spi->dev, "RX underrun\n"); - } - if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { - clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; + if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) dev_err(&spi->dev, "TX overrun\n"); - } - if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { - clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; + if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) dev_err(&spi->dev, "TX underrun\n"); - } - - /* Clear the pending irq by setting and then clearing it */ - writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); - writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR); return IRQ_HANDLED; } @@ -1041,13 +1036,9 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) writel(0, regs + S3C64XX_SPI_MODE_CFG); writel(0, regs + S3C64XX_SPI_PACKET_CNT); - /* Clear any irq pending bits, should set and clear the bits */ - val = S3C64XX_SPI_PND_RX_OVERRUN_CLR | - S3C64XX_SPI_PND_RX_UNDERRUN_CLR | - S3C64XX_SPI_PND_TX_OVERRUN_CLR | - S3C64XX_SPI_PND_TX_UNDERRUN_CLR; - writel(val, regs + S3C64XX_SPI_PENDING_CLR); - writel(0, regs + S3C64XX_SPI_PENDING_CLR); + /* Clear any irq pending bits */ + writel(readl(regs + S3C64XX_SPI_PENDING_CLR), + regs + S3C64XX_SPI_PENDING_CLR); writel(0, regs + S3C64XX_SPI_SWAP_CFG); diff --git a/trunk/drivers/spi/spi-tegra20-slink.c b/trunk/drivers/spi/spi-tegra20-slink.c index a829563f4713..b8698b389ef3 100644 --- a/trunk/drivers/spi/spi-tegra20-slink.c +++ b/trunk/drivers/spi/spi-tegra20-slink.c @@ -858,6 +858,21 @@ static int tegra_slink_setup(struct spi_device *spi) return 0; } +static int tegra_slink_prepare_transfer(struct spi_master *master) +{ + struct tegra_slink_data *tspi = spi_master_get_devdata(master); + + return pm_runtime_get_sync(tspi->dev); +} + +static int tegra_slink_unprepare_transfer(struct spi_master *master) +{ + struct tegra_slink_data *tspi = spi_master_get_devdata(master); + + pm_runtime_put(tspi->dev); + return 0; +} + static int tegra_slink_transfer_one_message(struct spi_master *master, struct spi_message *msg) { @@ -870,12 +885,6 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, msg->status = 0; msg->actual_length = 0; - ret = pm_runtime_get_sync(tspi->dev); - if (ret < 0) { - dev_err(tspi->dev, "runtime get failed: %d\n", ret); - goto done; - } - single_xfer = list_is_singular(&msg->transfers); list_for_each_entry(xfer, &msg->transfers, transfer_list) { INIT_COMPLETION(tspi->xfer_completion); @@ -912,8 +921,6 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, exit: tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); - pm_runtime_put(tspi->dev); -done: msg->status = ret; spi_finalize_current_message(master); return ret; @@ -1141,7 +1148,9 @@ static int tegra_slink_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->setup = tegra_slink_setup; + master->prepare_transfer_hardware = tegra_slink_prepare_transfer; master->transfer_one_message = tegra_slink_transfer_one_message; + master->unprepare_transfer_hardware = tegra_slink_unprepare_transfer; master->num_chipselect = MAX_CHIP_SELECT; master->bus_num = -1; diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 004b10f184d4..f996c600eb8c 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -543,16 +543,17 @@ static void spi_pump_messages(struct kthread_work *work) /* Lock queue and check for queue work */ spin_lock_irqsave(&master->queue_lock, flags); if (list_empty(&master->queue) || !master->running) { - if (!master->busy) { - spin_unlock_irqrestore(&master->queue_lock, flags); - return; + if (master->busy && master->unprepare_transfer_hardware) { + ret = master->unprepare_transfer_hardware(master); + if (ret) { + spin_unlock_irqrestore(&master->queue_lock, flags); + dev_err(&master->dev, + "failed to unprepare transfer hardware\n"); + return; + } } master->busy = false; spin_unlock_irqrestore(&master->queue_lock, flags); - if (master->unprepare_transfer_hardware && - master->unprepare_transfer_hardware(master)) - dev_err(&master->dev, - "failed to unprepare transfer hardware\n"); return; } @@ -983,7 +984,7 @@ static void acpi_register_spi_devices(struct spi_master *master) acpi_status status; acpi_handle handle; - handle = ACPI_HANDLE(master->dev.parent); + handle = ACPI_HANDLE(&master->dev); if (!handle) return; diff --git a/trunk/drivers/ssb/driver_chipcommon_pmu.c b/trunk/drivers/ssb/driver_chipcommon_pmu.c index 7b0bce936762..4c0f6d883dd3 100644 --- a/trunk/drivers/ssb/driver_chipcommon_pmu.c +++ b/trunk/drivers/ssb/driver_chipcommon_pmu.c @@ -675,32 +675,3 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc) return 0; } } - -void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid) -{ - u32 pmu_ctl = 0; - - switch (cc->dev->bus->chip_id) { - case 0x4322: - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070); - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a); - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854); - if (spuravoid == 1) - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828); - else - ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828); - pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD; - break; - case 43222: - /* TODO: BCM43222 requires updating PLLs too */ - return; - default: - ssb_printk(KERN_ERR PFX - "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", - cc->dev->bus->chip_id); - return; - } - - chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl); -} -EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate); diff --git a/trunk/drivers/target/target_core_alua.c b/trunk/drivers/target/target_core_alua.c index cbe48ab41745..ff1c5ee352cb 100644 --- a/trunk/drivers/target/target_core_alua.c +++ b/trunk/drivers/target/target_core_alua.c @@ -409,7 +409,6 @@ static inline int core_alua_state_standby( case REPORT_LUNS: case RECEIVE_DIAGNOSTIC: case SEND_DIAGNOSTIC: - return 0; case MAINTENANCE_IN: switch (cdb[1] & 0x1f) { case MI_REPORT_TARGET_PGS: @@ -452,7 +451,6 @@ static inline int core_alua_state_unavailable( switch (cdb[0]) { case INQUIRY: case REPORT_LUNS: - return 0; case MAINTENANCE_IN: switch (cdb[1] & 0x1f) { case MI_REPORT_TARGET_PGS: @@ -493,7 +491,6 @@ static inline int core_alua_state_transition( switch (cdb[0]) { case INQUIRY: case REPORT_LUNS: - return 0; case MAINTENANCE_IN: switch (cdb[1] & 0x1f) { case MI_REPORT_TARGET_PGS: diff --git a/trunk/drivers/tty/mxser.c b/trunk/drivers/tty/mxser.c index 302909ccf183..484b6a3c9b03 100644 --- a/trunk/drivers/tty/mxser.c +++ b/trunk/drivers/tty/mxser.c @@ -2643,9 +2643,9 @@ static int mxser_probe(struct pci_dev *pdev, mxvar_sdriver, brd->idx + i, &pdev->dev); if (IS_ERR(tty_dev)) { retval = PTR_ERR(tty_dev); - for (; i > 0; i--) + for (i--; i >= 0; i--) tty_unregister_device(mxvar_sdriver, - brd->idx + i - 1); + brd->idx + i); goto err_relbrd; } } @@ -2751,9 +2751,9 @@ static int __init mxser_module_init(void) tty_dev = tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, brd->idx + i, NULL); if (IS_ERR(tty_dev)) { - for (; i > 0; i--) + for (i--; i >= 0; i--) tty_unregister_device(mxvar_sdriver, - brd->idx + i - 1); + brd->idx + i); for (i = 0; i < brd->info->nports; i++) tty_port_destroy(&brd->ports[i].port); free_irq(brd->irq, brd); diff --git a/trunk/drivers/tty/serial/8250/8250_pnp.c b/trunk/drivers/tty/serial/8250/8250_pnp.c index 35d9ab95c5cb..b3455a970a1d 100644 --- a/trunk/drivers/tty/serial/8250/8250_pnp.c +++ b/trunk/drivers/tty/serial/8250/8250_pnp.c @@ -429,6 +429,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct uart_8250_port uart; int ret, line, flags = dev_id->driver_data; + struct resource *res = NULL; if (flags & UNKNOWN_DEV) { ret = serial_pnp_guess_board(dev); @@ -439,11 +440,12 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) memset(&uart, 0, sizeof(uart)); if (pnp_irq_valid(dev, 0)) uart.port.irq = pnp_irq(dev, 0); - if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) { - uart.port.iobase = pnp_port_start(dev, 2); - uart.port.iotype = UPIO_PORT; - } else if (pnp_port_valid(dev, 0)) { - uart.port.iobase = pnp_port_start(dev, 0); + if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) + res = pnp_get_resource(dev, IORESOURCE_IO, 2); + else if (pnp_port_valid(dev, 0)) + res = pnp_get_resource(dev, IORESOURCE_IO, 0); + if (pnp_resource_enabled(res)) { + uart.port.iobase = res->start; uart.port.iotype = UPIO_PORT; } else if (pnp_mem_valid(dev, 0)) { uart.port.mapbase = pnp_mem_start(dev, 0); diff --git a/trunk/drivers/tty/serial/omap-serial.c b/trunk/drivers/tty/serial/omap-serial.c index 30d4f7a783cd..4dc41408ecb7 100644 --- a/trunk/drivers/tty/serial/omap-serial.c +++ b/trunk/drivers/tty/serial/omap-serial.c @@ -886,17 +886,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ - up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; - /* - * NOTE: Setting OMAP_UART_SCR_RX_TRIG_GRANU1_MASK - * sets Enables the granularity of 1 for TRIGGER RX - * level. Along with setting RX FIFO trigger level - * to 1 (as noted below, 16 characters) and TLR[3:0] - * to zero this will result RX FIFO threshold level - * to 1 character, instead of 16 as noted in comment - * below. - */ - /* Set receive FIFO threshold to 16 characters and * transmit FIFO threshold to 16 spaces */ diff --git a/trunk/drivers/tty/tty_io.c b/trunk/drivers/tty/tty_io.c index b0452688308c..05400acbc456 100644 --- a/trunk/drivers/tty/tty_io.c +++ b/trunk/drivers/tty/tty_io.c @@ -941,14 +941,6 @@ void start_tty(struct tty_struct *tty) EXPORT_SYMBOL(start_tty); -static void tty_update_time(struct timespec *time) -{ - unsigned long sec = get_seconds(); - sec -= sec % 60; - if ((long)(sec - time->tv_sec) > 0) - time->tv_sec = sec; -} - /** * tty_read - read method for tty device files * @file: pointer to tty file @@ -968,11 +960,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int i; - struct inode *inode = file_inode(file); struct tty_struct *tty = file_tty(file); struct tty_ldisc *ld; - if (tty_paranoia_check(tty, inode, "tty_read")) + if (tty_paranoia_check(tty, file_inode(file), "tty_read")) return -EIO; if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) return -EIO; @@ -986,9 +977,6 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, i = -EIO; tty_ldisc_deref(ld); - if (i > 0) - tty_update_time(&inode->i_atime); - return i; } @@ -1089,10 +1077,8 @@ static inline ssize_t do_tty_write( break; cond_resched(); } - if (written) { - tty_update_time(&file_inode(file)->i_mtime); + if (written) ret = written; - } out: tty_write_unlock(tty); return ret; diff --git a/trunk/drivers/usb/core/port.c b/trunk/drivers/usb/core/port.c index 65d4e55552c6..797f9d514732 100644 --- a/trunk/drivers/usb/core/port.c +++ b/trunk/drivers/usb/core/port.c @@ -67,6 +67,7 @@ static void usb_port_device_release(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); + dev_pm_qos_hide_flags(dev); kfree(port_dev); } diff --git a/trunk/drivers/vfio/pci/vfio_pci.c b/trunk/drivers/vfio/pci/vfio_pci.c index 09d2e3ffd6fc..8189cb6a86af 100644 --- a/trunk/drivers/vfio/pci/vfio_pci.c +++ b/trunk/drivers/vfio/pci/vfio_pci.c @@ -70,7 +70,7 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev) pci_write_config_word(pdev, PCI_COMMAND, cmd); } - msix_pos = pdev->msix_cap; + msix_pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); if (msix_pos) { u16 flags; u32 table; @@ -78,8 +78,8 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev) pci_read_config_word(pdev, msix_pos + PCI_MSIX_FLAGS, &flags); pci_read_config_dword(pdev, msix_pos + PCI_MSIX_TABLE, &table); - vdev->msix_bar = table & PCI_MSIX_TABLE_BIR; - vdev->msix_offset = table & PCI_MSIX_TABLE_OFFSET; + vdev->msix_bar = table & PCI_MSIX_FLAGS_BIRMASK; + vdev->msix_offset = table & ~PCI_MSIX_FLAGS_BIRMASK; vdev->msix_size = ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) * 16; } else vdev->msix_bar = 0xFF; @@ -183,7 +183,7 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) u8 pos; u16 flags; - pos = vdev->pdev->msi_cap; + pos = pci_find_capability(vdev->pdev, PCI_CAP_ID_MSI); if (pos) { pci_read_config_word(vdev->pdev, pos + PCI_MSI_FLAGS, &flags); @@ -194,7 +194,7 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) u8 pos; u16 flags; - pos = vdev->pdev->msix_cap; + pos = pci_find_capability(vdev->pdev, PCI_CAP_ID_MSIX); if (pos) { pci_read_config_word(vdev->pdev, pos + PCI_MSIX_FLAGS, &flags); @@ -346,7 +346,6 @@ static long vfio_pci_ioctl(void *device_data, if (!(hdr.flags & VFIO_IRQ_SET_DATA_NONE)) { size_t size; - int max = vfio_pci_get_irq_count(vdev, hdr.index); if (hdr.flags & VFIO_IRQ_SET_DATA_BOOL) size = sizeof(uint8_t); @@ -356,7 +355,7 @@ static long vfio_pci_ioctl(void *device_data, return -EINVAL; if (hdr.argsz - minsz < hdr.count * size || - hdr.start >= max || hdr.start + hdr.count > max) + hdr.count > vfio_pci_get_irq_count(vdev, hdr.index)) return -EINVAL; data = memdup_user((void __user *)(arg + minsz), diff --git a/trunk/drivers/vhost/tcm_vhost.c b/trunk/drivers/vhost/tcm_vhost.c index 957a0b98a5d9..2968b4934659 100644 --- a/trunk/drivers/vhost/tcm_vhost.c +++ b/trunk/drivers/vhost/tcm_vhost.c @@ -74,8 +74,9 @@ enum { struct vhost_scsi { /* Protected by vhost_scsi->dev.mutex */ - struct tcm_vhost_tpg **vs_tpg; + struct tcm_vhost_tpg *vs_tpg[VHOST_SCSI_MAX_TARGET]; char vs_vhost_wwpn[TRANSPORT_IQN_LEN]; + bool vs_endpoint; struct vhost_dev dev; struct vhost_virtqueue vqs[VHOST_SCSI_MAX_VQ]; @@ -578,27 +579,9 @@ static void tcm_vhost_submission_work(struct work_struct *work) } } -static void vhost_scsi_send_bad_target(struct vhost_scsi *vs, - struct vhost_virtqueue *vq, int head, unsigned out) -{ - struct virtio_scsi_cmd_resp __user *resp; - struct virtio_scsi_cmd_resp rsp; - int ret; - - memset(&rsp, 0, sizeof(rsp)); - rsp.response = VIRTIO_SCSI_S_BAD_TARGET; - resp = vq->iov[out].iov_base; - ret = __copy_to_user(resp, &rsp, sizeof(rsp)); - if (!ret) - vhost_add_used_and_signal(&vs->dev, vq, head, 0); - else - pr_err("Faulted on virtio_scsi_cmd_resp\n"); -} - static void vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) { - struct tcm_vhost_tpg **vs_tpg; struct virtio_scsi_cmd_req v_req; struct tcm_vhost_tpg *tv_tpg; struct tcm_vhost_cmd *tv_cmd; @@ -607,16 +590,8 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, int head, ret; u8 target; - /* - * We can handle the vq only after the endpoint is setup by calling the - * VHOST_SCSI_SET_ENDPOINT ioctl. - * - * TODO: Check that we are running from vhost_worker which acts - * as read-side critical section for vhost kind of RCU. - * See the comments in struct vhost_virtqueue in drivers/vhost/vhost.h - */ - vs_tpg = rcu_dereference_check(vq->private_data, 1); - if (!vs_tpg) + /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */ + if (unlikely(!vs->vs_endpoint)) return; mutex_lock(&vq->mutex); @@ -686,11 +661,23 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, /* Extract the tpgt */ target = v_req.lun[1]; - tv_tpg = ACCESS_ONCE(vs_tpg[target]); + tv_tpg = vs->vs_tpg[target]; /* Target does not exist, fail the request */ if (unlikely(!tv_tpg)) { - vhost_scsi_send_bad_target(vs, vq, head, out); + struct virtio_scsi_cmd_resp __user *resp; + struct virtio_scsi_cmd_resp rsp; + + memset(&rsp, 0, sizeof(rsp)); + rsp.response = VIRTIO_SCSI_S_BAD_TARGET; + resp = vq->iov[out].iov_base; + ret = __copy_to_user(resp, &rsp, sizeof(rsp)); + if (!ret) + vhost_add_used_and_signal(&vs->dev, + vq, head, 0); + else + pr_err("Faulted on virtio_scsi_cmd_resp\n"); + continue; } @@ -703,13 +690,22 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, if (IS_ERR(tv_cmd)) { vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n", PTR_ERR(tv_cmd)); - goto err_cmd; + break; } pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction" ": %d\n", tv_cmd, exp_data_len, data_direction); tv_cmd->tvc_vhost = vs; tv_cmd->tvc_vq = vq; + + if (unlikely(vq->iov[out].iov_len != + sizeof(struct virtio_scsi_cmd_resp))) { + vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu" + " bytes, out: %d, in: %d\n", + vq->iov[out].iov_len, out, in); + break; + } + tv_cmd->tvc_resp = vq->iov[out].iov_base; /* @@ -729,7 +725,7 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", scsi_command_size(tv_cmd->tvc_cdb), TCM_VHOST_MAX_CDB_SIZE); - goto err_free; + break; /* TODO */ } tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF; @@ -742,7 +738,7 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, data_direction == DMA_TO_DEVICE); if (unlikely(ret)) { vq_err(vq, "Failed to map iov to sgl\n"); - goto err_free; + break; /* TODO */ } } @@ -763,13 +759,6 @@ static void vhost_scsi_handle_vq(struct vhost_scsi *vs, } mutex_unlock(&vq->mutex); - return; - -err_free: - vhost_scsi_free_cmd(tv_cmd); -err_cmd: - vhost_scsi_send_bad_target(vs, vq, head, out); - mutex_unlock(&vq->mutex); } static void vhost_scsi_ctl_handle_kick(struct vhost_work *work) @@ -791,20 +780,6 @@ static void vhost_scsi_handle_kick(struct vhost_work *work) vhost_scsi_handle_vq(vs, vq); } -static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index) -{ - vhost_poll_flush(&vs->dev.vqs[index].poll); -} - -static void vhost_scsi_flush(struct vhost_scsi *vs) -{ - int i; - - for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) - vhost_scsi_flush_vq(vs, i); - vhost_work_flush(&vs->dev, &vs->vs_completion_work); -} - /* * Called from vhost_scsi_ioctl() context to walk the list of available * tcm_vhost_tpg with an active struct tcm_vhost_nexus @@ -815,10 +790,8 @@ static int vhost_scsi_set_endpoint( { struct tcm_vhost_tport *tv_tport; struct tcm_vhost_tpg *tv_tpg; - struct tcm_vhost_tpg **vs_tpg; - struct vhost_virtqueue *vq; - int index, ret, i, len; bool match = false; + int index, ret; mutex_lock(&vs->dev.mutex); /* Verify that ring has been setup correctly. */ @@ -830,15 +803,6 @@ static int vhost_scsi_set_endpoint( } } - len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET; - vs_tpg = kzalloc(len, GFP_KERNEL); - if (!vs_tpg) { - mutex_unlock(&vs->dev.mutex); - return -ENOMEM; - } - if (vs->vs_tpg) - memcpy(vs_tpg, vs->vs_tpg, len); - mutex_lock(&tcm_vhost_mutex); list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { mutex_lock(&tv_tpg->tv_tpg_mutex); @@ -853,15 +817,14 @@ static int vhost_scsi_set_endpoint( tv_tport = tv_tpg->tport; if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) { - if (vs->vs_tpg && vs->vs_tpg[tv_tpg->tport_tpgt]) { + if (vs->vs_tpg[tv_tpg->tport_tpgt]) { mutex_unlock(&tv_tpg->tv_tpg_mutex); mutex_unlock(&tcm_vhost_mutex); mutex_unlock(&vs->dev.mutex); - kfree(vs_tpg); return -EEXIST; } tv_tpg->tv_tpg_vhost_count++; - vs_tpg[tv_tpg->tport_tpgt] = tv_tpg; + vs->vs_tpg[tv_tpg->tport_tpgt] = tv_tpg; smp_mb__after_atomic_inc(); match = true; } @@ -872,27 +835,12 @@ static int vhost_scsi_set_endpoint( if (match) { memcpy(vs->vs_vhost_wwpn, t->vhost_wwpn, sizeof(vs->vs_vhost_wwpn)); - for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { - vq = &vs->vqs[i]; - /* Flushing the vhost_work acts as synchronize_rcu */ - mutex_lock(&vq->mutex); - rcu_assign_pointer(vq->private_data, vs_tpg); - vhost_init_used(vq); - mutex_unlock(&vq->mutex); - } + vs->vs_endpoint = true; ret = 0; } else { ret = -EEXIST; } - /* - * Act as synchronize_rcu to make sure access to - * old vs->vs_tpg is finished. - */ - vhost_scsi_flush(vs); - kfree(vs->vs_tpg); - vs->vs_tpg = vs_tpg; - mutex_unlock(&vs->dev.mutex); return ret; } @@ -903,8 +851,6 @@ static int vhost_scsi_clear_endpoint( { struct tcm_vhost_tport *tv_tport; struct tcm_vhost_tpg *tv_tpg; - struct vhost_virtqueue *vq; - bool match = false; int index, ret, i; u8 target; @@ -916,14 +862,9 @@ static int vhost_scsi_clear_endpoint( goto err_dev; } } - - if (!vs->vs_tpg) { - mutex_unlock(&vs->dev.mutex); - return 0; - } - for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) { target = i; + tv_tpg = vs->vs_tpg[target]; if (!tv_tpg) continue; @@ -945,27 +886,10 @@ static int vhost_scsi_clear_endpoint( } tv_tpg->tv_tpg_vhost_count--; vs->vs_tpg[target] = NULL; - match = true; + vs->vs_endpoint = false; mutex_unlock(&tv_tpg->tv_tpg_mutex); } - if (match) { - for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) { - vq = &vs->vqs[i]; - /* Flushing the vhost_work acts as synchronize_rcu */ - mutex_lock(&vq->mutex); - rcu_assign_pointer(vq->private_data, NULL); - mutex_unlock(&vq->mutex); - } - } - /* - * Act as synchronize_rcu to make sure access to - * old vs->vs_tpg is finished. - */ - vhost_scsi_flush(vs); - kfree(vs->vs_tpg); - vs->vs_tpg = NULL; mutex_unlock(&vs->dev.mutex); - return 0; err_tpg: @@ -975,24 +899,6 @@ static int vhost_scsi_clear_endpoint( return ret; } -static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) -{ - if (features & ~VHOST_SCSI_FEATURES) - return -EOPNOTSUPP; - - mutex_lock(&vs->dev.mutex); - if ((features & (1 << VHOST_F_LOG_ALL)) && - !vhost_log_access_ok(&vs->dev)) { - mutex_unlock(&vs->dev.mutex); - return -EFAULT; - } - vs->dev.acked_features = features; - smp_wmb(); - vhost_scsi_flush(vs); - mutex_unlock(&vs->dev.mutex); - return 0; -} - static int vhost_scsi_open(struct inode *inode, struct file *f) { struct vhost_scsi *s; @@ -1033,6 +939,38 @@ static int vhost_scsi_release(struct inode *inode, struct file *f) return 0; } +static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index) +{ + vhost_poll_flush(&vs->dev.vqs[index].poll); +} + +static void vhost_scsi_flush(struct vhost_scsi *vs) +{ + int i; + + for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) + vhost_scsi_flush_vq(vs, i); + vhost_work_flush(&vs->dev, &vs->vs_completion_work); +} + +static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) +{ + if (features & ~VHOST_SCSI_FEATURES) + return -EOPNOTSUPP; + + mutex_lock(&vs->dev.mutex); + if ((features & (1 << VHOST_F_LOG_ALL)) && + !vhost_log_access_ok(&vs->dev)) { + mutex_unlock(&vs->dev.mutex); + return -EFAULT; + } + vs->dev.acked_features = features; + smp_wmb(); + vhost_scsi_flush(vs); + mutex_unlock(&vs->dev.mutex); + return 0; +} + static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, unsigned long arg) { diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 09394657926e..4c1546f71d56 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -2277,7 +2277,7 @@ config XEN_FBDEV_FRONTEND select FB_SYS_IMAGEBLIT select FB_SYS_FOPS select FB_DEFERRED_IO - select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC + select INPUT_XEN_KBDDEV_FRONTEND select XEN_XENBUS_FRONTEND default y help diff --git a/trunk/drivers/video/auo_k1900fb.c b/trunk/drivers/video/auo_k1900fb.c index 1a9ac6e1f4b3..d572d3e9c502 100644 --- a/trunk/drivers/video/auo_k1900fb.c +++ b/trunk/drivers/video/auo_k1900fb.c @@ -82,6 +82,7 @@ static void auok1900_update_region(struct auok190xfb_par *par, int mode, struct device *dev = par->info->device; unsigned char *buf = (unsigned char *)par->info->screen_base; int xres = par->info->var.xres; + int line_length = par->info->fix.line_length; u16 args[4]; pm_runtime_get_sync(dev); @@ -100,9 +101,9 @@ static void auok1900_update_region(struct auok190xfb_par *par, int mode, args[1] = y1 + 1; args[2] = xres; args[3] = y2 - y1; - buf += y1 * xres; + buf += y1 * line_length; auok190x_send_cmdargs_pixels(par, AUOK1900_CMD_PARTIALDISP, 4, args, - ((y2 - y1) * xres)/2, (u16 *) buf); + ((y2 - y1) * line_length)/2, (u16 *) buf); auok190x_send_command(par, AUOK190X_CMD_DATA_STOP); par->update_cnt++; diff --git a/trunk/drivers/video/auo_k1901fb.c b/trunk/drivers/video/auo_k1901fb.c index d1db1653cd88..9efbe2763447 100644 --- a/trunk/drivers/video/auo_k1901fb.c +++ b/trunk/drivers/video/auo_k1901fb.c @@ -121,6 +121,7 @@ static void auok1901_update_region(struct auok190xfb_par *par, int mode, struct device *dev = par->info->device; unsigned char *buf = (unsigned char *)par->info->screen_base; int xres = par->info->var.xres; + int line_length = par->info->fix.line_length; u16 args[5]; pm_runtime_get_sync(dev); @@ -139,9 +140,9 @@ static void auok1901_update_region(struct auok190xfb_par *par, int mode, args[1] = y1 + 1; args[2] = xres; args[3] = y2 - y1; - buf += y1 * xres; + buf += y1 * line_length; auok190x_send_cmdargs_pixels_nowait(par, AUOK1901_CMD_DMA_START, 4, - args, ((y2 - y1) * xres)/2, + args, ((y2 - y1) * line_length)/2, (u16 *) buf); auok190x_send_command_nowait(par, AUOK190X_CMD_DATA_STOP); diff --git a/trunk/drivers/video/auo_k190x.c b/trunk/drivers/video/auo_k190x.c index 53846cb534d4..bc0b6433eae6 100644 --- a/trunk/drivers/video/auo_k190x.c +++ b/trunk/drivers/video/auo_k190x.c @@ -224,8 +224,8 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info, { struct fb_deferred_io *fbdefio = info->fbdefio; struct auok190xfb_par *par = info->par; + u16 line_length = info->fix.line_length; u16 yres = info->var.yres; - u16 xres = info->var.xres; u16 y1 = 0, h = 0; int prev_index = -1; struct page *cur; @@ -254,7 +254,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info, } /* height increment is fixed per page */ - h_inc = DIV_ROUND_UP(PAGE_SIZE , xres); + h_inc = DIV_ROUND_UP(PAGE_SIZE , line_length); /* calculate number of pages from pixel height */ threshold = par->consecutive_threshold / h_inc; @@ -265,7 +265,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info, list_for_each_entry(cur, &fbdefio->pagelist, lru) { if (prev_index < 0) { /* just starting so assign first page */ - y1 = (cur->index << PAGE_SHIFT) / xres; + y1 = (cur->index << PAGE_SHIFT) / line_length; h = h_inc; } else if ((cur->index - prev_index) <= threshold) { /* page is within our threshold for single updates */ @@ -275,7 +275,7 @@ static void auok190xfb_dpy_deferred_io(struct fb_info *info, par->update_partial(par, y1, y1 + h); /* start over with our non consecutive page */ - y1 = (cur->index << PAGE_SHIFT) / xres; + y1 = (cur->index << PAGE_SHIFT) / line_length; h = h_inc; } prev_index = cur->index; @@ -896,13 +896,13 @@ int auok190x_common_probe(struct platform_device *pdev, info->var.yres = panel->w; info->var.xres_virtual = panel->h; info->var.yres_virtual = panel->w; - info->fix.line_length = panel->h; + info->fix.line_length = panel->h * info->var.bits_per_pixel / 8; } else { info->var.xres = panel->w; info->var.yres = panel->h; info->var.xres_virtual = panel->w; info->var.yres_virtual = panel->h; - info->fix.line_length = panel->w; + info->fix.line_length = panel->w * info->var.bits_per_pixel / 8; } par->resolution = board->resolution; @@ -910,7 +910,8 @@ int auok190x_common_probe(struct platform_device *pdev, /* videomemory handling */ - videomemorysize = roundup((panel->w * panel->h), PAGE_SIZE); + videomemorysize = roundup((panel->w * panel->h) * + info->var.bits_per_pixel / 8, PAGE_SIZE); videomemory = vmalloc(videomemorysize); if (!videomemory) { ret = -ENOMEM; diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index 86291dcd964a..7c254084b6a0 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -1373,12 +1373,15 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) { struct fb_info *info = file_fb_info(file); struct fb_ops *fb; - unsigned long mmio_pgoff; + unsigned long off; unsigned long start; u32 len; if (!info) return -ENODEV; + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + off = vma->vm_pgoff << PAGE_SHIFT; fb = info->fbops; if (!fb) return -ENODEV; @@ -1390,24 +1393,32 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) return res; } - /* - * Ugh. This can be either the frame buffer mapping, or - * if pgoff points past it, the mmio mapping. - */ + /* frame buffer memory */ start = info->fix.smem_start; - len = info->fix.smem_len; - mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; - if (vma->vm_pgoff >= mmio_pgoff) { - vma->vm_pgoff -= mmio_pgoff; + len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); + if (off >= len) { + /* memory mapped io */ + off -= len; + if (info->var.accel_flags) { + mutex_unlock(&info->mm_lock); + return -EINVAL; + } start = info->fix.mmio_start; - len = info->fix.mmio_len; + len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); } mutex_unlock(&info->mm_lock); - + start &= PAGE_MASK; + if ((vma->vm_end - vma->vm_start + off) > len) + return -EINVAL; + off += start; + vma->vm_pgoff = off >> PAGE_SHIFT; + /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); - fb_pgprotect(file, vma, start); - - return vm_iomap_memory(vma, start, len); + fb_pgprotect(file, vma, off); + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; + return 0; } static int diff --git a/trunk/drivers/video/fbmon.c b/trunk/drivers/video/fbmon.c index 7f6709991a5c..94ad0f71383c 100644 --- a/trunk/drivers/video/fbmon.c +++ b/trunk/drivers/video/fbmon.c @@ -1400,7 +1400,7 @@ int fb_videomode_from_videomode(const struct videomode *vm, fbmode->vmode = 0; if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH) fbmode->sync |= FB_SYNC_HOR_HIGH_ACT; - if (vm->dmt_flags & VESA_DMT_VSYNC_HIGH) + if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH) fbmode->sync |= FB_SYNC_VERT_HIGH_ACT; if (vm->data_flags & DISPLAY_FLAGS_INTERLACED) fbmode->vmode |= FB_VMODE_INTERLACED; diff --git a/trunk/drivers/video/mmp/core.c b/trunk/drivers/video/mmp/core.c index 84de2632857a..9ed83419038b 100644 --- a/trunk/drivers/video/mmp/core.c +++ b/trunk/drivers/video/mmp/core.c @@ -252,5 +252,7 @@ void mmp_unregister_path(struct mmp_path *path) kfree(path); mutex_unlock(&disp_lock); + + dev_info(path->dev, "de-register %s\n", path->name); } EXPORT_SYMBOL_GPL(mmp_unregister_path); diff --git a/trunk/drivers/video/sh_mobile_lcdcfb.c b/trunk/drivers/video/sh_mobile_lcdcfb.c index 0264704a52be..63203acef812 100644 --- a/trunk/drivers/video/sh_mobile_lcdcfb.c +++ b/trunk/drivers/video/sh_mobile_lcdcfb.c @@ -858,7 +858,6 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) tmp = ((mode->xres & 7) << 24) | ((display_h_total & 7) << 16) | ((mode->hsync_len & 7) << 8) | (hsync_pos & 7); lcdc_write_chan(ch, LDHAJR, tmp); - lcdc_write_chan_mirror(ch, LDHAJR, tmp); } static void sh_mobile_lcdc_overlay_setup(struct sh_mobile_lcdc_overlay *ovl) diff --git a/trunk/drivers/video/uvesafb.c b/trunk/drivers/video/uvesafb.c index d4284458377e..b75db0186488 100644 --- a/trunk/drivers/video/uvesafb.c +++ b/trunk/drivers/video/uvesafb.c @@ -1973,8 +1973,7 @@ static int uvesafb_init(void) err = -ENOMEM; if (err) { - if (uvesafb_device) - platform_device_put(uvesafb_device); + platform_device_put(uvesafb_device); platform_driver_unregister(&uvesafb_driver); cn_del_callback(&uvesafb_cn_id); return err; diff --git a/trunk/drivers/watchdog/Kconfig b/trunk/drivers/watchdog/Kconfig index e89fc3133972..9fcc70c11cea 100644 --- a/trunk/drivers/watchdog/Kconfig +++ b/trunk/drivers/watchdog/Kconfig @@ -117,7 +117,7 @@ config ARM_SP805_WATCHDOG config AT91RM9200_WATCHDOG tristate "AT91RM9200 watchdog" - depends on ARCH_AT91RM9200 + depends on ARCH_AT91 help Watchdog timer embedded into AT91RM9200 chips. This will reboot your system when the timeout is reached. diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index d8cc8127f19c..aa85881d17b2 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -85,7 +85,8 @@ enum xen_irq_type { * event channel - irq->event channel mapping * cpu - cpu this event channel is bound to * index - type-specific information: - * PIRQ - physical IRQ, GSI, flags, and owner domain + * PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM + * guest, or GSI (real passthrough IRQ) of the device. * VIRQ - virq number * IPI - IPI vector * EVTCHN - @@ -104,6 +105,7 @@ struct irq_info { struct { unsigned short pirq; unsigned short gsi; + unsigned char vector; unsigned char flags; uint16_t domid; } pirq; @@ -209,6 +211,7 @@ static void xen_irq_info_pirq_init(unsigned irq, unsigned short evtchn, unsigned short pirq, unsigned short gsi, + unsigned short vector, uint16_t domid, unsigned char flags) { @@ -218,6 +221,7 @@ static void xen_irq_info_pirq_init(unsigned irq, info->u.pirq.pirq = pirq; info->u.pirq.gsi = gsi; + info->u.pirq.vector = vector; info->u.pirq.domid = domid; info->u.pirq.flags = flags; } @@ -515,9 +519,6 @@ static void xen_free_irq(unsigned irq) { struct irq_info *info = irq_get_handler_data(irq); - if (WARN_ON(!info)) - return; - list_del(&info->list); irq_set_handler_data(irq, NULL); @@ -713,7 +714,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi, goto out; } - xen_irq_info_pirq_init(irq, 0, pirq, gsi, DOMID_SELF, + xen_irq_info_pirq_init(irq, 0, pirq, gsi, irq_op.vector, DOMID_SELF, shareable ? PIRQ_SHAREABLE : 0); pirq_query_unmask(irq); @@ -761,7 +762,8 @@ int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc) } int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, - int pirq, const char *name, domid_t domid) + int pirq, int vector, const char *name, + domid_t domid) { int irq, ret; @@ -774,7 +776,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq, name); - xen_irq_info_pirq_init(irq, 0, pirq, 0, domid, 0); + xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, domid, 0); ret = irq_set_msi_desc(irq, msidesc); if (ret < 0) goto error_irq; @@ -1006,9 +1008,6 @@ static void unbind_from_irq(unsigned int irq) int evtchn = evtchn_from_irq(irq); struct irq_info *info = irq_get_handler_data(irq); - if (WARN_ON(!info)) - return; - mutex_lock(&irq_mapping_update_lock); if (info->refcnt > 0) { @@ -1136,10 +1135,6 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi, void unbind_from_irqhandler(unsigned int irq, void *dev_id) { - struct irq_info *info = irq_get_handler_data(irq); - - if (WARN_ON(!info)) - return; free_irq(irq, dev_id); unbind_from_irq(irq); } @@ -1321,7 +1316,7 @@ static void __xen_evtchn_do_upcall(void) { int start_word_idx, start_bit_idx; int word_idx, bit_idx; - int i, irq; + int i; int cpu = get_cpu(); struct shared_info *s = HYPERVISOR_shared_info; struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); @@ -1329,8 +1324,6 @@ static void __xen_evtchn_do_upcall(void) do { xen_ulong_t pending_words; - xen_ulong_t pending_bits; - struct irq_desc *desc; vcpu_info->evtchn_upcall_pending = 0; @@ -1342,17 +1335,6 @@ static void __xen_evtchn_do_upcall(void) * selector flag. xchg_xen_ulong must contain an * appropriate barrier. */ - if ((irq = per_cpu(virq_to_irq, cpu)[VIRQ_TIMER]) != -1) { - int evtchn = evtchn_from_irq(irq); - word_idx = evtchn / BITS_PER_LONG; - pending_bits = evtchn % BITS_PER_LONG; - if (active_evtchns(cpu, s, word_idx) & (1ULL << pending_bits)) { - desc = irq_to_desc(irq); - if (desc) - generic_handle_irq_desc(irq, desc); - } - } - pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0); start_word_idx = __this_cpu_read(current_word_idx); @@ -1361,6 +1343,7 @@ static void __xen_evtchn_do_upcall(void) word_idx = start_word_idx; for (i = 0; pending_words != 0; i++) { + xen_ulong_t pending_bits; xen_ulong_t words; words = MASK_LSBS(pending_words, word_idx); @@ -1389,7 +1372,8 @@ static void __xen_evtchn_do_upcall(void) do { xen_ulong_t bits; - int port; + int port, irq; + struct irq_desc *desc; bits = MASK_LSBS(pending_bits, bit_idx); @@ -1462,9 +1446,6 @@ void rebind_evtchn_irq(int evtchn, int irq) { struct irq_info *info = info_for_irq(irq); - if (WARN_ON(!info)) - return; - /* Make sure the irq is masked, since the new event channel will also be masked. */ disable_irq(irq); @@ -1738,12 +1719,7 @@ void xen_poll_irq(int irq) int xen_test_irq_shared(int irq) { struct irq_info *info = info_for_irq(irq); - struct physdev_irq_status_query irq_status; - - if (WARN_ON(!info)) - return -ENOENT; - - irq_status.irq = info->u.pirq.pirq; + struct physdev_irq_status_query irq_status = { .irq = info->u.pirq.pirq }; if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status)) return 0; diff --git a/trunk/drivers/xen/xen-acpi-processor.c b/trunk/drivers/xen/xen-acpi-processor.c index 8abd7d579037..90e34ac7e522 100644 --- a/trunk/drivers/xen/xen-acpi-processor.c +++ b/trunk/drivers/xen/xen-acpi-processor.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -52,9 +51,9 @@ static DEFINE_MUTEX(acpi_ids_mutex); /* Which ACPI ID we have processed from 'struct acpi_processor'. */ static unsigned long *acpi_ids_done; /* Which ACPI ID exist in the SSDT/DSDT processor definitions. */ -static unsigned long *acpi_id_present; +static unsigned long __initdata *acpi_id_present; /* And if there is an _CST definition (or a PBLK) for the ACPI IDs */ -static unsigned long *acpi_id_cst_present; +static unsigned long __initdata *acpi_id_cst_present; static int push_cxx_to_hypervisor(struct acpi_processor *_pr) { @@ -330,7 +329,7 @@ static unsigned int __init get_max_acpi_id(void) * for_each_[present|online]_cpu macros which are banded to the virtual * CPU amount. */ -static acpi_status +static acpi_status __init read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) { u32 acpi_id; @@ -385,16 +384,12 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -static int check_acpi_ids(struct acpi_processor *pr_backup) +static int __init check_acpi_ids(struct acpi_processor *pr_backup) { if (!pr_backup) return -ENODEV; - if (acpi_id_present && acpi_id_cst_present) - /* OK, done this once .. skip to uploading */ - goto upload; - /* All online CPUs have been processed at this stage. Now verify * whether in fact "online CPUs" == physical CPUs. */ @@ -413,7 +408,6 @@ static int check_acpi_ids(struct acpi_processor *pr_backup) read_acpi_id, NULL, NULL, NULL); acpi_get_devices("ACPI0007", read_acpi_id, NULL, NULL); -upload: if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) { unsigned int i; for_each_set_bit(i, acpi_id_present, nr_acpi_bits) { @@ -423,7 +417,10 @@ static int check_acpi_ids(struct acpi_processor *pr_backup) (void)upload_pm_data(pr_backup); } } - + kfree(acpi_id_present); + acpi_id_present = NULL; + kfree(acpi_id_cst_present); + acpi_id_cst_present = NULL; return 0; } static int __init check_prereq(void) @@ -470,46 +467,9 @@ static void free_acpi_perf_data(void) free_percpu(acpi_perf_data); } -static int xen_upload_processor_pm_data(void) -{ - struct acpi_processor *pr_backup = NULL; - unsigned int i; - int rc = 0; - - pr_info(DRV_NAME "Uploading Xen processor PM info\n"); - - for_each_possible_cpu(i) { - struct acpi_processor *_pr; - _pr = per_cpu(processors, i /* APIC ID */); - if (!_pr) - continue; - - if (!pr_backup) { - pr_backup = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); - if (pr_backup) - memcpy(pr_backup, _pr, sizeof(struct acpi_processor)); - } - (void)upload_pm_data(_pr); - } - - rc = check_acpi_ids(pr_backup); - kfree(pr_backup); - - return rc; -} - -static void xen_acpi_processor_resume(void) -{ - bitmap_zero(acpi_ids_done, nr_acpi_bits); - xen_upload_processor_pm_data(); -} - -static struct syscore_ops xap_syscore_ops = { - .resume = xen_acpi_processor_resume, -}; - static int __init xen_acpi_processor_init(void) { + struct acpi_processor *pr_backup = NULL; unsigned int i; int rc = check_prereq(); @@ -554,12 +514,27 @@ static int __init xen_acpi_processor_init(void) goto err_out; } - rc = xen_upload_processor_pm_data(); + for_each_possible_cpu(i) { + struct acpi_processor *_pr; + _pr = per_cpu(processors, i /* APIC ID */); + if (!_pr) + continue; + + if (!pr_backup) { + pr_backup = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); + if (pr_backup) + memcpy(pr_backup, _pr, sizeof(struct acpi_processor)); + } + (void)upload_pm_data(_pr); + } + rc = check_acpi_ids(pr_backup); + + kfree(pr_backup); + pr_backup = NULL; + if (rc) goto err_unregister; - register_syscore_ops(&xap_syscore_ops); - return 0; err_unregister: for_each_possible_cpu(i) { @@ -577,10 +552,7 @@ static void __exit xen_acpi_processor_exit(void) { int i; - unregister_syscore_ops(&xap_syscore_ops); kfree(acpi_ids_done); - kfree(acpi_id_present); - kfree(acpi_id_cst_present); for_each_possible_cpu(i) { struct acpi_processor_performance *perf; perf = per_cpu_ptr(acpi_perf_data, i); diff --git a/trunk/firmware/Makefile b/trunk/firmware/Makefile index cbb09ce9730a..5d8ee1319b5c 100644 --- a/trunk/firmware/Makefile +++ b/trunk/firmware/Makefile @@ -82,7 +82,7 @@ fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \ qlogic/12160.bin fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin -fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw +fw-shipped-$(CONFIG_INFINIBAND_QIB) += intel/sd7220.fw fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw diff --git a/trunk/firmware/qlogic/sd7220.fw.ihex b/trunk/firmware/intel/sd7220.fw.ihex similarity index 100% rename from trunk/firmware/qlogic/sd7220.fw.ihex rename to trunk/firmware/intel/sd7220.fw.ihex diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 1dc8786f4588..3f941f2a3059 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -1029,9 +1029,9 @@ static int aio_read_evt(struct kioctx *ioctx, struct io_event *ent) spin_unlock(&info->ring_lock); out: + kunmap_atomic(ring); dprintk("leaving aio_read_evt: %d h%lu t%lu\n", ret, (unsigned long)ring->head, (unsigned long)ring->tail); - kunmap_atomic(ring); return ret; } diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 86af964c2425..3939829f6c5c 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -1137,7 +1137,6 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma, goto whole; if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE)) goto whole; - return 0; } /* Do not dump I/O mapped devices or special mappings */ diff --git a/trunk/fs/bio.c b/trunk/fs/bio.c index b96fc6ce4855..bb5768f59b32 100644 --- a/trunk/fs/bio.c +++ b/trunk/fs/bio.c @@ -1428,6 +1428,8 @@ void bio_endio(struct bio *bio, int error) else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) error = -EIO; + trace_block_bio_complete(bio, error); + if (bio->bi_end_io) bio->bi_end_io(bio, error); } diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index aae187a7f94a..aea605c98ba6 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -551,7 +551,6 @@ struct block_device *bdgrab(struct block_device *bdev) ihold(bdev->bd_inode); return bdev; } -EXPORT_SYMBOL(bdgrab); long nr_blockdev_pages(void) { diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index ef96381569a4..451fad96ecd1 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -317,7 +317,6 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, unsigned long src_ptr; unsigned long dst_ptr; int overwrite_root = 0; - bool inode_item = key->type == BTRFS_INODE_ITEM_KEY; if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) overwrite_root = 1; @@ -327,9 +326,6 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, /* look for the key in the destination tree */ ret = btrfs_search_slot(NULL, root, key, path, 0, 0); - if (ret < 0) - return ret; - if (ret == 0) { char *src_copy; char *dst_copy; @@ -371,30 +367,6 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, return 0; } - /* - * We need to load the old nbytes into the inode so when we - * replay the extents we've logged we get the right nbytes. - */ - if (inode_item) { - struct btrfs_inode_item *item; - u64 nbytes; - - item = btrfs_item_ptr(path->nodes[0], path->slots[0], - struct btrfs_inode_item); - nbytes = btrfs_inode_nbytes(path->nodes[0], item); - item = btrfs_item_ptr(eb, slot, - struct btrfs_inode_item); - btrfs_set_inode_nbytes(eb, item, nbytes); - } - } else if (inode_item) { - struct btrfs_inode_item *item; - - /* - * New inode, set nbytes to 0 so that the nbytes comes out - * properly when we replay the extents. - */ - item = btrfs_item_ptr(eb, slot, struct btrfs_inode_item); - btrfs_set_inode_nbytes(eb, item, 0); } insert: btrfs_release_path(path); @@ -514,7 +486,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, int found_type; u64 extent_end; u64 start = key->offset; - u64 nbytes = 0; + u64 saved_nbytes; struct btrfs_file_extent_item *item; struct inode *inode = NULL; unsigned long size; @@ -524,19 +496,10 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, found_type = btrfs_file_extent_type(eb, item); if (found_type == BTRFS_FILE_EXTENT_REG || - found_type == BTRFS_FILE_EXTENT_PREALLOC) { - nbytes = btrfs_file_extent_num_bytes(eb, item); - extent_end = start + nbytes; - - /* - * We don't add to the inodes nbytes if we are prealloc or a - * hole. - */ - if (btrfs_file_extent_disk_bytenr(eb, item) == 0) - nbytes = 0; - } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { + found_type == BTRFS_FILE_EXTENT_PREALLOC) + extent_end = start + btrfs_file_extent_num_bytes(eb, item); + else if (found_type == BTRFS_FILE_EXTENT_INLINE) { size = btrfs_file_extent_inline_len(eb, item); - nbytes = btrfs_file_extent_ram_bytes(eb, item); extent_end = ALIGN(start + size, root->sectorsize); } else { ret = 0; @@ -585,6 +548,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, } btrfs_release_path(path); + saved_nbytes = inode_get_bytes(inode); /* drop any overlapping extents */ ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1); BUG_ON(ret); @@ -671,7 +635,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, BUG_ON(ret); } - inode_add_bytes(inode, nbytes); + inode_set_bytes(inode, saved_nbytes); ret = btrfs_update_inode(trans, root, inode); out: if (inode) diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 21b3a291c327..991c63c6bdd0 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -1575,24 +1575,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } break; case Opt_blank_pass: + vol->password = NULL; + break; + case Opt_pass: /* passwords have to be handled differently * to allow the character used for deliminator * to be passed within them */ - /* - * Check if this is a case where the password - * starts with a delimiter - */ - tmp_end = strchr(data, '='); - tmp_end++; - if (!(tmp_end < end && tmp_end[1] == delim)) { - /* No it is not. Set the password to NULL */ - vol->password = NULL; - break; - } - /* Yes it is. Drop down to Opt_pass below.*/ - case Opt_pass: /* Obtain the value string */ value = strchr(data, '='); value++; diff --git a/trunk/fs/ecryptfs/miscdev.c b/trunk/fs/ecryptfs/miscdev.c index e4141f257495..412e6eda25f8 100644 --- a/trunk/fs/ecryptfs/miscdev.c +++ b/trunk/fs/ecryptfs/miscdev.c @@ -80,6 +80,13 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) int rc; mutex_lock(&ecryptfs_daemon_hash_mux); + rc = try_module_get(THIS_MODULE); + if (rc == 0) { + rc = -EIO; + printk(KERN_ERR "%s: Error attempting to increment module use " + "count; rc = [%d]\n", __func__, rc); + goto out_unlock_daemon_list; + } rc = ecryptfs_find_daemon_by_euid(&daemon); if (!rc) { rc = -EINVAL; @@ -89,7 +96,7 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) if (rc) { printk(KERN_ERR "%s: Error attempting to spawn daemon; " "rc = [%d]\n", __func__, rc); - goto out_unlock_daemon_list; + goto out_module_put_unlock_daemon_list; } mutex_lock(&daemon->mux); if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { @@ -101,6 +108,9 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) atomic_inc(&ecryptfs_num_miscdev_opens); out_unlock_daemon: mutex_unlock(&daemon->mux); +out_module_put_unlock_daemon_list: + if (rc) + module_put(THIS_MODULE); out_unlock_daemon_list: mutex_unlock(&ecryptfs_daemon_hash_mux); return rc; @@ -137,6 +147,7 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) "bug.\n", __func__, rc); BUG(); } + module_put(THIS_MODULE); return rc; } @@ -460,7 +471,6 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, static const struct file_operations ecryptfs_miscdev_fops = { - .owner = THIS_MODULE, .open = ecryptfs_miscdev_open, .poll = ecryptfs_miscdev_poll, .read = ecryptfs_miscdev_read, diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index 9c6d06dcef8b..56efcaadf848 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -2999,23 +2999,20 @@ static int ext4_split_extent_at(handle_t *handle, if (split_flag & EXT4_EXT_DATA_VALID1) { err = ext4_ext_zeroout(inode, ex2); zero_ex.ee_block = ex2->ee_block; - zero_ex.ee_len = cpu_to_le16( - ext4_ext_get_actual_len(ex2)); + zero_ex.ee_len = ext4_ext_get_actual_len(ex2); ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex2)); } else { err = ext4_ext_zeroout(inode, ex); zero_ex.ee_block = ex->ee_block; - zero_ex.ee_len = cpu_to_le16( - ext4_ext_get_actual_len(ex)); + zero_ex.ee_len = ext4_ext_get_actual_len(ex); ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); } } else { err = ext4_ext_zeroout(inode, &orig_ex); zero_ex.ee_block = orig_ex.ee_block; - zero_ex.ee_len = cpu_to_le16( - ext4_ext_get_actual_len(&orig_ex)); + zero_ex.ee_len = ext4_ext_get_actual_len(&orig_ex); ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(&orig_ex)); } @@ -3275,7 +3272,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, if (err) goto out; zero_ex.ee_block = ex->ee_block; - zero_ex.ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)); + zero_ex.ee_len = ext4_ext_get_actual_len(ex); ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); err = ext4_ext_get_access(handle, inode, path + depth); diff --git a/trunk/fs/ext4/indirect.c b/trunk/fs/ext4/indirect.c index a04183127ef0..b505a145a593 100644 --- a/trunk/fs/ext4/indirect.c +++ b/trunk/fs/ext4/indirect.c @@ -1539,9 +1539,9 @@ static int free_hole_blocks(handle_t *handle, struct inode *inode, blk = *i_data; if (level > 0) { ext4_lblk_t first2; - bh = sb_bread(inode->i_sb, le32_to_cpu(blk)); + bh = sb_bread(inode->i_sb, blk); if (!bh) { - EXT4_ERROR_INODE_BLOCK(inode, le32_to_cpu(blk), + EXT4_ERROR_INODE_BLOCK(inode, blk, "Read failure"); return -EIO; } diff --git a/trunk/fs/gfs2/file.c b/trunk/fs/gfs2/file.c index d79c2dadc536..019f45e45097 100644 --- a/trunk/fs/gfs2/file.c +++ b/trunk/fs/gfs2/file.c @@ -923,11 +923,8 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) cmd = F_SETLK; fl->fl_type = F_UNLCK; } - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { - if (fl->fl_type == F_UNLCK) - posix_lock_file_wait(file, fl); + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) return -EIO; - } if (IS_GETLK(cmd)) return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl); else if (fl->fl_type == F_UNLCK) diff --git a/trunk/fs/gfs2/incore.h b/trunk/fs/gfs2/incore.h index 5c29216e9cc1..156e42ec84ea 100644 --- a/trunk/fs/gfs2/incore.h +++ b/trunk/fs/gfs2/incore.h @@ -588,7 +588,6 @@ struct lm_lockstruct { struct dlm_lksb ls_control_lksb; /* control_lock */ char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */ struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */ - char *ls_lvb_bits; spinlock_t ls_recover_spin; /* protects following fields */ unsigned long ls_recover_flags; /* DFL_ */ diff --git a/trunk/fs/gfs2/lock_dlm.c b/trunk/fs/gfs2/lock_dlm.c index c8423d6de6c3..9802de0f85e6 100644 --- a/trunk/fs/gfs2/lock_dlm.c +++ b/trunk/fs/gfs2/lock_dlm.c @@ -483,8 +483,12 @@ static void control_lvb_write(struct lm_lockstruct *ls, uint32_t lvb_gen, static int all_jid_bits_clear(char *lvb) { - return !memchr_inv(lvb + JID_BITMAP_OFFSET, 0, - GDLM_LVB_SIZE - JID_BITMAP_OFFSET); + int i; + for (i = JID_BITMAP_OFFSET; i < GDLM_LVB_SIZE; i++) { + if (lvb[i]) + return 0; + } + return 1; } static void sync_wait_cb(void *arg) @@ -576,6 +580,7 @@ static void gfs2_control_func(struct work_struct *work) { struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work); struct lm_lockstruct *ls = &sdp->sd_lockstruct; + char lvb_bits[GDLM_LVB_SIZE]; uint32_t block_gen, start_gen, lvb_gen, flags; int recover_set = 0; int write_lvb = 0; @@ -629,7 +634,7 @@ static void gfs2_control_func(struct work_struct *work) return; } - control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits); + control_lvb_read(ls, &lvb_gen, lvb_bits); spin_lock(&ls->ls_recover_spin); if (block_gen != ls->ls_recover_block || @@ -659,10 +664,10 @@ static void gfs2_control_func(struct work_struct *work) ls->ls_recover_result[i] = 0; - if (!test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) + if (!test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) continue; - __clear_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET); + __clear_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); write_lvb = 1; } } @@ -686,7 +691,7 @@ static void gfs2_control_func(struct work_struct *work) continue; if (ls->ls_recover_submit[i] < start_gen) { ls->ls_recover_submit[i] = 0; - __set_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET); + __set_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); } } /* even if there are no bits to set, we need to write the @@ -700,7 +705,7 @@ static void gfs2_control_func(struct work_struct *work) spin_unlock(&ls->ls_recover_spin); if (write_lvb) { - control_lvb_write(ls, start_gen, ls->ls_lvb_bits); + control_lvb_write(ls, start_gen, lvb_bits); flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK; } else { flags = DLM_LKF_CONVERT; @@ -720,7 +725,7 @@ static void gfs2_control_func(struct work_struct *work) */ for (i = 0; i < recover_size; i++) { - if (test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) { + if (test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) { fs_info(sdp, "recover generation %u jid %d\n", start_gen, i); gfs2_recover_set(sdp, i); @@ -753,6 +758,7 @@ static void gfs2_control_func(struct work_struct *work) static int control_mount(struct gfs2_sbd *sdp) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; + char lvb_bits[GDLM_LVB_SIZE]; uint32_t start_gen, block_gen, mount_gen, lvb_gen; int mounted_mode; int retries = 0; @@ -851,7 +857,7 @@ static int control_mount(struct gfs2_sbd *sdp) * lvb_gen will be non-zero. */ - control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits); + control_lvb_read(ls, &lvb_gen, lvb_bits); if (lvb_gen == 0xFFFFFFFF) { /* special value to force mount attempts to fail */ @@ -881,7 +887,7 @@ static int control_mount(struct gfs2_sbd *sdp) * and all lvb bits to be clear (no pending journal recoveries.) */ - if (!all_jid_bits_clear(ls->ls_lvb_bits)) { + if (!all_jid_bits_clear(lvb_bits)) { /* journals need recovery, wait until all are clear */ fs_info(sdp, "control_mount wait for journal recovery\n"); goto restart; @@ -943,6 +949,7 @@ static int dlm_recovery_wait(void *word) static int control_first_done(struct gfs2_sbd *sdp) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; + char lvb_bits[GDLM_LVB_SIZE]; uint32_t start_gen, block_gen; int error; @@ -984,8 +991,8 @@ static int control_first_done(struct gfs2_sbd *sdp) memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t)); spin_unlock(&ls->ls_recover_spin); - memset(ls->ls_lvb_bits, 0, GDLM_LVB_SIZE); - control_lvb_write(ls, start_gen, ls->ls_lvb_bits); + memset(lvb_bits, 0, sizeof(lvb_bits)); + control_lvb_write(ls, start_gen, lvb_bits); error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT); if (error) @@ -1015,12 +1022,6 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots, uint32_t old_size, new_size; int i, max_jid; - if (!ls->ls_lvb_bits) { - ls->ls_lvb_bits = kzalloc(GDLM_LVB_SIZE, GFP_NOFS); - if (!ls->ls_lvb_bits) - return -ENOMEM; - } - max_jid = 0; for (i = 0; i < num_slots; i++) { if (max_jid < slots[i].slot - 1) @@ -1056,7 +1057,6 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots, static void free_recover_size(struct lm_lockstruct *ls) { - kfree(ls->ls_lvb_bits); kfree(ls->ls_recover_submit); kfree(ls->ls_recover_result); ls->ls_recover_submit = NULL; @@ -1205,7 +1205,6 @@ static int gdlm_mount(struct gfs2_sbd *sdp, const char *table) ls->ls_recover_size = 0; ls->ls_recover_submit = NULL; ls->ls_recover_result = NULL; - ls->ls_lvb_bits = NULL; error = set_recover_size(sdp, NULL, 0); if (error) diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index 5a51265a4341..d1f51fd73f86 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -576,7 +576,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) RB_CLEAR_NODE(&ip->i_res->rs_node); out: up_write(&ip->i_rw_mutex); - return error; + return 0; } static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) @@ -1181,9 +1181,12 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed) { struct super_block *sb = sdp->sd_vfs; + struct block_device *bdev = sb->s_bdev; + const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize / + bdev_logical_block_size(sb->s_bdev); u64 blk; sector_t start = 0; - sector_t nr_blks = 0; + sector_t nr_sects = 0; int rv; unsigned int x; u32 trimmed = 0; @@ -1203,34 +1206,35 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, if (diff == 0) continue; blk = offset + ((bi->bi_start + x) * GFS2_NBBY); + blk *= sects_per_blk; /* convert to sectors */ while(diff) { if (diff & 1) { - if (nr_blks == 0) + if (nr_sects == 0) goto start_new_extent; - if ((start + nr_blks) != blk) { - if (nr_blks >= minlen) { - rv = sb_issue_discard(sb, - start, nr_blks, + if ((start + nr_sects) != blk) { + if (nr_sects >= minlen) { + rv = blkdev_issue_discard(bdev, + start, nr_sects, GFP_NOFS, 0); if (rv) goto fail; - trimmed += nr_blks; + trimmed += nr_sects; } - nr_blks = 0; + nr_sects = 0; start_new_extent: start = blk; } - nr_blks++; + nr_sects += sects_per_blk; } diff >>= 2; - blk++; + blk += sects_per_blk; } } - if (nr_blks >= minlen) { - rv = sb_issue_discard(sb, start, nr_blks, GFP_NOFS, 0); + if (nr_sects >= minlen) { + rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0); if (rv) goto fail; - trimmed += nr_blks; + trimmed += nr_sects; } if (ptrimmed) *ptrimmed = trimmed; diff --git a/trunk/fs/hfsplus/extents.c b/trunk/fs/hfsplus/extents.c index fe0a76213d9e..a94f0f779d5e 100644 --- a/trunk/fs/hfsplus/extents.c +++ b/trunk/fs/hfsplus/extents.c @@ -533,7 +533,7 @@ void hfsplus_file_truncate(struct inode *inode) struct address_space *mapping = inode->i_mapping; struct page *page; void *fsdata; - loff_t size = inode->i_size; + u32 size = inode->i_size; res = pagecache_write_begin(NULL, mapping, size, 0, AOP_FLAG_UNINTERRUPTIBLE, diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index 523464e62849..84e3d856e91d 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -110,7 +110,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) * way when do_mmap_pgoff unwinds (may be important on powerpc * and ia64). */ - vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND; + vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND | VM_DONTDUMP; vma->vm_ops = &hugetlb_vm_ops; if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index a898b3d43ccf..f5f7c06c36fb 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -725,7 +725,7 @@ void prune_icache_sb(struct super_block *sb, int nr_to_scan) * inode to the back of the list so we don't spin on it. */ if (!spin_trylock(&inode->i_lock)) { - list_move(&inode->i_lru, &sb->s_inode_lru); + list_move_tail(&inode->i_lru, &sb->s_inode_lru); continue; } diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 341d3f564082..d581e45c0a9f 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -1690,7 +1690,7 @@ static int do_loopback(struct path *path, const char *old_name, if (IS_ERR(mnt)) { err = PTR_ERR(mnt); - goto out2; + goto out; } err = graft_tree(mnt, path); diff --git a/trunk/fs/nfs/nfs4client.c b/trunk/fs/nfs/nfs4client.c index 66b6664dcd4c..ac4fc9a8fdbc 100644 --- a/trunk/fs/nfs/nfs4client.c +++ b/trunk/fs/nfs/nfs4client.c @@ -300,7 +300,7 @@ int nfs40_walk_client_list(struct nfs_client *new, struct rpc_cred *cred) { struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); - struct nfs_client *pos, *prev = NULL; + struct nfs_client *pos, *n, *prev = NULL; struct nfs4_setclientid_res clid = { .clientid = new->cl_clientid, .confirm = new->cl_confirm, @@ -308,23 +308,10 @@ int nfs40_walk_client_list(struct nfs_client *new, int status = -NFS4ERR_STALE_CLIENTID; spin_lock(&nn->nfs_client_lock); - list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { + list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { /* If "pos" isn't marked ready, we can't trust the * remaining fields in "pos" */ - if (pos->cl_cons_state > NFS_CS_READY) { - atomic_inc(&pos->cl_count); - spin_unlock(&nn->nfs_client_lock); - - if (prev) - nfs_put_client(prev); - prev = pos; - - status = nfs_wait_client_init_complete(pos); - spin_lock(&nn->nfs_client_lock); - if (status < 0) - continue; - } - if (pos->cl_cons_state != NFS_CS_READY) + if (pos->cl_cons_state < NFS_CS_READY) continue; if (pos->rpc_ops != new->rpc_ops) @@ -436,16 +423,16 @@ int nfs41_walk_client_list(struct nfs_client *new, struct rpc_cred *cred) { struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); - struct nfs_client *pos, *prev = NULL; + struct nfs_client *pos, *n, *prev = NULL; int status = -NFS4ERR_STALE_CLIENTID; spin_lock(&nn->nfs_client_lock); - list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { + list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { /* If "pos" isn't marked ready, we can't trust the * remaining fields in "pos", especially the client * ID and serverowner fields. Wait for CREATE_SESSION * to finish. */ - if (pos->cl_cons_state > NFS_CS_READY) { + if (pos->cl_cons_state < NFS_CS_READY) { atomic_inc(&pos->cl_count); spin_unlock(&nn->nfs_client_lock); @@ -453,17 +440,18 @@ int nfs41_walk_client_list(struct nfs_client *new, nfs_put_client(prev); prev = pos; + nfs4_schedule_lease_recovery(pos); status = nfs_wait_client_init_complete(pos); - if (status == 0) { - nfs4_schedule_lease_recovery(pos); - status = nfs4_wait_clnt_recover(pos); + if (status < 0) { + nfs_put_client(pos); + spin_lock(&nn->nfs_client_lock); + continue; } + status = pos->cl_cons_state; spin_lock(&nn->nfs_client_lock); if (status < 0) continue; } - if (pos->cl_cons_state != NFS_CS_READY) - continue; if (pos->rpc_ops != new->rpc_ops) continue; @@ -481,18 +469,17 @@ int nfs41_walk_client_list(struct nfs_client *new, continue; atomic_inc(&pos->cl_count); - *result = pos; - status = 0; + spin_unlock(&nn->nfs_client_lock); dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", __func__, pos, atomic_read(&pos->cl_count)); - break; + + *result = pos; + return 0; } /* No matching nfs_client found. */ spin_unlock(&nn->nfs_client_lock); dprintk("NFS: <-- %s status = %d\n", __func__, status); - if (prev) - nfs_put_client(prev); return status; } #endif /* CONFIG_NFS_V4_1 */ diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 0ad025eb523b..26431cf62ddb 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -1046,7 +1046,6 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) /* Save the delegation */ nfs4_stateid_copy(&stateid, &delegation->stateid); rcu_read_unlock(); - nfs_release_seqid(opendata->o_arg.seqid); ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); if (ret != 0) goto out; diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index d41a3518509f..6ace365c6334 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -1886,13 +1886,7 @@ int nfs4_discover_server_trunking(struct nfs_client *clp, status = PTR_ERR(clnt); break; } - /* Note: this is safe because we haven't yet marked the - * client as ready, so we are the only user of - * clp->cl_rpcclient - */ - clnt = xchg(&clp->cl_rpcclient, clnt); - rpc_shutdown_client(clnt); - clnt = clp->cl_rpcclient; + clp->cl_rpcclient = clnt; goto again; case -NFS4ERR_MINOR_VERS_MISMATCH: diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index a2720071f282..01168865dd37 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -264,7 +264,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, iattr->ia_valid |= ATTR_SIZE; } if (bmval[0] & FATTR4_WORD0_ACL) { - u32 nace; + int nace; struct nfs4_ace *ace; READ_BUF(4); len += 4; diff --git a/trunk/fs/proc/array.c b/trunk/fs/proc/array.c index cbd0f1b324b9..f7ed9ee46eb9 100644 --- a/trunk/fs/proc/array.c +++ b/trunk/fs/proc/array.c @@ -143,7 +143,6 @@ static const char * const task_state_array[] = { "x (dead)", /* 64 */ "K (wakekill)", /* 128 */ "W (waking)", /* 256 */ - "P (parked)", /* 512 */ }; static inline const char *get_task_state(struct task_struct *tsk) diff --git a/trunk/fs/proc/generic.c b/trunk/fs/proc/generic.c index 21e1a8f1659d..4b3b3ffb52f1 100644 --- a/trunk/fs/proc/generic.c +++ b/trunk/fs/proc/generic.c @@ -755,8 +755,37 @@ void pde_put(struct proc_dir_entry *pde) free_proc_entry(pde); } -static void entry_rundown(struct proc_dir_entry *de) +/* + * Remove a /proc entry and free it if it's not currently in use. + */ +void remove_proc_entry(const char *name, struct proc_dir_entry *parent) { + struct proc_dir_entry **p; + struct proc_dir_entry *de = NULL; + const char *fn = name; + unsigned int len; + + spin_lock(&proc_subdir_lock); + if (__xlate_proc_name(name, &parent, &fn) != 0) { + spin_unlock(&proc_subdir_lock); + return; + } + len = strlen(fn); + + for (p = &parent->subdir; *p; p=&(*p)->next ) { + if (proc_match(len, fn, *p)) { + de = *p; + *p = de->next; + de->next = NULL; + break; + } + } + spin_unlock(&proc_subdir_lock); + if (!de) { + WARN(1, "name '%s'\n", name); + return; + } + spin_lock(&de->pde_unload_lock); /* * Stop accepting new callers into module. If you're @@ -788,40 +817,6 @@ static void entry_rundown(struct proc_dir_entry *de) spin_lock(&de->pde_unload_lock); } spin_unlock(&de->pde_unload_lock); -} - -/* - * Remove a /proc entry and free it if it's not currently in use. - */ -void remove_proc_entry(const char *name, struct proc_dir_entry *parent) -{ - struct proc_dir_entry **p; - struct proc_dir_entry *de = NULL; - const char *fn = name; - unsigned int len; - - spin_lock(&proc_subdir_lock); - if (__xlate_proc_name(name, &parent, &fn) != 0) { - spin_unlock(&proc_subdir_lock); - return; - } - len = strlen(fn); - - for (p = &parent->subdir; *p; p=&(*p)->next ) { - if (proc_match(len, fn, *p)) { - de = *p; - *p = de->next; - de->next = NULL; - break; - } - } - spin_unlock(&proc_subdir_lock); - if (!de) { - WARN(1, "name '%s'\n", name); - return; - } - - entry_rundown(de); if (S_ISDIR(de->mode)) parent->nlink--; @@ -832,57 +827,3 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) pde_put(de); } EXPORT_SYMBOL(remove_proc_entry); - -int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) -{ - struct proc_dir_entry **p; - struct proc_dir_entry *root = NULL, *de, *next; - const char *fn = name; - unsigned int len; - - spin_lock(&proc_subdir_lock); - if (__xlate_proc_name(name, &parent, &fn) != 0) { - spin_unlock(&proc_subdir_lock); - return -ENOENT; - } - len = strlen(fn); - - for (p = &parent->subdir; *p; p=&(*p)->next ) { - if (proc_match(len, fn, *p)) { - root = *p; - *p = root->next; - root->next = NULL; - break; - } - } - if (!root) { - spin_unlock(&proc_subdir_lock); - return -ENOENT; - } - de = root; - while (1) { - next = de->subdir; - if (next) { - de->subdir = next->next; - next->next = NULL; - de = next; - continue; - } - spin_unlock(&proc_subdir_lock); - - entry_rundown(de); - next = de->parent; - if (S_ISDIR(de->mode)) - next->nlink--; - de->nlink = 0; - if (de == root) - break; - pde_put(de); - - spin_lock(&proc_subdir_lock); - de = next; - } - pde_put(root); - return 0; -} -EXPORT_SYMBOL(remove_proc_subtree); diff --git a/trunk/fs/reiserfs/xattr.c b/trunk/fs/reiserfs/xattr.c index 4cce1d9552fb..c196369fe408 100644 --- a/trunk/fs/reiserfs/xattr.c +++ b/trunk/fs/reiserfs/xattr.c @@ -187,8 +187,8 @@ fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset, if (dbuf->count == ARRAY_SIZE(dbuf->dentries)) return -ENOSPC; - if (name[0] == '.' && (namelen < 2 || - (namelen == 2 && name[1] == '.'))) + if (name[0] == '.' && (name[1] == '\0' || + (name[1] == '.' && name[2] == '\0'))) return 0; dentry = lookup_one_len(name, dbuf->xadir, namelen); diff --git a/trunk/fs/ubifs/super.c b/trunk/fs/ubifs/super.c index f21acf0ef01f..ac838b844936 100644 --- a/trunk/fs/ubifs/super.c +++ b/trunk/fs/ubifs/super.c @@ -1568,12 +1568,6 @@ static int ubifs_remount_rw(struct ubifs_info *c) c->remounting_rw = 1; c->ro_mount = 0; - if (c->space_fixup) { - err = ubifs_fixup_free_space(c); - if (err) - return err; - } - err = check_free_space(c); if (err) goto out; @@ -1690,6 +1684,12 @@ static int ubifs_remount_rw(struct ubifs_info *c) err = dbg_check_space_info(c); } + if (c->space_fixup) { + err = ubifs_fixup_free_space(c); + if (err) + goto out; + } + mutex_unlock(&c->umount_mutex); return err; diff --git a/trunk/include/asm-generic/tlb.h b/trunk/include/asm-generic/tlb.h index b1b1fa6ffffe..25f01d0bc149 100644 --- a/trunk/include/asm-generic/tlb.h +++ b/trunk/include/asm-generic/tlb.h @@ -99,12 +99,7 @@ struct mmu_gather { unsigned int need_flush : 1, /* Did free PTEs */ fast_mode : 1; /* No batching */ - /* we are in the middle of an operation to clear - * a full mm and can make some optimizations */ - unsigned int fullmm : 1, - /* we have performed an operation which - * requires a complete flush of the tlb */ - need_flush_all : 1; + unsigned int fullmm; struct mmu_gather_batch *active; struct mmu_gather_batch local; diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 03053aca5b32..bcbdd7484e58 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -152,6 +152,15 @@ void acpi_penalize_isa_irq(int irq, int active); void acpi_pci_irq_disable (struct pci_dev *dev); +struct acpi_pci_driver { + struct list_head node; + int (*add)(struct acpi_pci_root *root); + void (*remove)(struct acpi_pci_root *root); +}; + +int acpi_pci_register_driver(struct acpi_pci_driver *driver); +void acpi_pci_unregister_driver(struct acpi_pci_driver *driver); + extern int ec_read(u8 addr, u8 *val); extern int ec_write(u8 addr, u8 val); extern int ec_transaction(u8 command, diff --git a/trunk/include/linux/ata.h b/trunk/include/linux/ata.h index ee0bd9524055..8f7a3d68371a 100644 --- a/trunk/include/linux/ata.h +++ b/trunk/include/linux/ata.h @@ -954,7 +954,7 @@ static inline int atapi_cdb_len(const u16 *dev_id) } } -static inline int atapi_command_packet_set(const u16 *dev_id) +static inline bool atapi_command_packet_set(const u16 *dev_id) { return (dev_id[ATA_ID_CONFIG] >> 8) & 0x1f; } diff --git a/trunk/include/linux/blktrace_api.h b/trunk/include/linux/blktrace_api.h index 7c2e030e72f1..0ea61e07a91c 100644 --- a/trunk/include/linux/blktrace_api.h +++ b/trunk/include/linux/blktrace_api.h @@ -12,6 +12,7 @@ struct blk_trace { int trace_state; + bool rq_based; struct rchan *rchan; unsigned long __percpu *sequence; unsigned char __percpu *msg_data; diff --git a/trunk/include/linux/capability.h b/trunk/include/linux/capability.h index d9a4f7f40f32..98503b792369 100644 --- a/trunk/include/linux/capability.h +++ b/trunk/include/linux/capability.h @@ -35,7 +35,6 @@ struct cpu_vfs_cap_data { #define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t)) -struct file; struct inode; struct dentry; struct user_namespace; @@ -212,7 +211,6 @@ extern bool capable(int cap); extern bool ns_capable(struct user_namespace *ns, int cap); extern bool nsown_capable(int cap); extern bool inode_capable(const struct inode *inode, int cap); -extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); /* audit system wants to get cap info from files as well */ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index 377cd8c3395e..76a87fb57ac2 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -141,11 +141,11 @@ typedef struct { } compat_sigset_t; struct compat_sigaction { -#ifndef __ARCH_HAS_IRIX_SIGACTION +#ifndef __ARCH_HAS_ODD_SIGACTION compat_uptr_t sa_handler; compat_ulong_t sa_flags; #else - compat_uint_t sa_flags; + compat_ulong_t sa_flags; compat_uptr_t sa_handler; #endif #ifdef __ARCH_HAS_SA_RESTORER diff --git a/trunk/include/linux/devfreq.h b/trunk/include/linux/devfreq.h index fe8c4476f7e4..e83ef39b3bea 100644 --- a/trunk/include/linux/devfreq.h +++ b/trunk/include/linux/devfreq.h @@ -213,7 +213,7 @@ struct devfreq_simple_ondemand_data { #endif #else /* !CONFIG_PM_DEVFREQ */ -static inline struct devfreq *devfreq_add_device(struct device *dev, +static struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, const char *governor_name, void *data) @@ -221,34 +221,34 @@ static inline struct devfreq *devfreq_add_device(struct device *dev, return NULL; } -static inline int devfreq_remove_device(struct devfreq *devfreq) +static int devfreq_remove_device(struct devfreq *devfreq) { return 0; } -static inline int devfreq_suspend_device(struct devfreq *devfreq) +static int devfreq_suspend_device(struct devfreq *devfreq) { return 0; } -static inline int devfreq_resume_device(struct devfreq *devfreq) +static int devfreq_resume_device(struct devfreq *devfreq) { return 0; } -static inline struct opp *devfreq_recommended_opp(struct device *dev, +static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { - return ERR_PTR(-EINVAL); + return -EINVAL; } -static inline int devfreq_register_opp_notifier(struct device *dev, +static int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq) { return -EINVAL; } -static inline int devfreq_unregister_opp_notifier(struct device *dev, +static int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq) { return -EINVAL; diff --git a/trunk/include/linux/efi.h b/trunk/include/linux/efi.h index 3d7df3d32c66..9bf2f1fcae27 100644 --- a/trunk/include/linux/efi.h +++ b/trunk/include/linux/efi.h @@ -333,7 +333,6 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules, unsigned long count, u64 *max_size, int *reset_type); -typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long size); /* * EFI Configuration Table and GUID definitions @@ -576,15 +575,9 @@ extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if pos #ifdef CONFIG_X86 extern void efi_late_init(void); extern void efi_free_boot_services(void); -extern efi_status_t efi_query_variable_store(u32 attributes, unsigned long size); #else static inline void efi_late_init(void) {} static inline void efi_free_boot_services(void) {} - -static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) -{ - return EFI_SUCCESS; -} #endif extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); extern u64 efi_get_iobase (void); @@ -738,7 +731,7 @@ struct efivar_operations { efi_get_variable_t *get_variable; efi_get_next_variable_t *get_next_variable; efi_set_variable_t *set_variable; - efi_query_variable_store_t *query_variable_store; + efi_query_variable_info_t *query_variable_info; }; struct efivars { diff --git a/trunk/include/linux/ftrace.h b/trunk/include/linux/ftrace.h index 52da2a250795..e5ca8ef50e9b 100644 --- a/trunk/include/linux/ftrace.h +++ b/trunk/include/linux/ftrace.h @@ -89,7 +89,6 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip, * that the call back has its own recursion protection. If it does * not set this, then the ftrace infrastructure will add recursion * protection for the caller. - * STUB - The ftrace_ops is just a place holder. */ enum { FTRACE_OPS_FL_ENABLED = 1 << 0, @@ -99,7 +98,6 @@ enum { FTRACE_OPS_FL_SAVE_REGS = 1 << 4, FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED = 1 << 5, FTRACE_OPS_FL_RECURSION_SAFE = 1 << 6, - FTRACE_OPS_FL_STUB = 1 << 7, }; struct ftrace_ops { @@ -396,6 +394,7 @@ ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos); ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos); +loff_t ftrace_regex_lseek(struct file *file, loff_t offset, int whence); int ftrace_regex_release(struct inode *inode, struct file *file); void __init @@ -568,8 +567,6 @@ static inline int ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; } #endif /* CONFIG_DYNAMIC_FTRACE */ -loff_t ftrace_filter_lseek(struct file *file, loff_t offset, int whence); - /* totally disable ftrace - can not re-enable after this */ void ftrace_kill(void); diff --git a/trunk/include/linux/kexec.h b/trunk/include/linux/kexec.h index d78d28a733b1..d2e6927bbaae 100644 --- a/trunk/include/linux/kexec.h +++ b/trunk/include/linux/kexec.h @@ -200,8 +200,6 @@ extern size_t vmcoreinfo_max_size; int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); -int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, - unsigned long long *crash_size, unsigned long long *crash_base); int parse_crashkernel_low(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); int crash_shrink_memory(unsigned long new_size); diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index c13958251927..cad77fe09d77 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -518,7 +518,7 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, void *data, unsigned long len); int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, - gpa_t gpa, unsigned long len); + gpa_t gpa); int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); diff --git a/trunk/include/linux/kvm_types.h b/trunk/include/linux/kvm_types.h index b0bcce0ddc95..fa7cc7244cbd 100644 --- a/trunk/include/linux/kvm_types.h +++ b/trunk/include/linux/kvm_types.h @@ -71,7 +71,6 @@ struct gfn_to_hva_cache { u64 generation; gpa_t gpa; unsigned long hva; - unsigned long len; struct kvm_memory_slot *memslot; }; diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index eae7a053dc51..91c9d109e5f1 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -398,7 +398,6 @@ enum { ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */ ATA_HORKAGE_BROKEN_FPDMA_AA = (1 << 15), /* skip AA */ ATA_HORKAGE_DUMP_ID = (1 << 16), /* dump IDENTIFY data */ - ATA_HORKAGE_MAX_SEC_LBA48 = (1 << 17), /* Set max sects to 65535 */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index e2091b88d24c..e19ff30ad0a2 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -1611,8 +1611,6 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); -int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len); - struct page *follow_page_mask(struct vm_area_struct *vma, unsigned long address, unsigned int foll_flags, diff --git a/trunk/include/linux/msi.h b/trunk/include/linux/msi.h index 20c2d6dd5d25..ce93a341337d 100644 --- a/trunk/include/linux/msi.h +++ b/trunk/include/linux/msi.h @@ -13,14 +13,14 @@ struct msi_msg { /* Helper functions */ struct irq_data; struct msi_desc; -void mask_msi_irq(struct irq_data *data); -void unmask_msi_irq(struct irq_data *data); -void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg); -void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); -void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg); -void read_msi_msg(unsigned int irq, struct msi_msg *msg); -void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); -void write_msi_msg(unsigned int irq, struct msi_msg *msg); +extern void mask_msi_irq(struct irq_data *data); +extern void unmask_msi_irq(struct irq_data *data); +extern void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg); +extern void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg); +extern void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg); +extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); +extern void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); +extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); struct msi_desc { struct { @@ -54,8 +54,9 @@ struct msi_desc { */ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); void arch_teardown_msi_irq(unsigned int irq); -int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); -void arch_teardown_msi_irqs(struct pci_dev *dev); -int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); +extern int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); +extern void arch_teardown_msi_irqs(struct pci_dev *dev); +extern int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); + #endif /* LINUX_MSI_H */ diff --git a/trunk/include/linux/mutex.h b/trunk/include/linux/mutex.h index 433da8a1a426..9121595a8ebf 100644 --- a/trunk/include/linux/mutex.h +++ b/trunk/include/linux/mutex.h @@ -53,9 +53,6 @@ struct mutex { #if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) struct task_struct *owner; #endif -#ifdef CONFIG_MUTEX_SPIN_ON_OWNER - void *spin_mlock; /* Spinner MCS lock */ -#endif #ifdef CONFIG_DEBUG_MUTEXES const char *name; void *magic; diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 6151e903eef0..b3d00fa4b314 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -210,9 +210,9 @@ struct netdev_hw_addr { #define NETDEV_HW_ADDR_T_SLAVE 3 #define NETDEV_HW_ADDR_T_UNICAST 4 #define NETDEV_HW_ADDR_T_MULTICAST 5 + bool synced; bool global_use; int refcount; - int synced; struct rcu_head rcu_head; }; @@ -895,7 +895,7 @@ struct netdev_fcoe_hbainfo { * * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh) * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq, - * struct net_device *dev, u32 filter_mask) + * struct net_device *dev) * * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier); * Called to change device carrier. Soft-devices (like dummy, team, etc) diff --git a/trunk/include/linux/netfilter/ipset/ip_set_ahash.h b/trunk/include/linux/netfilter/ipset/ip_set_ahash.h index 0214c4c146fa..01d25e6fc792 100644 --- a/trunk/include/linux/netfilter/ipset/ip_set_ahash.h +++ b/trunk/include/linux/netfilter/ipset/ip_set_ahash.h @@ -291,7 +291,6 @@ ip_set_hash_destroy(struct ip_set *set) #define type_pf_data_tlist TOKEN(TYPE, PF, _data_tlist) #define type_pf_data_next TOKEN(TYPE, PF, _data_next) #define type_pf_data_flags TOKEN(TYPE, PF, _data_flags) -#define type_pf_data_reset_flags TOKEN(TYPE, PF, _data_reset_flags) #ifdef IP_SET_HASH_WITH_NETS #define type_pf_data_match TOKEN(TYPE, PF, _data_match) #else @@ -386,9 +385,9 @@ type_pf_resize(struct ip_set *set, bool retried) struct ip_set_hash *h = set->data; struct htable *t, *orig = h->table; u8 htable_bits = orig->htable_bits; - struct type_pf_elem *data; + const struct type_pf_elem *data; struct hbucket *n, *m; - u32 i, j, flags = 0; + u32 i, j; int ret; retry: @@ -413,16 +412,9 @@ type_pf_resize(struct ip_set *set, bool retried) n = hbucket(orig, i); for (j = 0; j < n->pos; j++) { data = ahash_data(n, j); -#ifdef IP_SET_HASH_WITH_NETS - flags = 0; - type_pf_data_reset_flags(data, &flags); -#endif m = hbucket(t, HKEY(data, h->initval, htable_bits)); - ret = type_pf_elem_add(m, data, AHASH_MAX(h), flags); + ret = type_pf_elem_add(m, data, AHASH_MAX(h), 0); if (ret < 0) { -#ifdef IP_SET_HASH_WITH_NETS - type_pf_data_flags(data, flags); -#endif read_unlock_bh(&set->lock); ahash_destroy(t); if (ret == -EAGAIN) @@ -844,9 +836,9 @@ type_pf_tresize(struct ip_set *set, bool retried) struct ip_set_hash *h = set->data; struct htable *t, *orig = h->table; u8 htable_bits = orig->htable_bits; - struct type_pf_elem *data; + const struct type_pf_elem *data; struct hbucket *n, *m; - u32 i, j, flags = 0; + u32 i, j; int ret; /* Try to cleanup once */ @@ -881,17 +873,10 @@ type_pf_tresize(struct ip_set *set, bool retried) n = hbucket(orig, i); for (j = 0; j < n->pos; j++) { data = ahash_tdata(n, j); -#ifdef IP_SET_HASH_WITH_NETS - flags = 0; - type_pf_data_reset_flags(data, &flags); -#endif m = hbucket(t, HKEY(data, h->initval, htable_bits)); - ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), flags, - ip_set_timeout_get(type_pf_data_timeout(data))); + ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), 0, + ip_set_timeout_get(type_pf_data_timeout(data))); if (ret < 0) { -#ifdef IP_SET_HASH_WITH_NETS - type_pf_data_flags(data, flags); -#endif read_unlock_bh(&set->lock); ahash_destroy(t); if (ret == -EAGAIN) @@ -1202,7 +1187,6 @@ type_pf_gc_init(struct ip_set *set) #undef type_pf_data_tlist #undef type_pf_data_next #undef type_pf_data_flags -#undef type_pf_data_reset_flags #undef type_pf_data_match #undef type_pf_elem diff --git a/trunk/include/linux/pci-acpi.h b/trunk/include/linux/pci-acpi.h index 81b31613eb25..9a22b5efb384 100644 --- a/trunk/include/linux/pci-acpi.h +++ b/trunk/include/linux/pci-acpi.h @@ -41,37 +41,8 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus) return DEVICE_ACPI_HANDLE(dev); } - -void acpi_pci_add_bus(struct pci_bus *bus); -void acpi_pci_remove_bus(struct pci_bus *bus); - -#ifdef CONFIG_ACPI_PCI_SLOT -void acpi_pci_slot_init(void); -void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle); -void acpi_pci_slot_remove(struct pci_bus *bus); -#else -static inline void acpi_pci_slot_init(void) { } -static inline void acpi_pci_slot_enumerate(struct pci_bus *bus, - acpi_handle handle) { } -static inline void acpi_pci_slot_remove(struct pci_bus *bus) { } #endif -#ifdef CONFIG_HOTPLUG_PCI_ACPI -void acpiphp_init(void); -void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle); -void acpiphp_remove_slots(struct pci_bus *bus); -#else -static inline void acpiphp_init(void) { } -static inline void acpiphp_enumerate_slots(struct pci_bus *bus, - acpi_handle handle) { } -static inline void acpiphp_remove_slots(struct pci_bus *bus) { } -#endif - -#else /* CONFIG_ACPI */ -static inline void acpi_pci_add_bus(struct pci_bus *bus) { } -static inline void acpi_pci_remove_bus(struct pci_bus *bus) { } -#endif /* CONFIG_ACPI */ - #ifdef CONFIG_ACPI_APEI extern bool aer_acpi_firmware_first(void); #else diff --git a/trunk/include/linux/pci-aspm.h b/trunk/include/linux/pci-aspm.h index 8af4610c2e41..c8320144fe79 100644 --- a/trunk/include/linux/pci-aspm.h +++ b/trunk/include/linux/pci-aspm.h @@ -23,14 +23,14 @@ #define PCIE_LINK_STATE_CLKPM 4 #ifdef CONFIG_PCIEASPM -void pcie_aspm_init_link_state(struct pci_dev *pdev); -void pcie_aspm_exit_link_state(struct pci_dev *pdev); -void pcie_aspm_pm_state_change(struct pci_dev *pdev); -void pcie_aspm_powersave_config_link(struct pci_dev *pdev); -void pci_disable_link_state(struct pci_dev *pdev, int state); -void pci_disable_link_state_locked(struct pci_dev *pdev, int state); -void pcie_clear_aspm(struct pci_bus *bus); -void pcie_no_aspm(void); +extern void pcie_aspm_init_link_state(struct pci_dev *pdev); +extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); +extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); +extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev); +extern void pci_disable_link_state(struct pci_dev *pdev, int state); +extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state); +extern void pcie_clear_aspm(struct pci_bus *bus); +extern void pcie_no_aspm(void); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { @@ -56,8 +56,8 @@ static inline void pcie_no_aspm(void) #endif #ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */ -void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); -void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); +extern void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); +extern void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); #else static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) { diff --git a/trunk/include/linux/pci-ats.h b/trunk/include/linux/pci-ats.h index 68bcefd7fca0..7ef68724f0f0 100644 --- a/trunk/include/linux/pci-ats.h +++ b/trunk/include/linux/pci-ats.h @@ -14,9 +14,9 @@ struct pci_ats { #ifdef CONFIG_PCI_ATS -int pci_enable_ats(struct pci_dev *dev, int ps); -void pci_disable_ats(struct pci_dev *dev); -int pci_ats_queue_depth(struct pci_dev *dev); +extern int pci_enable_ats(struct pci_dev *dev, int ps); +extern void pci_disable_ats(struct pci_dev *dev); +extern int pci_ats_queue_depth(struct pci_dev *dev); /** * pci_ats_enabled - query the ATS status @@ -54,12 +54,12 @@ static inline int pci_ats_enabled(struct pci_dev *dev) #ifdef CONFIG_PCI_PRI -int pci_enable_pri(struct pci_dev *pdev, u32 reqs); -void pci_disable_pri(struct pci_dev *pdev); -bool pci_pri_enabled(struct pci_dev *pdev); -int pci_reset_pri(struct pci_dev *pdev); -bool pci_pri_stopped(struct pci_dev *pdev); -int pci_pri_status(struct pci_dev *pdev); +extern int pci_enable_pri(struct pci_dev *pdev, u32 reqs); +extern void pci_disable_pri(struct pci_dev *pdev); +extern bool pci_pri_enabled(struct pci_dev *pdev); +extern int pci_reset_pri(struct pci_dev *pdev); +extern bool pci_pri_stopped(struct pci_dev *pdev); +extern int pci_pri_status(struct pci_dev *pdev); #else /* CONFIG_PCI_PRI */ @@ -95,10 +95,10 @@ static inline int pci_pri_status(struct pci_dev *pdev) #ifdef CONFIG_PCI_PASID -int pci_enable_pasid(struct pci_dev *pdev, int features); -void pci_disable_pasid(struct pci_dev *pdev); -int pci_pasid_features(struct pci_dev *pdev); -int pci_max_pasids(struct pci_dev *pdev); +extern int pci_enable_pasid(struct pci_dev *pdev, int features); +extern void pci_disable_pasid(struct pci_dev *pdev); +extern int pci_pasid_features(struct pci_dev *pdev); +extern int pci_max_pasids(struct pci_dev *pdev); #else /* CONFIG_PCI_PASID */ diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index e73dfa308b87..2461033a7987 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -35,21 +35,6 @@ /* Include the ID list */ #include -/* - * The PCI interface treats multi-function devices as independent - * devices. The slot/function address of each device is encoded - * in a single byte as follows: - * - * 7:3 = slot - * 2:0 = function - * PCI_DEVFN(), PCI_SLOT(), and PCI_FUNC() are defined uapi/linux/pci.h - * In the interest of not exposing interfaces to user-space unnecessarily, - * the following kernel only defines are being added here. - */ -#define PCI_DEVID(bus, devfn) ((((u16)bus) << 8) | devfn) -/* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */ -#define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) - /* pci_slot represents a physical slot */ struct pci_slot { struct pci_bus *bus; /* The bus this slot is on */ @@ -247,8 +232,6 @@ struct pci_dev { u8 revision; /* PCI revision, low byte of class word */ u8 hdr_type; /* PCI header type (`multi' flag masked out) */ u8 pcie_cap; /* PCI-E capability offset */ - u8 msi_cap; /* MSI capability offset */ - u8 msix_cap; /* MSI-X capability offset */ u8 pcie_mpss:3; /* PCI-E Max Payload Size Supported */ u8 rom_base_reg; /* which config register controls the ROM */ u8 pin; /* which interrupt pin this device uses */ @@ -266,7 +249,8 @@ struct pci_dev { pci_power_t current_state; /* Current operating state. In ACPI-speak, this is D0-D3, D0 being fully functional, and D3 being off. */ - u8 pm_cap; /* PM capability offset */ + int pm_cap; /* PM capability offset in the + configuration space */ unsigned int pme_support:5; /* Bitmask of states from which PME# can be generated */ unsigned int pme_interrupt:1; @@ -364,7 +348,7 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev) return dev; } -struct pci_dev *alloc_pci_dev(void); +extern struct pci_dev *alloc_pci_dev(void); #define to_pci_dev(n) container_of(n, struct pci_dev, dev) #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) @@ -520,10 +504,10 @@ struct pci_ops { * ACPI needs to be able to access PCI config space before we've done a * PCI bus scan and created pci_bus structures. */ -int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, - int reg, int len, u32 *val); -int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, - int reg, int len, u32 val); +extern int raw_pci_read(unsigned int domain, unsigned int bus, + unsigned int devfn, int reg, int len, u32 *val); +extern int raw_pci_write(unsigned int domain, unsigned int bus, + unsigned int devfn, int reg, int len, u32 val); struct pci_bus_region { resource_size_t start; @@ -674,7 +658,7 @@ struct pci_driver { /* these external functions are only available when PCI support is enabled */ #ifdef CONFIG_PCI -void pcie_bus_configure_settings(struct pci_bus *bus, u8 smpss); +extern void pcie_bus_configure_settings(struct pci_bus *bus, u8 smpss); enum pcie_bus_config_types { PCIE_BUS_TUNE_OFF, @@ -691,11 +675,9 @@ extern struct bus_type pci_bus_type; * code, or pci core code. */ extern struct list_head pci_root_buses; /* list of all known PCI buses */ /* Some device drivers need know if pci is initiated */ -int no_pci_devices(void); +extern int no_pci_devices(void); void pcibios_resource_survey_bus(struct pci_bus *bus); -void pcibios_add_bus(struct pci_bus *bus); -void pcibios_remove_bus(struct pci_bus *bus); void pcibios_fixup_bus(struct pci_bus *); int __must_check pcibios_enable_device(struct pci_dev *, int mask); /* Architecture specific versions may override this (weak) */ @@ -717,7 +699,7 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region); void pcibios_scan_specific_bus(int busn); -struct pci_bus *pci_find_bus(int domain, int busnr); +extern struct pci_bus *pci_find_bus(int domain, int busnr); void pci_bus_add_devices(const struct pci_bus *bus); struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); @@ -750,14 +732,14 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev, u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin); int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); -struct pci_dev *pci_dev_get(struct pci_dev *dev); -void pci_dev_put(struct pci_dev *dev); -void pci_remove_bus(struct pci_bus *b); -void pci_stop_and_remove_bus_device(struct pci_dev *dev); +extern struct pci_dev *pci_dev_get(struct pci_dev *dev); +extern void pci_dev_put(struct pci_dev *dev); +extern void pci_remove_bus(struct pci_bus *b); +extern void pci_stop_and_remove_bus_device(struct pci_dev *dev); void pci_stop_root_bus(struct pci_bus *bus); void pci_remove_root_bus(struct pci_bus *bus); void pci_setup_cardbus(struct pci_bus *bus); -void pci_sort_breadthfirst(void); +extern void pci_sort_breadthfirst(void); #define dev_is_pci(d) ((d)->bus == &pci_bus_type) #define dev_is_pf(d) ((dev_is_pci(d) ? to_pci_dev(d)->is_physfn : false)) #define dev_num_vf(d) ((dev_is_pci(d) ? pci_num_vf(to_pci_dev(d)) : 0)) @@ -934,7 +916,6 @@ void pci_disable_rom(struct pci_dev *pdev); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); -void __iomem __must_check *pci_platform_rom(struct pci_dev *pdev, size_t *size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); @@ -1160,17 +1141,18 @@ static inline int pci_msi_enabled(void) return 0; } #else -int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); -int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); -void pci_msi_shutdown(struct pci_dev *dev); -void pci_disable_msi(struct pci_dev *dev); -int pci_msix_table_size(struct pci_dev *dev); -int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); -void pci_msix_shutdown(struct pci_dev *dev); -void pci_disable_msix(struct pci_dev *dev); -void msi_remove_pci_irq_vectors(struct pci_dev *dev); -void pci_restore_msi_state(struct pci_dev *dev); -int pci_msi_enabled(void); +extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); +extern int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); +extern void pci_msi_shutdown(struct pci_dev *dev); +extern void pci_disable_msi(struct pci_dev *dev); +extern int pci_msix_table_size(struct pci_dev *dev); +extern int pci_enable_msix(struct pci_dev *dev, + struct msix_entry *entries, int nvec); +extern void pci_msix_shutdown(struct pci_dev *dev); +extern void pci_disable_msix(struct pci_dev *dev); +extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); +extern void pci_restore_msi_state(struct pci_dev *dev); +extern int pci_msi_enabled(void); #endif #ifdef CONFIG_PCIEPORTBUS @@ -1185,8 +1167,8 @@ extern bool pcie_ports_auto; static inline int pcie_aspm_enabled(void) { return 0; } static inline bool pcie_aspm_support_enabled(void) { return false; } #else -int pcie_aspm_enabled(void); -bool pcie_aspm_support_enabled(void); +extern int pcie_aspm_enabled(void); +extern bool pcie_aspm_support_enabled(void); #endif #ifdef CONFIG_PCIEAER @@ -1204,8 +1186,8 @@ static inline void pcie_set_ecrc_checking(struct pci_dev *dev) } static inline void pcie_ecrc_get_policy(char *str) {}; #else -void pcie_set_ecrc_checking(struct pci_dev *dev); -void pcie_ecrc_get_policy(char *str); +extern void pcie_set_ecrc_checking(struct pci_dev *dev); +extern void pcie_ecrc_get_policy(char *str); #endif #define pci_enable_msi(pdev) pci_enable_msi_block(pdev, 1) @@ -1216,9 +1198,9 @@ int ht_create_irq(struct pci_dev *dev, int idx); void ht_destroy_irq(unsigned int irq); #endif /* CONFIG_HT_IRQ */ -void pci_cfg_access_lock(struct pci_dev *dev); -bool pci_cfg_access_trylock(struct pci_dev *dev); -void pci_cfg_access_unlock(struct pci_dev *dev); +extern void pci_cfg_access_lock(struct pci_dev *dev); +extern bool pci_cfg_access_trylock(struct pci_dev *dev); +extern void pci_cfg_access_unlock(struct pci_dev *dev); /* * PCI domain support. Sometimes called PCI segment (eg by ACPI), @@ -1243,7 +1225,7 @@ static inline int pci_proc_domain(struct pci_bus *bus) /* some architectures require additional setup to direct VGA traffic */ typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, unsigned int command_bits, u32 flags); -void pci_register_set_vga_state(arch_set_vga_state_t func); +extern void pci_register_set_vga_state(arch_set_vga_state_t func); #else /* CONFIG_PCI is not enabled */ @@ -1645,8 +1627,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, int pcibios_add_device(struct pci_dev *dev); #ifdef CONFIG_PCI_MMCONFIG -void __init pci_mmcfg_early_init(void); -void __init pci_mmcfg_late_init(void); +extern void __init pci_mmcfg_early_init(void); +extern void __init pci_mmcfg_late_init(void); #else static inline void pci_mmcfg_early_init(void) { } static inline void pci_mmcfg_late_init(void) { } @@ -1657,12 +1639,12 @@ int pci_ext_cfg_avail(void); void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar); #ifdef CONFIG_PCI_IOV -int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); -void pci_disable_sriov(struct pci_dev *dev); -irqreturn_t pci_sriov_migration(struct pci_dev *dev); -int pci_num_vf(struct pci_dev *dev); -int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); -int pci_sriov_get_totalvfs(struct pci_dev *dev); +extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); +extern void pci_disable_sriov(struct pci_dev *dev); +extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); +extern int pci_num_vf(struct pci_dev *dev); +extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); +extern int pci_sriov_get_totalvfs(struct pci_dev *dev); #else static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) { @@ -1690,8 +1672,8 @@ static inline int pci_sriov_get_totalvfs(struct pci_dev *dev) #endif #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) -void pci_hp_create_module_link(struct pci_slot *pci_slot); -void pci_hp_remove_module_link(struct pci_slot *pci_slot); +extern void pci_hp_create_module_link(struct pci_slot *pci_slot); +extern void pci_hp_remove_module_link(struct pci_slot *pci_slot); #endif /** @@ -1835,13 +1817,13 @@ int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off, /* PCI <-> OF binding helpers */ #ifdef CONFIG_OF struct device_node; -void pci_set_of_node(struct pci_dev *dev); -void pci_release_of_node(struct pci_dev *dev); -void pci_set_bus_of_node(struct pci_bus *bus); -void pci_release_bus_of_node(struct pci_bus *bus); +extern void pci_set_of_node(struct pci_dev *dev); +extern void pci_release_of_node(struct pci_dev *dev); +extern void pci_set_bus_of_node(struct pci_bus *bus); +extern void pci_release_bus_of_node(struct pci_bus *bus); /* Arch may override this (weak) */ -struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus); +extern struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus); static inline struct device_node * pci_device_to_OF_node(const struct pci_dev *pdev) diff --git a/trunk/include/linux/pci_hotplug.h b/trunk/include/linux/pci_hotplug.h index 8db71dcd6337..45fc162cbdc0 100644 --- a/trunk/include/linux/pci_hotplug.h +++ b/trunk/include/linux/pci_hotplug.h @@ -125,12 +125,12 @@ static inline const char *hotplug_slot_name(const struct hotplug_slot *slot) return pci_slot_name(slot->pci_slot); } -int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *pbus, int nr, - const char *name, struct module *owner, - const char *mod_name); -int pci_hp_deregister(struct hotplug_slot *slot); -int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, - struct hotplug_slot_info *info); +extern int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *pbus, + int nr, const char *name, + struct module *owner, const char *mod_name); +extern int pci_hp_deregister(struct hotplug_slot *slot); +extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot, + struct hotplug_slot_info *info); /* use a define to avoid include chaining to get THIS_MODULE & friends */ #define pci_hp_register(slot, pbus, devnr, name) \ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index a80f9e6ce9e5..f11c1c2609d5 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1604,7 +1604,6 @@ #define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334 #define PCI_VENDOR_ID_MARVELL 0x11ab -#define PCI_VENDOR_ID_MARVELL_EXT 0x1b4b #define PCI_DEVICE_ID_MARVELL_GT64111 0x4146 #define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 #define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 diff --git a/trunk/include/linux/pcieport_if.h b/trunk/include/linux/pcieport_if.h index 9572669eea97..e6f91b1406d8 100644 --- a/trunk/include/linux/pcieport_if.h +++ b/trunk/include/linux/pcieport_if.h @@ -62,7 +62,7 @@ struct pcie_port_service_driver { #define to_service_driver(d) \ container_of(d, struct pcie_port_service_driver, driver) -int pcie_port_service_register(struct pcie_port_service_driver *new); -void pcie_port_service_unregister(struct pcie_port_service_driver *new); +extern int pcie_port_service_register(struct pcie_port_service_driver *new); +extern void pcie_port_service_unregister(struct pcie_port_service_driver *new); #endif /* _PCIEPORT_IF_H_ */ diff --git a/trunk/include/linux/preempt.h b/trunk/include/linux/preempt.h index 87a03c746f17..5a710b9c578e 100644 --- a/trunk/include/linux/preempt.h +++ b/trunk/include/linux/preempt.h @@ -93,20 +93,14 @@ do { \ #else /* !CONFIG_PREEMPT_COUNT */ -/* - * Even if we don't have any preemption, we need preempt disable/enable - * to be barriers, so that we don't have things like get_user/put_user - * that can cause faults and scheduling migrate into our preempt-protected - * region. - */ -#define preempt_disable() barrier() -#define sched_preempt_enable_no_resched() barrier() -#define preempt_enable_no_resched() barrier() -#define preempt_enable() barrier() - -#define preempt_disable_notrace() barrier() -#define preempt_enable_no_resched_notrace() barrier() -#define preempt_enable_notrace() barrier() +#define preempt_disable() do { } while (0) +#define sched_preempt_enable_no_resched() do { } while (0) +#define preempt_enable_no_resched() do { } while (0) +#define preempt_enable() do { } while (0) + +#define preempt_disable_notrace() do { } while (0) +#define preempt_enable_no_resched_notrace() do { } while (0) +#define preempt_enable_notrace() do { } while (0) #endif /* CONFIG_PREEMPT_COUNT */ diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index 94dfb2aa5533..8307f2f94d86 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -117,7 +117,6 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, const struct file_operations *proc_fops, void *data); extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent); -extern int remove_proc_subtree(const char *name, struct proc_dir_entry *parent); struct pid_namespace; @@ -203,7 +202,6 @@ static inline struct proc_dir_entry *proc_create_data(const char *name, return NULL; } #define remove_proc_entry(name, parent) do {} while (0) -#define remove_proc_subtree(name, parent) do {} while (0) static inline struct proc_dir_entry *proc_symlink(const char *name, struct proc_dir_entry *parent,const char *dest) {return NULL;} diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 2d02c76a01be..d35d2b6ddbfb 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -163,10 +163,9 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) #define TASK_DEAD 64 #define TASK_WAKEKILL 128 #define TASK_WAKING 256 -#define TASK_PARKED 512 -#define TASK_STATE_MAX 1024 +#define TASK_STATE_MAX 512 -#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKWP" +#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW" extern char ___assert_task_state[1 - 2*!!( sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)]; @@ -321,6 +320,7 @@ extern signed long schedule_timeout_killable(signed long timeout); extern signed long schedule_timeout_uninterruptible(signed long timeout); asmlinkage void schedule(void); extern void schedule_preempt_disabled(void); +extern int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner); struct nsproxy; struct user_namespace; diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index 032c366ef1c6..eee7478cda70 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -1012,10 +1012,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * This hook can be used by the module to update any security state * associated with the TUN device's security structure. * @security pointer to the TUN devices's security structure. - * @skb_owned_by: - * This hook sets the packet's owning sock. - * @skb is the packet. - * @sk the sock which owns the packet. * * Security hooks for XFRM operations. * @@ -1642,7 +1638,6 @@ struct security_operations { int (*tun_dev_attach_queue) (void *security); int (*tun_dev_attach) (struct sock *sk, void *security); int (*tun_dev_open) (void *security); - void (*skb_owned_by) (struct sk_buff *skb, struct sock *sk); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -2593,8 +2588,6 @@ int security_tun_dev_attach_queue(void *security); int security_tun_dev_attach(struct sock *sk, void *security); int security_tun_dev_open(void *security); -void security_skb_owned_by(struct sk_buff *skb, struct sock *sk); - #else /* CONFIG_SECURITY_NETWORK */ static inline int security_unix_stream_connect(struct sock *sock, struct sock *other, @@ -2786,11 +2779,6 @@ static inline int security_tun_dev_open(void *security) { return 0; } - -static inline void security_skb_owned_by(struct sk_buff *skb, struct sock *sk) -{ -} - #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM diff --git a/trunk/include/linux/signal.h b/trunk/include/linux/signal.h index 9475c5cb28bc..a2dcb94ea49d 100644 --- a/trunk/include/linux/signal.h +++ b/trunk/include/linux/signal.h @@ -250,11 +250,11 @@ extern int show_unhandled_signals; extern int sigsuspend(sigset_t *); struct sigaction { -#ifndef __ARCH_HAS_IRIX_SIGACTION +#ifndef __ARCH_HAS_ODD_SIGACTION __sighandler_t sa_handler; unsigned long sa_flags; #else - unsigned int sa_flags; + unsigned long sa_flags; __sighandler_t sa_handler; #endif #ifdef __ARCH_HAS_SA_RESTORER diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index b8292d8cc9fa..441f5bfdab8e 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -2643,13 +2643,6 @@ static inline void nf_reset(struct sk_buff *skb) #endif } -static inline void nf_reset_trace(struct sk_buff *skb) -{ -#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) - skb->nf_trace = 0; -#endif -} - /* Note: This doesn't put any conntrack and bridge info in dst. */ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src) { diff --git a/trunk/include/linux/spinlock_up.h b/trunk/include/linux/spinlock_up.h index e2369c167dbd..a26e2fb604e6 100644 --- a/trunk/include/linux/spinlock_up.h +++ b/trunk/include/linux/spinlock_up.h @@ -16,10 +16,7 @@ * In the debug case, 1 means unlocked, 0 means locked. (the values * are inverted, to catch initialization bugs) * - * No atomicity anywhere, we are on UP. However, we still need - * the compiler barriers, because we do not want the compiler to - * move potentially faulting instructions (notably user accesses) - * into the locked sequence, resulting in non-atomic execution. + * No atomicity anywhere, we are on UP. */ #ifdef CONFIG_DEBUG_SPINLOCK @@ -28,7 +25,6 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) { lock->slock = 0; - barrier(); } static inline void @@ -36,7 +32,6 @@ arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) { local_irq_save(flags); lock->slock = 0; - barrier(); } static inline int arch_spin_trylock(arch_spinlock_t *lock) @@ -44,34 +39,32 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) char oldval = lock->slock; lock->slock = 0; - barrier(); return oldval > 0; } static inline void arch_spin_unlock(arch_spinlock_t *lock) { - barrier(); lock->slock = 1; } /* * Read-write spinlocks. No debug version. */ -#define arch_read_lock(lock) do { barrier(); (void)(lock); } while (0) -#define arch_write_lock(lock) do { barrier(); (void)(lock); } while (0) -#define arch_read_trylock(lock) ({ barrier(); (void)(lock); 1; }) -#define arch_write_trylock(lock) ({ barrier(); (void)(lock); 1; }) -#define arch_read_unlock(lock) do { barrier(); (void)(lock); } while (0) -#define arch_write_unlock(lock) do { barrier(); (void)(lock); } while (0) +#define arch_read_lock(lock) do { (void)(lock); } while (0) +#define arch_write_lock(lock) do { (void)(lock); } while (0) +#define arch_read_trylock(lock) ({ (void)(lock); 1; }) +#define arch_write_trylock(lock) ({ (void)(lock); 1; }) +#define arch_read_unlock(lock) do { (void)(lock); } while (0) +#define arch_write_unlock(lock) do { (void)(lock); } while (0) #else /* DEBUG_SPINLOCK */ #define arch_spin_is_locked(lock) ((void)(lock), 0) /* for sched.c and kernel_lock.c: */ -# define arch_spin_lock(lock) do { barrier(); (void)(lock); } while (0) -# define arch_spin_lock_flags(lock, flags) do { barrier(); (void)(lock); } while (0) -# define arch_spin_unlock(lock) do { barrier(); (void)(lock); } while (0) -# define arch_spin_trylock(lock) ({ barrier(); (void)(lock); 1; }) +# define arch_spin_lock(lock) do { (void)(lock); } while (0) +# define arch_spin_lock_flags(lock, flags) do { (void)(lock); } while (0) +# define arch_spin_unlock(lock) do { (void)(lock); } while (0) +# define arch_spin_trylock(lock) ({ (void)(lock); 1; }) #endif /* DEBUG_SPINLOCK */ #define arch_spin_is_contended(lock) (((void)(lock), 0)) diff --git a/trunk/include/linux/ssb/ssb_driver_chipcommon.h b/trunk/include/linux/ssb/ssb_driver_chipcommon.h index 6fcfe99bd999..9e492be5244b 100644 --- a/trunk/include/linux/ssb/ssb_driver_chipcommon.h +++ b/trunk/include/linux/ssb/ssb_driver_chipcommon.h @@ -219,7 +219,6 @@ #define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */ #define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */ #define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16 -#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400 #define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */ #define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */ #define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */ @@ -668,6 +667,5 @@ enum ssb_pmu_ldo_volt_id { void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, enum ssb_pmu_ldo_volt_id id, u32 voltage); void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on); -void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid); #endif /* LINUX_SSB_CHIPCO_H_ */ diff --git a/trunk/include/linux/swiotlb.h b/trunk/include/linux/swiotlb.h index a5ffd32642fd..2de42f9401d2 100644 --- a/trunk/include/linux/swiotlb.h +++ b/trunk/include/linux/swiotlb.h @@ -25,7 +25,6 @@ extern int swiotlb_force; extern void swiotlb_init(int verbose); int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose); extern unsigned long swiotlb_nr_tbl(void); -unsigned long swiotlb_size_or_default(void); extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs); /* diff --git a/trunk/include/linux/ucs2_string.h b/trunk/include/linux/ucs2_string.h deleted file mode 100644 index cbb20afdbc01..000000000000 --- a/trunk/include/linux/ucs2_string.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _LINUX_UCS2_STRING_H_ -#define _LINUX_UCS2_STRING_H_ - -#include /* for size_t */ -#include /* for NULL */ - -typedef u16 ucs2_char_t; - -unsigned long ucs2_strnlen(const ucs2_char_t *s, size_t maxlength); -unsigned long ucs2_strlen(const ucs2_char_t *s); -unsigned long ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength); -int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len); - -#endif /* _LINUX_UCS2_STRING_H_ */ diff --git a/trunk/include/net/addrconf.h b/trunk/include/net/addrconf.h index 84a6440f1f19..40be2a0d8ae1 100644 --- a/trunk/include/net/addrconf.h +++ b/trunk/include/net/addrconf.h @@ -199,7 +199,6 @@ extern bool ipv6_chk_acast_addr(struct net *net, struct net_device *dev, /* Device notifier */ extern int register_inet6addr_notifier(struct notifier_block *nb); extern int unregister_inet6addr_notifier(struct notifier_block *nb); -extern int inet6addr_notifier_call_chain(unsigned long val, void *v); extern void inet6_netconf_notify_devconf(struct net *net, int type, int ifindex, struct ipv6_devconf *devconf); diff --git a/trunk/include/net/irda/irlmp.h b/trunk/include/net/irda/irlmp.h index f132924cc9da..f74109144d3f 100644 --- a/trunk/include/net/irda/irlmp.h +++ b/trunk/include/net/irda/irlmp.h @@ -256,8 +256,7 @@ static inline __u32 irlmp_get_daddr(const struct lsap_cb *self) return (self && self->lap) ? self->lap->daddr : 0; } -const char *irlmp_reason_str(LM_REASON reason); - +extern const char *irlmp_reasons[]; extern int sysctl_discovery_timeout; extern int sysctl_discovery_slots; extern int sysctl_discovery; diff --git a/trunk/include/net/iucv/af_iucv.h b/trunk/include/net/iucv/af_iucv.h index 714cc9a54a4c..cc7c19732389 100644 --- a/trunk/include/net/iucv/af_iucv.h +++ b/trunk/include/net/iucv/af_iucv.h @@ -130,14 +130,6 @@ struct iucv_sock { enum iucv_tx_notify n); }; -struct iucv_skb_cb { - u32 class; /* target class of message */ - u32 tag; /* tag associated with message */ - u32 offset; /* offset for skb receival */ -}; - -#define IUCV_SKB_CB(__skb) ((struct iucv_skb_cb *)&((__skb)->cb[0])) - /* iucv socket options (SOL_IUCV) */ #define SO_IPRMDATA_MSG 0x0080 /* send/recv IPRM_DATA msgs */ #define SO_MSGLIMIT 0x1000 /* get/set IUCV MSGLIMIT */ diff --git a/trunk/include/net/scm.h b/trunk/include/net/scm.h index b11708105681..975cca01048b 100644 --- a/trunk/include/net/scm.h +++ b/trunk/include/net/scm.h @@ -56,8 +56,8 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm, scm->pid = get_pid(pid); scm->cred = cred ? get_cred(cred) : NULL; scm->creds.pid = pid_vnr(pid); - scm->creds.uid = cred ? cred->uid : INVALID_UID; - scm->creds.gid = cred ? cred->gid : INVALID_GID; + scm->creds.uid = cred ? cred->euid : INVALID_UID; + scm->creds.gid = cred ? cred->egid : INVALID_GID; } static __inline__ void scm_destroy_cred(struct scm_cookie *scm) diff --git a/trunk/include/scsi/libfc.h b/trunk/include/scsi/libfc.h index e1379b4e8faf..399162b50a8d 100644 --- a/trunk/include/scsi/libfc.h +++ b/trunk/include/scsi/libfc.h @@ -1074,8 +1074,7 @@ void fc_rport_terminate_io(struct fc_rport *); /* * DISCOVERY LAYER *****************************/ -void fc_disc_init(struct fc_lport *); -void fc_disc_config(struct fc_lport *, void *); +int fc_disc_init(struct fc_lport *); static inline struct fc_lport *fc_disc_lport(struct fc_disc *disc) { diff --git a/trunk/include/sound/max98090.h b/trunk/include/sound/max98090.h old mode 100644 new mode 100755 diff --git a/trunk/include/sound/soc-dapm.h b/trunk/include/sound/soc-dapm.h index 44a30b108683..e1ef63d4a5c4 100644 --- a/trunk/include/sound/soc-dapm.h +++ b/trunk/include/sound/soc-dapm.h @@ -488,7 +488,6 @@ struct snd_soc_dapm_path { /* status */ u32 connect:1; /* source and sink widgets are connected */ u32 walked:1; /* path has been walked */ - u32 walking:1; /* path is in the process of being walked */ u32 weak:1; /* path ignored for power management */ int (*connected)(struct snd_soc_dapm_widget *source, diff --git a/trunk/include/trace/events/block.h b/trunk/include/trace/events/block.h index 9c1467357b03..9961726523d0 100644 --- a/trunk/include/trace/events/block.h +++ b/trunk/include/trace/events/block.h @@ -257,7 +257,6 @@ TRACE_EVENT(block_bio_bounce, /** * block_bio_complete - completed all work on the block operation - * @q: queue holding the block operation * @bio: block operation completed * @error: io error value * @@ -266,9 +265,9 @@ TRACE_EVENT(block_bio_bounce, */ TRACE_EVENT(block_bio_complete, - TP_PROTO(struct request_queue *q, struct bio *bio, int error), + TP_PROTO(struct bio *bio, int error), - TP_ARGS(q, bio, error), + TP_ARGS(bio, error), TP_STRUCT__entry( __field( dev_t, dev ) @@ -279,7 +278,8 @@ TRACE_EVENT(block_bio_complete, ), TP_fast_assign( - __entry->dev = bio->bi_bdev->bd_dev; + __entry->dev = bio->bi_bdev ? + bio->bi_bdev->bd_dev : 0; __entry->sector = bio->bi_sector; __entry->nr_sector = bio->bi_size >> 9; __entry->error = error; diff --git a/trunk/include/trace/events/sched.h b/trunk/include/trace/events/sched.h index e5586caff67a..5a8671e8a67f 100644 --- a/trunk/include/trace/events/sched.h +++ b/trunk/include/trace/events/sched.h @@ -147,7 +147,7 @@ TRACE_EVENT(sched_switch, __print_flags(__entry->prev_state & (TASK_STATE_MAX-1), "|", { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" }, { 16, "Z" }, { 32, "X" }, { 64, "x" }, - { 128, "K" }, { 256, "W" }, { 512, "P" }) : "R", + { 128, "W" }) : "R", __entry->prev_state & TASK_STATE_MAX ? "+" : "", __entry->next_comm, __entry->next_pid, __entry->next_prio) ); diff --git a/trunk/include/uapi/linux/fuse.h b/trunk/include/uapi/linux/fuse.h index 706d035fa748..4c43b4448792 100644 --- a/trunk/include/uapi/linux/fuse.h +++ b/trunk/include/uapi/linux/fuse.h @@ -95,10 +95,15 @@ #ifndef _LINUX_FUSE_H #define _LINUX_FUSE_H -#ifdef __KERNEL__ +#ifdef __linux__ #include #else #include +#define __u64 uint64_t +#define __s64 int64_t +#define __u32 uint32_t +#define __s32 int32_t +#define __u16 uint16_t #endif /* @@ -134,42 +139,42 @@ userspace works under 64bit kernels */ struct fuse_attr { - uint64_t ino; - uint64_t size; - uint64_t blocks; - uint64_t atime; - uint64_t mtime; - uint64_t ctime; - uint32_t atimensec; - uint32_t mtimensec; - uint32_t ctimensec; - uint32_t mode; - uint32_t nlink; - uint32_t uid; - uint32_t gid; - uint32_t rdev; - uint32_t blksize; - uint32_t padding; + __u64 ino; + __u64 size; + __u64 blocks; + __u64 atime; + __u64 mtime; + __u64 ctime; + __u32 atimensec; + __u32 mtimensec; + __u32 ctimensec; + __u32 mode; + __u32 nlink; + __u32 uid; + __u32 gid; + __u32 rdev; + __u32 blksize; + __u32 padding; }; struct fuse_kstatfs { - uint64_t blocks; - uint64_t bfree; - uint64_t bavail; - uint64_t files; - uint64_t ffree; - uint32_t bsize; - uint32_t namelen; - uint32_t frsize; - uint32_t padding; - uint32_t spare[6]; + __u64 blocks; + __u64 bfree; + __u64 bavail; + __u64 files; + __u64 ffree; + __u32 bsize; + __u32 namelen; + __u32 frsize; + __u32 padding; + __u32 spare[6]; }; struct fuse_file_lock { - uint64_t start; - uint64_t end; - uint32_t type; - uint32_t pid; /* tgid */ + __u64 start; + __u64 end; + __u32 type; + __u32 pid; /* tgid */ }; /** @@ -359,143 +364,143 @@ enum fuse_notify_code { #define FUSE_COMPAT_ENTRY_OUT_SIZE 120 struct fuse_entry_out { - uint64_t nodeid; /* Inode ID */ - uint64_t generation; /* Inode generation: nodeid:gen must - be unique for the fs's lifetime */ - uint64_t entry_valid; /* Cache timeout for the name */ - uint64_t attr_valid; /* Cache timeout for the attributes */ - uint32_t entry_valid_nsec; - uint32_t attr_valid_nsec; + __u64 nodeid; /* Inode ID */ + __u64 generation; /* Inode generation: nodeid:gen must + be unique for the fs's lifetime */ + __u64 entry_valid; /* Cache timeout for the name */ + __u64 attr_valid; /* Cache timeout for the attributes */ + __u32 entry_valid_nsec; + __u32 attr_valid_nsec; struct fuse_attr attr; }; struct fuse_forget_in { - uint64_t nlookup; + __u64 nlookup; }; struct fuse_forget_one { - uint64_t nodeid; - uint64_t nlookup; + __u64 nodeid; + __u64 nlookup; }; struct fuse_batch_forget_in { - uint32_t count; - uint32_t dummy; + __u32 count; + __u32 dummy; }; struct fuse_getattr_in { - uint32_t getattr_flags; - uint32_t dummy; - uint64_t fh; + __u32 getattr_flags; + __u32 dummy; + __u64 fh; }; #define FUSE_COMPAT_ATTR_OUT_SIZE 96 struct fuse_attr_out { - uint64_t attr_valid; /* Cache timeout for the attributes */ - uint32_t attr_valid_nsec; - uint32_t dummy; + __u64 attr_valid; /* Cache timeout for the attributes */ + __u32 attr_valid_nsec; + __u32 dummy; struct fuse_attr attr; }; #define FUSE_COMPAT_MKNOD_IN_SIZE 8 struct fuse_mknod_in { - uint32_t mode; - uint32_t rdev; - uint32_t umask; - uint32_t padding; + __u32 mode; + __u32 rdev; + __u32 umask; + __u32 padding; }; struct fuse_mkdir_in { - uint32_t mode; - uint32_t umask; + __u32 mode; + __u32 umask; }; struct fuse_rename_in { - uint64_t newdir; + __u64 newdir; }; struct fuse_link_in { - uint64_t oldnodeid; + __u64 oldnodeid; }; struct fuse_setattr_in { - uint32_t valid; - uint32_t padding; - uint64_t fh; - uint64_t size; - uint64_t lock_owner; - uint64_t atime; - uint64_t mtime; - uint64_t unused2; - uint32_t atimensec; - uint32_t mtimensec; - uint32_t unused3; - uint32_t mode; - uint32_t unused4; - uint32_t uid; - uint32_t gid; - uint32_t unused5; + __u32 valid; + __u32 padding; + __u64 fh; + __u64 size; + __u64 lock_owner; + __u64 atime; + __u64 mtime; + __u64 unused2; + __u32 atimensec; + __u32 mtimensec; + __u32 unused3; + __u32 mode; + __u32 unused4; + __u32 uid; + __u32 gid; + __u32 unused5; }; struct fuse_open_in { - uint32_t flags; - uint32_t unused; + __u32 flags; + __u32 unused; }; struct fuse_create_in { - uint32_t flags; - uint32_t mode; - uint32_t umask; - uint32_t padding; + __u32 flags; + __u32 mode; + __u32 umask; + __u32 padding; }; struct fuse_open_out { - uint64_t fh; - uint32_t open_flags; - uint32_t padding; + __u64 fh; + __u32 open_flags; + __u32 padding; }; struct fuse_release_in { - uint64_t fh; - uint32_t flags; - uint32_t release_flags; - uint64_t lock_owner; + __u64 fh; + __u32 flags; + __u32 release_flags; + __u64 lock_owner; }; struct fuse_flush_in { - uint64_t fh; - uint32_t unused; - uint32_t padding; - uint64_t lock_owner; + __u64 fh; + __u32 unused; + __u32 padding; + __u64 lock_owner; }; struct fuse_read_in { - uint64_t fh; - uint64_t offset; - uint32_t size; - uint32_t read_flags; - uint64_t lock_owner; - uint32_t flags; - uint32_t padding; + __u64 fh; + __u64 offset; + __u32 size; + __u32 read_flags; + __u64 lock_owner; + __u32 flags; + __u32 padding; }; #define FUSE_COMPAT_WRITE_IN_SIZE 24 struct fuse_write_in { - uint64_t fh; - uint64_t offset; - uint32_t size; - uint32_t write_flags; - uint64_t lock_owner; - uint32_t flags; - uint32_t padding; + __u64 fh; + __u64 offset; + __u32 size; + __u32 write_flags; + __u64 lock_owner; + __u32 flags; + __u32 padding; }; struct fuse_write_out { - uint32_t size; - uint32_t padding; + __u32 size; + __u32 padding; }; #define FUSE_COMPAT_STATFS_SIZE 48 @@ -505,32 +510,32 @@ struct fuse_statfs_out { }; struct fuse_fsync_in { - uint64_t fh; - uint32_t fsync_flags; - uint32_t padding; + __u64 fh; + __u32 fsync_flags; + __u32 padding; }; struct fuse_setxattr_in { - uint32_t size; - uint32_t flags; + __u32 size; + __u32 flags; }; struct fuse_getxattr_in { - uint32_t size; - uint32_t padding; + __u32 size; + __u32 padding; }; struct fuse_getxattr_out { - uint32_t size; - uint32_t padding; + __u32 size; + __u32 padding; }; struct fuse_lk_in { - uint64_t fh; - uint64_t owner; + __u64 fh; + __u64 owner; struct fuse_file_lock lk; - uint32_t lk_flags; - uint32_t padding; + __u32 lk_flags; + __u32 padding; }; struct fuse_lk_out { @@ -538,135 +543,134 @@ struct fuse_lk_out { }; struct fuse_access_in { - uint32_t mask; - uint32_t padding; + __u32 mask; + __u32 padding; }; struct fuse_init_in { - uint32_t major; - uint32_t minor; - uint32_t max_readahead; - uint32_t flags; + __u32 major; + __u32 minor; + __u32 max_readahead; + __u32 flags; }; struct fuse_init_out { - uint32_t major; - uint32_t minor; - uint32_t max_readahead; - uint32_t flags; - uint16_t max_background; - uint16_t congestion_threshold; - uint32_t max_write; + __u32 major; + __u32 minor; + __u32 max_readahead; + __u32 flags; + __u16 max_background; + __u16 congestion_threshold; + __u32 max_write; }; #define CUSE_INIT_INFO_MAX 4096 struct cuse_init_in { - uint32_t major; - uint32_t minor; - uint32_t unused; - uint32_t flags; + __u32 major; + __u32 minor; + __u32 unused; + __u32 flags; }; struct cuse_init_out { - uint32_t major; - uint32_t minor; - uint32_t unused; - uint32_t flags; - uint32_t max_read; - uint32_t max_write; - uint32_t dev_major; /* chardev major */ - uint32_t dev_minor; /* chardev minor */ - uint32_t spare[10]; + __u32 major; + __u32 minor; + __u32 unused; + __u32 flags; + __u32 max_read; + __u32 max_write; + __u32 dev_major; /* chardev major */ + __u32 dev_minor; /* chardev minor */ + __u32 spare[10]; }; struct fuse_interrupt_in { - uint64_t unique; + __u64 unique; }; struct fuse_bmap_in { - uint64_t block; - uint32_t blocksize; - uint32_t padding; + __u64 block; + __u32 blocksize; + __u32 padding; }; struct fuse_bmap_out { - uint64_t block; + __u64 block; }; struct fuse_ioctl_in { - uint64_t fh; - uint32_t flags; - uint32_t cmd; - uint64_t arg; - uint32_t in_size; - uint32_t out_size; + __u64 fh; + __u32 flags; + __u32 cmd; + __u64 arg; + __u32 in_size; + __u32 out_size; }; struct fuse_ioctl_iovec { - uint64_t base; - uint64_t len; + __u64 base; + __u64 len; }; struct fuse_ioctl_out { - int32_t result; - uint32_t flags; - uint32_t in_iovs; - uint32_t out_iovs; + __s32 result; + __u32 flags; + __u32 in_iovs; + __u32 out_iovs; }; struct fuse_poll_in { - uint64_t fh; - uint64_t kh; - uint32_t flags; - uint32_t events; + __u64 fh; + __u64 kh; + __u32 flags; + __u32 events; }; struct fuse_poll_out { - uint32_t revents; - uint32_t padding; + __u32 revents; + __u32 padding; }; struct fuse_notify_poll_wakeup_out { - uint64_t kh; + __u64 kh; }; struct fuse_fallocate_in { - uint64_t fh; - uint64_t offset; - uint64_t length; - uint32_t mode; - uint32_t padding; + __u64 fh; + __u64 offset; + __u64 length; + __u32 mode; + __u32 padding; }; struct fuse_in_header { - uint32_t len; - uint32_t opcode; - uint64_t unique; - uint64_t nodeid; - uint32_t uid; - uint32_t gid; - uint32_t pid; - uint32_t padding; + __u32 len; + __u32 opcode; + __u64 unique; + __u64 nodeid; + __u32 uid; + __u32 gid; + __u32 pid; + __u32 padding; }; struct fuse_out_header { - uint32_t len; - int32_t error; - uint64_t unique; + __u32 len; + __s32 error; + __u64 unique; }; struct fuse_dirent { - uint64_t ino; - uint64_t off; - uint32_t namelen; - uint32_t type; + __u64 ino; + __u64 off; + __u32 namelen; + __u32 type; char name[]; }; #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) -#define FUSE_DIRENT_ALIGN(x) \ - (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1)) +#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1)) #define FUSE_DIRENT_SIZE(d) \ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) @@ -681,47 +685,47 @@ struct fuse_direntplus { FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen) struct fuse_notify_inval_inode_out { - uint64_t ino; - int64_t off; - int64_t len; + __u64 ino; + __s64 off; + __s64 len; }; struct fuse_notify_inval_entry_out { - uint64_t parent; - uint32_t namelen; - uint32_t padding; + __u64 parent; + __u32 namelen; + __u32 padding; }; struct fuse_notify_delete_out { - uint64_t parent; - uint64_t child; - uint32_t namelen; - uint32_t padding; + __u64 parent; + __u64 child; + __u32 namelen; + __u32 padding; }; struct fuse_notify_store_out { - uint64_t nodeid; - uint64_t offset; - uint32_t size; - uint32_t padding; + __u64 nodeid; + __u64 offset; + __u32 size; + __u32 padding; }; struct fuse_notify_retrieve_out { - uint64_t notify_unique; - uint64_t nodeid; - uint64_t offset; - uint32_t size; - uint32_t padding; + __u64 notify_unique; + __u64 nodeid; + __u64 offset; + __u32 size; + __u32 padding; }; /* Matches the size of fuse_write_in */ struct fuse_notify_retrieve_in { - uint64_t dummy1; - uint64_t offset; - uint32_t size; - uint32_t dummy2; - uint64_t dummy3; - uint64_t dummy4; + __u64 dummy1; + __u64 offset; + __u32 size; + __u32 dummy2; + __u64 dummy3; + __u64 dummy4; }; #endif /* _LINUX_FUSE_H */ diff --git a/trunk/include/uapi/linux/pci_regs.h b/trunk/include/uapi/linux/pci_regs.h index 864e324da80d..ebfadc56d1b4 100644 --- a/trunk/include/uapi/linux/pci_regs.h +++ b/trunk/include/uapi/linux/pci_regs.h @@ -292,12 +292,12 @@ /* Message Signalled Interrupts registers */ -#define PCI_MSI_FLAGS 2 /* Message Control */ -#define PCI_MSI_FLAGS_ENABLE 0x0001 /* MSI feature enabled */ -#define PCI_MSI_FLAGS_QMASK 0x000e /* Maximum queue size available */ -#define PCI_MSI_FLAGS_QSIZE 0x0070 /* Message queue size configured */ -#define PCI_MSI_FLAGS_64BIT 0x0080 /* 64-bit addresses allowed */ -#define PCI_MSI_FLAGS_MASKBIT 0x0100 /* Per-vector masking capable */ +#define PCI_MSI_FLAGS 2 /* Various flags */ +#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */ +#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */ +#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */ +#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */ +#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */ #define PCI_MSI_RFU 3 /* Rest of capability flags */ #define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */ #define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ @@ -309,17 +309,13 @@ #define PCI_MSI_PENDING_64 20 /* Pending intrs for 64-bit devices */ /* MSI-X registers */ -#define PCI_MSIX_FLAGS 2 /* Message Control */ -#define PCI_MSIX_FLAGS_QSIZE 0x07FF /* Table size */ -#define PCI_MSIX_FLAGS_MASKALL 0x4000 /* Mask all vectors for this function */ -#define PCI_MSIX_FLAGS_ENABLE 0x8000 /* MSI-X enable */ -#define PCI_MSIX_TABLE 4 /* Table offset */ -#define PCI_MSIX_TABLE_BIR 0x00000007 /* BAR index */ -#define PCI_MSIX_TABLE_OFFSET 0xfffffff8 /* Offset into specified BAR */ -#define PCI_MSIX_PBA 8 /* Pending Bit Array offset */ -#define PCI_MSIX_PBA_BIR 0x00000007 /* BAR index */ -#define PCI_MSIX_PBA_OFFSET 0xfffffff8 /* Offset into specified BAR */ -#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) /* deprecated */ +#define PCI_MSIX_FLAGS 2 +#define PCI_MSIX_FLAGS_QSIZE 0x7FF +#define PCI_MSIX_FLAGS_ENABLE (1 << 15) +#define PCI_MSIX_FLAGS_MASKALL (1 << 14) +#define PCI_MSIX_TABLE 4 +#define PCI_MSIX_PBA 8 +#define PCI_MSIX_FLAGS_BIRMASK (7 << 0) #define PCI_CAP_MSIX_SIZEOF 12 /* size of MSIX registers */ /* MSI-X entry's format */ diff --git a/trunk/include/xen/events.h b/trunk/include/xen/events.h index b2b27c6a0f7b..c6bfe01acf6b 100644 --- a/trunk/include/xen/events.h +++ b/trunk/include/xen/events.h @@ -90,7 +90,8 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi, int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); /* Bind an PSI pirq to an irq. */ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, - int pirq, const char *name, domid_t domid); + int pirq, int vector, const char *name, + domid_t domid); #endif /* De-allocates the above mentioned physical interrupt. */ diff --git a/trunk/ipc/msg.c b/trunk/ipc/msg.c index fede1d06ef30..31cd1bf6af27 100644 --- a/trunk/ipc/msg.c +++ b/trunk/ipc/msg.c @@ -872,7 +872,6 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, goto out_unlock; break; } - msg = ERR_PTR(-EAGAIN); } else break; msg_counter++; diff --git a/trunk/kernel/.gitignore b/trunk/kernel/.gitignore index b3097bde4e9c..ab4f1090f437 100644 --- a/trunk/kernel/.gitignore +++ b/trunk/kernel/.gitignore @@ -4,4 +4,3 @@ config_data.h config_data.gz timeconst.h -hz.bc diff --git a/trunk/kernel/capability.c b/trunk/kernel/capability.c index f6c2ce5701e1..493d97259484 100644 --- a/trunk/kernel/capability.c +++ b/trunk/kernel/capability.c @@ -392,30 +392,6 @@ bool ns_capable(struct user_namespace *ns, int cap) } EXPORT_SYMBOL(ns_capable); -/** - * file_ns_capable - Determine if the file's opener had a capability in effect - * @file: The file we want to check - * @ns: The usernamespace we want the capability in - * @cap: The capability to be tested for - * - * Return true if task that opened the file had a capability in effect - * when the file was opened. - * - * This does not set PF_SUPERPRIV because the caller may not - * actually be privileged. - */ -bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap) -{ - if (WARN_ON_ONCE(!cap_valid(cap))) - return false; - - if (security_capable(file->f_cred, ns, cap) == 0) - return true; - - return false; -} -EXPORT_SYMBOL(file_ns_capable); - /** * capable - Determine if the current task has a superior capability in effect * @cap: The capability to be tested for diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index 9fcb0944f071..59412d037eed 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -4596,7 +4596,6 @@ void perf_event_comm(struct task_struct *task) struct perf_event_context *ctx; int ctxn; - rcu_read_lock(); for_each_task_context_nr(ctxn) { ctx = task->perf_event_ctxp[ctxn]; if (!ctx) @@ -4604,7 +4603,6 @@ void perf_event_comm(struct task_struct *task) perf_event_enable_on_exec(ctx); } - rcu_read_unlock(); if (!atomic_read(&nr_comm_events)) return; @@ -4739,8 +4737,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) } else { if (arch_vma_name(mmap_event->vma)) { name = strncpy(tmp, arch_vma_name(mmap_event->vma), - sizeof(tmp) - 1); - tmp[sizeof(tmp) - 1] = '\0'; + sizeof(tmp)); goto got_name; } @@ -5333,7 +5330,7 @@ static void sw_perf_event_destroy(struct perf_event *event) static int perf_swevent_init(struct perf_event *event) { - u64 event_id = event->attr.config; + int event_id = event->attr.config; if (event->attr.type != PERF_TYPE_SOFTWARE) return -ENOENT; @@ -5989,7 +5986,6 @@ int perf_pmu_register(struct pmu *pmu, char *name, int type) if (pmu->pmu_cpu_context) goto got_cpu_context; - ret = -ENOMEM; pmu->pmu_cpu_context = alloc_percpu(struct perf_cpu_context); if (!pmu->pmu_cpu_context) goto free_dev; diff --git a/trunk/kernel/events/internal.h b/trunk/kernel/events/internal.h index eb675c4d59df..d56a64c99a8b 100644 --- a/trunk/kernel/events/internal.h +++ b/trunk/kernel/events/internal.h @@ -16,7 +16,7 @@ struct ring_buffer { int page_order; /* allocation order */ #endif int nr_pages; /* nr of data pages */ - int overwrite; /* can overwrite itself */ + int writable; /* are we writable */ atomic_t poll; /* POLL_ for wakeups */ diff --git a/trunk/kernel/events/ring_buffer.c b/trunk/kernel/events/ring_buffer.c index 97fddb09762b..23cb34ff3973 100644 --- a/trunk/kernel/events/ring_buffer.c +++ b/trunk/kernel/events/ring_buffer.c @@ -18,24 +18,12 @@ static bool perf_output_space(struct ring_buffer *rb, unsigned long tail, unsigned long offset, unsigned long head) { - unsigned long sz = perf_data_size(rb); - unsigned long mask = sz - 1; + unsigned long mask; - /* - * check if user-writable - * overwrite : over-write its own tail - * !overwrite: buffer possibly drops events. - */ - if (rb->overwrite) + if (!rb->writable) return true; - /* - * verify that payload is not bigger than buffer - * otherwise masking logic may fail to detect - * the "not enough space" condition - */ - if ((head - offset) > sz) - return false; + mask = perf_data_size(rb) - 1; offset = (offset - tail) & mask; head = (head - tail) & mask; @@ -224,9 +212,7 @@ ring_buffer_init(struct ring_buffer *rb, long watermark, int flags) rb->watermark = max_size / 2; if (flags & RING_BUFFER_WRITABLE) - rb->overwrite = 0; - else - rb->overwrite = 1; + rb->writable = 1; atomic_set(&rb->refcount, 1); diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 14be27feda49..cc47812d3feb 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -63,7 +63,6 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = { - .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock), .clock_base = { { @@ -1643,6 +1642,8 @@ static void __cpuinit init_hrtimers_cpu(int cpu) struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu); int i; + raw_spin_lock_init(&cpu_base->lock); + for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { cpu_base->clock_base[i].cpu_base = cpu_base; timerqueue_init_head(&cpu_base->clock_base[i].active); diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index ffd4e111fd67..bddd3d7a74b6 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -55,7 +55,7 @@ struct resource crashk_res = { .flags = IORESOURCE_BUSY | IORESOURCE_MEM }; struct resource crashk_low_res = { - .name = "Crash kernel", + .name = "Crash kernel low", .start = 0, .end = 0, .flags = IORESOURCE_BUSY | IORESOURCE_MEM @@ -1368,114 +1368,35 @@ static int __init parse_crashkernel_simple(char *cmdline, return 0; } -#define SUFFIX_HIGH 0 -#define SUFFIX_LOW 1 -#define SUFFIX_NULL 2 -static __initdata char *suffix_tbl[] = { - [SUFFIX_HIGH] = ",high", - [SUFFIX_LOW] = ",low", - [SUFFIX_NULL] = NULL, -}; - /* - * That function parses "suffix" crashkernel command lines like - * - * crashkernel=size,[high|low] - * - * It returns 0 on success and -EINVAL on failure. + * That function is the entry point for command line parsing and should be + * called from the arch-specific code. */ -static int __init parse_crashkernel_suffix(char *cmdline, - unsigned long long *crash_size, - unsigned long long *crash_base, - const char *suffix) -{ - char *cur = cmdline; - - *crash_size = memparse(cmdline, &cur); - if (cmdline == cur) { - pr_warn("crashkernel: memory value expected\n"); - return -EINVAL; - } - - /* check with suffix */ - if (strncmp(cur, suffix, strlen(suffix))) { - pr_warn("crashkernel: unrecognized char\n"); - return -EINVAL; - } - cur += strlen(suffix); - if (*cur != ' ' && *cur != '\0') { - pr_warn("crashkernel: unrecognized char\n"); - return -EINVAL; - } - - return 0; -} - -static __init char *get_last_crashkernel(char *cmdline, - const char *name, - const char *suffix) -{ - char *p = cmdline, *ck_cmdline = NULL; - - /* find crashkernel and use the last one if there are more */ - p = strstr(p, name); - while (p) { - char *end_p = strchr(p, ' '); - char *q; - - if (!end_p) - end_p = p + strlen(p); - - if (!suffix) { - int i; - - /* skip the one with any known suffix */ - for (i = 0; suffix_tbl[i]; i++) { - q = end_p - strlen(suffix_tbl[i]); - if (!strncmp(q, suffix_tbl[i], - strlen(suffix_tbl[i]))) - goto next; - } - ck_cmdline = p; - } else { - q = end_p - strlen(suffix); - if (!strncmp(q, suffix, strlen(suffix))) - ck_cmdline = p; - } -next: - p = strstr(p+1, name); - } - - if (!ck_cmdline) - return NULL; - - return ck_cmdline; -} - static int __init __parse_crashkernel(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base, - const char *name, - const char *suffix) + const char *name) { + char *p = cmdline, *ck_cmdline = NULL; char *first_colon, *first_space; - char *ck_cmdline; BUG_ON(!crash_size || !crash_base); *crash_size = 0; *crash_base = 0; - ck_cmdline = get_last_crashkernel(cmdline, name, suffix); + /* find crashkernel and use the last one if there are more */ + p = strstr(p, name); + while (p) { + ck_cmdline = p; + p = strstr(p+1, name); + } if (!ck_cmdline) return -EINVAL; ck_cmdline += strlen(name); - if (suffix) - return parse_crashkernel_suffix(ck_cmdline, crash_size, - crash_base, suffix); /* * if the commandline contains a ':', then that's the extended * syntax -- if not, it must be the classic syntax @@ -1492,26 +1413,13 @@ static int __init __parse_crashkernel(char *cmdline, return 0; } -/* - * That function is the entry point for command line parsing and should be - * called from the arch-specific code. - */ int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base) { return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base, - "crashkernel=", NULL); -} - -int __init parse_crashkernel_high(char *cmdline, - unsigned long long system_ram, - unsigned long long *crash_size, - unsigned long long *crash_base) -{ - return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base, - "crashkernel=", suffix_tbl[SUFFIX_HIGH]); + "crashkernel="); } int __init parse_crashkernel_low(char *cmdline, @@ -1520,7 +1428,7 @@ int __init parse_crashkernel_low(char *cmdline, unsigned long long *crash_base) { return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base, - "crashkernel=", suffix_tbl[SUFFIX_LOW]); + "crashkernel_low="); } static void update_vmcoreinfo_note(void) diff --git a/trunk/kernel/kprobes.c b/trunk/kernel/kprobes.c index 3fed7f0cbcdf..e35be53f6613 100644 --- a/trunk/kernel/kprobes.c +++ b/trunk/kernel/kprobes.c @@ -794,16 +794,16 @@ static __kprobes void try_to_optimize_kprobe(struct kprobe *p) } #ifdef CONFIG_SYSCTL +/* This should be called with kprobe_mutex locked */ static void __kprobes optimize_all_kprobes(void) { struct hlist_head *head; struct kprobe *p; unsigned int i; - mutex_lock(&kprobe_mutex); /* If optimization is already allowed, just return */ if (kprobes_allow_optimization) - goto out; + return; kprobes_allow_optimization = true; for (i = 0; i < KPROBE_TABLE_SIZE; i++) { @@ -813,22 +813,18 @@ static void __kprobes optimize_all_kprobes(void) optimize_kprobe(p); } printk(KERN_INFO "Kprobes globally optimized\n"); -out: - mutex_unlock(&kprobe_mutex); } +/* This should be called with kprobe_mutex locked */ static void __kprobes unoptimize_all_kprobes(void) { struct hlist_head *head; struct kprobe *p; unsigned int i; - mutex_lock(&kprobe_mutex); /* If optimization is already prohibited, just return */ - if (!kprobes_allow_optimization) { - mutex_unlock(&kprobe_mutex); + if (!kprobes_allow_optimization) return; - } kprobes_allow_optimization = false; for (i = 0; i < KPROBE_TABLE_SIZE; i++) { @@ -838,14 +834,11 @@ static void __kprobes unoptimize_all_kprobes(void) unoptimize_kprobe(p, false); } } - mutex_unlock(&kprobe_mutex); - /* Wait for unoptimizing completion */ wait_for_kprobe_optimizer(); printk(KERN_INFO "Kprobes globally unoptimized\n"); } -static DEFINE_MUTEX(kprobe_sysctl_mutex); int sysctl_kprobes_optimization; int proc_kprobes_optimization_handler(struct ctl_table *table, int write, void __user *buffer, size_t *length, @@ -853,7 +846,7 @@ int proc_kprobes_optimization_handler(struct ctl_table *table, int write, { int ret; - mutex_lock(&kprobe_sysctl_mutex); + mutex_lock(&kprobe_mutex); sysctl_kprobes_optimization = kprobes_allow_optimization ? 1 : 0; ret = proc_dointvec_minmax(table, write, buffer, length, ppos); @@ -861,7 +854,7 @@ int proc_kprobes_optimization_handler(struct ctl_table *table, int write, optimize_all_kprobes(); else unoptimize_all_kprobes(); - mutex_unlock(&kprobe_sysctl_mutex); + mutex_unlock(&kprobe_mutex); return ret; } diff --git a/trunk/kernel/kthread.c b/trunk/kernel/kthread.c index 9eb7fed0bbaa..691dc2ef9baf 100644 --- a/trunk/kernel/kthread.c +++ b/trunk/kernel/kthread.c @@ -124,12 +124,12 @@ void *kthread_data(struct task_struct *task) static void __kthread_parkme(struct kthread *self) { - __set_current_state(TASK_PARKED); + __set_current_state(TASK_INTERRUPTIBLE); while (test_bit(KTHREAD_SHOULD_PARK, &self->flags)) { if (!test_and_set_bit(KTHREAD_IS_PARKED, &self->flags)) complete(&self->parked); schedule(); - __set_current_state(TASK_PARKED); + __set_current_state(TASK_INTERRUPTIBLE); } clear_bit(KTHREAD_IS_PARKED, &self->flags); __set_current_state(TASK_RUNNING); @@ -256,13 +256,8 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), } EXPORT_SYMBOL(kthread_create_on_node); -static void __kthread_bind(struct task_struct *p, unsigned int cpu, long state) +static void __kthread_bind(struct task_struct *p, unsigned int cpu) { - /* Must have done schedule() in kthread() before we set_task_cpu */ - if (!wait_task_inactive(p, state)) { - WARN_ON(1); - return; - } /* It's safe because the task is inactive. */ do_set_cpus_allowed(p, cpumask_of(cpu)); p->flags |= PF_THREAD_BOUND; @@ -279,7 +274,12 @@ static void __kthread_bind(struct task_struct *p, unsigned int cpu, long state) */ void kthread_bind(struct task_struct *p, unsigned int cpu) { - __kthread_bind(p, cpu, TASK_UNINTERRUPTIBLE); + /* Must have done schedule() in kthread() before we set_task_cpu */ + if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) { + WARN_ON(1); + return; + } + __kthread_bind(p, cpu); } EXPORT_SYMBOL(kthread_bind); @@ -324,22 +324,6 @@ static struct kthread *task_get_live_kthread(struct task_struct *k) return NULL; } -static void __kthread_unpark(struct task_struct *k, struct kthread *kthread) -{ - clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags); - /* - * We clear the IS_PARKED bit here as we don't wait - * until the task has left the park code. So if we'd - * park before that happens we'd see the IS_PARKED bit - * which might be about to be cleared. - */ - if (test_and_clear_bit(KTHREAD_IS_PARKED, &kthread->flags)) { - if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags)) - __kthread_bind(k, kthread->cpu, TASK_PARKED); - wake_up_state(k, TASK_PARKED); - } -} - /** * kthread_unpark - unpark a thread created by kthread_create(). * @k: thread created by kthread_create(). @@ -352,8 +336,20 @@ void kthread_unpark(struct task_struct *k) { struct kthread *kthread = task_get_live_kthread(k); - if (kthread) - __kthread_unpark(k, kthread); + if (kthread) { + clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags); + /* + * We clear the IS_PARKED bit here as we don't wait + * until the task has left the park code. So if we'd + * park before that happens we'd see the IS_PARKED bit + * which might be about to be cleared. + */ + if (test_and_clear_bit(KTHREAD_IS_PARKED, &kthread->flags)) { + if (test_bit(KTHREAD_IS_PER_CPU, &kthread->flags)) + __kthread_bind(k, kthread->cpu); + wake_up_process(k); + } + } put_task_struct(k); } @@ -411,7 +407,7 @@ int kthread_stop(struct task_struct *k) trace_sched_kthread_stop(k); if (kthread) { set_bit(KTHREAD_SHOULD_STOP, &kthread->flags); - __kthread_unpark(k, kthread); + clear_bit(KTHREAD_SHOULD_PARK, &kthread->flags); wake_up_process(k); wait_for_completion(&kthread->exited); } diff --git a/trunk/kernel/lockdep.c b/trunk/kernel/lockdep.c index 6a3bccba7e7d..8a0efac4f99d 100644 --- a/trunk/kernel/lockdep.c +++ b/trunk/kernel/lockdep.c @@ -380,13 +380,6 @@ static int verbose(struct lock_class *class) unsigned long nr_stack_trace_entries; static unsigned long stack_trace[MAX_STACK_TRACE_ENTRIES]; -static void print_lockdep_off(const char *bug_msg) -{ - printk(KERN_DEBUG "%s\n", bug_msg); - printk(KERN_DEBUG "turning off the locking correctness validator.\n"); - printk(KERN_DEBUG "Please attach the output of /proc/lock_stat to the bug report\n"); -} - static int save_trace(struct stack_trace *trace) { trace->nr_entries = 0; @@ -416,7 +409,8 @@ static int save_trace(struct stack_trace *trace) if (!debug_locks_off_graph_unlock()) return 0; - print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!"); + printk("BUG: MAX_STACK_TRACE_ENTRIES too low!\n"); + printk("turning off the locking correctness validator.\n"); dump_stack(); return 0; @@ -769,7 +763,8 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) } raw_local_irq_restore(flags); - print_lockdep_off("BUG: MAX_LOCKDEP_KEYS too low!"); + printk("BUG: MAX_LOCKDEP_KEYS too low!\n"); + printk("turning off the locking correctness validator.\n"); dump_stack(); return NULL; } @@ -839,7 +834,8 @@ static struct lock_list *alloc_list_entry(void) if (!debug_locks_off_graph_unlock()) return NULL; - print_lockdep_off("BUG: MAX_LOCKDEP_ENTRIES too low!"); + printk("BUG: MAX_LOCKDEP_ENTRIES too low!\n"); + printk("turning off the locking correctness validator.\n"); dump_stack(); return NULL; } @@ -2004,7 +2000,7 @@ static inline int lookup_chain_cache(struct task_struct *curr, struct lock_class *class = hlock_class(hlock); struct list_head *hash_head = chainhashentry(chain_key); struct lock_chain *chain; - struct held_lock *hlock_curr; + struct held_lock *hlock_curr, *hlock_next; int i, j; /* @@ -2052,7 +2048,8 @@ static inline int lookup_chain_cache(struct task_struct *curr, if (!debug_locks_off_graph_unlock()) return 0; - print_lockdep_off("BUG: MAX_LOCKDEP_CHAINS too low!"); + printk("BUG: MAX_LOCKDEP_CHAINS too low!\n"); + printk("turning off the locking correctness validator.\n"); dump_stack(); return 0; } @@ -2060,10 +2057,12 @@ static inline int lookup_chain_cache(struct task_struct *curr, chain->chain_key = chain_key; chain->irq_context = hlock->irq_context; /* Find the first held_lock of current chain */ + hlock_next = hlock; for (i = curr->lockdep_depth - 1; i >= 0; i--) { hlock_curr = curr->held_locks + i; - if (hlock_curr->irq_context != hlock->irq_context) + if (hlock_curr->irq_context != hlock_next->irq_context) break; + hlock_next = hlock; } i++; chain->depth = curr->lockdep_depth + 1 - i; @@ -3191,9 +3190,9 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, #endif if (unlikely(curr->lockdep_depth >= MAX_LOCK_DEPTH)) { debug_locks_off(); - print_lockdep_off("BUG: MAX_LOCK_DEPTH too low!"); - printk(KERN_DEBUG "depth: %i max: %lu!\n", + printk("BUG: MAX_LOCK_DEPTH too low, depth: %i max: %lu!\n", curr->lockdep_depth, MAX_LOCK_DEPTH); + printk("turning off the locking correctness validator.\n"); lockdep_print_held_locks(current); debug_show_all_locks(); diff --git a/trunk/kernel/mutex.c b/trunk/kernel/mutex.c index ad53a664f113..52f23011b6e0 100644 --- a/trunk/kernel/mutex.c +++ b/trunk/kernel/mutex.c @@ -37,12 +37,6 @@ # include #endif -/* - * A negative mutex count indicates that waiters are sleeping waiting for the - * mutex. - */ -#define MUTEX_SHOW_NO_WAITER(mutex) (atomic_read(&(mutex)->count) >= 0) - void __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) { @@ -50,9 +44,6 @@ __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) spin_lock_init(&lock->wait_lock); INIT_LIST_HEAD(&lock->wait_list); mutex_clear_owner(lock); -#ifdef CONFIG_MUTEX_SPIN_ON_OWNER - lock->spin_mlock = NULL; -#endif debug_mutex_init(lock, name, key); } @@ -104,124 +95,6 @@ void __sched mutex_lock(struct mutex *lock) EXPORT_SYMBOL(mutex_lock); #endif -#ifdef CONFIG_MUTEX_SPIN_ON_OWNER -/* - * In order to avoid a stampede of mutex spinners from acquiring the mutex - * more or less simultaneously, the spinners need to acquire a MCS lock - * first before spinning on the owner field. - * - * We don't inline mspin_lock() so that perf can correctly account for the - * time spent in this lock function. - */ -struct mspin_node { - struct mspin_node *next ; - int locked; /* 1 if lock acquired */ -}; -#define MLOCK(mutex) ((struct mspin_node **)&((mutex)->spin_mlock)) - -static noinline -void mspin_lock(struct mspin_node **lock, struct mspin_node *node) -{ - struct mspin_node *prev; - - /* Init node */ - node->locked = 0; - node->next = NULL; - - prev = xchg(lock, node); - if (likely(prev == NULL)) { - /* Lock acquired */ - node->locked = 1; - return; - } - ACCESS_ONCE(prev->next) = node; - smp_wmb(); - /* Wait until the lock holder passes the lock down */ - while (!ACCESS_ONCE(node->locked)) - arch_mutex_cpu_relax(); -} - -static void mspin_unlock(struct mspin_node **lock, struct mspin_node *node) -{ - struct mspin_node *next = ACCESS_ONCE(node->next); - - if (likely(!next)) { - /* - * Release the lock by setting it to NULL - */ - if (cmpxchg(lock, node, NULL) == node) - return; - /* Wait until the next pointer is set */ - while (!(next = ACCESS_ONCE(node->next))) - arch_mutex_cpu_relax(); - } - ACCESS_ONCE(next->locked) = 1; - smp_wmb(); -} - -/* - * Mutex spinning code migrated from kernel/sched/core.c - */ - -static inline bool owner_running(struct mutex *lock, struct task_struct *owner) -{ - if (lock->owner != owner) - return false; - - /* - * Ensure we emit the owner->on_cpu, dereference _after_ checking - * lock->owner still matches owner, if that fails, owner might - * point to free()d memory, if it still matches, the rcu_read_lock() - * ensures the memory stays valid. - */ - barrier(); - - return owner->on_cpu; -} - -/* - * Look out! "owner" is an entirely speculative pointer - * access and not reliable. - */ -static noinline -int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner) -{ - rcu_read_lock(); - while (owner_running(lock, owner)) { - if (need_resched()) - break; - - arch_mutex_cpu_relax(); - } - rcu_read_unlock(); - - /* - * We break out the loop above on need_resched() and when the - * owner changed, which is a sign for heavy contention. Return - * success only when lock->owner is NULL. - */ - return lock->owner == NULL; -} - -/* - * Initial check for entering the mutex spinning loop - */ -static inline int mutex_can_spin_on_owner(struct mutex *lock) -{ - int retval = 1; - - rcu_read_lock(); - if (lock->owner) - retval = lock->owner->on_cpu; - rcu_read_unlock(); - /* - * if lock->owner is not set, the mutex owner may have just acquired - * it and not set the owner yet or the mutex has been released. - */ - return retval; -} -#endif - static __used noinline void __sched __mutex_unlock_slowpath(atomic_t *lock_count); /** @@ -285,39 +158,25 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, * * We can't do this for DEBUG_MUTEXES because that relies on wait_lock * to serialize everything. - * - * The mutex spinners are queued up using MCS lock so that only one - * spinner can compete for the mutex. However, if mutex spinning isn't - * going to happen, there is no point in going through the lock/unlock - * overhead. */ - if (!mutex_can_spin_on_owner(lock)) - goto slowpath; for (;;) { struct task_struct *owner; - struct mspin_node node; /* * If there's an owner, wait for it to either * release the lock or go to sleep. */ - mspin_lock(MLOCK(lock), &node); owner = ACCESS_ONCE(lock->owner); - if (owner && !mutex_spin_on_owner(lock, owner)) { - mspin_unlock(MLOCK(lock), &node); + if (owner && !mutex_spin_on_owner(lock, owner)) break; - } - if ((atomic_read(&lock->count) == 1) && - (atomic_cmpxchg(&lock->count, 1, 0) == 1)) { + if (atomic_cmpxchg(&lock->count, 1, 0) == 1) { lock_acquired(&lock->dep_map, ip); mutex_set_owner(lock); - mspin_unlock(MLOCK(lock), &node); preempt_enable(); return 0; } - mspin_unlock(MLOCK(lock), &node); /* * When there's no owner, we might have preempted between the @@ -336,7 +195,6 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, */ arch_mutex_cpu_relax(); } -slowpath: #endif spin_lock_mutex(&lock->wait_lock, flags); @@ -347,7 +205,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, list_add_tail(&waiter.list, &lock->wait_list); waiter.task = task; - if (MUTEX_SHOW_NO_WAITER(lock) && (atomic_xchg(&lock->count, -1) == 1)) + if (atomic_xchg(&lock->count, -1) == 1) goto done; lock_contended(&lock->dep_map, ip); @@ -362,8 +220,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, * that when we release the lock, we properly wake up the * other waiters: */ - if (MUTEX_SHOW_NO_WAITER(lock) && - (atomic_xchg(&lock->count, -1) == 1)) + if (atomic_xchg(&lock->count, -1) == 1) break; /* diff --git a/trunk/kernel/rtmutex-tester.c b/trunk/kernel/rtmutex-tester.c index 1d96dd0d93c1..7890b10084a7 100644 --- a/trunk/kernel/rtmutex-tester.c +++ b/trunk/kernel/rtmutex-tester.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "rtmutex.h" @@ -367,8 +366,8 @@ static ssize_t sysfs_test_status(struct device *dev, struct device_attribute *at return curr - buf; } -static DEVICE_ATTR(status, S_IRUSR, sysfs_test_status, NULL); -static DEVICE_ATTR(command, S_IWUSR, NULL, sysfs_test_command); +static DEVICE_ATTR(status, 0600, sysfs_test_status, NULL); +static DEVICE_ATTR(command, 0600, NULL, sysfs_test_command); static struct bus_type rttest_subsys = { .name = "rttest", diff --git a/trunk/kernel/sched/clock.c b/trunk/kernel/sched/clock.c index c3ae1446461c..c685e31492df 100644 --- a/trunk/kernel/sched/clock.c +++ b/trunk/kernel/sched/clock.c @@ -176,36 +176,10 @@ static u64 sched_clock_remote(struct sched_clock_data *scd) u64 this_clock, remote_clock; u64 *ptr, old_val, val; -#if BITS_PER_LONG != 64 -again: - /* - * Careful here: The local and the remote clock values need to - * be read out atomic as we need to compare the values and - * then update either the local or the remote side. So the - * cmpxchg64 below only protects one readout. - * - * We must reread via sched_clock_local() in the retry case on - * 32bit as an NMI could use sched_clock_local() via the - * tracer and hit between the readout of - * the low32bit and the high 32bit portion. - */ - this_clock = sched_clock_local(my_scd); - /* - * We must enforce atomic readout on 32bit, otherwise the - * update on the remote cpu can hit inbetween the readout of - * the low32bit and the high 32bit portion. - */ - remote_clock = cmpxchg64(&scd->clock, 0, 0); -#else - /* - * On 64bit the read of [my]scd->clock is atomic versus the - * update, so we can avoid the above 32bit dance. - */ sched_clock_local(my_scd); again: this_clock = my_scd->clock; remote_clock = scd->clock; -#endif /* * Use the opportunity that we have both locks diff --git a/trunk/kernel/sched/core.c b/trunk/kernel/sched/core.c index 42053547e0f5..7f12624a393c 100644 --- a/trunk/kernel/sched/core.c +++ b/trunk/kernel/sched/core.c @@ -1498,10 +1498,8 @@ static void try_to_wake_up_local(struct task_struct *p) { struct rq *rq = task_rq(p); - if (WARN_ON_ONCE(rq != this_rq()) || - WARN_ON_ONCE(p == current)) - return; - + BUG_ON(rq != this_rq()); + BUG_ON(p == current); lockdep_assert_held(&rq->lock); if (!raw_spin_trylock(&p->pi_lock)) { @@ -2999,6 +2997,51 @@ void __sched schedule_preempt_disabled(void) preempt_disable(); } +#ifdef CONFIG_MUTEX_SPIN_ON_OWNER + +static inline bool owner_running(struct mutex *lock, struct task_struct *owner) +{ + if (lock->owner != owner) + return false; + + /* + * Ensure we emit the owner->on_cpu, dereference _after_ checking + * lock->owner still matches owner, if that fails, owner might + * point to free()d memory, if it still matches, the rcu_read_lock() + * ensures the memory stays valid. + */ + barrier(); + + return owner->on_cpu; +} + +/* + * Look out! "owner" is an entirely speculative pointer + * access and not reliable. + */ +int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner) +{ + if (!sched_feat(OWNER_SPIN)) + return 0; + + rcu_read_lock(); + while (owner_running(lock, owner)) { + if (need_resched()) + break; + + arch_mutex_cpu_relax(); + } + rcu_read_unlock(); + + /* + * We break out the loop above on need_resched() and when the + * owner changed, which is a sign for heavy contention. Return + * success only when lock->owner is NULL. + */ + return lock->owner == NULL; +} +#endif + #ifdef CONFIG_PREEMPT /* * this is the entry point to schedule() from in-kernel preemption @@ -4956,7 +4999,7 @@ static void sd_free_ctl_entry(struct ctl_table **tablep) } static int min_load_idx = 0; -static int max_load_idx = CPU_LOAD_IDX_MAX-1; +static int max_load_idx = CPU_LOAD_IDX_MAX; static void set_table_entry(struct ctl_table *entry, diff --git a/trunk/kernel/sched/cputime.c b/trunk/kernel/sched/cputime.c index e93cca92f38b..ed12cbb135f4 100644 --- a/trunk/kernel/sched/cputime.c +++ b/trunk/kernel/sched/cputime.c @@ -310,7 +310,7 @@ void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times) t = tsk; do { - task_cputime(t, &utime, &stime); + task_cputime(tsk, &utime, &stime); times->utime += utime; times->stime += stime; times->sum_exec_runtime += task_sched_runtime(t); diff --git a/trunk/kernel/sched/features.h b/trunk/kernel/sched/features.h index 99399f8e4799..1ad1d2b5395f 100644 --- a/trunk/kernel/sched/features.h +++ b/trunk/kernel/sched/features.h @@ -45,6 +45,13 @@ SCHED_FEAT(HRTICK, false) SCHED_FEAT(DOUBLE_TICK, false) SCHED_FEAT(LB_BIAS, true) +/* + * Spin-wait on mutex acquisition when the mutex owner is running on + * another cpu -- assumes that when the owner is running, it will soon + * release the lock. Decreases scheduling overhead. + */ +SCHED_FEAT(OWNER_SPIN, true) + /* * Decrement CPU power based on time not spent running tasks */ diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 598dc06be421..dd72567767d9 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -2948,7 +2948,7 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) static int do_tkill(pid_t tgid, pid_t pid, int sig) { - struct siginfo info = {}; + struct siginfo info; info.si_signo = sig; info.si_errno = 0; diff --git a/trunk/kernel/smpboot.c b/trunk/kernel/smpboot.c index 02fc5c933673..8eaed9aa9cf0 100644 --- a/trunk/kernel/smpboot.c +++ b/trunk/kernel/smpboot.c @@ -185,18 +185,8 @@ __smpboot_create_thread(struct smp_hotplug_thread *ht, unsigned int cpu) } get_task_struct(tsk); *per_cpu_ptr(ht->store, cpu) = tsk; - if (ht->create) { - /* - * Make sure that the task has actually scheduled out - * into park position, before calling the create - * callback. At least the migration thread callback - * requires that the task is off the runqueue. - */ - if (!wait_task_inactive(tsk, TASK_PARKED)) - WARN_ON(1); - else - ht->create(cpu); - } + if (ht->create) + ht->create(cpu); return 0; } diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index 0da73cf73e60..39c9c4a2949f 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -324,6 +324,7 @@ void kernel_restart_prepare(char *cmd) system_state = SYSTEM_RESTART; usermodehelper_disable(); device_shutdown(); + syscore_shutdown(); } /** @@ -369,7 +370,6 @@ void kernel_restart(char *cmd) { kernel_restart_prepare(cmd); disable_nonboot_cpus(); - syscore_shutdown(); if (!cmd) printk(KERN_EMERG "Restarting system.\n"); else @@ -395,7 +395,6 @@ static void kernel_shutdown_prepare(enum system_states state) void kernel_halt(void) { kernel_shutdown_prepare(SYSTEM_HALT); - disable_nonboot_cpus(); syscore_shutdown(); printk(KERN_EMERG "System halted.\n"); kmsg_dump(KMSG_DUMP_HALT); diff --git a/trunk/kernel/trace/blktrace.c b/trunk/kernel/trace/blktrace.c index 5a0f781cd729..9e5b8c272eec 100644 --- a/trunk/kernel/trace/blktrace.c +++ b/trunk/kernel/trace/blktrace.c @@ -739,6 +739,12 @@ static void blk_add_trace_rq_complete(void *ignore, struct request_queue *q, struct request *rq) { + struct blk_trace *bt = q->blk_trace; + + /* if control ever passes through here, it's a request based driver */ + if (unlikely(bt && !bt->rq_based)) + bt->rq_based = true; + blk_add_trace_rq(q, rq, BLK_TA_COMPLETE); } @@ -774,10 +780,24 @@ static void blk_add_trace_bio_bounce(void *ignore, blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0); } -static void blk_add_trace_bio_complete(void *ignore, - struct request_queue *q, struct bio *bio, - int error) +static void blk_add_trace_bio_complete(void *ignore, struct bio *bio, int error) { + struct request_queue *q; + struct blk_trace *bt; + + if (!bio->bi_bdev) + return; + + q = bdev_get_queue(bio->bi_bdev); + bt = q->blk_trace; + + /* + * Request based drivers will generate both rq and bio completions. + * Ignore bio ones. + */ + if (likely(!bt) || bt->rq_based) + return; + blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error); } diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index b3fde6d7b7fc..6893d5a2bf08 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -66,7 +66,7 @@ static struct ftrace_ops ftrace_list_end __read_mostly = { .func = ftrace_stub, - .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_STUB, + .flags = FTRACE_OPS_FL_RECURSION_SAFE, }; /* ftrace_enabled is a method to turn ftrace on or off */ @@ -694,6 +694,7 @@ int ftrace_profile_pages_init(struct ftrace_profile_stat *stat) free_page(tmp); } + free_page((unsigned long)stat->pages); stat->pages = NULL; stat->start = NULL; @@ -1052,19 +1053,6 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer) static struct pid * const ftrace_swapper_pid = &init_struct_pid; -loff_t -ftrace_filter_lseek(struct file *file, loff_t offset, int whence) -{ - loff_t ret; - - if (file->f_mode & FMODE_READ) - ret = seq_lseek(file, offset, whence); - else - file->f_pos = ret = 1; - - return ret; -} - #ifdef CONFIG_DYNAMIC_FTRACE #ifndef CONFIG_FTRACE_MCOUNT_RECORD @@ -2625,7 +2613,7 @@ static void ftrace_filter_reset(struct ftrace_hash *hash) * routine, you can use ftrace_filter_write() for the write * routine if @flag has FTRACE_ITER_FILTER set, or * ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set. - * ftrace_filter_lseek() should be used as the lseek routine, and + * ftrace_regex_lseek() should be used as the lseek routine, and * release must call ftrace_regex_release(). */ int @@ -2709,6 +2697,19 @@ ftrace_notrace_open(struct inode *inode, struct file *file) inode, file); } +loff_t +ftrace_regex_lseek(struct file *file, loff_t offset, int whence) +{ + loff_t ret; + + if (file->f_mode & FMODE_READ) + ret = seq_lseek(file, offset, whence); + else + file->f_pos = ret = 1; + + return ret; +} + static int ftrace_match(char *str, char *regex, int len, int type) { int matched = 0; @@ -3440,14 +3441,14 @@ static char ftrace_filter_buf[FTRACE_FILTER_SIZE] __initdata; static int __init set_ftrace_notrace(char *str) { - strlcpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE); + strncpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE); return 1; } __setup("ftrace_notrace=", set_ftrace_notrace); static int __init set_ftrace_filter(char *str) { - strlcpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE); + strncpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE); return 1; } __setup("ftrace_filter=", set_ftrace_filter); @@ -3570,7 +3571,7 @@ static const struct file_operations ftrace_filter_fops = { .open = ftrace_filter_open, .read = seq_read, .write = ftrace_filter_write, - .llseek = ftrace_filter_lseek, + .llseek = ftrace_regex_lseek, .release = ftrace_regex_release, }; @@ -3578,7 +3579,7 @@ static const struct file_operations ftrace_notrace_fops = { .open = ftrace_notrace_open, .read = seq_read, .write = ftrace_notrace_write, - .llseek = ftrace_filter_lseek, + .llseek = ftrace_regex_lseek, .release = ftrace_regex_release, }; @@ -3783,8 +3784,8 @@ static const struct file_operations ftrace_graph_fops = { .open = ftrace_graph_open, .read = seq_read, .write = ftrace_graph_write, - .llseek = ftrace_filter_lseek, .release = ftrace_graph_release, + .llseek = seq_lseek, }; #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ @@ -4130,8 +4131,7 @@ ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip, preempt_disable_notrace(); trace_recursion_set(TRACE_CONTROL_BIT); do_for_each_ftrace_op(op, ftrace_control_list) { - if (!(op->flags & FTRACE_OPS_FL_STUB) && - !ftrace_function_local_disabled(op) && + if (!ftrace_function_local_disabled(op) && ftrace_ops_test(op, ip)) op->func(ip, parent_ip, op, regs); } while_for_each_ftrace_op(op); @@ -4439,7 +4439,7 @@ static const struct file_operations ftrace_pid_fops = { .open = ftrace_pid_open, .write = ftrace_pid_write, .read = seq_read, - .llseek = ftrace_filter_lseek, + .llseek = seq_lseek, .release = ftrace_pid_release, }; @@ -4555,8 +4555,12 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, ftrace_startup_sysctl(); /* we are starting ftrace again */ - if (ftrace_ops_list != &ftrace_list_end) - update_ftrace_function(); + if (ftrace_ops_list != &ftrace_list_end) { + if (ftrace_ops_list->next == &ftrace_list_end) + ftrace_trace_function = ftrace_ops_list->func; + else + ftrace_trace_function = ftrace_ops_list_func; + } } else { /* stopping ftrace calls (just send to ftrace_stub) */ diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 66338c4f7f4b..4f1dade56981 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -132,7 +132,7 @@ static char *default_bootup_tracer; static int __init set_cmdline_ftrace(char *str) { - strlcpy(bootup_tracer_buf, str, MAX_TRACER_SIZE); + strncpy(bootup_tracer_buf, str, MAX_TRACER_SIZE); default_bootup_tracer = bootup_tracer_buf; /* We are using ftrace early, expand it */ ring_buffer_expanded = 1; @@ -162,7 +162,7 @@ static char *trace_boot_options __initdata; static int __init set_trace_boot_options(char *str) { - strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); + strncpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); trace_boot_options = trace_boot_options_buf; return 0; } @@ -744,11 +744,8 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) return; WARN_ON_ONCE(!irqs_disabled()); - if (!current_trace->allocated_snapshot) { - /* Only the nop tracer should hit this when disabling */ - WARN_ON_ONCE(current_trace != &nop_trace); + if (WARN_ON_ONCE(!current_trace->allocated_snapshot)) return; - } arch_spin_lock(&ftrace_max_lock); diff --git a/trunk/kernel/trace/trace_stack.c b/trunk/kernel/trace/trace_stack.c index 83a8b5b7bd35..42ca822fc701 100644 --- a/trunk/kernel/trace/trace_stack.c +++ b/trunk/kernel/trace/trace_stack.c @@ -322,7 +322,7 @@ static const struct file_operations stack_trace_filter_fops = { .open = stack_trace_filter_open, .read = seq_read, .write = ftrace_filter_write, - .llseek = ftrace_filter_lseek, + .llseek = ftrace_regex_lseek, .release = ftrace_regex_release, }; diff --git a/trunk/kernel/user_namespace.c b/trunk/kernel/user_namespace.c index e134d8f365dd..a54f26f82eb2 100644 --- a/trunk/kernel/user_namespace.c +++ b/trunk/kernel/user_namespace.c @@ -25,8 +25,7 @@ static struct kmem_cache *user_ns_cachep __read_mostly; -static bool new_idmap_permitted(const struct file *file, - struct user_namespace *ns, int cap_setid, +static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, struct uid_gid_map *map); static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns) @@ -613,10 +612,10 @@ static ssize_t map_write(struct file *file, const char __user *buf, if (map->nr_extents != 0) goto out; - /* - * Adjusting namespace settings requires capabilities on the target. + /* Require the appropriate privilege CAP_SETUID or CAP_SETGID + * over the user namespace in order to set the id mapping. */ - if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN)) + if (cap_valid(cap_setid) && !ns_capable(ns, cap_setid)) goto out; /* Get a buffer */ @@ -701,7 +700,7 @@ static ssize_t map_write(struct file *file, const char __user *buf, ret = -EPERM; /* Validate the user is allowed to use user id's mapped to. */ - if (!new_idmap_permitted(file, ns, cap_setid, &new_map)) + if (!new_idmap_permitted(ns, cap_setid, &new_map)) goto out; /* Map the lower ids from the parent user namespace to the @@ -788,8 +787,7 @@ ssize_t proc_projid_map_write(struct file *file, const char __user *buf, size_t &ns->projid_map, &ns->parent->projid_map); } -static bool new_idmap_permitted(const struct file *file, - struct user_namespace *ns, int cap_setid, +static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, struct uid_gid_map *new_map) { /* Allow mapping to your own filesystem ids */ @@ -797,12 +795,12 @@ static bool new_idmap_permitted(const struct file *file, u32 id = new_map->extent[0].lower_first; if (cap_setid == CAP_SETUID) { kuid_t uid = make_kuid(ns->parent, id); - if (uid_eq(uid, file->f_cred->fsuid)) + if (uid_eq(uid, current_fsuid())) return true; } else if (cap_setid == CAP_SETGID) { kgid_t gid = make_kgid(ns->parent, id); - if (gid_eq(gid, file->f_cred->fsgid)) + if (gid_eq(gid, current_fsgid())) return true; } } @@ -813,10 +811,8 @@ static bool new_idmap_permitted(const struct file *file, /* Allow the specified ids if we have the appropriate capability * (CAP_SETUID or CAP_SETGID) over the parent user namespace. - * And the opener of the id file also had the approprpiate capability. */ - if (ns_capable(ns->parent, cap_setid) && - file_ns_capable(file, ns->parent, cap_setid)) + if (ns_capable(ns->parent, cap_setid)) return true; return false; diff --git a/trunk/lib/Kconfig b/trunk/lib/Kconfig index fe01d418b09a..3958dc4389f9 100644 --- a/trunk/lib/Kconfig +++ b/trunk/lib/Kconfig @@ -404,7 +404,4 @@ config OID_REGISTRY help Enable fast lookup object identifier registry. -config UCS2_STRING - tristate - endmenu diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index 6e2cc561f761..d7946ff75b2e 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -174,5 +174,3 @@ quiet_cmd_build_OID_registry = GEN $@ cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@ clean-files += oid_registry_data.c - -obj-$(CONFIG_UCS2_STRING) += ucs2_string.o diff --git a/trunk/lib/kobject.c b/trunk/lib/kobject.c index a65486613d79..e07ee1fcd6f1 100644 --- a/trunk/lib/kobject.c +++ b/trunk/lib/kobject.c @@ -529,13 +529,6 @@ struct kobject *kobject_get(struct kobject *kobj) return kobj; } -static struct kobject *kobject_get_unless_zero(struct kobject *kobj) -{ - if (!kref_get_unless_zero(&kobj->kref)) - kobj = NULL; - return kobj; -} - /* * kobject_cleanup - free kobject resources. * @kobj: object to cleanup @@ -758,7 +751,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char *name) list_for_each_entry(k, &kset->list, entry) { if (kobject_name(k) && !strcmp(kobject_name(k), name)) { - ret = kobject_get_unless_zero(k); + ret = kobject_get(k); break; } } diff --git a/trunk/lib/swiotlb.c b/trunk/lib/swiotlb.c index d23762e6652c..bfe02b8fc55b 100644 --- a/trunk/lib/swiotlb.c +++ b/trunk/lib/swiotlb.c @@ -105,9 +105,9 @@ setup_io_tlb_npages(char *str) if (!strcmp(str, "force")) swiotlb_force = 1; - return 0; + return 1; } -early_param("swiotlb", setup_io_tlb_npages); +__setup("swiotlb=", setup_io_tlb_npages); /* make io_tlb_overflow tunable too? */ unsigned long swiotlb_nr_tbl(void) @@ -115,18 +115,6 @@ unsigned long swiotlb_nr_tbl(void) return io_tlb_nslabs; } EXPORT_SYMBOL_GPL(swiotlb_nr_tbl); - -/* default to 64MB */ -#define IO_TLB_DEFAULT_SIZE (64UL<<20) -unsigned long swiotlb_size_or_default(void) -{ - unsigned long size; - - size = io_tlb_nslabs << IO_TLB_SHIFT; - - return size ? size : (IO_TLB_DEFAULT_SIZE); -} - /* Note that this doesn't work with highmem page */ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, volatile void *address) @@ -200,7 +188,8 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) void __init swiotlb_init(int verbose) { - size_t default_size = IO_TLB_DEFAULT_SIZE; + /* default to 64MB */ + size_t default_size = 64UL<<20; unsigned char *vstart; unsigned long bytes; diff --git a/trunk/lib/ucs2_string.c b/trunk/lib/ucs2_string.c deleted file mode 100644 index 6f500ef2301d..000000000000 --- a/trunk/lib/ucs2_string.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -/* Return the number of unicode characters in data */ -unsigned long -ucs2_strnlen(const ucs2_char_t *s, size_t maxlength) -{ - unsigned long length = 0; - - while (*s++ != 0 && length < maxlength) - length++; - return length; -} -EXPORT_SYMBOL(ucs2_strnlen); - -unsigned long -ucs2_strlen(const ucs2_char_t *s) -{ - return ucs2_strnlen(s, ~0UL); -} -EXPORT_SYMBOL(ucs2_strlen); - -/* - * Return the number of bytes is the length of this string - * Note: this is NOT the same as the number of unicode characters - */ -unsigned long -ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength) -{ - return ucs2_strnlen(data, maxlength/sizeof(ucs2_char_t)) * sizeof(ucs2_char_t); -} -EXPORT_SYMBOL(ucs2_strsize); - -int -ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len) -{ - while (1) { - if (len == 0) - return 0; - if (*a < *b) - return -1; - if (*a > *b) - return 1; - if (*a == 0) /* implies *b == 0 */ - return 0; - a++; - b++; - len--; - } -} -EXPORT_SYMBOL(ucs2_strncmp); diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 1a12f5b9a0ab..ca9a7c6d7e97 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -2961,17 +2961,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, break; } - /* - * We need call hugetlb_fault for both hugepages under migration - * (in which case hugetlb_fault waits for the migration,) and - * hwpoisoned hugepages (in which case we need to prevent the - * caller from accessing to them.) In order to do this, we use - * here is_swap_pte instead of is_hugetlb_entry_migration and - * is_hugetlb_entry_hwpoisoned. This is because it simply covers - * both cases, and because we can't follow correct pages - * directly from any kind of swap entries. - */ - if (absent || is_swap_pte(huge_ptep_get(pte)) || + if (absent || ((flags & FOLL_WRITE) && !pte_write(huge_ptep_get(pte)))) { int ret; diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index ba94dec5b259..494526ae024a 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -216,7 +216,6 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm) tlb->mm = mm; tlb->fullmm = fullmm; - tlb->need_flush_all = 0; tlb->start = -1UL; tlb->end = 0; tlb->need_flush = 0; @@ -2393,53 +2392,6 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(remap_pfn_range); -/** - * vm_iomap_memory - remap memory to userspace - * @vma: user vma to map to - * @start: start of area - * @len: size of area - * - * This is a simplified io_remap_pfn_range() for common driver use. The - * driver just needs to give us the physical memory range to be mapped, - * we'll figure out the rest from the vma information. - * - * NOTE! Some drivers might want to tweak vma->vm_page_prot first to get - * whatever write-combining details or similar. - */ -int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len) -{ - unsigned long vm_len, pfn, pages; - - /* Check that the physical memory area passed in looks valid */ - if (start + len < start) - return -EINVAL; - /* - * You *really* shouldn't map things that aren't page-aligned, - * but we've historically allowed it because IO memory might - * just have smaller alignment. - */ - len += start & ~PAGE_MASK; - pfn = start >> PAGE_SHIFT; - pages = (len + ~PAGE_MASK) >> PAGE_SHIFT; - if (pfn + pages < pfn) - return -EINVAL; - - /* We start the mapping 'vm_pgoff' pages into the area */ - if (vma->vm_pgoff > pages) - return -EINVAL; - pfn += vma->vm_pgoff; - pages -= vma->vm_pgoff; - - /* Can we fit all of the mapping? */ - vm_len = vma->vm_end - vma->vm_start; - if (vm_len >> PAGE_SHIFT > pages) - return -EINVAL; - - /* Ok, let it rip */ - return io_remap_pfn_range(vma, vma->vm_start, pfn, vm_len, vma->vm_page_prot); -} -EXPORT_SYMBOL(vm_iomap_memory); - static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd, unsigned long addr, unsigned long end, pte_fn_t fn, void *data) diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 0db0de1c2fbe..6466699b16cb 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -1940,7 +1940,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr) /* Check the cache first. */ /* (Cache hit rate is typically around 35%.) */ - vma = ACCESS_ONCE(mm->mmap_cache); + vma = mm->mmap_cache; if (!(vma && vma->vm_end > addr && vma->vm_start <= addr)) { struct rb_node *rb_node; diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index e001768b14e8..e19328087534 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -821,7 +821,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr) struct vm_area_struct *vma; /* check the cache first */ - vma = ACCESS_ONCE(mm->mmap_cache); + vma = mm->mmap_cache; if (vma && vma->vm_start <= addr && vma->vm_end > addr) return vma; @@ -1838,16 +1838,6 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(remap_pfn_range); -int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len) -{ - unsigned long pfn = start >> PAGE_SHIFT; - unsigned long vm_len = vma->vm_end - vma->vm_start; - - pfn += vma->vm_pgoff; - return io_remap_pfn_range(vma, vma->vm_start, pfn, vm_len, vma->vm_page_prot); -} -EXPORT_SYMBOL(vm_iomap_memory); - int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, unsigned long pgoff) { diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 669fba39be1a..88c5fed8b9a4 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -3188,9 +3188,9 @@ int kswapd_run(int nid) if (IS_ERR(pgdat->kswapd)) { /* failure at boot is fatal */ BUG_ON(system_state == SYSTEM_BOOTING); + pgdat->kswapd = NULL; pr_err("Failed to start kswapd on node %d\n", nid); ret = PTR_ERR(pgdat->kswapd); - pgdat->kswapd = NULL; } return ret; } diff --git a/trunk/net/802/mrp.c b/trunk/net/802/mrp.c index e085bcc754f6..a4cc3229952a 100644 --- a/trunk/net/802/mrp.c +++ b/trunk/net/802/mrp.c @@ -870,12 +870,8 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl) * all pending messages before the applicant is gone. */ del_timer_sync(&app->join_timer); - - spin_lock(&app->lock); mrp_mad_event(app, MRP_EVENT_TX); mrp_pdu_queue(app); - spin_unlock(&app->lock); - mrp_queue_xmit(app); dev_mc_del(dev, appl->group_address); diff --git a/trunk/net/atm/common.c b/trunk/net/atm/common.c index 737bef59ce89..7b491006eaf4 100644 --- a/trunk/net/atm/common.c +++ b/trunk/net/atm/common.c @@ -531,8 +531,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, struct sk_buff *skb; int copied, error = -EINVAL; - msg->msg_namelen = 0; - if (sock->state != SS_CONNECTED) return -ENOTCONN; diff --git a/trunk/net/ax25/af_ax25.c b/trunk/net/ax25/af_ax25.c index e277e38f736b..7b11f8bc5071 100644 --- a/trunk/net/ax25/af_ax25.c +++ b/trunk/net/ax25/af_ax25.c @@ -1642,7 +1642,6 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock, ax25_address src; const unsigned char *mac = skb_mac_header(skb); - memset(sax, 0, sizeof(struct full_sockaddr_ax25)); ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL, &digi, NULL, NULL); sax->sax25_family = AF_AX25; diff --git a/trunk/net/batman-adv/main.c b/trunk/net/batman-adv/main.c index fa563e497c48..0488d70c8c35 100644 --- a/trunk/net/batman-adv/main.c +++ b/trunk/net/batman-adv/main.c @@ -169,7 +169,7 @@ void batadv_mesh_free(struct net_device *soft_iface) atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); } -int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr) +int batadv_is_my_mac(const uint8_t *addr) { const struct batadv_hard_iface *hard_iface; @@ -178,9 +178,6 @@ int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr) if (hard_iface->if_status != BATADV_IF_ACTIVE) continue; - if (hard_iface->soft_iface != bat_priv->soft_iface) - continue; - if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) { rcu_read_unlock(); return 1; diff --git a/trunk/net/batman-adv/main.h b/trunk/net/batman-adv/main.h index d40910dfc8ea..ced08b936a96 100644 --- a/trunk/net/batman-adv/main.h +++ b/trunk/net/batman-adv/main.h @@ -162,7 +162,7 @@ extern struct workqueue_struct *batadv_event_workqueue; int batadv_mesh_init(struct net_device *soft_iface); void batadv_mesh_free(struct net_device *soft_iface); -int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr); +int batadv_is_my_mac(const uint8_t *addr); struct batadv_hard_iface * batadv_seq_print_text_primary_if_get(struct seq_file *seq); int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, diff --git a/trunk/net/batman-adv/routing.c b/trunk/net/batman-adv/routing.c index 319f2906c71a..5ee21cebbbb0 100644 --- a/trunk/net/batman-adv/routing.c +++ b/trunk/net/batman-adv/routing.c @@ -402,7 +402,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, goto out; /* not for me */ - if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) + if (!batadv_is_my_mac(ethhdr->h_dest)) goto out; icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; @@ -416,7 +416,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, } /* packet for me */ - if (batadv_is_my_mac(bat_priv, icmp_packet->dst)) + if (batadv_is_my_mac(icmp_packet->dst)) return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size); /* TTL exceeded */ @@ -548,8 +548,7 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, return router; } -static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, - struct sk_buff *skb, int hdr_size) +static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size) { struct ethhdr *ethhdr; @@ -568,7 +567,7 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, return -1; /* not for me */ - if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) + if (!batadv_is_my_mac(ethhdr->h_dest)) return -1; return 0; @@ -583,7 +582,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) char tt_flag; size_t packet_size; - if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0) + if (batadv_check_unicast_packet(skb, hdr_size) < 0) return NET_RX_DROP; /* I could need to modify it */ @@ -615,7 +614,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) case BATADV_TT_RESPONSE: batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX); - if (batadv_is_my_mac(bat_priv, tt_query->dst)) { + if (batadv_is_my_mac(tt_query->dst)) { /* packet needs to be linearized to access the TT * changes */ @@ -658,15 +657,14 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if) struct batadv_roam_adv_packet *roam_adv_packet; struct batadv_orig_node *orig_node; - if (batadv_check_unicast_packet(bat_priv, skb, - sizeof(*roam_adv_packet)) < 0) + if (batadv_check_unicast_packet(skb, sizeof(*roam_adv_packet)) < 0) goto out; batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); roam_adv_packet = (struct batadv_roam_adv_packet *)skb->data; - if (!batadv_is_my_mac(bat_priv, roam_adv_packet->dst)) + if (!batadv_is_my_mac(roam_adv_packet->dst)) return batadv_route_unicast_packet(skb, recv_if); /* check if it is a backbone gateway. we don't accept @@ -969,7 +967,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, * last time) the packet had an updated information or not */ curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); - if (!batadv_is_my_mac(bat_priv, unicast_packet->dest)) { + if (!batadv_is_my_mac(unicast_packet->dest)) { orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->dest); /* if it is not possible to find the orig_node representing the @@ -1046,14 +1044,14 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, if (is4addr) hdr_size = sizeof(*unicast_4addr_packet); - if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0) + if (batadv_check_unicast_packet(skb, hdr_size) < 0) return NET_RX_DROP; if (!batadv_check_unicast_ttvn(bat_priv, skb)) return NET_RX_DROP; /* packet for me */ - if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { + if (batadv_is_my_mac(unicast_packet->dest)) { if (is4addr) { batadv_dat_inc_counter(bat_priv, unicast_4addr_packet->subtype); @@ -1090,7 +1088,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, struct sk_buff *new_skb = NULL; int ret; - if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0) + if (batadv_check_unicast_packet(skb, hdr_size) < 0) return NET_RX_DROP; if (!batadv_check_unicast_ttvn(bat_priv, skb)) @@ -1099,7 +1097,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, unicast_packet = (struct batadv_unicast_frag_packet *)skb->data; /* packet for me */ - if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { + if (batadv_is_my_mac(unicast_packet->dest)) { ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); if (ret == NET_RX_DROP) @@ -1153,13 +1151,13 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, goto out; /* ignore broadcasts sent by myself */ - if (batadv_is_my_mac(bat_priv, ethhdr->h_source)) + if (batadv_is_my_mac(ethhdr->h_source)) goto out; bcast_packet = (struct batadv_bcast_packet *)skb->data; /* ignore broadcasts originated by myself */ - if (batadv_is_my_mac(bat_priv, bcast_packet->orig)) + if (batadv_is_my_mac(bcast_packet->orig)) goto out; if (bcast_packet->header.ttl < 2) @@ -1245,14 +1243,14 @@ int batadv_recv_vis_packet(struct sk_buff *skb, ethhdr = (struct ethhdr *)skb_mac_header(skb); /* not for me */ - if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) + if (!batadv_is_my_mac(ethhdr->h_dest)) return NET_RX_DROP; /* ignore own packets */ - if (batadv_is_my_mac(bat_priv, vis_packet->vis_orig)) + if (batadv_is_my_mac(vis_packet->vis_orig)) return NET_RX_DROP; - if (batadv_is_my_mac(bat_priv, vis_packet->sender_orig)) + if (batadv_is_my_mac(vis_packet->sender_orig)) return NET_RX_DROP; switch (vis_packet->vis_type) { diff --git a/trunk/net/batman-adv/translation-table.c b/trunk/net/batman-adv/translation-table.c index 7abee19567e9..98a66a021a60 100644 --- a/trunk/net/batman-adv/translation-table.c +++ b/trunk/net/batman-adv/translation-table.c @@ -1953,7 +1953,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, bool batadv_send_tt_response(struct batadv_priv *bat_priv, struct batadv_tt_query_packet *tt_request) { - if (batadv_is_my_mac(bat_priv, tt_request->dst)) { + if (batadv_is_my_mac(tt_request->dst)) { /* don't answer backbone gws! */ if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) return true; diff --git a/trunk/net/batman-adv/vis.c b/trunk/net/batman-adv/vis.c index 6a1e646be96d..c053244b97bd 100644 --- a/trunk/net/batman-adv/vis.c +++ b/trunk/net/batman-adv/vis.c @@ -477,7 +477,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv, /* Are we the target for this VIS packet? */ if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && - batadv_is_my_mac(bat_priv, vis_packet->target_orig)) + batadv_is_my_mac(vis_packet->target_orig)) are_target = 1; spin_lock_bh(&bat_priv->vis.hash_lock); @@ -496,7 +496,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv, batadv_send_list_add(bat_priv, info); /* ... we're not the recipient (and thus need to forward). */ - } else if (!batadv_is_my_mac(bat_priv, packet->target_orig)) { + } else if (!batadv_is_my_mac(packet->target_orig)) { batadv_send_list_add(bat_priv, info); } diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index 0d1b08cc76e1..d3ee69b35a78 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -230,8 +230,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & (MSG_OOB)) return -EOPNOTSUPP; - msg->msg_namelen = 0; - skb = skb_recv_datagram(sk, flags, noblock, &err); if (!skb) { if (sk->sk_shutdown & RCV_SHUTDOWN) @@ -239,6 +237,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, return err; } + msg->msg_namelen = 0; + copied = skb->len; if (len < copied) { msg->msg_flags |= MSG_TRUNC; diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index 7c9224bcce17..c23bae86263b 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -608,7 +608,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { rfcomm_dlc_accept(d); - msg->msg_namelen = 0; return 0; } diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index fb6192c9812e..fad0302bdb32 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -665,7 +665,6 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { hci_conn_accept(pi->conn->hcon, 0); sk->sk_state = BT_CONFIG; - msg->msg_namelen = 0; release_sock(sk); return 0; diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index 459dab22b3f6..ef1b91431c6b 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -67,8 +67,7 @@ void br_port_carrier_check(struct net_bridge_port *p) struct net_device *dev = p->dev; struct net_bridge *br = p->br; - if (!(p->flags & BR_ADMIN_COST) && - netif_running(dev) && netif_oper_up(dev)) + if (netif_running(dev) && netif_oper_up(dev)) p->path_cost = port_cost(dev); if (!netif_running(br->dev)) diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index d2c043a857b6..3cbf5beb3d4b 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -156,7 +156,6 @@ struct net_bridge_port #define BR_BPDU_GUARD 0x00000002 #define BR_ROOT_BLOCK 0x00000004 #define BR_MULTICAST_FAST_LEAVE 0x00000008 -#define BR_ADMIN_COST 0x00000010 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING u32 multicast_startup_queries_sent; diff --git a/trunk/net/bridge/br_stp_if.c b/trunk/net/bridge/br_stp_if.c index d45e760141bb..0bdb4ebd362b 100644 --- a/trunk/net/bridge/br_stp_if.c +++ b/trunk/net/bridge/br_stp_if.c @@ -288,7 +288,6 @@ int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost) path_cost > BR_MAX_PATH_COST) return -ERANGE; - p->flags |= BR_ADMIN_COST; p->path_cost = path_cost; br_configuration_update(p->br); br_port_state_selection(p->br); diff --git a/trunk/net/caif/caif_socket.c b/trunk/net/caif/caif_socket.c index ff2ff3ce6965..095259f83902 100644 --- a/trunk/net/caif/caif_socket.c +++ b/trunk/net/caif/caif_socket.c @@ -286,8 +286,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, if (m->msg_flags&MSG_OOB) goto read_error; - m->msg_namelen = 0; - skb = skb_recv_datagram(sk, flags, 0 , &ret); if (!skb) goto read_error; diff --git a/trunk/net/can/gw.c b/trunk/net/can/gw.c index 117814a7e73c..2d117dc5ebea 100644 --- a/trunk/net/can/gw.c +++ b/trunk/net/can/gw.c @@ -466,7 +466,7 @@ static int cgw_notifier(struct notifier_block *nb, if (gwj->src.dev == dev || gwj->dst.dev == dev) { hlist_del(&gwj->list); cgw_unregister_filter(gwj); - kmem_cache_free(cgw_cache, gwj); + kfree(gwj); } } } @@ -864,7 +864,7 @@ static void cgw_remove_all_jobs(void) hlist_for_each_entry_safe(gwj, nx, &cgw_list, list) { hlist_del(&gwj->list); cgw_unregister_filter(gwj); - kmem_cache_free(cgw_cache, gwj); + kfree(gwj); } } @@ -920,7 +920,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) hlist_del(&gwj->list); cgw_unregister_filter(gwj); - kmem_cache_free(cgw_cache, gwj); + kfree(gwj); err = 0; break; } diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index b24ab0e98eb4..b13e5c766c11 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1624,6 +1624,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) } skb_orphan(skb); + nf_reset(skb); if (unlikely(!is_skb_forwardable(dev, skb))) { atomic_long_inc(&dev->rx_dropped); @@ -1639,7 +1640,6 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) skb->mark = 0; secpath_reset(skb); nf_reset(skb); - nf_reset_trace(skb); return netif_rx(skb); } EXPORT_SYMBOL_GPL(dev_forward_skb); @@ -2148,9 +2148,6 @@ static void skb_warn_bad_offload(const struct sk_buff *skb) struct net_device *dev = skb->dev; const char *driver = ""; - if (!net_ratelimit()) - return; - if (dev && dev->dev.parent) driver = dev_driver_string(dev->dev.parent); @@ -3317,7 +3314,6 @@ int netdev_rx_handler_register(struct net_device *dev, if (dev->rx_handler) return -EBUSY; - /* Note: rx_handler_data must be set before rx_handler */ rcu_assign_pointer(dev->rx_handler_data, rx_handler_data); rcu_assign_pointer(dev->rx_handler, rx_handler); @@ -3338,11 +3334,6 @@ void netdev_rx_handler_unregister(struct net_device *dev) ASSERT_RTNL(); RCU_INIT_POINTER(dev->rx_handler, NULL); - /* a reader seeing a non NULL rx_handler in a rcu_read_lock() - * section has a guarantee to see a non NULL rx_handler_data - * as well. - */ - synchronize_net(); RCU_INIT_POINTER(dev->rx_handler_data, NULL); } EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); diff --git a/trunk/net/core/dev_addr_lists.c b/trunk/net/core/dev_addr_lists.c index abdc9e6ef33e..bd2eb9d3e369 100644 --- a/trunk/net/core/dev_addr_lists.c +++ b/trunk/net/core/dev_addr_lists.c @@ -37,7 +37,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list, ha->type = addr_type; ha->refcount = 1; ha->global_use = global; - ha->synced = 0; + ha->synced = false; list_add_tail_rcu(&ha->list, &list->list); list->count++; @@ -165,7 +165,7 @@ int __hw_addr_sync(struct netdev_hw_addr_list *to_list, addr_len, ha->type); if (err) break; - ha->synced++; + ha->synced = true; ha->refcount++; } else if (ha->refcount == 1) { __hw_addr_del(to_list, ha->addr, addr_len, ha->type); @@ -186,7 +186,7 @@ void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, if (ha->synced) { __hw_addr_del(to_list, ha->addr, addr_len, ha->type); - ha->synced--; + ha->synced = false; __hw_addr_del(from_list, ha->addr, addr_len, ha->type); } diff --git a/trunk/net/core/flow.c b/trunk/net/core/flow.c index 2bfd081c59f7..c56ea6f7f6c7 100644 --- a/trunk/net/core/flow.c +++ b/trunk/net/core/flow.c @@ -328,7 +328,7 @@ static void flow_cache_flush_per_cpu(void *data) struct flow_flush_info *info = data; struct tasklet_struct *tasklet; - tasklet = &this_cpu_ptr(info->cache->percpu)->flush_tasklet; + tasklet = this_cpu_ptr(&info->cache->percpu->flush_tasklet); tasklet->data = (unsigned long)info; tasklet_schedule(tasklet); } diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 23854b51a259..5fb8d7e47294 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -496,10 +496,8 @@ static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev) } if (ops->fill_info) { data = nla_nest_start(skb, IFLA_INFO_DATA); - if (data == NULL) { - err = -EMSGSIZE; + if (data == NULL) goto err_cancel_link; - } err = ops->fill_info(skb, dev); if (err < 0) goto err_cancel_data; @@ -1072,7 +1070,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) rcu_read_lock(); cb->seq = net->dev_base_seq; - if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, + if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ifla_policy) >= 0) { if (tb[IFLA_EXT_MASK]) @@ -1922,7 +1920,7 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) u32 ext_filter_mask = 0; u16 min_ifinfo_dump_size = 0; - if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, + if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ifla_policy) >= 0) { if (tb[IFLA_EXT_MASK]) ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index c6287cd978c2..f678507bc829 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -587,16 +587,13 @@ static void check_lifetime(struct work_struct *work) { unsigned long now, next, next_sec, next_sched; struct in_ifaddr *ifa; - struct hlist_node *n; int i; now = jiffies; next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); + rcu_read_lock(); for (i = 0; i < IN4_ADDR_HSIZE; i++) { - bool change_needed = false; - - rcu_read_lock(); hlist_for_each_entry_rcu(ifa, &inet_addr_lst[i], hash) { unsigned long age; @@ -609,7 +606,16 @@ static void check_lifetime(struct work_struct *work) if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME && age >= ifa->ifa_valid_lft) { - change_needed = true; + struct in_ifaddr **ifap ; + + rtnl_lock(); + for (ifap = &ifa->ifa_dev->ifa_list; + *ifap != NULL; ifap = &ifa->ifa_next) { + if (*ifap == ifa) + inet_del_ifa(ifa->ifa_dev, + ifap, 1); + } + rtnl_unlock(); } else if (ifa->ifa_preferred_lft == INFINITY_LIFE_TIME) { continue; @@ -619,8 +625,10 @@ static void check_lifetime(struct work_struct *work) next = ifa->ifa_tstamp + ifa->ifa_valid_lft * HZ; - if (!(ifa->ifa_flags & IFA_F_DEPRECATED)) - change_needed = true; + if (!(ifa->ifa_flags & IFA_F_DEPRECATED)) { + ifa->ifa_flags |= IFA_F_DEPRECATED; + rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0); + } } else if (time_before(ifa->ifa_tstamp + ifa->ifa_preferred_lft * HZ, next)) { @@ -628,42 +636,8 @@ static void check_lifetime(struct work_struct *work) ifa->ifa_preferred_lft * HZ; } } - rcu_read_unlock(); - if (!change_needed) - continue; - rtnl_lock(); - hlist_for_each_entry_safe(ifa, n, &inet_addr_lst[i], hash) { - unsigned long age; - - if (ifa->ifa_flags & IFA_F_PERMANENT) - continue; - - /* We try to batch several events at once. */ - age = (now - ifa->ifa_tstamp + - ADDRCONF_TIMER_FUZZ_MINUS) / HZ; - - if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME && - age >= ifa->ifa_valid_lft) { - struct in_ifaddr **ifap; - - for (ifap = &ifa->ifa_dev->ifa_list; - *ifap != NULL; ifap = &(*ifap)->ifa_next) { - if (*ifap == ifa) { - inet_del_ifa(ifa->ifa_dev, - ifap, 1); - break; - } - } - } else if (ifa->ifa_preferred_lft != - INFINITY_LIFE_TIME && - age >= ifa->ifa_preferred_lft && - !(ifa->ifa_flags & IFA_F_DEPRECATED)) { - ifa->ifa_flags |= IFA_F_DEPRECATED; - rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0); - } - } - rtnl_unlock(); } + rcu_read_unlock(); next_sec = round_jiffies_up(next); next_sched = next; @@ -828,12 +802,8 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg if (nlh->nlmsg_flags & NLM_F_EXCL || !(nlh->nlmsg_flags & NLM_F_REPLACE)) return -EEXIST; - ifa = ifa_existing; - set_ifa_lifetime(ifa, valid_lft, prefered_lft); - cancel_delayed_work(&check_lifetime_work); - schedule_delayed_work(&check_lifetime_work, 0); - rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid); - blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); + + set_ifa_lifetime(ifa_existing, valid_lft, prefered_lft); } return 0; } diff --git a/trunk/net/ipv4/esp4.c b/trunk/net/ipv4/esp4.c index 4cfe34d4cc96..3b4f0cd2e63e 100644 --- a/trunk/net/ipv4/esp4.c +++ b/trunk/net/ipv4/esp4.c @@ -139,6 +139,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) /* skb is pure payload to encrypt */ + err = -ENOMEM; + esp = x->data; aead = esp->aead; alen = crypto_aead_authsize(aead); @@ -174,10 +176,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) } tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); - if (!tmp) { - err = -ENOMEM; + if (!tmp) goto error; - } seqhi = esp_tmp_seqhi(tmp); iv = esp_tmp_iv(aead, tmp, seqhilen); diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 52c273ea05c3..a6445b843ef4 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -248,7 +248,8 @@ static void ip_expire(unsigned long arg) if (!head->dev) goto out_rcu_unlock; - /* skb has no dst, perform route lookup again */ + /* skb dst is stale, drop it, and perform route lookup again */ + skb_dst_drop(head); iph = ip_hdr(head); err = ip_route_input_noref(head, iph->daddr, iph->saddr, iph->tos, head->dev); @@ -522,16 +523,9 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) qp->q.max_size = skb->len + ihl; if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && - qp->q.meat == qp->q.len) { - unsigned long orefdst = skb->_skb_refdst; + qp->q.meat == qp->q.len) + return ip_frag_reasm(qp, prev, dev); - skb->_skb_refdst = 0UL; - err = ip_frag_reasm(qp, prev, dev); - skb->_skb_refdst = orefdst; - return err; - } - - skb_dst_drop(skb); inet_frag_lru_move(&qp->q); return -EINPROGRESS; diff --git a/trunk/net/ipv4/netfilter/ipt_rpfilter.c b/trunk/net/ipv4/netfilter/ipt_rpfilter.c index c49dcd0284a0..c30130062cd6 100644 --- a/trunk/net/ipv4/netfilter/ipt_rpfilter.c +++ b/trunk/net/ipv4/netfilter/ipt_rpfilter.c @@ -66,12 +66,6 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4, return dev_match; } -static bool rpfilter_is_local(const struct sk_buff *skb) -{ - const struct rtable *rt = skb_rtable(skb); - return rt && (rt->rt_flags & RTCF_LOCAL); -} - static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_rpfilter_info *info; @@ -82,7 +76,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) info = par->matchinfo; invert = info->flags & XT_RPFILTER_INVERT; - if (rpfilter_is_local(skb)) + if (par->in->flags & IFF_LOOPBACK) return true ^ invert; iph = ip_hdr(skb); diff --git a/trunk/net/ipv4/syncookies.c b/trunk/net/ipv4/syncookies.c index 397e0f69435f..ef54377fb11c 100644 --- a/trunk/net/ipv4/syncookies.c +++ b/trunk/net/ipv4/syncookies.c @@ -349,8 +349,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, * hasn't changed since we received the original syn, but I see * no easy way to do this. */ - flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark, - RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP, + flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), + RT_SCOPE_UNIVERSE, IPPROTO_TCP, inet_sk_flowi_flags(sk), (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, ireq->loc_addr, th->source, th->dest); diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 13b9c08fc158..3bd55bad230a 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -113,7 +113,6 @@ int sysctl_tcp_early_retrans __read_mostly = 2; #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ #define FLAG_NONHEAD_RETRANS_ACKED 0x1000 /* Non-head rexmitted data was ACKed */ #define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ -#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) @@ -3565,27 +3564,6 @@ static void tcp_send_challenge_ack(struct sock *sk) } } -static void tcp_store_ts_recent(struct tcp_sock *tp) -{ - tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; - tp->rx_opt.ts_recent_stamp = get_seconds(); -} - -static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) -{ - if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { - /* PAWS bug workaround wrt. ACK frames, the PAWS discard - * extra check below makes sure this can only happen - * for pure ACK frames. -DaveM - * - * Not only, also it occurs for expired timestamps. - */ - - if (tcp_paws_check(&tp->rx_opt, 0)) - tcp_store_ts_recent(tp); - } -} - /* This routine deals with incoming acks, but not outgoing ones. */ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) { @@ -3629,12 +3607,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) prior_fackets = tp->fackets_out; prior_in_flight = tcp_packets_in_flight(tp); - /* ts_recent update must be made after we are sure that the packet - * is in window. - */ - if (flag & FLAG_UPDATE_TS_RECENT) - tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); - if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) { /* Window is constant, pure forward advance. * No more checks are required. @@ -3955,6 +3927,27 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) EXPORT_SYMBOL(tcp_parse_md5sig_option); #endif +static inline void tcp_store_ts_recent(struct tcp_sock *tp) +{ + tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; + tp->rx_opt.ts_recent_stamp = get_seconds(); +} + +static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) +{ + if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { + /* PAWS bug workaround wrt. ACK frames, the PAWS discard + * extra check below makes sure this can only happen + * for pure ACK frames. -DaveM + * + * Not only, also it occurs for expired timestamps. + */ + + if (tcp_paws_check(&tp->rx_opt, 0)) + tcp_store_ts_recent(tp); + } +} + /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM * * It is not fatal. If this ACK does _not_ change critical state (seqs, window) @@ -5550,9 +5543,14 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, return 0; step5: - if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0) + if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) goto discard; + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + tcp_rcv_rtt_measure_ts(sk, skb); /* Process urgent data. */ @@ -5988,8 +5986,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, /* step 5: check the ACK field */ if (true) { - int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH | - FLAG_UPDATE_TS_RECENT) > 0; + int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0; switch (sk->sk_state) { case TCP_SYN_RECV: @@ -6140,6 +6137,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, } } + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + /* step 6: check the URG bit */ tcp_urg(sk, skb, th); diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 509912a5ff98..5d0b4387cba6 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -2388,12 +2388,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) */ TCP_SKB_CB(skb)->when = tcp_time_stamp; - /* make sure skb->data is aligned on arches that require it - * and check if ack-trimming & collapsing extended the headroom - * beyond what csum_start can cover. - */ - if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) || - skb_headroom(skb) >= 0xFFFF)) { + /* make sure skb->data is aligned on arches that require it */ + if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, GFP_ATOMIC); return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : @@ -2713,7 +2709,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, skb_reserve(skb, MAX_TCP_HEADER); skb_dst_set(skb, dst); - security_skb_owned_by(skb, sk); mss = dst_metric_advmss(dst); if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index dae802c0af7c..26512250e095 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -168,6 +168,8 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, struct net_device *dev); +static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); + static struct ipv6_devconf ipv6_devconf __read_mostly = { .forwarding = 0, .hop_limit = IPV6_DEFAULT_HOPLIMIT, @@ -835,7 +837,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, rcu_read_unlock_bh(); if (likely(err == 0)) - inet6addr_notifier_call_chain(NETDEV_UP, ifa); + atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); else { kfree(ifa); ifa = ERR_PTR(err); @@ -925,7 +927,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) ipv6_ifa_notify(RTM_DELADDR, ifp); - inet6addr_notifier_call_chain(NETDEV_DOWN, ifp); + atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); /* * Purge or update corresponding prefix @@ -2527,9 +2529,6 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) static void init_loopback(struct net_device *dev) { struct inet6_dev *idev; - struct net_device *sp_dev; - struct inet6_ifaddr *sp_ifa; - struct rt6_info *sp_rt; /* ::1 */ @@ -2541,30 +2540,6 @@ static void init_loopback(struct net_device *dev) } add_addr(idev, &in6addr_loopback, 128, IFA_HOST); - - /* Add routes to other interface's IPv6 addresses */ - for_each_netdev(dev_net(dev), sp_dev) { - if (!strcmp(sp_dev->name, dev->name)) - continue; - - idev = __in6_dev_get(sp_dev); - if (!idev) - continue; - - read_lock_bh(&idev->lock); - list_for_each_entry(sp_ifa, &idev->addr_list, if_list) { - - if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) - continue; - - sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); - - /* Failure cases are ignored */ - if (!IS_ERR(sp_rt)) - ip6_ins_rt(sp_rt); - } - read_unlock_bh(&idev->lock); - } } static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) @@ -2986,7 +2961,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) if (state != INET6_IFADDR_STATE_DEAD) { __ipv6_ifa_notify(RTM_DELADDR, ifa); - inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); + atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); } in6_ifa_put(ifa); @@ -4867,6 +4842,22 @@ static struct pernet_operations addrconf_ops = { .exit = addrconf_exit_net, }; +/* + * Device notifier + */ + +int register_inet6addr_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&inet6addr_chain, nb); +} +EXPORT_SYMBOL(register_inet6addr_notifier); + +int unregister_inet6addr_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&inet6addr_chain, nb); +} +EXPORT_SYMBOL(unregister_inet6addr_notifier); + static struct rtnl_af_ops inet6_ops = { .family = AF_INET6, .fill_link_af = inet6_fill_link_af, diff --git a/trunk/net/ipv6/addrconf_core.c b/trunk/net/ipv6/addrconf_core.c index 72104562c864..d051e5f4bf34 100644 --- a/trunk/net/ipv6/addrconf_core.c +++ b/trunk/net/ipv6/addrconf_core.c @@ -78,22 +78,3 @@ int __ipv6_addr_type(const struct in6_addr *addr) } EXPORT_SYMBOL(__ipv6_addr_type); -static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); - -int register_inet6addr_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(&inet6addr_chain, nb); -} -EXPORT_SYMBOL(register_inet6addr_notifier); - -int unregister_inet6addr_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&inet6addr_chain, nb); -} -EXPORT_SYMBOL(unregister_inet6addr_notifier); - -int inet6addr_notifier_call_chain(unsigned long val, void *v) -{ - return atomic_notifier_call_chain(&inet6addr_chain, val, v); -} -EXPORT_SYMBOL(inet6addr_notifier_call_chain); diff --git a/trunk/net/ipv6/ip6_input.c b/trunk/net/ipv6/ip6_input.c index 2bab2aa59745..e33fe0ab2568 100644 --- a/trunk/net/ipv6/ip6_input.c +++ b/trunk/net/ipv6/ip6_input.c @@ -118,18 +118,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt ipv6_addr_loopback(&hdr->daddr)) goto err; - /* RFC4291 Errata ID: 3480 - * Interface-Local scope spans only a single interface on a - * node and is useful only for loopback transmission of - * multicast. Packets with interface-local scope received - * from another node must be discarded. - */ - if (!(skb->pkt_type == PACKET_LOOPBACK || - dev->flags & IFF_LOOPBACK) && - ipv6_addr_is_multicast(&hdr->daddr) && - IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1) - goto err; - /* RFC4291 2.7 * Nodes must not originate a packet to a multicast address whose scope * field contains the reserved value 0; if such a packet is received, it diff --git a/trunk/net/ipv6/netfilter/ip6t_NPT.c b/trunk/net/ipv6/netfilter/ip6t_NPT.c index cb631143721c..33608c610276 100644 --- a/trunk/net/ipv6/netfilter/ip6t_NPT.c +++ b/trunk/net/ipv6/netfilter/ip6t_NPT.c @@ -57,7 +57,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, if (pfx_len - i >= 32) mask = 0; else - mask = htonl((1 << (i - pfx_len + 32)) - 1); + mask = htonl(~((1 << (pfx_len - i)) - 1)); idx = i / 32; addr->s6_addr32[idx] &= mask; diff --git a/trunk/net/ipv6/netfilter/ip6t_rpfilter.c b/trunk/net/ipv6/netfilter/ip6t_rpfilter.c index e0983f3648a6..5060d54199ab 100644 --- a/trunk/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/trunk/net/ipv6/netfilter/ip6t_rpfilter.c @@ -71,12 +71,6 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb, return ret; } -static bool rpfilter_is_local(const struct sk_buff *skb) -{ - const struct rt6_info *rt = (const void *) skb_dst(skb); - return rt && (rt->rt6i_flags & RTF_LOCAL); -} - static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_rpfilter_info *info = par->matchinfo; @@ -84,7 +78,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) struct ipv6hdr *iph; bool invert = info->flags & XT_RPFILTER_INVERT; - if (rpfilter_is_local(skb)) + if (par->in->flags & IFF_LOOPBACK) return true ^ invert; iph = ipv6_hdr(skb); diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index 0ba10e53a629..196ab9347ad1 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -330,17 +330,9 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, } if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && - fq->q.meat == fq->q.len) { - int res; - unsigned long orefdst = skb->_skb_refdst; - - skb->_skb_refdst = 0UL; - res = ip6_frag_reasm(fq, prev, dev); - skb->_skb_refdst = orefdst; - return res; - } + fq->q.meat == fq->q.len) + return ip6_frag_reasm(fq, prev, dev); - skb_dst_drop(skb); inet_frag_lru_move(&fq->q); return -1; diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 46a5be85be87..f6d629fd6aee 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -386,7 +386,6 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (dst) dst->ops->redirect(dst, sk, skb); - goto out; } if (type == ICMPV6_PKT_TOOBIG) { diff --git a/trunk/net/irda/af_irda.c b/trunk/net/irda/af_irda.c index e493b3397ae3..d28e7f014cc6 100644 --- a/trunk/net/irda/af_irda.c +++ b/trunk/net/irda/af_irda.c @@ -1386,8 +1386,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(4, "%s()\n", __func__); - msg->msg_namelen = 0; - skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); if (!skb) diff --git a/trunk/net/irda/iriap.c b/trunk/net/irda/iriap.c index e1b37f5a2691..29340a9a6fb9 100644 --- a/trunk/net/irda/iriap.c +++ b/trunk/net/irda/iriap.c @@ -303,8 +303,7 @@ static void iriap_disconnect_indication(void *instance, void *sap, { struct iriap_cb *self; - IRDA_DEBUG(4, "%s(), reason=%s [%d]\n", __func__, - irlmp_reason_str(reason), reason); + IRDA_DEBUG(4, "%s(), reason=%s\n", __func__, irlmp_reasons[reason]); self = instance; diff --git a/trunk/net/irda/irlmp.c b/trunk/net/irda/irlmp.c index 1064621da6f6..6115a44c0a24 100644 --- a/trunk/net/irda/irlmp.c +++ b/trunk/net/irda/irlmp.c @@ -66,15 +66,8 @@ const char *irlmp_reasons[] = { "LM_LAP_RESET", "LM_INIT_DISCONNECT", "ERROR, NOT USED", - "UNKNOWN", }; -const char *irlmp_reason_str(LM_REASON reason) -{ - reason = min_t(size_t, reason, ARRAY_SIZE(irlmp_reasons) - 1); - return irlmp_reasons[reason]; -} - /* * Function irlmp_init (void) * @@ -754,8 +747,7 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, { struct lsap_cb *lsap; - IRDA_DEBUG(1, "%s(), reason=%s [%d]\n", __func__, - irlmp_reason_str(reason), reason); + IRDA_DEBUG(1, "%s(), reason=%s\n", __func__, irlmp_reasons[reason]); IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); diff --git a/trunk/net/iucv/af_iucv.c b/trunk/net/iucv/af_iucv.c index 206ce6db2c36..a7d11ffe4284 100644 --- a/trunk/net/iucv/af_iucv.c +++ b/trunk/net/iucv/af_iucv.c @@ -49,6 +49,12 @@ static const u8 iprm_shutdown[8] = #define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class)) +/* macros to set/get socket control buffer at correct offset */ +#define CB_TAG(skb) ((skb)->cb) /* iucv message tag */ +#define CB_TAG_LEN (sizeof(((struct iucv_message *) 0)->tag)) +#define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */ +#define CB_TRGCLS_LEN (TRGCLS_SIZE) + #define __iucv_sock_wait(sk, condition, timeo, ret) \ do { \ DEFINE_WAIT(__wait); \ @@ -1135,7 +1141,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, /* increment and save iucv message tag for msg_completion cbk */ txmsg.tag = iucv->send_tag++; - IUCV_SKB_CB(skb)->tag = txmsg.tag; + memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN); if (iucv->transport == AF_IUCV_TRANS_HIPER) { atomic_inc(&iucv->msg_sent); @@ -1218,7 +1224,7 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) return -ENOMEM; /* copy target class to control buffer of new skb */ - IUCV_SKB_CB(nskb)->class = IUCV_SKB_CB(skb)->class; + memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN); /* copy data fragment */ memcpy(nskb->data, skb->data + copied, size); @@ -1250,7 +1256,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, /* store msg target class in the second 4 bytes of skb ctrl buffer */ /* Note: the first 4 bytes are reserved for msg tag */ - IUCV_SKB_CB(skb)->class = msg->class; + memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN); /* check for special IPRM messages (e.g. iucv_sock_shutdown) */ if ((msg->flags & IUCV_IPRMDATA) && len > 7) { @@ -1286,7 +1292,6 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, } } - IUCV_SKB_CB(skb)->offset = 0; if (sock_queue_rcv_skb(sk, skb)) skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb); } @@ -1322,9 +1327,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, unsigned int copied, rlen; struct sk_buff *skb, *rskb, *cskb; int err = 0; - u32 offset; - - msg->msg_namelen = 0; if ((sk->sk_state == IUCV_DISCONN) && skb_queue_empty(&iucv->backlog_skb_q) && @@ -1344,14 +1346,13 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, return err; } - offset = IUCV_SKB_CB(skb)->offset; - rlen = skb->len - offset; /* real length of skb */ + rlen = skb->len; /* real length of skb */ copied = min_t(unsigned int, rlen, len); if (!rlen) sk->sk_shutdown = sk->sk_shutdown | RCV_SHUTDOWN; cskb = skb; - if (skb_copy_datagram_iovec(cskb, offset, msg->msg_iov, copied)) { + if (skb_copy_datagram_iovec(cskb, 0, msg->msg_iov, copied)) { if (!(flags & MSG_PEEK)) skb_queue_head(&sk->sk_receive_queue, skb); return -EFAULT; @@ -1369,8 +1370,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, * get the trgcls from the control buffer of the skb due to * fragmentation of original iucv message. */ err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS, - sizeof(IUCV_SKB_CB(skb)->class), - (void *)&IUCV_SKB_CB(skb)->class); + CB_TRGCLS_LEN, CB_TRGCLS(skb)); if (err) { if (!(flags & MSG_PEEK)) skb_queue_head(&sk->sk_receive_queue, skb); @@ -1382,8 +1382,9 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, /* SOCK_STREAM: re-queue skb if it contains unreceived data */ if (sk->sk_type == SOCK_STREAM) { - if (copied < rlen) { - IUCV_SKB_CB(skb)->offset = offset + copied; + skb_pull(skb, copied); + if (skb->len) { + skb_queue_head(&sk->sk_receive_queue, skb); goto done; } } @@ -1402,7 +1403,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, spin_lock_bh(&iucv->message_q.lock); rskb = skb_dequeue(&iucv->backlog_skb_q); while (rskb) { - IUCV_SKB_CB(rskb)->offset = 0; if (sock_queue_rcv_skb(sk, rskb)) { skb_queue_head(&iucv->backlog_skb_q, rskb); @@ -1830,7 +1830,7 @@ static void iucv_callback_txdone(struct iucv_path *path, spin_lock_irqsave(&list->lock, flags); while (list_skb != (struct sk_buff *)list) { - if (msg->tag != IUCV_SKB_CB(list_skb)->tag) { + if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) { this = list_skb; break; } @@ -2091,7 +2091,6 @@ static int afiucv_hs_callback_rx(struct sock *sk, struct sk_buff *skb) skb_pull(skb, sizeof(struct af_iucv_trans_hdr)); skb_reset_transport_header(skb); skb_reset_network_header(skb); - IUCV_SKB_CB(skb)->offset = 0; spin_lock(&iucv->message_q.lock); if (skb_queue_empty(&iucv->backlog_skb_q)) { if (sock_queue_rcv_skb(sk, skb)) { @@ -2196,7 +2195,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev, /* fall through and receive zero length data */ case 0: /* plain data frame */ - IUCV_SKB_CB(skb)->class = trans_hdr->iucv_hdr.class; + memcpy(CB_TRGCLS(skb), &trans_hdr->iucv_hdr.class, + CB_TRGCLS_LEN); err = afiucv_hs_callback_rx(sk, skb); break; default: diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index 5b1e5af25713..8555f331ea60 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -2693,7 +2693,6 @@ static int key_notify_policy_flush(const struct km_event *c) hdr->sadb_msg_pid = c->portid; hdr->sadb_msg_version = PF_KEY_V2; hdr->sadb_msg_errno = (uint8_t) 0; - hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); return 0; diff --git a/trunk/net/l2tp/l2tp_ip6.c b/trunk/net/l2tp/l2tp_ip6.c index b8a6039314e8..c74f5a91ff6a 100644 --- a/trunk/net/l2tp/l2tp_ip6.c +++ b/trunk/net/l2tp/l2tp_ip6.c @@ -690,7 +690,6 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk, lsa->l2tp_addr = ipv6_hdr(skb)->saddr; lsa->l2tp_flowinfo = 0; lsa->l2tp_scope_id = 0; - lsa->l2tp_conn_id = 0; if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL) lsa->l2tp_scope_id = IP6CB(skb)->iif; } diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index 48aaa89253e0..88709882c464 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -720,8 +720,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, int target; /* Read at least this many bytes */ long timeo; - msg->msg_namelen = 0; - lock_sock(sk); copied = -ENOTCONN; if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN)) diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index a6893602f87a..fb306814576a 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -2582,7 +2582,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, list_del(&dep->list); mutex_unlock(&local->mtx); - ieee80211_roc_notify_destroy(dep, true); + ieee80211_roc_notify_destroy(dep); return 0; } @@ -2622,7 +2622,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, ieee80211_start_next_roc(local); mutex_unlock(&local->mtx); - ieee80211_roc_notify_destroy(found, true); + ieee80211_roc_notify_destroy(found); } else { /* work may be pending so use it all the time */ found->abort = true; @@ -2632,8 +2632,6 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, /* work will clean up etc */ flush_delayed_work(&found->work); - WARN_ON(!found->to_be_freed); - kfree(found); } return 0; diff --git a/trunk/net/mac80211/chan.c b/trunk/net/mac80211/chan.c index 931be419ab5a..78c0d90dd641 100644 --- a/trunk/net/mac80211/chan.c +++ b/trunk/net/mac80211/chan.c @@ -63,7 +63,6 @@ ieee80211_new_chanctx(struct ieee80211_local *local, enum ieee80211_chanctx_mode mode) { struct ieee80211_chanctx *ctx; - u32 changed; int err; lockdep_assert_held(&local->chanctx_mtx); @@ -77,13 +76,6 @@ ieee80211_new_chanctx(struct ieee80211_local *local, ctx->conf.rx_chains_dynamic = 1; ctx->mode = mode; - /* acquire mutex to prevent idle from changing */ - mutex_lock(&local->mtx); - /* turn idle off *before* setting channel -- some drivers need that */ - changed = ieee80211_idle_off(local); - if (changed) - ieee80211_hw_config(local, changed); - if (!local->use_chanctx) { local->_oper_channel_type = cfg80211_get_chandef_type(chandef); @@ -93,17 +85,14 @@ ieee80211_new_chanctx(struct ieee80211_local *local, err = drv_add_chanctx(local, ctx); if (err) { kfree(ctx); - ctx = ERR_PTR(err); - - ieee80211_recalc_idle(local); - goto out; + return ERR_PTR(err); } } - /* and keep the mutex held until the new chanctx is on the list */ list_add_rcu(&ctx->list, &local->chanctx_list); - out: + mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); mutex_unlock(&local->mtx); return ctx; diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 5672533a0832..388580a1bada 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -309,7 +309,6 @@ struct ieee80211_roc_work { struct ieee80211_channel *chan; bool started, abort, hw_begun, notified; - bool to_be_freed; unsigned long hw_start_time; @@ -1348,7 +1347,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local); void ieee80211_roc_setup(struct ieee80211_local *local); void ieee80211_start_next_roc(struct ieee80211_local *local); void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); -void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free); +void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc); void ieee80211_sw_roc_work(struct work_struct *work); void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); @@ -1362,7 +1361,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type); void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); void ieee80211_remove_interfaces(struct ieee80211_local *local); -u32 ieee80211_idle_off(struct ieee80211_local *local); void ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, const int offset); diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 9ed49ad0380f..baaa8608e52d 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); } -static u32 __ieee80211_idle_off(struct ieee80211_local *local) +static u32 ieee80211_idle_off(struct ieee80211_local *local) { if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) return 0; @@ -87,7 +87,7 @@ static u32 __ieee80211_idle_off(struct ieee80211_local *local) return IEEE80211_CONF_CHANGE_IDLE; } -static u32 __ieee80211_idle_on(struct ieee80211_local *local) +static u32 ieee80211_idle_on(struct ieee80211_local *local) { if (local->hw.conf.flags & IEEE80211_CONF_IDLE) return 0; @@ -98,18 +98,16 @@ static u32 __ieee80211_idle_on(struct ieee80211_local *local) return IEEE80211_CONF_CHANGE_IDLE; } -static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, - bool force_active) +void ieee80211_recalc_idle(struct ieee80211_local *local) { bool working = false, scanning, active; unsigned int led_trig_start = 0, led_trig_stop = 0; struct ieee80211_roc_work *roc; + u32 change; lockdep_assert_held(&local->mtx); - active = force_active || - !list_empty(&local->chanctx_list) || - local->monitors; + active = !list_empty(&local->chanctx_list) || local->monitors; if (!local->ops->remain_on_channel) { list_for_each_entry(roc, &local->roc_list, list) { @@ -134,18 +132,9 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); if (working || scanning || active) - return __ieee80211_idle_off(local); - return __ieee80211_idle_on(local); -} - -u32 ieee80211_idle_off(struct ieee80211_local *local) -{ - return __ieee80211_recalc_idle(local, true); -} - -void ieee80211_recalc_idle(struct ieee80211_local *local) -{ - u32 change = __ieee80211_recalc_idle(local, false); + change = ieee80211_idle_off(local); + else + change = ieee80211_idle_on(local); if (change) ieee80211_hw_config(local, change); } @@ -360,19 +349,21 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; - int ret; + int ret = 0; if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) return 0; - ASSERT_RTNL(); + mutex_lock(&local->iflist_mtx); if (local->monitor_sdata) - return 0; + goto out_unlock; sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); - if (!sdata) - return -ENOMEM; + if (!sdata) { + ret = -ENOMEM; + goto out_unlock; + } /* set up data */ sdata->local = local; @@ -386,13 +377,13 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) if (WARN_ON(ret)) { /* ok .. stupid driver, it asked for this! */ kfree(sdata); - return ret; + goto out_unlock; } ret = ieee80211_check_queues(sdata); if (ret) { kfree(sdata); - return ret; + goto out_unlock; } ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, @@ -400,14 +391,13 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) if (ret) { drv_remove_interface(local, sdata); kfree(sdata); - return ret; + goto out_unlock; } - mutex_lock(&local->iflist_mtx); rcu_assign_pointer(local->monitor_sdata, sdata); + out_unlock: mutex_unlock(&local->iflist_mtx); - - return 0; + return ret; } static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) @@ -417,20 +407,14 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) return; - ASSERT_RTNL(); - mutex_lock(&local->iflist_mtx); sdata = rcu_dereference_protected(local->monitor_sdata, lockdep_is_held(&local->iflist_mtx)); - if (!sdata) { - mutex_unlock(&local->iflist_mtx); - return; - } + if (!sdata) + goto out_unlock; rcu_assign_pointer(local->monitor_sdata, NULL); - mutex_unlock(&local->iflist_mtx); - synchronize_net(); ieee80211_vif_release_channel(sdata); @@ -438,6 +422,8 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) drv_remove_interface(local, sdata); kfree(sdata); + out_unlock: + mutex_unlock(&local->iflist_mtx); } /* diff --git a/trunk/net/mac80211/mesh.c b/trunk/net/mac80211/mesh.c index 4749b3858695..29ce2aa87e7b 100644 --- a/trunk/net/mac80211/mesh.c +++ b/trunk/net/mac80211/mesh.c @@ -1060,8 +1060,7 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) - if (ieee80211_vif_is_mesh(&sdata->vif) && - ieee80211_sdata_running(sdata)) + if (ieee80211_vif_is_mesh(&sdata->vif)) ieee80211_queue_work(&local->hw, &sdata->work); rcu_read_unlock(); } diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 346ad4cfb013..141577412d84 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -3608,10 +3608,8 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) /* Restart STA timers */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (ieee80211_sdata_running(sdata)) - ieee80211_restart_sta_timer(sdata); - } + list_for_each_entry_rcu(sdata, &local->interfaces, list) + ieee80211_restart_sta_timer(sdata); rcu_read_unlock(); } @@ -3964,16 +3962,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, /* prep auth_data so we don't go into idle on disassoc */ ifmgd->auth_data = auth_data; - if (ifmgd->associated) { - u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; - - ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, - WLAN_REASON_UNSPECIFIED, - false, frame_buf); - - __cfg80211_send_deauth(sdata->dev, frame_buf, - sizeof(frame_buf)); - } + if (ifmgd->associated) + ieee80211_set_disassoc(sdata, 0, 0, false, NULL); sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); @@ -4033,16 +4023,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, mutex_lock(&ifmgd->mtx); - if (ifmgd->associated) { - u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; - - ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, - WLAN_REASON_UNSPECIFIED, - false, frame_buf); - - __cfg80211_send_deauth(sdata->dev, frame_buf, - sizeof(frame_buf)); - } + if (ifmgd->associated) + ieee80211_set_disassoc(sdata, 0, 0, false, NULL); if (ifmgd->auth_data && !ifmgd->auth_data->done) { err = -EBUSY; diff --git a/trunk/net/mac80211/offchannel.c b/trunk/net/mac80211/offchannel.c index 430bd254e496..cc79b4a2e821 100644 --- a/trunk/net/mac80211/offchannel.c +++ b/trunk/net/mac80211/offchannel.c @@ -297,13 +297,10 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) } } -void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free) +void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) { struct ieee80211_roc_work *dep, *tmp; - if (WARN_ON(roc->to_be_freed)) - return; - /* was never transmitted */ if (roc->frame) { cfg80211_mgmt_tx_status(&roc->sdata->wdev, @@ -319,12 +316,9 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free) GFP_KERNEL); list_for_each_entry_safe(dep, tmp, &roc->dependents, list) - ieee80211_roc_notify_destroy(dep, true); + ieee80211_roc_notify_destroy(dep); - if (free) - kfree(roc); - else - roc->to_be_freed = true; + kfree(roc); } void ieee80211_sw_roc_work(struct work_struct *work) @@ -337,9 +331,6 @@ void ieee80211_sw_roc_work(struct work_struct *work) mutex_lock(&local->mtx); - if (roc->to_be_freed) - goto out_unlock; - if (roc->abort) goto finish; @@ -379,7 +370,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) finish: list_del(&roc->list); started = roc->started; - ieee80211_roc_notify_destroy(roc, !roc->abort); + ieee80211_roc_notify_destroy(roc); if (started) { drv_flush(local, false); @@ -419,7 +410,7 @@ static void ieee80211_hw_roc_done(struct work_struct *work) list_del(&roc->list); - ieee80211_roc_notify_destroy(roc, true); + ieee80211_roc_notify_destroy(roc); /* if there's another roc, start it now */ ieee80211_start_next_roc(local); @@ -469,14 +460,12 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) list_for_each_entry_safe(roc, tmp, &tmp_list, list) { if (local->ops->remain_on_channel) { list_del(&roc->list); - ieee80211_roc_notify_destroy(roc, true); + ieee80211_roc_notify_destroy(roc); } else { ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); /* work will clean up etc */ flush_delayed_work(&roc->work); - WARN_ON(!roc->to_be_freed); - kfree(roc); } } diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index c6844ad080be..bb73ed2d20b9 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -2675,19 +2675,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) memset(nskb->cb, 0, sizeof(nskb->cb)); - if (rx->sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(nskb); - - info->flags = IEEE80211_TX_CTL_TX_OFFCHAN | - IEEE80211_TX_INTFL_OFFCHAN_TX_OK | - IEEE80211_TX_CTL_NO_CCK_RATE; - if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) - info->hw_queue = - local->hw.offchannel_tx_hw_queue; - } - - __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7, - status->band); + ieee80211_tx_skb(rx->sdata, nskb); } dev_kfree_skb(rx->skb); return RX_QUEUED; diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index 238a0cca320e..a79ce820cb50 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -766,7 +766,6 @@ int __must_check __sta_info_destroy(struct sta_info *sta) struct ieee80211_local *local; struct ieee80211_sub_if_data *sdata; int ret, i; - bool have_key = false; might_sleep(); @@ -794,19 +793,12 @@ int __must_check __sta_info_destroy(struct sta_info *sta) list_del_rcu(&sta->list); mutex_lock(&local->key_mtx); - for (i = 0; i < NUM_DEFAULT_KEYS; i++) { + for (i = 0; i < NUM_DEFAULT_KEYS; i++) __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i])); - have_key = true; - } - if (sta->ptk) { + if (sta->ptk) __ieee80211_key_free(key_mtx_dereference(local, sta->ptk)); - have_key = true; - } mutex_unlock(&local->key_mtx); - if (!have_key) - synchronize_net(); - sta->dead = true; local->num_sta--; diff --git a/trunk/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/trunk/net/netfilter/ipset/ip_set_bitmap_ipmac.c index d7df6ac2c6f1..0f92dc24cb89 100644 --- a/trunk/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/trunk/net/netfilter/ipset/ip_set_bitmap_ipmac.c @@ -339,11 +339,7 @@ bitmap_ipmac_tlist(const struct ip_set *set, nla_put_failure: nla_nest_cancel(skb, nested); ipset_nest_end(skb, atd); - if (unlikely(id == first)) { - cb->args[2] = 0; - return -EMSGSIZE; - } - return 0; + return -EMSGSIZE; } static int diff --git a/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c b/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c index 10a30b4fc7db..f2627226a087 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -104,15 +104,6 @@ hash_ipportnet4_data_flags(struct hash_ipportnet4_elem *dst, u32 flags) dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); } -static inline void -hash_ipportnet4_data_reset_flags(struct hash_ipportnet4_elem *dst, u32 *flags) -{ - if (dst->nomatch) { - *flags = IPSET_FLAG_NOMATCH; - dst->nomatch = 0; - } -} - static inline int hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem) { @@ -423,15 +414,6 @@ hash_ipportnet6_data_flags(struct hash_ipportnet6_elem *dst, u32 flags) dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); } -static inline void -hash_ipportnet6_data_reset_flags(struct hash_ipportnet6_elem *dst, u32 *flags) -{ - if (dst->nomatch) { - *flags = IPSET_FLAG_NOMATCH; - dst->nomatch = 0; - } -} - static inline int hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem) { diff --git a/trunk/net/netfilter/ipset/ip_set_hash_net.c b/trunk/net/netfilter/ipset/ip_set_hash_net.c index d6a59154d710..4b677cf6bf7d 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_net.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_net.c @@ -87,16 +87,7 @@ hash_net4_data_copy(struct hash_net4_elem *dst, static inline void hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags) { - dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); -} - -static inline void -hash_net4_data_reset_flags(struct hash_net4_elem *dst, u32 *flags) -{ - if (dst->nomatch) { - *flags = IPSET_FLAG_NOMATCH; - dst->nomatch = 0; - } + dst->nomatch = flags & IPSET_FLAG_NOMATCH; } static inline int @@ -317,16 +308,7 @@ hash_net6_data_copy(struct hash_net6_elem *dst, static inline void hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags) { - dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); -} - -static inline void -hash_net6_data_reset_flags(struct hash_net6_elem *dst, u32 *flags) -{ - if (dst->nomatch) { - *flags = IPSET_FLAG_NOMATCH; - dst->nomatch = 0; - } + dst->nomatch = flags & IPSET_FLAG_NOMATCH; } static inline int diff --git a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c index f2b0a3c30130..6ba985f1c96f 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_netiface.c @@ -198,16 +198,7 @@ hash_netiface4_data_copy(struct hash_netiface4_elem *dst, static inline void hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags) { - dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); -} - -static inline void -hash_netiface4_data_reset_flags(struct hash_netiface4_elem *dst, u32 *flags) -{ - if (dst->nomatch) { - *flags = IPSET_FLAG_NOMATCH; - dst->nomatch = 0; - } + dst->nomatch = flags & IPSET_FLAG_NOMATCH; } static inline int @@ -503,7 +494,7 @@ hash_netiface6_data_copy(struct hash_netiface6_elem *dst, static inline void hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags) { - dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); + dst->nomatch = flags & IPSET_FLAG_NOMATCH; } static inline int @@ -512,15 +503,6 @@ hash_netiface6_data_match(const struct hash_netiface6_elem *elem) return elem->nomatch ? -ENOTEMPTY : 1; } -static inline void -hash_netiface6_data_reset_flags(struct hash_netiface6_elem *dst, u32 *flags) -{ - if (dst->nomatch) { - *flags = IPSET_FLAG_NOMATCH; - dst->nomatch = 0; - } -} - static inline void hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem) { diff --git a/trunk/net/netfilter/ipset/ip_set_hash_netport.c b/trunk/net/netfilter/ipset/ip_set_hash_netport.c index 349deb672a2d..af20c0c5ced2 100644 --- a/trunk/net/netfilter/ipset/ip_set_hash_netport.c +++ b/trunk/net/netfilter/ipset/ip_set_hash_netport.c @@ -104,15 +104,6 @@ hash_netport4_data_flags(struct hash_netport4_elem *dst, u32 flags) dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); } -static inline void -hash_netport4_data_reset_flags(struct hash_netport4_elem *dst, u32 *flags) -{ - if (dst->nomatch) { - *flags = IPSET_FLAG_NOMATCH; - dst->nomatch = 0; - } -} - static inline int hash_netport4_data_match(const struct hash_netport4_elem *elem) { @@ -384,15 +375,6 @@ hash_netport6_data_flags(struct hash_netport6_elem *dst, u32 flags) dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); } -static inline void -hash_netport6_data_reset_flags(struct hash_netport6_elem *dst, u32 *flags) -{ - if (dst->nomatch) { - *flags = IPSET_FLAG_NOMATCH; - dst->nomatch = 0; - } -} - static inline int hash_netport6_data_match(const struct hash_netport6_elem *elem) { diff --git a/trunk/net/netfilter/ipset/ip_set_list_set.c b/trunk/net/netfilter/ipset/ip_set_list_set.c index 09c744aa8982..8371c2bac2e4 100644 --- a/trunk/net/netfilter/ipset/ip_set_list_set.c +++ b/trunk/net/netfilter/ipset/ip_set_list_set.c @@ -174,13 +174,9 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id, { const struct set_elem *e = list_set_elem(map, i); - if (e->id != IPSET_INVALID_ID) { - const struct set_elem *x = list_set_elem(map, map->size - 1); - - /* Last element replaced or pushed off */ - if (x->id != IPSET_INVALID_ID) - ip_set_put_byindex(x->id); - } + if (i == map->size - 1 && e->id != IPSET_INVALID_ID) + /* Last element replaced: e.g. add new,before,last */ + ip_set_put_byindex(e->id); if (with_timeout(map->timeout)) list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); else diff --git a/trunk/net/netfilter/nf_conntrack_sip.c b/trunk/net/netfilter/nf_conntrack_sip.c index e0c4373b4747..0e7d423324c3 100644 --- a/trunk/net/netfilter/nf_conntrack_sip.c +++ b/trunk/net/netfilter/nf_conntrack_sip.c @@ -1593,8 +1593,10 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, end += strlen("\r\n\r\n") + clen; msglen = origlen = end - dptr; - if (msglen > datalen) - return NF_ACCEPT; + if (msglen > datalen) { + nf_ct_helper_log(skb, ct, "incomplete/bad SIP message"); + return NF_DROP; + } ret = process_sip_msg(skb, ct, protoff, dataoff, &dptr, &msglen); diff --git a/trunk/net/netfilter/nf_conntrack_standalone.c b/trunk/net/netfilter/nf_conntrack_standalone.c index fedee3943661..6bcce401fd1c 100644 --- a/trunk/net/netfilter/nf_conntrack_standalone.c +++ b/trunk/net/netfilter/nf_conntrack_standalone.c @@ -568,7 +568,6 @@ static int __init nf_conntrack_standalone_init(void) register_net_sysctl(&init_net, "net", nf_ct_netfilter_table); if (!nf_ct_netfilter_header) { pr_err("nf_conntrack: can't register to sysctl.\n"); - ret = -ENOMEM; goto out_sysctl; } #endif diff --git a/trunk/net/netfilter/nf_nat_core.c b/trunk/net/netfilter/nf_nat_core.c index ad24be070e53..8d5769c6d16e 100644 --- a/trunk/net/netfilter/nf_nat_core.c +++ b/trunk/net/netfilter/nf_nat_core.c @@ -467,22 +467,33 @@ EXPORT_SYMBOL_GPL(nf_nat_packet); struct nf_nat_proto_clean { u8 l3proto; u8 l4proto; + bool hash; }; -/* kill conntracks with affected NAT section */ -static int nf_nat_proto_remove(struct nf_conn *i, void *data) +/* Clear NAT section of all conntracks, in case we're loaded again. */ +static int nf_nat_proto_clean(struct nf_conn *i, void *data) { const struct nf_nat_proto_clean *clean = data; struct nf_conn_nat *nat = nfct_nat(i); if (!nat) return 0; - + if (!(i->status & IPS_SRC_NAT_DONE)) + return 0; if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) || (clean->l4proto && nf_ct_protonum(i) != clean->l4proto)) return 0; - return i->status & IPS_NAT_MASK ? 1 : 0; + if (clean->hash) { + spin_lock_bh(&nf_nat_lock); + hlist_del_rcu(&nat->bysource); + spin_unlock_bh(&nf_nat_lock); + } else { + memset(nat, 0, sizeof(*nat)); + i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | + IPS_SEQ_ADJUST); + } + return 0; } static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) @@ -494,8 +505,16 @@ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) struct net *net; rtnl_lock(); + /* Step 1 - remove from bysource hash */ + clean.hash = true; for_each_net(net) - nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); + nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); + synchronize_rcu(); + + /* Step 2 - clean NAT section */ + clean.hash = false; + for_each_net(net) + nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); rtnl_unlock(); } @@ -507,9 +526,16 @@ static void nf_nat_l3proto_clean(u8 l3proto) struct net *net; rtnl_lock(); + /* Step 1 - remove from bysource hash */ + clean.hash = true; + for_each_net(net) + nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); + synchronize_rcu(); + /* Step 2 - clean NAT section */ + clean.hash = false; for_each_net(net) - nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); + nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); rtnl_unlock(); } @@ -747,7 +773,7 @@ static void __net_exit nf_nat_net_exit(struct net *net) { struct nf_nat_proto_clean clean = {}; - nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean); + nf_ct_iterate_cleanup(net, &nf_nat_proto_clean, &clean); synchronize_rcu(); nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size); } diff --git a/trunk/net/netfilter/nfnetlink_acct.c b/trunk/net/netfilter/nfnetlink_acct.c index dc3fd5d44464..589d686f0b4c 100644 --- a/trunk/net/netfilter/nfnetlink_acct.c +++ b/trunk/net/netfilter/nfnetlink_acct.c @@ -49,8 +49,6 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, return -EINVAL; acct_name = nla_data(tb[NFACCT_NAME]); - if (strlen(acct_name) == 0) - return -EINVAL; list_for_each_entry(nfacct, &nfnl_acct_list, head) { if (strncmp(nfacct->name, acct_name, NFACCT_NAME_MAX) != 0) diff --git a/trunk/net/netfilter/nfnetlink_queue_core.c b/trunk/net/netfilter/nfnetlink_queue_core.c index 42680b2baa11..1cb48540f86a 100644 --- a/trunk/net/netfilter/nfnetlink_queue_core.c +++ b/trunk/net/netfilter/nfnetlink_queue_core.c @@ -1062,10 +1062,8 @@ static int __init nfnetlink_queue_init(void) #ifdef CONFIG_PROC_FS if (!proc_create("nfnetlink_queue", 0440, - proc_net_netfilter, &nfqnl_file_ops)) { - status = -ENOMEM; + proc_net_netfilter, &nfqnl_file_ops)) goto cleanup_subsys; - } #endif register_netdevice_notifier(&nfqnl_dev_notifier); diff --git a/trunk/net/netrom/af_netrom.c b/trunk/net/netrom/af_netrom.c index 103bd704b5fc..d1fa1d9ffd2e 100644 --- a/trunk/net/netrom/af_netrom.c +++ b/trunk/net/netrom/af_netrom.c @@ -1173,7 +1173,6 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, } if (sax != NULL) { - memset(sax, 0, sizeof(*sax)); sax->sax25_family = AF_NETROM; skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, AX25_ADDR_LEN); diff --git a/trunk/net/nfc/llcp/llcp.c b/trunk/net/nfc/llcp/llcp.c index ee25f25f0cd6..b530afadd76c 100644 --- a/trunk/net/nfc/llcp/llcp.c +++ b/trunk/net/nfc/llcp/llcp.c @@ -107,6 +107,8 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, accept_sk->sk_state_change(sk); bh_unlock_sock(accept_sk); + + sock_orphan(accept_sk); } if (listen == true) { @@ -132,6 +134,8 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, bh_unlock_sock(sk); + sock_orphan(sk); + sk_del_node_init(sk); } @@ -160,6 +164,8 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, bh_unlock_sock(sk); + sock_orphan(sk); + sk_del_node_init(sk); } @@ -821,6 +827,7 @@ static void nfc_llcp_recv_ui(struct nfc_llcp_local *local, skb_get(skb); } else { pr_err("Receive queue is full\n"); + kfree_skb(skb); } nfc_llcp_sock_put(llcp_sock); @@ -1021,6 +1028,7 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, skb_get(skb); } else { pr_err("Receive queue is full\n"); + kfree_skb(skb); } } diff --git a/trunk/net/nfc/llcp/sock.c b/trunk/net/nfc/llcp/sock.c index 6c94447ec414..5c7cdf3f2a83 100644 --- a/trunk/net/nfc/llcp/sock.c +++ b/trunk/net/nfc/llcp/sock.c @@ -270,9 +270,7 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, } if (sk->sk_state == LLCP_CONNECTED || !newsock) { - list_del_init(&lsk->accept_queue); - sock_put(sk); - + nfc_llcp_accept_unlink(sk); if (newsock) sock_graft(sk, newsock); @@ -466,6 +464,8 @@ static int llcp_sock_release(struct socket *sock) nfc_llcp_accept_unlink(accept_sk); release_sock(accept_sk); + + sock_orphan(accept_sk); } } @@ -646,8 +646,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, pr_debug("%p %zu\n", sk, len); - msg->msg_namelen = 0; - lock_sock(sk); if (sk->sk_state == LLCP_CLOSED && @@ -693,7 +691,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock, pr_debug("Datagram socket %d %d\n", ui_cb->dsap, ui_cb->ssap); - memset(sockaddr, 0, sizeof(*sockaddr)); sockaddr->sa_family = AF_NFC; sockaddr->nfc_protocol = NFC_PROTO_NFC_DEP; sockaddr->dsap = ui_cb->dsap; diff --git a/trunk/net/openvswitch/datapath.c b/trunk/net/openvswitch/datapath.c index 6980c3e6f066..a4b724708a1a 100644 --- a/trunk/net/openvswitch/datapath.c +++ b/trunk/net/openvswitch/datapath.c @@ -1593,8 +1593,10 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid, return ERR_PTR(-ENOMEM); retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd); - BUG_ON(retval < 0); - + if (retval < 0) { + kfree_skb(skb); + return ERR_PTR(retval); + } return skb; } @@ -1724,32 +1726,24 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type) err = -EINVAL; - reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!reply) { - err = -ENOMEM; - goto exit_unlock; - } - if (!err && a[OVS_VPORT_ATTR_OPTIONS]) err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]); if (err) - goto exit_free; - + goto exit_unlock; if (a[OVS_VPORT_ATTR_UPCALL_PID]) vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); - err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid, - info->snd_seq, 0, OVS_VPORT_CMD_NEW); - BUG_ON(err < 0); + reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq, + OVS_VPORT_CMD_NEW); + if (IS_ERR(reply)) { + netlink_set_err(sock_net(skb->sk)->genl_sock, 0, + ovs_dp_vport_multicast_group.id, PTR_ERR(reply)); + goto exit_unlock; + } genl_notify(reply, genl_info_net(info), info->snd_portid, ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL); - rtnl_unlock(); - return 0; - -exit_free: - kfree_skb(reply); exit_unlock: rtnl_unlock(); return err; diff --git a/trunk/net/openvswitch/flow.c b/trunk/net/openvswitch/flow.c index 67a2b783fe70..fe0e4215c73d 100644 --- a/trunk/net/openvswitch/flow.c +++ b/trunk/net/openvswitch/flow.c @@ -795,9 +795,9 @@ void ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow) void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow) { - BUG_ON(table->count == 0); hlist_del_rcu(&flow->hash_node[table->node_ver]); table->count--; + BUG_ON(table->count < 0); } /* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */ diff --git a/trunk/net/rose/af_rose.c b/trunk/net/rose/af_rose.c index 9c8347451597..cf68e6e4054a 100644 --- a/trunk/net/rose/af_rose.c +++ b/trunk/net/rose/af_rose.c @@ -1253,7 +1253,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock, skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); if (srose != NULL) { - memset(srose, 0, msg->msg_namelen); srose->srose_family = AF_ROSE; srose->srose_addr = rose->dest_addr; srose->srose_call = rose->dest_call; diff --git a/trunk/net/sched/cls_fw.c b/trunk/net/sched/cls_fw.c index 9b97172db84a..1135d8227f9b 100644 --- a/trunk/net/sched/cls_fw.c +++ b/trunk/net/sched/cls_fw.c @@ -204,6 +204,7 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, if (err < 0) return err; + err = -EINVAL; if (tb[TCA_FW_CLASSID]) { f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); tcf_bind_filter(tp, &f->res, base); @@ -217,7 +218,6 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, } #endif /* CONFIG_NET_CLS_IND */ - err = -EINVAL; if (tb[TCA_FW_MASK]) { mask = nla_get_u32(tb[TCA_FW_MASK]); if (mask != head->mask) diff --git a/trunk/net/sched/sch_cbq.c b/trunk/net/sched/sch_cbq.c index 1bc210ffcba2..13aa47aa2ffb 100644 --- a/trunk/net/sched/sch_cbq.c +++ b/trunk/net/sched/sch_cbq.c @@ -962,11 +962,8 @@ cbq_dequeue(struct Qdisc *sch) cbq_update(q); if ((incr -= incr2) < 0) incr = 0; - q->now += incr; - } else { - if (now > q->now) - q->now = now; } + q->now += incr; q->now_rt = now; for (;;) { diff --git a/trunk/net/sched/sch_fq_codel.c b/trunk/net/sched/sch_fq_codel.c index 55786283a3df..4e606fcb2534 100644 --- a/trunk/net/sched/sch_fq_codel.c +++ b/trunk/net/sched/sch_fq_codel.c @@ -195,7 +195,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) flow->deficit = q->quantum; flow->dropped = 0; } - if (++sch->q.qlen <= sch->limit) + if (++sch->q.qlen < sch->limit) return NET_XMIT_SUCCESS; q->drop_overlimit++; diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index eac7e0ee23c1..ffad48109a22 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -904,7 +904,7 @@ void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate) u64 mult; int shift; - r->rate_bps = (u64)rate << 3; + r->rate_bps = rate << 3; r->shift = 0; r->mult = 1; /* diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index d5f35f15af98..dcc446e7fbf6 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -304,8 +304,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru err = rpciod_up(); if (err) goto out_no_rpciod; - err = -EINVAL; + if (!xprt) + goto out_no_xprt; + if (args->version >= program->nrvers) goto out_err; version = program->version[args->version]; @@ -380,9 +382,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru out_no_stats: kfree(clnt); out_err: + xprt_put(xprt); +out_no_xprt: rpciod_down(); out_no_rpciod: - xprt_put(xprt); return ERR_PTR(err); } @@ -509,7 +512,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, new = rpc_new_client(args, xprt); if (IS_ERR(new)) { err = PTR_ERR(new); - goto out_err; + goto out_put; } atomic_inc(&clnt->cl_count); @@ -522,6 +525,8 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, new->cl_chatty = clnt->cl_chatty; return new; +out_put: + xprt_put(xprt); out_err: dprintk("RPC: %s: returned error %d\n", __func__, err); return ERR_PTR(err); diff --git a/trunk/net/tipc/socket.c b/trunk/net/tipc/socket.c index 515ce38e4f4c..a9622b6cd916 100644 --- a/trunk/net/tipc/socket.c +++ b/trunk/net/tipc/socket.c @@ -790,7 +790,6 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) if (addr) { addr->family = AF_TIPC; addr->addrtype = TIPC_ADDR_ID; - memset(&addr->addr, 0, sizeof(addr->addr)); addr->addr.id.ref = msg_origport(msg); addr->addr.id.node = msg_orignode(msg); addr->addr.name.domain = 0; /* could leave uninitialized */ @@ -905,9 +904,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock, goto exit; } - /* will be updated in set_orig_addr() if needed */ - m->msg_namelen = 0; - timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); restart: @@ -1017,9 +1013,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, goto exit; } - /* will be updated in set_orig_addr() if needed */ - m->msg_namelen = 0; - target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 2db702d82e7d..971282b6f6a3 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -1412,8 +1412,8 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, if (UNIXCB(skb).cred) return; if (test_bit(SOCK_PASSCRED, &sock->flags) || - !other->sk_socket || - test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { + (other->sk_socket && + test_bit(SOCK_PASSCRED, &other->sk_socket->flags))) { UNIXCB(skb).pid = get_pid(task_tgid(current)); UNIXCB(skb).cred = get_current_cred(); } @@ -1993,7 +1993,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if ((UNIXCB(skb).pid != siocb->scm->pid) || (UNIXCB(skb).cred != siocb->scm->cred)) break; - } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { + } else { /* Copy credentials */ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); check_creds = 1; diff --git a/trunk/net/vmw_vsock/af_vsock.c b/trunk/net/vmw_vsock/af_vsock.c index 7f93e2a42d7a..ca511c4f388a 100644 --- a/trunk/net/vmw_vsock/af_vsock.c +++ b/trunk/net/vmw_vsock/af_vsock.c @@ -207,7 +207,7 @@ static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr) struct vsock_sock *vsk; list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table) - if (addr->svm_port == vsk->local_addr.svm_port) + if (vsock_addr_equals_addr_any(addr, &vsk->local_addr)) return sk_vsock(vsk); return NULL; @@ -220,8 +220,8 @@ static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src, list_for_each_entry(vsk, vsock_connected_sockets(src, dst), connected_table) { - if (vsock_addr_equals_addr(src, &vsk->remote_addr) && - dst->svm_port == vsk->local_addr.svm_port) { + if (vsock_addr_equals_addr(src, &vsk->remote_addr) + && vsock_addr_equals_addr(dst, &vsk->local_addr)) { return sk_vsock(vsk); } } @@ -1670,8 +1670,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb, vsk = vsock_sk(sk); err = 0; - msg->msg_namelen = 0; - lock_sock(sk); if (sk->sk_state != SS_CONNECTED) { diff --git a/trunk/net/vmw_vsock/vmci_transport.c b/trunk/net/vmw_vsock/vmci_transport.c index 5e04d3d96285..a70ace83a153 100644 --- a/trunk/net/vmw_vsock/vmci_transport.c +++ b/trunk/net/vmw_vsock/vmci_transport.c @@ -464,16 +464,19 @@ static struct sock *vmci_transport_get_pending( struct vsock_sock *vlistener; struct vsock_sock *vpending; struct sock *pending; - struct sockaddr_vm src; - - vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); vlistener = vsock_sk(listener); list_for_each_entry(vpending, &vlistener->pending_links, pending_links) { + struct sockaddr_vm src; + struct sockaddr_vm dst; + + vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); + vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port); + if (vsock_addr_equals_addr(&src, &vpending->remote_addr) && - pkt->dst_port == vpending->local_addr.svm_port) { + vsock_addr_equals_addr(&dst, &vpending->local_addr)) { pending = sk_vsock(vpending); sock_hold(pending); goto found; @@ -736,15 +739,10 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg) */ bh_lock_sock(sk); - if (!sock_owned_by_user(sk)) { - /* The local context ID may be out of date, update it. */ - vsk->local_addr.svm_cid = dst.svm_cid; - - if (sk->sk_state == SS_CONNECTED) - vmci_trans(vsk)->notify_ops->handle_notify_pkt( - sk, pkt, true, &dst, &src, - &bh_process_pkt); - } + if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED) + vmci_trans(vsk)->notify_ops->handle_notify_pkt( + sk, pkt, true, &dst, &src, + &bh_process_pkt); bh_unlock_sock(sk); @@ -904,9 +902,6 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work) lock_sock(sk); - /* The local context ID may be out of date. */ - vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context; - switch (sk->sk_state) { case SS_LISTEN: vmci_transport_recv_listen(sk, pkt); @@ -963,10 +958,6 @@ static int vmci_transport_recv_listen(struct sock *sk, pending = vmci_transport_get_pending(sk, pkt); if (pending) { lock_sock(pending); - - /* The local context ID may be out of date. */ - vsock_sk(pending)->local_addr.svm_cid = pkt->dg.dst.context; - switch (pending->sk_state) { case SS_CONNECTING: err = vmci_transport_recv_connecting_server(sk, @@ -1736,8 +1727,6 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb, if (flags & MSG_OOB || flags & MSG_ERRQUEUE) return -EOPNOTSUPP; - msg->msg_namelen = 0; - /* Retrieve the head sk_buff from the socket's receive queue. */ err = 0; skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err); @@ -1770,6 +1759,7 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb, if (err) goto out; + msg->msg_namelen = 0; if (msg->msg_name) { struct sockaddr_vm *vm_addr; diff --git a/trunk/net/vmw_vsock/vsock_addr.c b/trunk/net/vmw_vsock/vsock_addr.c index ec2611b4ea0e..b7df1aea7c59 100644 --- a/trunk/net/vmw_vsock/vsock_addr.c +++ b/trunk/net/vmw_vsock/vsock_addr.c @@ -64,6 +64,16 @@ bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, } EXPORT_SYMBOL_GPL(vsock_addr_equals_addr); +bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr, + const struct sockaddr_vm *other) +{ + return (addr->svm_cid == VMADDR_CID_ANY || + other->svm_cid == VMADDR_CID_ANY || + addr->svm_cid == other->svm_cid) && + addr->svm_port == other->svm_port; +} +EXPORT_SYMBOL_GPL(vsock_addr_equals_addr_any); + int vsock_addr_cast(const struct sockaddr *addr, size_t len, struct sockaddr_vm **out_addr) { diff --git a/trunk/net/vmw_vsock/vsock_addr.h b/trunk/net/vmw_vsock/vsock_addr.h index 9ccd5316eac0..cdfbcefdf843 100644 --- a/trunk/net/vmw_vsock/vsock_addr.h +++ b/trunk/net/vmw_vsock/vsock_addr.h @@ -24,6 +24,8 @@ bool vsock_addr_bound(const struct sockaddr_vm *addr); void vsock_addr_unbind(struct sockaddr_vm *addr); bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, const struct sockaddr_vm *other); +bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr, + const struct sockaddr_vm *other); int vsock_addr_cast(const struct sockaddr *addr, size_t len, struct sockaddr_vm **out_addr); diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index 6ddf74f0ae1e..ea4155fe9733 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -212,39 +212,6 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) rdev_rfkill_poll(rdev); } -void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev) -{ - lockdep_assert_held(&rdev->devlist_mtx); - lockdep_assert_held(&rdev->sched_scan_mtx); - - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)) - return; - - if (!wdev->p2p_started) - return; - - rdev_stop_p2p_device(rdev, wdev); - wdev->p2p_started = false; - - rdev->opencount--; - - if (rdev->scan_req && rdev->scan_req->wdev == wdev) { - bool busy = work_busy(&rdev->scan_done_wk); - - /* - * If the work isn't pending or running (in which case it would - * be waiting for the lock we hold) the driver didn't properly - * cancel the scan when the interface was removed. In this case - * warn and leak the scan request object to not crash later. - */ - WARN_ON(!busy); - - rdev->scan_req->aborted = true; - ___cfg80211_scan_done(rdev, !busy); - } -} - static int cfg80211_rfkill_set_block(void *data, bool blocked) { struct cfg80211_registered_device *rdev = data; @@ -254,8 +221,7 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) return 0; rtnl_lock(); - - /* read-only iteration need not hold the devlist_mtx */ + mutex_lock(&rdev->devlist_mtx); list_for_each_entry(wdev, &rdev->wdev_list, list) { if (wdev->netdev) { @@ -265,18 +231,18 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) /* otherwise, check iftype */ switch (wdev->iftype) { case NL80211_IFTYPE_P2P_DEVICE: - /* but this requires it */ - mutex_lock(&rdev->devlist_mtx); - mutex_lock(&rdev->sched_scan_mtx); - cfg80211_stop_p2p_device(rdev, wdev); - mutex_unlock(&rdev->sched_scan_mtx); - mutex_unlock(&rdev->devlist_mtx); + if (!wdev->p2p_started) + break; + rdev_stop_p2p_device(rdev, wdev); + wdev->p2p_started = false; + rdev->opencount--; break; default: break; } } + mutex_unlock(&rdev->devlist_mtx); rtnl_unlock(); return 0; @@ -779,13 +745,17 @@ static void wdev_cleanup_work(struct work_struct *work) wdev = container_of(work, struct wireless_dev, cleanup_work); rdev = wiphy_to_dev(wdev->wiphy); - mutex_lock(&rdev->sched_scan_mtx); + cfg80211_lock_rdev(rdev); if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { rdev->scan_req->aborted = true; ___cfg80211_scan_done(rdev, true); } + cfg80211_unlock_rdev(rdev); + + mutex_lock(&rdev->sched_scan_mtx); + if (WARN_ON(rdev->sched_scan_req && rdev->sched_scan_req->dev == wdev->netdev)) { __cfg80211_stop_sched_scan(rdev, false); @@ -811,19 +781,21 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev) return; mutex_lock(&rdev->devlist_mtx); - mutex_lock(&rdev->sched_scan_mtx); list_del_rcu(&wdev->list); rdev->devlist_generation++; switch (wdev->iftype) { case NL80211_IFTYPE_P2P_DEVICE: - cfg80211_stop_p2p_device(rdev, wdev); + if (!wdev->p2p_started) + break; + rdev_stop_p2p_device(rdev, wdev); + wdev->p2p_started = false; + rdev->opencount--; break; default: WARN_ON_ONCE(1); break; } - mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); } EXPORT_SYMBOL(cfg80211_unregister_wdev); @@ -964,7 +936,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, cfg80211_update_iface_num(rdev, wdev->iftype, 1); cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); - mutex_lock(&rdev->sched_scan_mtx); wdev_lock(wdev); switch (wdev->iftype) { #ifdef CONFIG_CFG80211_WEXT @@ -996,7 +967,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, break; } wdev_unlock(wdev); - mutex_unlock(&rdev->sched_scan_mtx); rdev->opencount++; mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); diff --git a/trunk/net/wireless/core.h b/trunk/net/wireless/core.h index 5845c2b37aa8..3aec0e429d8a 100644 --- a/trunk/net/wireless/core.h +++ b/trunk/net/wireless/core.h @@ -503,9 +503,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, enum nl80211_iftype iftype, int num); -void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev); - #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 58e13a8c95f9..d44ab216c0ec 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -4702,19 +4702,14 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->scan) return -EOPNOTSUPP; - mutex_lock(&rdev->sched_scan_mtx); - if (rdev->scan_req) { - err = -EBUSY; - goto unlock; - } + if (rdev->scan_req) + return -EBUSY; if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { n_channels = validate_scan_freqs( info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); - if (!n_channels) { - err = -EINVAL; - goto unlock; - } + if (!n_channels) + return -EINVAL; } else { enum ieee80211_band band; n_channels = 0; @@ -4728,29 +4723,23 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) n_ssids++; - if (n_ssids > wiphy->max_scan_ssids) { - err = -EINVAL; - goto unlock; - } + if (n_ssids > wiphy->max_scan_ssids) + return -EINVAL; if (info->attrs[NL80211_ATTR_IE]) ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); else ie_len = 0; - if (ie_len > wiphy->max_scan_ie_len) { - err = -EINVAL; - goto unlock; - } + if (ie_len > wiphy->max_scan_ie_len) + return -EINVAL; request = kzalloc(sizeof(*request) + sizeof(*request->ssids) * n_ssids + sizeof(*request->channels) * n_channels + ie_len, GFP_KERNEL); - if (!request) { - err = -ENOMEM; - goto unlock; - } + if (!request) + return -ENOMEM; if (n_ssids) request->ssids = (void *)&request->channels[n_channels]; @@ -4887,8 +4876,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) kfree(request); } - unlock: - mutex_unlock(&rdev->sched_scan_mtx); return err; } @@ -7762,9 +7749,20 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->stop_p2p_device) return -EOPNOTSUPP; - mutex_lock(&rdev->sched_scan_mtx); - cfg80211_stop_p2p_device(rdev, wdev); - mutex_unlock(&rdev->sched_scan_mtx); + if (!wdev->p2p_started) + return 0; + + rdev_stop_p2p_device(rdev, wdev); + wdev->p2p_started = false; + + mutex_lock(&rdev->devlist_mtx); + rdev->opencount--; + mutex_unlock(&rdev->devlist_mtx); + + if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { + rdev->scan_req->aborted = true; + ___cfg80211_scan_done(rdev, true); + } return 0; } @@ -8488,7 +8486,7 @@ static int nl80211_add_scan_req(struct sk_buff *msg, struct nlattr *nest; int i; - lockdep_assert_held(&rdev->sched_scan_mtx); + ASSERT_RDEV_LOCK(rdev); if (WARN_ON(!req)) return 0; diff --git a/trunk/net/wireless/scan.c b/trunk/net/wireless/scan.c index fd99ea495b7e..674aadca0079 100644 --- a/trunk/net/wireless/scan.c +++ b/trunk/net/wireless/scan.c @@ -169,7 +169,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) union iwreq_data wrqu; #endif - lockdep_assert_held(&rdev->sched_scan_mtx); + ASSERT_RDEV_LOCK(rdev); request = rdev->scan_req; @@ -230,9 +230,9 @@ void __cfg80211_scan_done(struct work_struct *wk) rdev = container_of(wk, struct cfg80211_registered_device, scan_done_wk); - mutex_lock(&rdev->sched_scan_mtx); + cfg80211_lock_rdev(rdev); ___cfg80211_scan_done(rdev, false); - mutex_unlock(&rdev->sched_scan_mtx); + cfg80211_unlock_rdev(rdev); } void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) @@ -698,6 +698,11 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR); if (found) { + found->pub.beacon_interval = tmp->pub.beacon_interval; + found->pub.signal = tmp->pub.signal; + found->pub.capability = tmp->pub.capability; + found->ts = tmp->ts; + /* Update IEs */ if (rcu_access_pointer(tmp->pub.proberesp_ies)) { const struct cfg80211_bss_ies *old; @@ -718,8 +723,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, if (found->pub.hidden_beacon_bss && !list_empty(&found->hidden_list)) { - const struct cfg80211_bss_ies *f; - /* * The found BSS struct is one of the probe * response members of a group, but we're @@ -729,10 +732,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, * SSID to showing it, which is confusing so * drop this information. */ - - f = rcu_access_pointer(tmp->pub.beacon_ies); - kfree_rcu((struct cfg80211_bss_ies *)f, - rcu_head); goto drop; } @@ -762,11 +761,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); } - - found->pub.beacon_interval = tmp->pub.beacon_interval; - found->pub.signal = tmp->pub.signal; - found->pub.capability = tmp->pub.capability; - found->ts = tmp->ts; } else { struct cfg80211_internal_bss *new; struct cfg80211_internal_bss *hidden; @@ -1062,7 +1056,6 @@ int cfg80211_wext_siwscan(struct net_device *dev, if (IS_ERR(rdev)) return PTR_ERR(rdev); - mutex_lock(&rdev->sched_scan_mtx); if (rdev->scan_req) { err = -EBUSY; goto out; @@ -1169,7 +1162,6 @@ int cfg80211_wext_siwscan(struct net_device *dev, dev_hold(dev); } out: - mutex_unlock(&rdev->sched_scan_mtx); kfree(creq); cfg80211_unlock_rdev(rdev); return err; diff --git a/trunk/net/wireless/sme.c b/trunk/net/wireless/sme.c index 482c70e70127..f432bd3755b1 100644 --- a/trunk/net/wireless/sme.c +++ b/trunk/net/wireless/sme.c @@ -85,7 +85,6 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) ASSERT_RTNL(); ASSERT_RDEV_LOCK(rdev); ASSERT_WDEV_LOCK(wdev); - lockdep_assert_held(&rdev->sched_scan_mtx); if (rdev->scan_req) return -EBUSY; @@ -224,7 +223,6 @@ void cfg80211_conn_work(struct work_struct *work) rtnl_lock(); cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); - mutex_lock(&rdev->sched_scan_mtx); list_for_each_entry(wdev, &rdev->wdev_list, list) { wdev_lock(wdev); @@ -249,7 +247,6 @@ void cfg80211_conn_work(struct work_struct *work) wdev_unlock(wdev); } - mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); rtnl_unlock(); @@ -323,9 +320,11 @@ void cfg80211_sme_scan_done(struct net_device *dev) { struct wireless_dev *wdev = dev->ieee80211_ptr; + mutex_lock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx); wdev_lock(wdev); __cfg80211_sme_scan_done(dev); wdev_unlock(wdev); + mutex_unlock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx); } void cfg80211_sme_rx_auth(struct net_device *dev, @@ -925,12 +924,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, int err; mutex_lock(&rdev->devlist_mtx); - /* might request scan - scan_mtx -> wdev_mtx dependency */ - mutex_lock(&rdev->sched_scan_mtx); wdev_lock(dev->ieee80211_ptr); err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL); wdev_unlock(dev->ieee80211_ptr); - mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); return err; diff --git a/trunk/net/wireless/trace.h b/trunk/net/wireless/trace.h index 7586de77a2f8..b7a531380e19 100644 --- a/trunk/net/wireless/trace.h +++ b/trunk/net/wireless/trace.h @@ -27,8 +27,7 @@ #define WIPHY_PR_ARG __entry->wiphy_name #define WDEV_ENTRY __field(u32, id) -#define WDEV_ASSIGN (__entry->id) = (!IS_ERR_OR_NULL(wdev) \ - ? wdev->identifier : 0) +#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0) #define WDEV_PR_FMT "wdev(%u)" #define WDEV_PR_ARG (__entry->id) @@ -1779,7 +1778,7 @@ TRACE_EVENT(rdev_set_mac_acl, ), TP_fast_assign( WIPHY_ASSIGN; - NETDEV_ASSIGN; + WIPHY_ASSIGN; __entry->acl_policy = params->acl_policy; ), TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", acl policy: %d", diff --git a/trunk/net/wireless/wext-sme.c b/trunk/net/wireless/wext-sme.c index e79cb5c0655a..fb9622f6d99c 100644 --- a/trunk/net/wireless/wext-sme.c +++ b/trunk/net/wireless/wext-sme.c @@ -89,7 +89,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); - mutex_lock(&rdev->sched_scan_mtx); wdev_lock(wdev); if (wdev->sme_state != CFG80211_SME_IDLE) { @@ -136,7 +135,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, err = cfg80211_mgd_wext_connect(rdev, wdev); out: wdev_unlock(wdev); - mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); return err; @@ -192,7 +190,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); - mutex_lock(&rdev->sched_scan_mtx); wdev_lock(wdev); err = 0; @@ -226,7 +223,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, err = cfg80211_mgd_wext_connect(rdev, wdev); out: wdev_unlock(wdev); - mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); return err; @@ -289,7 +285,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev, cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); - mutex_lock(&rdev->sched_scan_mtx); wdev_lock(wdev); if (wdev->sme_state != CFG80211_SME_IDLE) { @@ -318,7 +313,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev, err = cfg80211_mgd_wext_connect(rdev, wdev); out: wdev_unlock(wdev); - mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); return err; diff --git a/trunk/net/xfrm/xfrm_replay.c b/trunk/net/xfrm/xfrm_replay.c index 8dafe6d3c6e4..35754cc8a9e5 100644 --- a/trunk/net/xfrm/xfrm_replay.c +++ b/trunk/net/xfrm/xfrm_replay.c @@ -334,70 +334,6 @@ static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event) x->xflags &= ~XFRM_TIME_DEFER; } -static void xfrm_replay_notify_esn(struct xfrm_state *x, int event) -{ - u32 seq_diff, oseq_diff; - struct km_event c; - struct xfrm_replay_state_esn *replay_esn = x->replay_esn; - struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn; - - /* we send notify messages in case - * 1. we updated on of the sequence numbers, and the seqno difference - * is at least x->replay_maxdiff, in this case we also update the - * timeout of our timer function - * 2. if x->replay_maxage has elapsed since last update, - * and there were changes - * - * The state structure must be locked! - */ - - switch (event) { - case XFRM_REPLAY_UPDATE: - if (!x->replay_maxdiff) - break; - - if (replay_esn->seq_hi == preplay_esn->seq_hi) - seq_diff = replay_esn->seq - preplay_esn->seq; - else - seq_diff = ~preplay_esn->seq + replay_esn->seq + 1; - - if (replay_esn->oseq_hi == preplay_esn->oseq_hi) - oseq_diff = replay_esn->oseq - preplay_esn->oseq; - else - oseq_diff = ~preplay_esn->oseq + replay_esn->oseq + 1; - - if (seq_diff < x->replay_maxdiff && - oseq_diff < x->replay_maxdiff) { - - if (x->xflags & XFRM_TIME_DEFER) - event = XFRM_REPLAY_TIMEOUT; - else - return; - } - - break; - - case XFRM_REPLAY_TIMEOUT: - if (memcmp(x->replay_esn, x->preplay_esn, - xfrm_replay_state_esn_len(replay_esn)) == 0) { - x->xflags |= XFRM_TIME_DEFER; - return; - } - - break; - } - - memcpy(x->preplay_esn, x->replay_esn, - xfrm_replay_state_esn_len(replay_esn)); - c.event = XFRM_MSG_NEWAE; - c.data.aevent = event; - km_state_notify(x, &c); - - if (x->replay_maxage && - !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) - x->xflags &= ~XFRM_TIME_DEFER; -} - static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb) { int err = 0; @@ -574,7 +510,7 @@ static struct xfrm_replay xfrm_replay_esn = { .advance = xfrm_replay_advance_esn, .check = xfrm_replay_check_esn, .recheck = xfrm_replay_recheck_esn, - .notify = xfrm_replay_notify_esn, + .notify = xfrm_replay_notify_bmp, .overflow = xfrm_replay_overflow_esn, }; diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index 4de4bc48493b..b28cc384a5bc 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -3016,7 +3016,6 @@ sub process { $dstat !~ /^'X'$/ && # character constants $dstat !~ /$exceptions/ && $dstat !~ /^\.$Ident\s*=/ && # .foo = - $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) $dstat !~ /^for\s*$Constant$/ && # for (...) $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() diff --git a/trunk/security/capability.c b/trunk/security/capability.c index 6783c3e6c88e..579775088967 100644 --- a/trunk/security/capability.c +++ b/trunk/security/capability.c @@ -737,11 +737,6 @@ static int cap_tun_dev_open(void *security) { return 0; } - -static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk) -{ -} - #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -1076,7 +1071,6 @@ void __init security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, tun_dev_open); set_to_cap_if_null(ops, tun_dev_attach_queue); set_to_cap_if_null(ops, tun_dev_attach); - set_to_cap_if_null(ops, skb_owned_by); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM set_to_cap_if_null(ops, xfrm_policy_alloc_security); diff --git a/trunk/security/security.c b/trunk/security/security.c index 03f248b84e9f..7b88c6aeaed4 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -1290,11 +1290,6 @@ int security_tun_dev_open(void *security) } EXPORT_SYMBOL(security_tun_dev_open); -void security_skb_owned_by(struct sk_buff *skb, struct sock *sk) -{ - security_ops->skb_owned_by(skb, sk); -} - #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 7171a957b933..2fa28c88900c 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -51,7 +51,6 @@ #include #include #include /* for local_port_range[] */ -#include #include /* struct or_callable used in sock_rcv_skb */ #include #include @@ -4364,11 +4363,6 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); } -static void selinux_skb_owned_by(struct sk_buff *skb, struct sock *sk) -{ - skb_set_owner_w(skb, sk); -} - static int selinux_secmark_relabel_packet(u32 sid) { const struct task_security_struct *__tsec; @@ -5670,7 +5664,6 @@ static struct security_operations selinux_ops = { .tun_dev_attach_queue = selinux_tun_dev_attach_queue, .tun_dev_attach = selinux_tun_dev_attach, .tun_dev_open = selinux_tun_dev_open, - .skb_owned_by = selinux_skb_owned_by, #ifdef CONFIG_SECURITY_NETWORK_XFRM .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index eb560fa32321..71ae86ca64ac 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -3222,10 +3222,18 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_struct *area) { - struct snd_pcm_runtime *runtime = substream->runtime;; + long size; + unsigned long offset; area->vm_page_prot = pgprot_noncached(area->vm_page_prot); - return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); + area->vm_flags |= VM_IO; + size = area->vm_end - area->vm_start; + offset = area->vm_pgoff << PAGE_SHIFT; + if (io_remap_pfn_range(area, area->vm_start, + (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, + size, area->vm_page_prot)) + return -EAGAIN; + return 0; } EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index 4aba7646dd9c..ecdf30eb5879 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -173,7 +173,7 @@ const char *snd_hda_get_jack_type(u32 cfg) "Line Out", "Speaker", "HP Out", "CD", "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand", "Line In", "Aux", "Mic", "Telephony", - "SPDIF In", "Digital In", "Reserved", "Other" + "SPDIF In", "Digitial In", "Reserved", "Other" }; return jack_types[(cfg & AC_DEFCFG_DEVICE) diff --git a/trunk/sound/pci/hda/hda_eld.c b/trunk/sound/pci/hda/hda_eld.c index d0d7ac1e99d2..7dd846380a50 100644 --- a/trunk/sound/pci/hda/hda_eld.c +++ b/trunk/sound/pci/hda/hda_eld.c @@ -320,7 +320,7 @@ int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid, unsigned char *buf, int *eld_size) { int i; - int ret = 0; + int ret; int size; /* diff --git a/trunk/sound/pci/hda/hda_generic.c b/trunk/sound/pci/hda/hda_generic.c index 2dbe767be16b..43c2ea539561 100644 --- a/trunk/sound/pci/hda/hda_generic.c +++ b/trunk/sound/pci/hda/hda_generic.c @@ -740,7 +740,7 @@ EXPORT_SYMBOL_HDA(snd_hda_activate_path); static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path) { struct hda_gen_spec *spec = codec->spec; - bool changed = false; + bool changed; int i; if (!spec->power_down_unused || path->active) diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index bcd40ee488e3..418bfc0eb0a3 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -134,8 +134,8 @@ MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " * this may give more power-saving, but will take longer time to * wake up. */ -static bool power_save_controller = 1; -module_param(power_save_controller, bool, 0644); +static int power_save_controller = -1; +module_param(power_save_controller, bint, 0644); MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); #endif /* CONFIG_PM */ @@ -2931,6 +2931,8 @@ static int azx_runtime_idle(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; + if (power_save_controller > 0) + return 0; if (!power_save_controller || !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) return -EBUSY; diff --git a/trunk/sound/pci/hda/patch_hdmi.c b/trunk/sound/pci/hda/patch_hdmi.c index de8ac5c07fd0..78e1827d0a95 100644 --- a/trunk/sound/pci/hda/patch_hdmi.c +++ b/trunk/sound/pci/hda/patch_hdmi.c @@ -1196,7 +1196,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) _snd_printd(SND_PR_VERBOSE, "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, pin_nid, pin_eld->monitor_present, eld->eld_valid); + codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); if (eld->eld_valid) { if (snd_hdmi_get_eld(codec, pin_nid, eld->eld_buffer, diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index f15c36bde540..563c24df4d6f 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -3440,8 +3440,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec) const hda_nid_t *ssids; if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || - codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || - codec->vendor_id == 0x10ec0671) + codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) ssids = alc663_ssids; else ssids = alc662_ssids; @@ -3895,7 +3894,6 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, - { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, diff --git a/trunk/sound/soc/codecs/max98090.c b/trunk/sound/soc/codecs/max98090.c old mode 100644 new mode 100755 diff --git a/trunk/sound/soc/codecs/max98090.h b/trunk/sound/soc/codecs/max98090.h old mode 100644 new mode 100755 diff --git a/trunk/sound/soc/codecs/si476x.c b/trunk/sound/soc/codecs/si476x.c index 566ea3256e2d..f2d61a187830 100644 --- a/trunk/sound/soc/codecs/si476x.c +++ b/trunk/sound/soc/codecs/si476x.c @@ -159,7 +159,6 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: width = SI476X_PCM_FORMAT_S8; - break; case SNDRV_PCM_FORMAT_S16_LE: width = SI476X_PCM_FORMAT_S16_LE; break; diff --git a/trunk/sound/soc/codecs/wm5102.c b/trunk/sound/soc/codecs/wm5102.c index 34d0201d6a78..b82bbf584146 100644 --- a/trunk/sound/soc/codecs/wm5102.c +++ b/trunk/sound/soc/codecs/wm5102.c @@ -584,7 +584,7 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - struct arizona *arizona = dev_get_drvdata(codec->dev->parent); + struct arizona *arizona = dev_get_drvdata(codec->dev); struct regmap *regmap = codec->control_data; const struct reg_default *patch = NULL; int i, patch_size; diff --git a/trunk/sound/soc/codecs/wm8903.c b/trunk/sound/soc/codecs/wm8903.c index f8a31ad0b203..134e41c870b9 100644 --- a/trunk/sound/soc/codecs/wm8903.c +++ b/trunk/sound/soc/codecs/wm8903.c @@ -1083,8 +1083,6 @@ static const struct snd_soc_dapm_route wm8903_intercon[] = { { "ROP", NULL, "Right Speaker PGA" }, { "RON", NULL, "Right Speaker PGA" }, - { "Charge Pump", NULL, "CLK_DSP" }, - { "Left Headphone Output PGA", NULL, "Charge Pump" }, { "Right Headphone Output PGA", NULL, "Charge Pump" }, { "Left Line Output PGA", NULL, "Charge Pump" }, diff --git a/trunk/sound/soc/codecs/wm_adsp.c b/trunk/sound/soc/codecs/wm_adsp.c index 9af1bddc4c62..f3f7e75f8628 100644 --- a/trunk/sound/soc/codecs/wm_adsp.c +++ b/trunk/sound/soc/codecs/wm_adsp.c @@ -828,8 +828,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) &buf_list); if (!buf) { adsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; + return -ENOMEM; } adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", @@ -866,7 +865,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) wm_adsp_buf_free(&buf_list); out: kfree(file); - return ret; + return 0; } int wm_adsp1_init(struct wm_adsp *adsp) diff --git a/trunk/sound/soc/fsl/imx-ssi.c b/trunk/sound/soc/fsl/imx-ssi.c index 810c7eeb7b03..55464a5b0706 100644 --- a/trunk/sound/soc/fsl/imx-ssi.c +++ b/trunk/sound/soc/fsl/imx-ssi.c @@ -496,8 +496,6 @@ static void imx_ssi_ac97_reset(struct snd_ac97 *ac97) if (imx_ssi->ac97_reset) imx_ssi->ac97_reset(ac97); - /* First read sometimes fails, do a dummy read */ - imx_ssi_ac97_read(ac97, 0); } static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97) @@ -506,9 +504,6 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97) if (imx_ssi->ac97_warm_reset) imx_ssi->ac97_warm_reset(ac97); - - /* First read sometimes fails, do a dummy read */ - imx_ssi_ac97_read(ac97, 0); } struct snd_ac97_bus_ops soc_ac97_ops = { diff --git a/trunk/sound/soc/fsl/pcm030-audio-fabric.c b/trunk/sound/soc/fsl/pcm030-audio-fabric.c index eb4373840bb6..8e52c1485df3 100644 --- a/trunk/sound/soc/fsl/pcm030-audio-fabric.c +++ b/trunk/sound/soc/fsl/pcm030-audio-fabric.c @@ -51,7 +51,7 @@ static struct snd_soc_card pcm030_card = { .num_links = ARRAY_SIZE(pcm030_fabric_dai), }; -static int pcm030_fabric_probe(struct platform_device *op) +static int __init pcm030_fabric_probe(struct platform_device *op) { struct device_node *np = op->dev.of_node; struct device_node *platform_np; diff --git a/trunk/sound/soc/samsung/i2s.c b/trunk/sound/soc/samsung/i2s.c index 6bbeb0bf1a73..d7231e336a7c 100644 --- a/trunk/sound/soc/samsung/i2s.c +++ b/trunk/sound/soc/samsung/i2s.c @@ -972,7 +972,6 @@ static const struct snd_soc_dai_ops samsung_i2s_dai_ops = { static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) { struct i2s_dai *i2s; - int ret; i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL); if (i2s == NULL) @@ -997,18 +996,16 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) i2s->i2s_dai_drv.capture.channels_max = 2; i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; - dev_set_drvdata(&i2s->pdev->dev, i2s); } else { /* Create a new platform_device for Secondary */ - i2s->pdev = platform_device_alloc("samsung-i2s-sec", -1); + i2s->pdev = platform_device_register_resndata(NULL, + "samsung-i2s-sec", -1, NULL, 0, NULL, 0); if (IS_ERR(i2s->pdev)) return NULL; - - platform_set_drvdata(i2s->pdev, i2s); - ret = platform_device_add(i2s->pdev); - if (ret < 0) - return NULL; } + /* Pre-assign snd_soc_dai_set_drvdata */ + dev_set_drvdata(&i2s->pdev->dev, i2s); + return i2s; } @@ -1110,10 +1107,6 @@ static int samsung_i2s_probe(struct platform_device *pdev) if (samsung_dai_type == TYPE_SEC) { sec_dai = dev_get_drvdata(&pdev->dev); - if (!sec_dai) { - dev_err(&pdev->dev, "Unable to get drvdata\n"); - return -EFAULT; - } snd_soc_register_dai(&sec_dai->pdev->dev, &sec_dai->i2s_dai_drv); asoc_dma_platform_register(&pdev->dev); diff --git a/trunk/sound/soc/sh/dma-sh7760.c b/trunk/sound/soc/sh/dma-sh7760.c index 1a8b03e4b41b..19eff8fc4fdd 100644 --- a/trunk/sound/soc/sh/dma-sh7760.c +++ b/trunk/sound/soc/sh/dma-sh7760.c @@ -342,8 +342,8 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) return 0; } -static struct snd_soc_platform_driver sh7760_soc_platform = { - .ops = &camelot_pcm_ops, +static struct snd_soc_platform sh7760_soc_platform = { + .pcm_ops = &camelot_pcm_ops, .pcm_new = camelot_pcm_new, .pcm_free = camelot_pcm_free, }; diff --git a/trunk/sound/soc/soc-compress.c b/trunk/sound/soc/soc-compress.c index ed0bfb0ddb96..b5b3db71e253 100644 --- a/trunk/sound/soc/soc-compress.c +++ b/trunk/sound/soc/soc-compress.c @@ -211,27 +211,19 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream, if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) { ret = platform->driver->compr_ops->set_params(cstream, params); if (ret < 0) - goto err; + goto out; } if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) { ret = rtd->dai_link->compr_ops->set_params(cstream); if (ret < 0) - goto err; + goto out; } snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, SND_SOC_DAPM_STREAM_START); - /* cancel any delayed stream shutdown that is pending */ - rtd->pop_wait = 0; - mutex_unlock(&rtd->pcm_mutex); - - cancel_delayed_work_sync(&rtd->delayed_work); - - return ret; - -err: +out: mutex_unlock(&rtd->pcm_mutex); return ret; } diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index ff4b45a5d796..b7e84a7cd9ee 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -2963,7 +2963,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, val = val << shift; ret = snd_soc_update_bits_locked(codec, reg, val_mask, val); - if (ret < 0) + if (ret != 0) return ret; if (snd_soc_volsw_is_stereo(mc)) { @@ -3140,7 +3140,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, if (params->mask) { ret = regmap_read(codec->control_data, params->base, &val); if (ret != 0) - goto out; + return ret; val &= params->mask; @@ -3158,15 +3158,13 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, ((u32 *)data)[0] |= cpu_to_be32(val); break; default: - ret = -EINVAL; - goto out; + return -EINVAL; } } ret = regmap_raw_write(codec->control_data, params->base, data, len); -out: kfree(data); return ret; @@ -4199,6 +4197,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, dev_err(card->dev, "ASoC: Property '%s' index %d could not be read: %d\n", propname, 2 * i, ret); + kfree(routes); return -EINVAL; } ret = of_property_read_string_index(np, propname, @@ -4207,6 +4206,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, dev_err(card->dev, "ASoC: Property '%s' index %d could not be read: %d\n", propname, (2 * i) + 1, ret); + kfree(routes); return -EINVAL; } } diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index d6d9ba2e6916..1d6a9b3ceb27 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -831,9 +831,6 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, if (path->weak) continue; - if (path->walking) - return 1; - if (path->walked) continue; @@ -841,7 +838,6 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, if (path->sink && path->connect) { path->walked = 1; - path->walking = 1; /* do we need to add this widget to the list ? */ if (list) { @@ -851,14 +847,11 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, dev_err(widget->dapm->dev, "ASoC: could not add widget %s\n", widget->name); - path->walking = 0; return con; } } con += is_connected_output_ep(path->sink, list); - - path->walking = 0; } } @@ -938,9 +931,6 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, if (path->weak) continue; - if (path->walking) - return 1; - if (path->walked) continue; @@ -948,7 +938,6 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, if (path->source && path->connect) { path->walked = 1; - path->walking = 1; /* do we need to add this widget to the list ? */ if (list) { @@ -958,14 +947,11 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, dev_err(widget->dapm->dev, "ASoC: could not add widget %s\n", widget->name); - path->walking = 0; return con; } } con += is_connected_input_ep(path->source, list); - - path->walking = 0; } } diff --git a/trunk/sound/soc/spear/spear_pcm.c b/trunk/sound/soc/spear/spear_pcm.c index 5e7aebe1e664..9b76cc5a1148 100644 --- a/trunk/sound/soc/spear/spear_pcm.c +++ b/trunk/sound/soc/spear/spear_pcm.c @@ -149,9 +149,9 @@ static void spear_pcm_free(struct snd_pcm *pcm) static u64 spear_pcm_dmamask = DMA_BIT_MASK(32); -static int spear_pcm_new(struct snd_soc_pcm_runtime *rtd) +static int spear_pcm_new(struct snd_card *card, + struct snd_soc_dai *dai, struct snd_pcm *pcm) { - struct snd_card *card = rtd->card->snd_card; int ret; if (!card->dev->dma_mask) @@ -159,16 +159,16 @@ static int spear_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (rtd->cpu_dai->driver->playback.channels_min) { - ret = spear_pcm_preallocate_dma_buffer(rtd->pcm, + if (dai->driver->playback.channels_min) { + ret = spear_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK, spear_pcm_hardware.buffer_bytes_max); if (ret) return ret; } - if (rtd->cpu_dai->driver->capture.channels_min) { - ret = spear_pcm_preallocate_dma_buffer(rtd->pcm, + if (dai->driver->capture.channels_min) { + ret = spear_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE, spear_pcm_hardware.buffer_bytes_max); if (ret) diff --git a/trunk/sound/soc/tegra/tegra_pcm.c b/trunk/sound/soc/tegra/tegra_pcm.c index 5e2c55c5b255..c925ab0adeb6 100644 --- a/trunk/sound/soc/tegra/tegra_pcm.c +++ b/trunk/sound/soc/tegra/tegra_pcm.c @@ -43,6 +43,8 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_INTERLEAVED, .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 2, @@ -125,6 +127,26 @@ static int tegra_pcm_hw_free(struct snd_pcm_substream *substream) return 0; } +static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + return snd_dmaengine_pcm_trigger(substream, + SNDRV_PCM_TRIGGER_START); + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + return snd_dmaengine_pcm_trigger(substream, + SNDRV_PCM_TRIGGER_STOP); + default: + return -EINVAL; + } + return 0; +} + static int tegra_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { @@ -142,7 +164,7 @@ static struct snd_pcm_ops tegra_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = tegra_pcm_hw_params, .hw_free = tegra_pcm_hw_free, - .trigger = snd_dmaengine_pcm_trigger, + .trigger = tegra_pcm_trigger, .pointer = snd_dmaengine_pcm_pointer, .mmap = tegra_pcm_mmap, }; diff --git a/trunk/sound/usb/clock.c b/trunk/sound/usb/clock.c index 9e2703a25156..5e634a2eb282 100644 --- a/trunk/sound/usb/clock.c +++ b/trunk/sound/usb/clock.c @@ -253,7 +253,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, { struct usb_device *dev = chip->dev; unsigned char data[4]; - int err, cur_rate, prev_rate; + int err, crate; int clock = snd_usb_clock_find_source(chip, fmt->clock); if (clock < 0) @@ -266,19 +266,6 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, return -ENXIO; } - err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, - USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, - snd_usb_ctrl_intf(chip) | (clock << 8), - data, sizeof(data)); - if (err < 0) { - snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", - dev->devnum, iface, fmt->altsetting); - prev_rate = 0; - } else { - prev_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - } - data[0] = rate; data[1] = rate >> 8; data[2] = rate >> 16; @@ -293,31 +280,19 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, return err; } - err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, - USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, - snd_usb_ctrl_intf(chip) | (clock << 8), - data, sizeof(data)); - if (err < 0) { + if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), + data, sizeof(data))) < 0) { snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", dev->devnum, iface, fmt->altsetting); - cur_rate = 0; - } else { - cur_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - } - - if (cur_rate != rate) { - snd_printd(KERN_WARNING - "current rate %d is different from the runtime rate %d\n", - cur_rate, rate); + return err; } - /* Some devices doesn't respond to sample rate changes while the - * interface is active. */ - if (rate != prev_rate) { - usb_set_interface(dev, iface, 0); - usb_set_interface(dev, iface, fmt->altsetting); - } + crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + if (crate != rate) + snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); return 0; } diff --git a/trunk/sound/usb/mixer_quirks.c b/trunk/sound/usb/mixer_quirks.c index ebe91440a068..497d2741d119 100644 --- a/trunk/sound/usb/mixer_quirks.c +++ b/trunk/sound/usb/mixer_quirks.c @@ -509,7 +509,7 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, else ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0, wIndex, + 0, cpu_to_le16(wIndex), &tmp, sizeof(tmp), 1000); up_read(&mixer->chip->shutdown_rwsem); @@ -540,7 +540,7 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, else ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - wValue, wIndex, + cpu_to_le16(wValue), cpu_to_le16(wIndex), NULL, 0, 1000); up_read(&mixer->chip->shutdown_rwsem); diff --git a/trunk/sound/usb/quirks.c b/trunk/sound/usb/quirks.c index 9c5ab22358b1..5325a3869bb7 100644 --- a/trunk/sound/usb/quirks.c +++ b/trunk/sound/usb/quirks.c @@ -486,7 +486,7 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev) { int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 1, 0, NULL, 0, 1000); + cpu_to_le16(1), 0, NULL, 0, 1000); if (ret < 0) return ret; diff --git a/trunk/tools/power/x86/turbostat/turbostat.c b/trunk/tools/power/x86/turbostat/turbostat.c index 321e066a0753..6f3214ed4444 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.c +++ b/trunk/tools/power/x86/turbostat/turbostat.c @@ -1421,7 +1421,6 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) case 0x3C: /* HSW */ case 0x3F: /* HSW */ case 0x45: /* HSW */ - case 0x46: /* HSW */ return 1; case 0x2E: /* Nehalem-EX Xeon - Beckton */ case 0x2F: /* Westmere-EX Xeon - Eagleton */ @@ -1516,7 +1515,6 @@ void rapl_probe(unsigned int family, unsigned int model) case 0x3C: /* HSW */ case 0x3F: /* HSW */ case 0x45: /* HSW */ - case 0x46: /* HSW */ do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX; break; case 0x2D: @@ -1756,7 +1754,6 @@ int is_snb(unsigned int family, unsigned int model) case 0x3C: /* HSW */ case 0x3F: /* HSW */ case 0x45: /* HSW */ - case 0x46: /* HSW */ return 1; } return 0; @@ -2279,7 +2276,7 @@ int main(int argc, char **argv) cmdline(argc, argv); if (verbose) - fprintf(stderr, "turbostat v3.3 March 15, 2013" + fprintf(stderr, "turbostat v3.2 February 11, 2013" " - Len Brown \n"); turbostat_init(); diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index f18013f09e68..adc68feb5c5a 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -1541,38 +1541,21 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, } int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, - gpa_t gpa, unsigned long len) + gpa_t gpa) { struct kvm_memslots *slots = kvm_memslots(kvm); int offset = offset_in_page(gpa); - gfn_t start_gfn = gpa >> PAGE_SHIFT; - gfn_t end_gfn = (gpa + len - 1) >> PAGE_SHIFT; - gfn_t nr_pages_needed = end_gfn - start_gfn + 1; - gfn_t nr_pages_avail; + gfn_t gfn = gpa >> PAGE_SHIFT; ghc->gpa = gpa; ghc->generation = slots->generation; - ghc->len = len; - ghc->memslot = gfn_to_memslot(kvm, start_gfn); - ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, &nr_pages_avail); - if (!kvm_is_error_hva(ghc->hva) && nr_pages_avail >= nr_pages_needed) { + ghc->memslot = gfn_to_memslot(kvm, gfn); + ghc->hva = gfn_to_hva_many(ghc->memslot, gfn, NULL); + if (!kvm_is_error_hva(ghc->hva)) ghc->hva += offset; - } else { - /* - * If the requested region crosses two memslots, we still - * verify that the entire region is valid here. - */ - while (start_gfn <= end_gfn) { - ghc->memslot = gfn_to_memslot(kvm, start_gfn); - ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, - &nr_pages_avail); - if (kvm_is_error_hva(ghc->hva)) - return -EFAULT; - start_gfn += nr_pages_avail; - } - /* Use the slow path for cross page reads and writes. */ - ghc->memslot = NULL; - } + else + return -EFAULT; + return 0; } EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init); @@ -1583,13 +1566,8 @@ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, struct kvm_memslots *slots = kvm_memslots(kvm); int r; - BUG_ON(len > ghc->len); - if (slots->generation != ghc->generation) - kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len); - - if (unlikely(!ghc->memslot)) - return kvm_write_guest(kvm, ghc->gpa, data, len); + kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); if (kvm_is_error_hva(ghc->hva)) return -EFAULT; @@ -1609,13 +1587,8 @@ int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, struct kvm_memslots *slots = kvm_memslots(kvm); int r; - BUG_ON(len > ghc->len); - if (slots->generation != ghc->generation) - kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len); - - if (unlikely(!ghc->memslot)) - return kvm_read_guest(kvm, ghc->gpa, data, len); + kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); if (kvm_is_error_hva(ghc->hva)) return -EFAULT;