Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 16 May 2015 22:33:25 +0000 (15:33 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 16 May 2015 22:33:25 +0000 (15:33 -0700)
Pull ARM SoC fixes from Arnd Bergmann:
 "Nothing frightening this time, just smaller fixes in a number of
  places.

  The other changes contained here are:

   MAINTAINERS file updates:

   - The mach-gemini maintainer is back in action and has a new git tree

   - Krzysztof Kozlowski has volunteered to be a new co-maintainer for
     the samsung platforms

   - updates to the files that belong to Marvell mvebu

  Bug fixes:

   - The largest changes are on omap2, but are only to avoid some
     harmless warnings and to fix reset on omap4

   - a small regression fix on tegra

   - multiple fixes for incorrect IRQ affinity on vexpress

   - the missing system controller on arm64 juno is added

   - one revert of a patch that was accidentally applied twice for
     mach-rockchip

   - two clock related DT fixes for mvebu

   - a workaround for suspend with old DT binaries on new exynos kernels

   - Another fix for suspend on exynos, needs to be backported"

* tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (21 commits)
  MAINTAINERS: Add dts entries for some of the Marvell SoCs
  MAINTAINERS: ARM: EXYNOS: Add Krzysztof Kozlowski as co-maintainer
  ARM: EXYNOS: Use of_machine_is_compatible instead of soc_is_exynos4
  ARM: EXYNOS: Fix failed second suspend on Exynos4
  Revert "ARM: rockchip: fix undefined instruction of reset_ctrl_regs"
  ARM: EXYNOS: Fix dereference of ERR_PTR returned by of_genpd_get_from_provider
  ARM: EXYNOS: Don't try to initialize suspend on old DT
  ARM: dts: Add keep-power-in-suspend to WiFi SDIO node for Peach Boards
  ARM: gemini: fix compiler warning due wrong data type
  ARM: vexpress/tc2: Add interrupt-affinity to the PMU node
  ARM: vexpress/ca9: Add interrupt-affinity to the PMU node
  ARM: vexpress/ca9: Add unified-cache property to l2 cache node
  ARM64: juno: add sp810 support and fix sp804 clock frequency
  ARM: Gemini: Maintainers update
  ARM: OMAP2+: Remove bogus struct clk comparison for timer clock
  ARM: dove: Add clock-names to CuBox Si5351 clk generator
  ARM: AM33xx+: hwmod: re-use omap4 implementations for reset functionality
  ARM: OMAP4+: PRM: add support for passing status register/bit info to reset
  ARM: AM43xx: hwmod: add VPFE hwmod entries
  ARM: mvebu: Fix the main PLL frequency on Armada 375, 38x and 39x SoCs
  ...

202 files changed:
MAINTAINERS
arch/arm/net/bpf_jit_32.c
arch/arm64/crypto/crc32-arm64.c
arch/arm64/crypto/sha1-ce-glue.c
arch/arm64/crypto/sha2-ce-glue.c
arch/arm64/kernel/alternative.c
arch/arm64/kernel/perf_event.c
arch/arm64/mm/dump.c
arch/arm64/net/bpf_jit_comp.c
arch/mips/include/asm/smp.h
arch/mips/kernel/elf.c
arch/mips/kernel/smp.c
arch/parisc/include/asm/elf.h
arch/parisc/kernel/process.c
arch/parisc/kernel/sys_parisc.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_rapl.c
arch/x86/net/bpf_jit_comp.c
arch/x86/vdso/Makefile
drivers/acpi/acpica/utglobal.c
drivers/acpi/osl.c
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/ahci_st.c
drivers/ata/libahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/pata_scc.c [deleted file]
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btbcm.c
drivers/bluetooth/btbcm.h
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_ath.c
drivers/firmware/dmi_scan.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_dp_mst.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/radeon/si.c
drivers/ide/Kconfig
drivers/ide/Makefile
drivers/ide/scc_pata.c [deleted file]
drivers/infiniband/core/iwpm_msg.c
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/device.c
drivers/infiniband/hw/ehca/ehca_mcast.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/qib/qib.h
drivers/infiniband/hw/qib/qib_wc_x86_64.c
drivers/iommu/amd_iommu_v2.c
drivers/iommu/arm-smmu.c
drivers/iommu/rockchip-iommu.c
drivers/irqchip/irq-tegra.c
drivers/md/raid0.c
drivers/md/raid5.c
drivers/net/can/xilinx_can.c
drivers/net/dsa/mv88e6xxx.c
drivers/net/ethernet/amd/Kconfig
drivers/net/ethernet/apm/xgene/Kconfig
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/intel/e1000e/e1000.h
drivers/net/ethernet/intel/fm10k/fm10k_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/mellanox/mlx4/en_port.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
drivers/net/ethernet/qualcomm/qca_spi.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/smsc/smc91x.c
drivers/net/ethernet/smsc/smsc911x.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/ethernet/xilinx/ll_temac_main.c
drivers/net/hyperv/netvsc.c
drivers/net/ieee802154/at86rf230.c
drivers/net/macvlan.c
drivers/net/phy/Kconfig
drivers/net/phy/mdio-gpio.c
drivers/net/phy/micrel.c
drivers/net/ppp/pppoe.c
drivers/net/usb/r8152.c
drivers/net/usb/usbnet.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/iwlwifi/iwl-fw-file.h
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/rtlwifi/usb.c
drivers/parisc/superio.c
drivers/power/axp288_fuel_gauge.c
drivers/power/bq27x00_battery.c
drivers/power/collie_battery.c
drivers/power/reset/Kconfig
drivers/power/reset/at91-reset.c
drivers/power/reset/ltc2952-poweroff.c
drivers/rtc/rtc-armada38x.c
drivers/spi/Kconfig
drivers/spi/spi-bcm2835.c
drivers/spi/spi-bitbang.c
drivers/spi/spi-fsl-cpm.c
drivers/spi/spi-fsl-espi.c
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi.c
drivers/thermal/intel_powerclamp.c
drivers/thermal/rockchip_thermal.c
drivers/thermal/thermal_core.h
fs/exec.c
fs/kernfs/dir.c
fs/nfsd/blocklayout.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4state.c
fs/nfsd/state.h
fs/nfsd/xdr4.h
include/drm/drm_pciids.h
include/linux/gfp.h
include/linux/libata.h
include/linux/memcontrol.h
include/linux/netdevice.h
include/linux/sched/rt.h
include/linux/tcp.h
include/linux/uidgid.h
include/net/cfg802154.h
include/net/codel.h
include/net/mac80211.h
include/net/mac802154.h
include/net/tcp.h
include/uapi/linux/inet_diag.h
include/uapi/linux/mpls.h
include/uapi/linux/tcp.h
kernel/events/core.c
kernel/locking/rtmutex.c
kernel/sched/core.c
mm/kmemleak.c
mm/mempolicy.c
mm/page_isolation.c
net/bluetooth/hci_core.c
net/core/dev.c
net/core/net_namespace.c
net/core/sock.c
net/ieee802154/Makefile
net/ieee802154/nl-phy.c
net/ieee802154/nl802154.c
net/ieee802154/rdev-ops.h
net/ieee802154/trace.c [new file with mode: 0644]
net/ieee802154/trace.h [new file with mode: 0644]
net/ipv4/inet_diag.c
net/ipv4/tcp.c
net/ipv4/tcp_dctcp.c
net/ipv4/tcp_fastopen.c
net/ipv4/tcp_illinois.c
net/ipv4/tcp_input.c
net/ipv4/tcp_vegas.c
net/ipv4/tcp_vegas.h
net/ipv4/tcp_westwood.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/mac80211/iface.c
net/mac80211/sta_info.c
net/mac802154/cfg.c
net/mac802154/ieee802154_i.h
net/mac802154/iface.c
net/mac802154/llsec.c
net/mac802154/main.c
net/mpls/af_mpls.c
net/mpls/internal.h
net/netlink/af_netlink.c
net/packet/af_packet.c
net/rds/connection.c
net/rds/ib_cm.c
net/rds/tcp_connect.c
net/rds/tcp_listen.c
net/sched/cls_api.c
net/sched/sch_codel.c
net/sched/sch_fq_codel.c
net/sched/sch_gred.c
net/sunrpc/auth_gss/gss_rpc_xdr.c
tools/lib/lockdep/Makefile
tools/lib/lockdep/uinclude/linux/kernel.h
tools/perf/Makefile
tools/testing/selftests/x86/Makefile
tools/testing/selftests/x86/check_cc.sh [new file with mode: 0755]
tools/testing/selftests/x86/run_x86_tests.sh [deleted file]
tools/testing/selftests/x86/trivial_32bit_program.c
tools/testing/selftests/x86/trivial_64bit_program.c [new file with mode: 0644]
tools/thermal/tmon/Makefile
tools/vm/Makefile

index 892b2cf0b42e1d74362981e2dd2ca1e72eb7bd01..f8e0afb708b4fe2a60f3f6a3b697bd1dd60753d4 100644 (file)
@@ -1944,7 +1944,7 @@ S:        Maintained
 F:     drivers/net/wireless/b43legacy/
 
 BACKLIGHT CLASS/SUBSYSTEM
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 M:     Lee Jones <lee.jones@linaro.org>
 S:     Maintained
 F:     drivers/video/backlight/
@@ -3927,7 +3927,7 @@ F:        drivers/extcon/
 F:     Documentation/extcon/
 
 EXYNOS DP DRIVER
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 L:     dri-devel@lists.freedesktop.org
 S:     Maintained
 F:     drivers/gpu/drm/exynos/exynos_dp*
@@ -4386,11 +4386,10 @@ F:      fs/gfs2/
 F:     include/uapi/linux/gfs2_ondisk.h
 
 GIGASET ISDN DRIVERS
-M:     Hansjoerg Lipp <hjlipp@web.de>
-M:     Tilman Schmidt <tilman@imap.cc>
+M:     Paul Bolle <pebolle@tiscali.nl>
 L:     gigaset307x-common@lists.sourceforge.net
 W:     http://gigaset307x.sourceforge.net/
-S:     Maintained
+S:     Odd Fixes
 F:     Documentation/isdn/README.gigaset
 F:     drivers/isdn/gigaset/
 F:     include/uapi/linux/gigaset_dev.h
@@ -5063,7 +5062,7 @@ M:        Hal Rosenstock <hal.rosenstock@gmail.com>
 L:     linux-rdma@vger.kernel.org
 W:     http://www.openfabrics.org/
 Q:     http://patchwork.kernel.org/project/linux-rdma/list/
-T:     git git://github.com/dledford/linux.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma.git
 S:     Supported
 F:     Documentation/infiniband/
 F:     drivers/infiniband/
@@ -6968,6 +6967,17 @@ T:       git git://git.rocketboards.org/linux-socfpga-next.git
 S:     Maintained
 F:     arch/nios2/
 
+NOKIA N900 POWER SUPPLY DRIVERS
+M:     Pali Rohár <pali.rohar@gmail.com>
+S:     Maintained
+F:     include/linux/power/bq2415x_charger.h
+F:     include/linux/power/bq27x00_battery.h
+F:     include/linux/power/isp1704_charger.h
+F:     drivers/power/bq2415x_charger.c
+F:     drivers/power/bq27x00_battery.c
+F:     drivers/power/isp1704_charger.c
+F:     drivers/power/rx51_battery.c
+
 NTB DRIVER
 M:     Jon Mason <jdmason@kudzu.us>
 M:     Dave Jiang <dave.jiang@intel.com>
@@ -7556,7 +7566,7 @@ S:        Maintained
 F:     drivers/pci/host/*rcar*
 
 PCI DRIVER FOR SAMSUNG EXYNOS
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 L:     linux-pci@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
@@ -7564,7 +7574,7 @@ S:        Maintained
 F:     drivers/pci/host/pci-exynos.c
 
 PCI DRIVER FOR SYNOPSIS DESIGNWARE
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 L:     linux-pci@vger.kernel.org
 S:     Maintained
 F:     drivers/pci/host/*designware*
@@ -8520,7 +8530,7 @@ S:        Supported
 F:     sound/soc/samsung/
 
 SAMSUNG FRAMEBUFFER DRIVER
-M:     Jingoo Han <jg1.han@samsung.com>
+M:     Jingoo Han <jingoohan1@gmail.com>
 L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/fbdev/s3c-fb.c
@@ -8825,10 +8835,11 @@ W:      http://www.emulex.com
 S:     Supported
 F:     drivers/scsi/be2iscsi/
 
-SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
-M:     Sathya Perla <sathya.perla@emulex.com>
-M:     Subbu Seetharaman <subbu.seetharaman@emulex.com>
-M:     Ajit Khaparde <ajit.khaparde@emulex.com>
+Emulex 10Gbps NIC BE2, BE3-R, Lancer, Skyhawk-R DRIVER
+M:     Sathya Perla <sathya.perla@avagotech.com>
+M:     Ajit Khaparde <ajit.khaparde@avagotech.com>
+M:     Padmanabh Ratnakar <padmanabh.ratnakar@avagotech.com>
+M:     Sriharsha Basavapatna <sriharsha.basavapatna@avagotech.com>
 L:     netdev@vger.kernel.org
 W:     http://www.emulex.com
 S:     Supported
index e1268f90502682c75dfd7a98e6ed15272ea8d512..e0e23582c8b4e4687209a219c0d2bbc86b88bbd9 100644 (file)
@@ -54,6 +54,7 @@
 #define SEEN_DATA              (1 << (BPF_MEMWORDS + 3))
 
 #define FLAG_NEED_X_RESET      (1 << 0)
+#define FLAG_IMM_OVERFLOW      (1 << 1)
 
 struct jit_ctx {
        const struct bpf_prog *skf;
@@ -293,6 +294,15 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx)
        /* PC in ARM mode == address of the instruction + 8 */
        imm = offset - (8 + ctx->idx * 4);
 
+       if (imm & ~0xfff) {
+               /*
+                * literal pool is too far, signal it into flags. we
+                * can only detect it on the second pass unfortunately.
+                */
+               ctx->flags |= FLAG_IMM_OVERFLOW;
+               return 0;
+       }
+
        return imm;
 }
 
@@ -449,10 +459,21 @@ static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
                return;
        }
 #endif
-       if (rm != ARM_R0)
-               emit(ARM_MOV_R(ARM_R0, rm), ctx);
+
+       /*
+        * For BPF_ALU | BPF_DIV | BPF_K instructions, rm is ARM_R4
+        * (r_A) and rn is ARM_R0 (r_scratch) so load rn first into
+        * ARM_R1 to avoid accidentally overwriting ARM_R0 with rm
+        * before using it as a source for ARM_R1.
+        *
+        * For BPF_ALU | BPF_DIV | BPF_X rm is ARM_R4 (r_A) and rn is
+        * ARM_R5 (r_X) so there is no particular register overlap
+        * issues.
+        */
        if (rn != ARM_R1)
                emit(ARM_MOV_R(ARM_R1, rn), ctx);
+       if (rm != ARM_R0)
+               emit(ARM_MOV_R(ARM_R0, rm), ctx);
 
        ctx->seen |= SEEN_CALL;
        emit_mov_i(ARM_R3, (u32)jit_udiv, ctx);
@@ -855,6 +876,14 @@ b_epilogue:
                default:
                        return -1;
                }
+
+               if (ctx->flags & FLAG_IMM_OVERFLOW)
+                       /*
+                        * this instruction generated an overflow when
+                        * trying to access the literal pool, so
+                        * delegate this filter to the kernel interpreter.
+                        */
+                       return -1;
        }
 
        /* compute offsets only during the first pass */
@@ -917,7 +946,14 @@ void bpf_jit_compile(struct bpf_prog *fp)
        ctx.idx = 0;
 
        build_prologue(&ctx);
-       build_body(&ctx);
+       if (build_body(&ctx) < 0) {
+#if __LINUX_ARM_ARCH__ < 7
+               if (ctx.imm_count)
+                       kfree(ctx.imms);
+#endif
+               bpf_jit_binary_free(header);
+               goto out;
+       }
        build_epilogue(&ctx);
 
        flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
index 9499199924aebd4d6b27ced325d69918b641ddf3..6a37c3c6b11d39acc0db9d142652abcb18d21b9c 100644 (file)
@@ -147,13 +147,21 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
 {
        struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
+       put_unaligned_le32(ctx->crc, out);
+       return 0;
+}
+
+static int chksumc_final(struct shash_desc *desc, u8 *out)
+{
+       struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
        put_unaligned_le32(~ctx->crc, out);
        return 0;
 }
 
 static int __chksum_finup(u32 crc, const u8 *data, unsigned int len, u8 *out)
 {
-       put_unaligned_le32(~crc32_arm64_le_hw(crc, data, len), out);
+       put_unaligned_le32(crc32_arm64_le_hw(crc, data, len), out);
        return 0;
 }
 
@@ -199,6 +207,14 @@ static int crc32_cra_init(struct crypto_tfm *tfm)
 {
        struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
 
+       mctx->key = 0;
+       return 0;
+}
+
+static int crc32c_cra_init(struct crypto_tfm *tfm)
+{
+       struct chksum_ctx *mctx = crypto_tfm_ctx(tfm);
+
        mctx->key = ~0;
        return 0;
 }
@@ -229,7 +245,7 @@ static struct shash_alg crc32c_alg = {
        .setkey                 =       chksum_setkey,
        .init                   =       chksum_init,
        .update                 =       chksumc_update,
-       .final                  =       chksum_final,
+       .final                  =       chksumc_final,
        .finup                  =       chksumc_finup,
        .digest                 =       chksumc_digest,
        .descsize               =       sizeof(struct chksum_desc_ctx),
@@ -241,7 +257,7 @@ static struct shash_alg crc32c_alg = {
                .cra_alignmask          =       0,
                .cra_ctxsize            =       sizeof(struct chksum_ctx),
                .cra_module             =       THIS_MODULE,
-               .cra_init               =       crc32_cra_init,
+               .cra_init               =       crc32c_cra_init,
        }
 };
 
index 114e7cc5de8c09b4eb75f6b11294e9c689d1ebbc..aefda9868627bde843227d1074e7cc9b17004298 100644 (file)
@@ -74,6 +74,9 @@ static int sha1_ce_finup(struct shash_desc *desc, const u8 *data,
 
 static int sha1_ce_final(struct shash_desc *desc, u8 *out)
 {
+       struct sha1_ce_state *sctx = shash_desc_ctx(desc);
+
+       sctx->finalize = 0;
        kernel_neon_begin_partial(16);
        sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_ce_transform);
        kernel_neon_end();
index 1340e44c048beab91279b6dd317f10590a6f06b9..7cd587564a4176e902f12c7c7043b714caab48ea 100644 (file)
@@ -75,6 +75,9 @@ static int sha256_ce_finup(struct shash_desc *desc, const u8 *data,
 
 static int sha256_ce_final(struct shash_desc *desc, u8 *out)
 {
+       struct sha256_ce_state *sctx = shash_desc_ctx(desc);
+
+       sctx->finalize = 0;
        kernel_neon_begin_partial(28);
        sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform);
        kernel_neon_end();
index 21033bba939051b7db11e415983d7b10fcc485ca..28f8365edc4c43edd00043f38d89f8ae8be6476f 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/cacheflush.h>
 #include <asm/alternative.h>
 #include <asm/cpufeature.h>
-#include <asm/insn.h>
 #include <linux/stop_machine.h>
 
 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
@@ -34,48 +33,6 @@ struct alt_region {
        struct alt_instr *end;
 };
 
-/*
- * Decode the imm field of a b/bl instruction, and return the byte
- * offset as a signed value (so it can be used when computing a new
- * branch target).
- */
-static s32 get_branch_offset(u32 insn)
-{
-       s32 imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn);
-
-       /* sign-extend the immediate before turning it into a byte offset */
-       return (imm << 6) >> 4;
-}
-
-static u32 get_alt_insn(u8 *insnptr, u8 *altinsnptr)
-{
-       u32 insn;
-
-       aarch64_insn_read(altinsnptr, &insn);
-
-       /* Stop the world on instructions we don't support... */
-       BUG_ON(aarch64_insn_is_cbz(insn));
-       BUG_ON(aarch64_insn_is_cbnz(insn));
-       BUG_ON(aarch64_insn_is_bcond(insn));
-       /* ... and there is probably more. */
-
-       if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) {
-               enum aarch64_insn_branch_type type;
-               unsigned long target;
-
-               if (aarch64_insn_is_b(insn))
-                       type = AARCH64_INSN_BRANCH_NOLINK;
-               else
-                       type = AARCH64_INSN_BRANCH_LINK;
-
-               target = (unsigned long)altinsnptr + get_branch_offset(insn);
-               insn = aarch64_insn_gen_branch_imm((unsigned long)insnptr,
-                                                  target, type);
-       }
-
-       return insn;
-}
-
 static int __apply_alternatives(void *alt_region)
 {
        struct alt_instr *alt;
@@ -83,9 +40,6 @@ static int __apply_alternatives(void *alt_region)
        u8 *origptr, *replptr;
 
        for (alt = region->begin; alt < region->end; alt++) {
-               u32 insn;
-               int i;
-
                if (!cpus_have_cap(alt->cpufeature))
                        continue;
 
@@ -95,12 +49,7 @@ static int __apply_alternatives(void *alt_region)
 
                origptr = (u8 *)&alt->orig_offset + alt->orig_offset;
                replptr = (u8 *)&alt->alt_offset + alt->alt_offset;
-
-               for (i = 0; i < alt->alt_len; i += sizeof(insn)) {
-                       insn = get_alt_insn(origptr + i, replptr + i);
-                       aarch64_insn_write(origptr + i, insn);
-               }
-
+               memcpy(origptr, replptr, alt->alt_len);
                flush_icache_range((uintptr_t)origptr,
                                   (uintptr_t)(origptr + alt->alt_len));
        }
index 23f25acf43a9021ee9b4ad0f79e3b3e5d6ef49c4..cce18c85d2e8edc6edcf23d13ef13e99f6cbf835 100644 (file)
@@ -1315,15 +1315,15 @@ static int armpmu_device_probe(struct platform_device *pdev)
        if (!cpu_pmu)
                return -ENODEV;
 
-       irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
-       if (!irqs)
-               return -ENOMEM;
-
        /* Don't bother with PPIs; they're already affine */
        irq = platform_get_irq(pdev, 0);
        if (irq >= 0 && irq_is_percpu(irq))
                return 0;
 
+       irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
+       if (!irqs)
+               return -ENOMEM;
+
        for (i = 0; i < pdev->num_resources; ++i) {
                struct device_node *dn;
                int cpu;
index 74c256744b254e09c989cabcd9072aee93c9fd6d..f3d6221cd5bdd4c7bf59fd99c71415d3922e2572 100644 (file)
@@ -328,10 +328,12 @@ static int ptdump_init(void)
                        for (j = 0; j < pg_level[i].num; j++)
                                pg_level[i].mask |= pg_level[i].bits[j].mask;
 
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
        address_markers[VMEMMAP_START_NR].start_address =
                                (unsigned long)virt_to_page(PAGE_OFFSET);
        address_markers[VMEMMAP_END_NR].start_address =
                                (unsigned long)virt_to_page(high_memory);
+#endif
 
        pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL,
                                 &ptdump_fops);
index edba042b23259c6f4b642a842fc1a2eb740c59b3..dc6a4842683aa500b9a5fc3af41caec349472902 100644 (file)
@@ -487,7 +487,7 @@ emit_cond_jmp:
                        return -EINVAL;
                }
 
-               imm64 = (u64)insn1.imm << 32 | imm;
+               imm64 = (u64)insn1.imm << 32 | (u32)imm;
                emit_a64_mov_i64(dst, imm64, ctx);
 
                return 1;
index bb02fac9b4fa0188e12b263376f3e1e08f83b022..2b25d1ba1ea037ca82212ec542a165e714ecf29c 100644 (file)
@@ -45,7 +45,7 @@ extern int __cpu_logical_map[NR_CPUS];
 #define SMP_DUMP               0x8
 #define SMP_ASK_C0COUNT                0x10
 
-extern volatile cpumask_t cpu_callin_map;
+extern cpumask_t cpu_callin_map;
 
 /* Mask of CPUs which are currently definitely operating coherently */
 extern cpumask_t cpu_coherent_mask;
index be4899f3c393275a992083d6f7e9f19c2fde5b87..4a4d9e067c89427fc34e990586f0e8237a9418ba 100644 (file)
@@ -76,14 +76,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
 
        /* Lets see if this is an O32 ELF */
        if (ehdr32->e_ident[EI_CLASS] == ELFCLASS32) {
-               /* FR = 1 for N32 */
-               if (ehdr32->e_flags & EF_MIPS_ABI2)
-                       state->overall_fp_mode = FP_FR1;
-               else
-                       /* Set a good default FPU mode for O32 */
-                       state->overall_fp_mode = cpu_has_mips_r6 ?
-                               FP_FRE : FP_FR0;
-
                if (ehdr32->e_flags & EF_MIPS_FP64) {
                        /*
                         * Set MIPS_ABI_FP_OLD_64 for EF_MIPS_FP64. We will override it
@@ -104,9 +96,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
                                  (char *)&abiflags,
                                  sizeof(abiflags));
        } else {
-               /* FR=1 is really the only option for 64-bit */
-               state->overall_fp_mode = FP_FR1;
-
                if (phdr64->p_type != PT_MIPS_ABIFLAGS)
                        return 0;
                if (phdr64->p_filesz < sizeof(abiflags))
@@ -137,6 +126,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
        struct elf32_hdr *ehdr = _ehdr;
        struct mode_req prog_req, interp_req;
        int fp_abi, interp_fp_abi, abi0, abi1, max_abi;
+       bool is_mips64;
 
        if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
                return 0;
@@ -152,10 +142,22 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
                abi0 = abi1 = fp_abi;
        }
 
-       /* ABI limits. O32 = FP_64A, N32/N64 = FP_SOFT */
-       max_abi = ((ehdr->e_ident[EI_CLASS] == ELFCLASS32) &&
-                  (!(ehdr->e_flags & EF_MIPS_ABI2))) ?
-               MIPS_ABI_FP_64A : MIPS_ABI_FP_SOFT;
+       is_mips64 = (ehdr->e_ident[EI_CLASS] == ELFCLASS64) ||
+                   (ehdr->e_flags & EF_MIPS_ABI2);
+
+       if (is_mips64) {
+               /* MIPS64 code always uses FR=1, thus the default is easy */
+               state->overall_fp_mode = FP_FR1;
+
+               /* Disallow access to the various FPXX & FP64 ABIs */
+               max_abi = MIPS_ABI_FP_SOFT;
+       } else {
+               /* Default to a mode capable of running code expecting FR=0 */
+               state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
+
+               /* Allow all ABIs we know about */
+               max_abi = MIPS_ABI_FP_64A;
+       }
 
        if ((abi0 > max_abi && abi0 != MIPS_ABI_FP_UNKNOWN) ||
            (abi1 > max_abi && abi1 != MIPS_ABI_FP_UNKNOWN))
index 193ace7955fb5eec377b666db534d76173a014c5..faa46ebd9ddae2fc43f20d6ff65f28688f665c4f 100644 (file)
@@ -43,7 +43,7 @@
 #include <asm/time.h>
 #include <asm/setup.h>
 
-volatile cpumask_t cpu_callin_map;     /* Bitmask of started secondaries */
+cpumask_t cpu_callin_map;              /* Bitmask of started secondaries */
 
 int __cpu_number_map[NR_CPUS];         /* Map physical to logical */
 EXPORT_SYMBOL(__cpu_number_map);
@@ -218,8 +218,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
        /*
         * Trust is futile.  We should really have timeouts ...
         */
-       while (!cpumask_test_cpu(cpu, &cpu_callin_map))
+       while (!cpumask_test_cpu(cpu, &cpu_callin_map)) {
                udelay(100);
+               schedule();
+       }
 
        synchronise_count_master(cpu);
        return 0;
index 3391d061eccc02fb64ebff9211cb9146c9f50a1c..78c9fd32c5546b6ec91d591e853d89a761383c92 100644 (file)
@@ -348,6 +348,10 @@ struct pt_regs;    /* forward declaration... */
 
 #define ELF_HWCAP      0
 
+#define STACK_RND_MASK (is_32bit_task() ? \
+                               0x7ff >> (PAGE_SHIFT - 12) : \
+                               0x3ffff >> (PAGE_SHIFT - 12))
+
 struct mm_struct;
 extern unsigned long arch_randomize_brk(struct mm_struct *);
 #define arch_randomize_brk arch_randomize_brk
index 8a488c22a99f7bb3836fc93a23a31561a237fb86..809905a811ed72a543ad257c1394900a4b976af8 100644 (file)
@@ -181,9 +181,12 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
        return 1;
 }
 
+/*
+ * Copy architecture-specific thread state
+ */
 int
 copy_thread(unsigned long clone_flags, unsigned long usp,
-           unsigned long arg, struct task_struct *p)
+           unsigned long kthread_arg, struct task_struct *p)
 {
        struct pt_regs *cregs = &(p->thread.regs);
        void *stack = task_stack_page(p);
@@ -195,11 +198,10 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
        extern void * const child_return;
 
        if (unlikely(p->flags & PF_KTHREAD)) {
+               /* kernel thread */
                memset(cregs, 0, sizeof(struct pt_regs));
                if (!usp) /* idle thread */
                        return 0;
-
-               /* kernel thread */
                /* Must exit via ret_from_kernel_thread in order
                 * to call schedule_tail()
                 */
@@ -215,7 +217,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
 #else
                cregs->gr[26] = usp;
 #endif
-               cregs->gr[25] = arg;
+               cregs->gr[25] = kthread_arg;
        } else {
                /* user thread */
                /* usp must be word aligned.  This also prevents users from
index e1ffea2f9a0b05ccda844969dcb7c519ab17077a..5aba01ac457ffc5d4823cf09c071f02f00a1d015 100644 (file)
@@ -77,6 +77,9 @@ static unsigned long mmap_upper_limit(void)
        if (stack_base > STACK_SIZE_MAX)
                stack_base = STACK_SIZE_MAX;
 
+       /* Add space for stack randomization. */
+       stack_base += (STACK_RND_MASK << PAGE_SHIFT);
+
        return PAGE_ALIGN(STACK_TOP - stack_base);
 }
 
index 960e85de13fbca45c317eeb8b719f05c7914ba1f..3998131d1a683058d6382b527c187028a7fede38 100644 (file)
@@ -1134,7 +1134,7 @@ static __initconst const u64 slm_hw_cache_extra_regs
  [ C(LL  ) ] = {
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = SLM_DMND_READ|SLM_LLC_ACCESS,
-               [ C(RESULT_MISS)   ] = SLM_DMND_READ|SLM_LLC_MISS,
+               [ C(RESULT_MISS)   ] = 0,
        },
        [ C(OP_WRITE) ] = {
                [ C(RESULT_ACCESS) ] = SLM_DMND_WRITE|SLM_LLC_ACCESS,
@@ -1184,8 +1184,7 @@ static __initconst const u64 slm_hw_cache_event_ids
        [ C(OP_READ) ] = {
                /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
                [ C(RESULT_ACCESS) ] = 0x01b7,
-               /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
-               [ C(RESULT_MISS)   ] = 0x01b7,
+               [ C(RESULT_MISS)   ] = 0,
        },
        [ C(OP_WRITE) ] = {
                /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
@@ -1217,7 +1216,7 @@ static __initconst const u64 slm_hw_cache_event_ids
  [ C(ITLB) ] = {
        [ C(OP_READ) ] = {
                [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
-               [ C(RESULT_MISS)   ] = 0x0282, /* ITLB.MISSES */
+               [ C(RESULT_MISS)   ] = 0x40205, /* PAGE_WALKS.I_SIDE_WALKS */
        },
        [ C(OP_WRITE) ] = {
                [ C(RESULT_ACCESS) ] = -1,
index 999289b94025623415693df205054e754e9a7d4b..358c54ad20d4084db807a05ae49def561aa4dd32 100644 (file)
@@ -722,6 +722,7 @@ static int __init rapl_pmu_init(void)
                break;
        case 60: /* Haswell */
        case 69: /* Haswell-Celeron */
+       case 61: /* Broadwell */
                rapl_cntr_mask = RAPL_IDX_HSW;
                rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
                break;
index 987514396c1e443376bffe70e050b72f86509102..99f76103c6b733e3d587652e3ab4228d20d57ac9 100644 (file)
@@ -559,6 +559,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                                if (is_ereg(dst_reg))
                                        EMIT1(0x41);
                                EMIT3(0xC1, add_1reg(0xC8, dst_reg), 8);
+
+                               /* emit 'movzwl eax, ax' */
+                               if (is_ereg(dst_reg))
+                                       EMIT3(0x45, 0x0F, 0xB7);
+                               else
+                                       EMIT2(0x0F, 0xB7);
+                               EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
                                break;
                        case 32:
                                /* emit 'bswap eax' to swap lower 4 bytes */
@@ -577,6 +584,27 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                        break;
 
                case BPF_ALU | BPF_END | BPF_FROM_LE:
+                       switch (imm32) {
+                       case 16:
+                               /* emit 'movzwl eax, ax' to zero extend 16-bit
+                                * into 64 bit
+                                */
+                               if (is_ereg(dst_reg))
+                                       EMIT3(0x45, 0x0F, 0xB7);
+                               else
+                                       EMIT2(0x0F, 0xB7);
+                               EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
+                               break;
+                       case 32:
+                               /* emit 'mov eax, eax' to clear upper 32-bits */
+                               if (is_ereg(dst_reg))
+                                       EMIT1(0x45);
+                               EMIT2(0x89, add_2reg(0xC0, dst_reg, dst_reg));
+                               break;
+                       case 64:
+                               /* nop */
+                               break;
+                       }
                        break;
 
                        /* ST: *(u8*)(dst_reg + off) = imm */
index 275a3a8b78afa3221b78296d2a7e3c2945de512b..e97032069f88cdcc8f1c692bd63960fd8bda517d 100644 (file)
@@ -51,7 +51,7 @@ VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
 $(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
        $(call if_changed,vdso)
 
-HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi
+HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/x86/include/uapi
 hostprogs-y                    += vdso2c
 
 quiet_cmd_vdso2c = VDSO2C  $@
index a72685c1e819660768933e84abe9d1076c953bff..5e8df9177da44781ac07942d146e47b97e954cda 100644 (file)
@@ -102,19 +102,12 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
        {"_SB_", ACPI_TYPE_DEVICE, NULL},
        {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
        {"_TZ_", ACPI_TYPE_DEVICE, NULL},
-       /*
-        * March, 2015:
-        * The _REV object is in the process of being deprecated, because
-        * other ACPI implementations permanently return 2. Thus, it
-        * has little or no value. Return 2 for compatibility with
-        * other ACPI implementations.
-        */
-       {"_REV", ACPI_TYPE_INTEGER, ACPI_CAST_PTR(char, 2)},
+       {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
        {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
-       {"_GL_", ACPI_TYPE_MUTEX, ACPI_CAST_PTR(char, 1)},
+       {"_GL_", ACPI_TYPE_MUTEX, (char *)1},
 
 #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
-       {"_OSI", ACPI_TYPE_METHOD, ACPI_CAST_PTR(char, 1)},
+       {"_OSI", ACPI_TYPE_METHOD, (char *)1},
 #endif
 
        /* Table terminator */
index 39748bb3a5430111b8cf4723462eb837137b0213..7ccba395c9ddbeb7a6725b336d69d01abd4b82b1 100644 (file)
@@ -182,7 +182,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas,
                request_mem_region(addr, length, desc);
 }
 
-static int __init acpi_reserve_resources(void)
+static void __init acpi_reserve_resources(void)
 {
        acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
                "ACPI PM1a_EVT_BLK");
@@ -211,10 +211,7 @@ static int __init acpi_reserve_resources(void)
        if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
                acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
                               acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
-
-       return 0;
 }
-device_initcall(acpi_reserve_resources);
 
 void acpi_os_printf(const char *fmt, ...)
 {
@@ -1845,6 +1842,7 @@ acpi_status __init acpi_os_initialize(void)
 
 acpi_status __init acpi_os_initialize1(void)
 {
+       acpi_reserve_resources();
        kacpid_wq = alloc_workqueue("kacpid", 0, 1);
        kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
        kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
index 5f601553b9b043fff9ac80552ab55dbc4173c714..9dca4b995be0792b6c4f1920b9786cb6517a2b5f 100644 (file)
@@ -270,6 +270,7 @@ config ATA_PIIX
 config SATA_DWC
        tristate "DesignWare Cores SATA support"
        depends on 460EX
+       select DW_DMAC
        help
          This option enables support for the on-chip SATA controller of the
          AppliedMicro processor 460EX.
@@ -729,15 +730,6 @@ config PATA_SC1200
 
          If unsure, say N.
 
-config PATA_SCC
-       tristate "Toshiba's Cell Reference Set IDE support"
-       depends on PCI && PPC_CELLEB
-       help
-         This option enables support for the built-in IDE controller on
-         Toshiba Cell Reference Board.
-
-         If unsure, say N.
-
 config PATA_SCH
        tristate "Intel SCH PATA support"
        depends on PCI
index b67e995179a947bcdda7e5bf6f5d95275841ad49..40f7865f20a1dbf62123da6998fcef81fa9a2690 100644 (file)
@@ -75,7 +75,6 @@ obj-$(CONFIG_PATA_PDC_OLD)    += pata_pdc202xx_old.o
 obj-$(CONFIG_PATA_RADISYS)     += pata_radisys.o
 obj-$(CONFIG_PATA_RDC)         += pata_rdc.o
 obj-$(CONFIG_PATA_SC1200)      += pata_sc1200.o
-obj-$(CONFIG_PATA_SCC)         += pata_scc.o
 obj-$(CONFIG_PATA_SCH)         += pata_sch.o
 obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
 obj-$(CONFIG_PATA_SIL680)      += pata_sil680.o
index c7a92a743ed035e9af81ac779180fc65456a8390..65ee94454bbd2c92f1879386b19a346a5632794f 100644 (file)
@@ -66,6 +66,7 @@ enum board_ids {
        board_ahci_yes_fbs,
 
        /* board IDs for specific chipsets in alphabetical order */
+       board_ahci_avn,
        board_ahci_mcp65,
        board_ahci_mcp77,
        board_ahci_mcp89,
@@ -84,6 +85,8 @@ enum board_ids {
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
                                 unsigned long deadline);
+static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
+                             unsigned long deadline);
 static void ahci_mcp89_apple_enable(struct pci_dev *pdev);
 static bool is_mcp89_apple(struct pci_dev *pdev);
 static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
@@ -107,6 +110,11 @@ static struct ata_port_operations ahci_p5wdh_ops = {
        .hardreset              = ahci_p5wdh_hardreset,
 };
 
+static struct ata_port_operations ahci_avn_ops = {
+       .inherits               = &ahci_ops,
+       .hardreset              = ahci_avn_hardreset,
+};
+
 static const struct ata_port_info ahci_port_info[] = {
        /* by features */
        [board_ahci] = {
@@ -151,6 +159,12 @@ static const struct ata_port_info ahci_port_info[] = {
                .port_ops       = &ahci_ops,
        },
        /* by chipsets */
+       [board_ahci_avn] = {
+               .flags          = AHCI_FLAG_COMMON,
+               .pio_mask       = ATA_PIO4,
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &ahci_avn_ops,
+       },
        [board_ahci_mcp65] = {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
                                 AHCI_HFLAG_YES_NCQ),
@@ -290,14 +304,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */
-       { PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */
-       { PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
-       { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f32), board_ahci_avn }, /* Avoton AHCI */
+       { PCI_VDEVICE(INTEL, 0x1f33), board_ahci_avn }, /* Avoton AHCI */
+       { PCI_VDEVICE(INTEL, 0x1f34), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f35), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f36), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */
+       { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */
        { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */
        { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */
        { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
@@ -670,6 +684,79 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
        return rc;
 }
 
+/*
+ * ahci_avn_hardreset - attempt more aggressive recovery of Avoton ports.
+ *
+ * It has been observed with some SSDs that the timing of events in the
+ * link synchronization phase can leave the port in a state that can not
+ * be recovered by a SATA-hard-reset alone.  The failing signature is
+ * SStatus.DET stuck at 1 ("Device presence detected but Phy
+ * communication not established").  It was found that unloading and
+ * reloading the driver when this problem occurs allows the drive
+ * connection to be recovered (DET advanced to 0x3).  The critical
+ * component of reloading the driver is that the port state machines are
+ * reset by bouncing "port enable" in the AHCI PCS configuration
+ * register.  So, reproduce that effect by bouncing a port whenever we
+ * see DET==1 after a reset.
+ */
+static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
+                             unsigned long deadline)
+{
+       const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+       struct ata_port *ap = link->ap;
+       struct ahci_port_priv *pp = ap->private_data;
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+       unsigned long tmo = deadline - jiffies;
+       struct ata_taskfile tf;
+       bool online;
+       int rc, i;
+
+       DPRINTK("ENTER\n");
+
+       ahci_stop_engine(ap);
+
+       for (i = 0; i < 2; i++) {
+               u16 val;
+               u32 sstatus;
+               int port = ap->port_no;
+               struct ata_host *host = ap->host;
+               struct pci_dev *pdev = to_pci_dev(host->dev);
+
+               /* clear D2H reception area to properly wait for D2H FIS */
+               ata_tf_init(link->device, &tf);
+               tf.command = ATA_BUSY;
+               ata_tf_to_fis(&tf, 0, 0, d2h_fis);
+
+               rc = sata_link_hardreset(link, timing, deadline, &online,
+                               ahci_check_ready);
+
+               if (sata_scr_read(link, SCR_STATUS, &sstatus) != 0 ||
+                               (sstatus & 0xf) != 1)
+                       break;
+
+               ata_link_printk(link, KERN_INFO, "avn bounce port%d\n",
+                               port);
+
+               pci_read_config_word(pdev, 0x92, &val);
+               val &= ~(1 << port);
+               pci_write_config_word(pdev, 0x92, val);
+               ata_msleep(ap, 1000);
+               val |= 1 << port;
+               pci_write_config_word(pdev, 0x92, val);
+               deadline += tmo;
+       }
+
+       hpriv->start_engine(ap);
+
+       if (online)
+               *class = ahci_dev_classify(ap);
+
+       DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
+       return rc;
+}
+
+
 #ifdef CONFIG_PM
 static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
index ea0ff005b86ce702e4ccd0224c5b8f14c0fcfc89..8ff428fe8e0fa00659218f58f041cf948ae8327c 100644 (file)
@@ -37,7 +37,6 @@ struct st_ahci_drv_data {
        struct reset_control *pwr;
        struct reset_control *sw_rst;
        struct reset_control *pwr_rst;
-       struct ahci_host_priv *hpriv;
 };
 
 static void st_ahci_configure_oob(void __iomem *mmio)
@@ -55,9 +54,10 @@ static void st_ahci_configure_oob(void __iomem *mmio)
        writel(new_val, mmio + ST_AHCI_OOBR);
 }
 
-static int st_ahci_deassert_resets(struct device *dev)
+static int st_ahci_deassert_resets(struct ahci_host_priv *hpriv,
+                               struct device *dev)
 {
-       struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
+       struct st_ahci_drv_data *drv_data = hpriv->plat_data;
        int err;
 
        if (drv_data->pwr) {
@@ -90,8 +90,8 @@ static int st_ahci_deassert_resets(struct device *dev)
 static void st_ahci_host_stop(struct ata_host *host)
 {
        struct ahci_host_priv *hpriv = host->private_data;
+       struct st_ahci_drv_data *drv_data = hpriv->plat_data;
        struct device *dev = host->dev;
-       struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
        int err;
 
        if (drv_data->pwr) {
@@ -103,29 +103,30 @@ static void st_ahci_host_stop(struct ata_host *host)
        ahci_platform_disable_resources(hpriv);
 }
 
-static int st_ahci_probe_resets(struct platform_device *pdev)
+static int st_ahci_probe_resets(struct ahci_host_priv *hpriv,
+                               struct device *dev)
 {
-       struct st_ahci_drv_data *drv_data = platform_get_drvdata(pdev);
+       struct st_ahci_drv_data *drv_data = hpriv->plat_data;
 
-       drv_data->pwr = devm_reset_control_get(&pdev->dev, "pwr-dwn");
+       drv_data->pwr = devm_reset_control_get(dev, "pwr-dwn");
        if (IS_ERR(drv_data->pwr)) {
-               dev_info(&pdev->dev, "power reset control not defined\n");
+               dev_info(dev, "power reset control not defined\n");
                drv_data->pwr = NULL;
        }
 
-       drv_data->sw_rst = devm_reset_control_get(&pdev->dev, "sw-rst");
+       drv_data->sw_rst = devm_reset_control_get(dev, "sw-rst");
        if (IS_ERR(drv_data->sw_rst)) {
-               dev_info(&pdev->dev, "soft reset control not defined\n");
+               dev_info(dev, "soft reset control not defined\n");
                drv_data->sw_rst = NULL;
        }
 
-       drv_data->pwr_rst = devm_reset_control_get(&pdev->dev, "pwr-rst");
+       drv_data->pwr_rst = devm_reset_control_get(dev, "pwr-rst");
        if (IS_ERR(drv_data->pwr_rst)) {
-               dev_dbg(&pdev->dev, "power soft reset control not defined\n");
+               dev_dbg(dev, "power soft reset control not defined\n");
                drv_data->pwr_rst = NULL;
        }
 
-       return st_ahci_deassert_resets(&pdev->dev);
+       return st_ahci_deassert_resets(hpriv, dev);
 }
 
 static struct ata_port_operations st_ahci_port_ops = {
@@ -154,15 +155,12 @@ static int st_ahci_probe(struct platform_device *pdev)
        if (!drv_data)
                return -ENOMEM;
 
-       platform_set_drvdata(pdev, drv_data);
-
        hpriv = ahci_platform_get_resources(pdev);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
+       hpriv->plat_data = drv_data;
 
-       drv_data->hpriv = hpriv;
-
-       err = st_ahci_probe_resets(pdev);
+       err = st_ahci_probe_resets(hpriv, &pdev->dev);
        if (err)
                return err;
 
@@ -170,7 +168,7 @@ static int st_ahci_probe(struct platform_device *pdev)
        if (err)
                return err;
 
-       st_ahci_configure_oob(drv_data->hpriv->mmio);
+       st_ahci_configure_oob(hpriv->mmio);
 
        err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
                                      &ahci_platform_sht);
@@ -185,8 +183,9 @@ static int st_ahci_probe(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int st_ahci_suspend(struct device *dev)
 {
-       struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
-       struct ahci_host_priv *hpriv = drv_data->hpriv;
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct ahci_host_priv *hpriv = host->private_data;
+       struct st_ahci_drv_data *drv_data = hpriv->plat_data;
        int err;
 
        err = ahci_platform_suspend_host(dev);
@@ -208,21 +207,21 @@ static int st_ahci_suspend(struct device *dev)
 
 static int st_ahci_resume(struct device *dev)
 {
-       struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
-       struct ahci_host_priv *hpriv = drv_data->hpriv;
+       struct ata_host *host = dev_get_drvdata(dev);
+       struct ahci_host_priv *hpriv = host->private_data;
        int err;
 
        err = ahci_platform_enable_resources(hpriv);
        if (err)
                return err;
 
-       err = st_ahci_deassert_resets(dev);
+       err = st_ahci_deassert_resets(hpriv, dev);
        if (err) {
                ahci_platform_disable_resources(hpriv);
                return err;
        }
 
-       st_ahci_configure_oob(drv_data->hpriv->mmio);
+       st_ahci_configure_oob(hpriv->mmio);
 
        return ahci_platform_resume_host(dev);
 }
index 61a9c07e0dff5b277dba35cfa135bac449f9ce84..287c4ba0219f7ced8c76af999dd1eeb3e5ed2639 100644 (file)
@@ -1707,8 +1707,7 @@ static void ahci_handle_port_interrupt(struct ata_port *ap,
        if (unlikely(resetting))
                status &= ~PORT_IRQ_BAD_PMP;
 
-       /* if LPM is enabled, PHYRDY doesn't mean anything */
-       if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) {
+       if (sata_lpm_ignore_phy_events(&ap->link)) {
                status &= ~PORT_IRQ_PHYRDY;
                ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG);
        }
index f6cb1f1b30b7466278d47dae09bc959db24dfef1..577849c6611ac5efa2c948c7b274dc894a19890d 100644 (file)
@@ -4235,7 +4235,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
        { "Crucial_CT*MX100*",          "MU01", ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
-       { "Samsung SSD 850 PRO*",       NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
+       { "Samsung SSD 8*",             NULL,   ATA_HORKAGE_NO_NCQ_TRIM |
                                                ATA_HORKAGE_ZERO_AFTER_TRIM, },
 
        /*
@@ -6752,6 +6752,38 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val,
        return tmp;
 }
 
+/**
+ *     sata_lpm_ignore_phy_events - test if PHY event should be ignored
+ *     @link: Link receiving the event
+ *
+ *     Test whether the received PHY event has to be ignored or not.
+ *
+ *     LOCKING:
+ *     None:
+ *
+ *     RETURNS:
+ *     True if the event has to be ignored.
+ */
+bool sata_lpm_ignore_phy_events(struct ata_link *link)
+{
+       unsigned long lpm_timeout = link->last_lpm_change +
+                                   msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY);
+
+       /* if LPM is enabled, PHYRDY doesn't mean anything */
+       if (link->lpm_policy > ATA_LPM_MAX_POWER)
+               return true;
+
+       /* ignore the first PHY event after the LPM policy changed
+        * as it is might be spurious
+        */
+       if ((link->flags & ATA_LFLAG_CHANGED) &&
+           time_before(jiffies, lpm_timeout))
+               return true;
+
+       return false;
+}
+EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events);
+
 /*
  * Dummy port_ops
  */
index 07f41be38fbe556ffff9bd5efcacf8ed4538034e..cf0022ec07f2420c37fb8a52dc904530f0df2e38 100644 (file)
@@ -3597,6 +3597,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
                }
        }
 
+       link->last_lpm_change = jiffies;
+       link->flags |= ATA_LFLAG_CHANGED;
+
        return 0;
 
 fail:
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
deleted file mode 100644 (file)
index 5cd60d6..0000000
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- * Support for IDE interfaces on Celleb platform
- *
- * (C) Copyright 2006 TOSHIBA CORPORATION
- *
- * This code is based on drivers/ata/ata_piix.c:
- *  Copyright 2003-2005 Red Hat Inc
- *  Copyright 2003-2005 Jeff Garzik
- *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
- *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
- *  Copyright (C) 2003 Red Hat Inc
- *
- * and drivers/ata/ahci.c:
- *  Copyright 2004-2005 Red Hat, Inc.
- *
- * and drivers/ata/libata-core.c:
- *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved.
- *  Copyright 2003-2004 Jeff Garzik
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <scsi/scsi_host.h>
-#include <linux/libata.h>
-
-#define DRV_NAME               "pata_scc"
-#define DRV_VERSION            "0.3"
-
-#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA          0x01b4
-
-/* PCI BARs */
-#define SCC_CTRL_BAR           0
-#define SCC_BMID_BAR           1
-
-/* offset of CTRL registers */
-#define SCC_CTL_PIOSHT         0x000
-#define SCC_CTL_PIOCT          0x004
-#define SCC_CTL_MDMACT         0x008
-#define SCC_CTL_MCRCST         0x00C
-#define SCC_CTL_SDMACT         0x010
-#define SCC_CTL_SCRCST         0x014
-#define SCC_CTL_UDENVT         0x018
-#define SCC_CTL_TDVHSEL        0x020
-#define SCC_CTL_MODEREG        0x024
-#define SCC_CTL_ECMODE         0xF00
-#define SCC_CTL_MAEA0          0xF50
-#define SCC_CTL_MAEC0          0xF54
-#define SCC_CTL_CCKCTRL        0xFF0
-
-/* offset of BMID registers */
-#define SCC_DMA_CMD            0x000
-#define SCC_DMA_STATUS         0x004
-#define SCC_DMA_TABLE_OFS      0x008
-#define SCC_DMA_INTMASK        0x010
-#define SCC_DMA_INTST          0x014
-#define SCC_DMA_PTERADD        0x018
-#define SCC_REG_CMD_ADDR       0x020
-#define SCC_REG_DATA           0x000
-#define SCC_REG_ERR            0x004
-#define SCC_REG_FEATURE        0x004
-#define SCC_REG_NSECT          0x008
-#define SCC_REG_LBAL           0x00C
-#define SCC_REG_LBAM           0x010
-#define SCC_REG_LBAH           0x014
-#define SCC_REG_DEVICE         0x018
-#define SCC_REG_STATUS         0x01C
-#define SCC_REG_CMD            0x01C
-#define SCC_REG_ALTSTATUS      0x020
-
-/* register value */
-#define TDVHSEL_MASTER         0x00000001
-#define TDVHSEL_SLAVE          0x00000004
-
-#define MODE_JCUSFEN           0x00000080
-
-#define ECMODE_VALUE           0x01
-
-#define CCKCTRL_ATARESET       0x00040000
-#define CCKCTRL_BUFCNT         0x00020000
-#define CCKCTRL_CRST           0x00010000
-#define CCKCTRL_OCLKEN         0x00000100
-#define CCKCTRL_ATACLKOEN      0x00000002
-#define CCKCTRL_LCLKEN         0x00000001
-
-#define QCHCD_IOS_SS           0x00000001
-
-#define QCHSD_STPDIAG          0x00020000
-
-#define INTMASK_MSK            0xD1000012
-#define INTSTS_SERROR          0x80000000
-#define INTSTS_PRERR           0x40000000
-#define INTSTS_RERR            0x10000000
-#define INTSTS_ICERR           0x01000000
-#define INTSTS_BMSINT          0x00000010
-#define INTSTS_BMHE            0x00000008
-#define INTSTS_IOIRQS          0x00000004
-#define INTSTS_INTRQ           0x00000002
-#define INTSTS_ACTEINT         0x00000001
-
-
-/* PIO transfer mode table */
-/* JCHST */
-static const unsigned long JCHSTtbl[2][7] = {
-       {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00},     /* 100MHz */
-       {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00}      /* 133MHz */
-};
-
-/* JCHHT */
-static const unsigned long JCHHTtbl[2][7] = {
-       {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00},     /* 100MHz */
-       {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}      /* 133MHz */
-};
-
-/* JCHCT */
-static const unsigned long JCHCTtbl[2][7] = {
-       {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00},     /* 100MHz */
-       {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00}      /* 133MHz */
-};
-
-/* DMA transfer mode  table */
-/* JCHDCTM/JCHDCTS */
-static const unsigned long JCHDCTxtbl[2][7] = {
-       {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00},     /* 100MHz */
-       {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00}      /* 133MHz */
-};
-
-/* JCSTWTM/JCSTWTS  */
-static const unsigned long JCSTWTxtbl[2][7] = {
-       {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00},     /* 100MHz */
-       {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02}      /* 133MHz */
-};
-
-/* JCTSS */
-static const unsigned long JCTSStbl[2][7] = {
-       {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00},     /* 100MHz */
-       {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}      /* 133MHz */
-};
-
-/* JCENVT */
-static const unsigned long JCENVTtbl[2][7] = {
-       {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00},     /* 100MHz */
-       {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}      /* 133MHz */
-};
-
-/* JCACTSELS/JCACTSELM */
-static const unsigned long JCACTSELtbl[2][7] = {
-       {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00},     /* 100MHz */
-       {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}      /* 133MHz */
-};
-
-static const struct pci_device_id scc_pci_tbl[] = {
-       { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0},
-       { }     /* terminate list */
-};
-
-/**
- *     scc_set_piomode - Initialize host controller PATA PIO timings
- *     @ap: Port whose timings we are configuring
- *     @adev: um
- *
- *     Set PIO mode for device.
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev)
-{
-       unsigned int pio = adev->pio_mode - XFER_PIO_0;
-       void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
-       void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
-       void __iomem *piosht_port = ctrl_base + SCC_CTL_PIOSHT;
-       void __iomem *pioct_port = ctrl_base + SCC_CTL_PIOCT;
-       unsigned long reg;
-       int offset;
-
-       reg = in_be32(cckctrl_port);
-       if (reg & CCKCTRL_ATACLKOEN)
-               offset = 1;     /* 133MHz */
-       else
-               offset = 0;     /* 100MHz */
-
-       reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio];
-       out_be32(piosht_port, reg);
-       reg = JCHCTtbl[offset][pio];
-       out_be32(pioct_port, reg);
-}
-
-/**
- *     scc_set_dmamode - Initialize host controller PATA DMA timings
- *     @ap: Port whose timings we are configuring
- *     @adev: um
- *
- *     Set UDMA mode for device.
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev)
-{
-       unsigned int udma = adev->dma_mode;
-       unsigned int is_slave = (adev->devno != 0);
-       u8 speed = udma;
-       void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
-       void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
-       void __iomem *mdmact_port = ctrl_base + SCC_CTL_MDMACT;
-       void __iomem *mcrcst_port = ctrl_base + SCC_CTL_MCRCST;
-       void __iomem *sdmact_port = ctrl_base + SCC_CTL_SDMACT;
-       void __iomem *scrcst_port = ctrl_base + SCC_CTL_SCRCST;
-       void __iomem *udenvt_port = ctrl_base + SCC_CTL_UDENVT;
-       void __iomem *tdvhsel_port = ctrl_base + SCC_CTL_TDVHSEL;
-       int offset, idx;
-
-       if (in_be32(cckctrl_port) & CCKCTRL_ATACLKOEN)
-               offset = 1;     /* 133MHz */
-       else
-               offset = 0;     /* 100MHz */
-
-       if (speed >= XFER_UDMA_0)
-               idx = speed - XFER_UDMA_0;
-       else
-               return;
-
-       if (is_slave) {
-               out_be32(sdmact_port, JCHDCTxtbl[offset][idx]);
-               out_be32(scrcst_port, JCSTWTxtbl[offset][idx]);
-               out_be32(tdvhsel_port,
-                        (in_be32(tdvhsel_port) & ~TDVHSEL_SLAVE) | (JCACTSELtbl[offset][idx] << 2));
-       } else {
-               out_be32(mdmact_port, JCHDCTxtbl[offset][idx]);
-               out_be32(mcrcst_port, JCSTWTxtbl[offset][idx]);
-               out_be32(tdvhsel_port,
-                        (in_be32(tdvhsel_port) & ~TDVHSEL_MASTER) | JCACTSELtbl[offset][idx]);
-       }
-       out_be32(udenvt_port,
-                JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]);
-}
-
-unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask)
-{
-       /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */
-       if (adev->class == ATA_DEV_ATAPI &&
-           (mask & (0xE0 << ATA_SHIFT_UDMA))) {
-               printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
-               mask &= ~(0xE0 << ATA_SHIFT_UDMA);
-       }
-       return mask;
-}
-
-/**
- *     scc_tf_load - send taskfile registers to host controller
- *     @ap: Port to which output is sent
- *     @tf: ATA taskfile register set
- *
- *     Note: Original code is ata_sff_tf_load().
- */
-
-static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-
-       if (tf->ctl != ap->last_ctl) {
-               out_be32(ioaddr->ctl_addr, tf->ctl);
-               ap->last_ctl = tf->ctl;
-               ata_wait_idle(ap);
-       }
-
-       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-               out_be32(ioaddr->feature_addr, tf->hob_feature);
-               out_be32(ioaddr->nsect_addr, tf->hob_nsect);
-               out_be32(ioaddr->lbal_addr, tf->hob_lbal);
-               out_be32(ioaddr->lbam_addr, tf->hob_lbam);
-               out_be32(ioaddr->lbah_addr, tf->hob_lbah);
-               VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
-                       tf->hob_feature,
-                       tf->hob_nsect,
-                       tf->hob_lbal,
-                       tf->hob_lbam,
-                       tf->hob_lbah);
-       }
-
-       if (is_addr) {
-               out_be32(ioaddr->feature_addr, tf->feature);
-               out_be32(ioaddr->nsect_addr, tf->nsect);
-               out_be32(ioaddr->lbal_addr, tf->lbal);
-               out_be32(ioaddr->lbam_addr, tf->lbam);
-               out_be32(ioaddr->lbah_addr, tf->lbah);
-               VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
-                       tf->feature,
-                       tf->nsect,
-                       tf->lbal,
-                       tf->lbam,
-                       tf->lbah);
-       }
-
-       if (tf->flags & ATA_TFLAG_DEVICE) {
-               out_be32(ioaddr->device_addr, tf->device);
-               VPRINTK("device 0x%X\n", tf->device);
-       }
-
-       ata_wait_idle(ap);
-}
-
-/**
- *     scc_check_status - Read device status reg & clear interrupt
- *     @ap: port where the device is
- *
- *     Note: Original code is ata_check_status().
- */
-
-static u8 scc_check_status (struct ata_port *ap)
-{
-       return in_be32(ap->ioaddr.status_addr);
-}
-
-/**
- *     scc_tf_read - input device's ATA taskfile shadow registers
- *     @ap: Port from which input is read
- *     @tf: ATA taskfile register set for storing input
- *
- *     Note: Original code is ata_sff_tf_read().
- */
-
-static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-       tf->command = scc_check_status(ap);
-       tf->feature = in_be32(ioaddr->error_addr);
-       tf->nsect = in_be32(ioaddr->nsect_addr);
-       tf->lbal = in_be32(ioaddr->lbal_addr);
-       tf->lbam = in_be32(ioaddr->lbam_addr);
-       tf->lbah = in_be32(ioaddr->lbah_addr);
-       tf->device = in_be32(ioaddr->device_addr);
-
-       if (tf->flags & ATA_TFLAG_LBA48) {
-               out_be32(ioaddr->ctl_addr, tf->ctl | ATA_HOB);
-               tf->hob_feature = in_be32(ioaddr->error_addr);
-               tf->hob_nsect = in_be32(ioaddr->nsect_addr);
-               tf->hob_lbal = in_be32(ioaddr->lbal_addr);
-               tf->hob_lbam = in_be32(ioaddr->lbam_addr);
-               tf->hob_lbah = in_be32(ioaddr->lbah_addr);
-               out_be32(ioaddr->ctl_addr, tf->ctl);
-               ap->last_ctl = tf->ctl;
-       }
-}
-
-/**
- *     scc_exec_command - issue ATA command to host controller
- *     @ap: port to which command is being issued
- *     @tf: ATA taskfile register set
- *
- *     Note: Original code is ata_sff_exec_command().
- */
-
-static void scc_exec_command (struct ata_port *ap,
-                             const struct ata_taskfile *tf)
-{
-       DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
-
-       out_be32(ap->ioaddr.command_addr, tf->command);
-       ata_sff_pause(ap);
-}
-
-/**
- *     scc_check_altstatus - Read device alternate status reg
- *     @ap: port where the device is
- */
-
-static u8 scc_check_altstatus (struct ata_port *ap)
-{
-       return in_be32(ap->ioaddr.altstatus_addr);
-}
-
-/**
- *     scc_dev_select - Select device 0/1 on ATA bus
- *     @ap: ATA channel to manipulate
- *     @device: ATA device (numbered from zero) to select
- *
- *     Note: Original code is ata_sff_dev_select().
- */
-
-static void scc_dev_select (struct ata_port *ap, unsigned int device)
-{
-       u8 tmp;
-
-       if (device == 0)
-               tmp = ATA_DEVICE_OBS;
-       else
-               tmp = ATA_DEVICE_OBS | ATA_DEV1;
-
-       out_be32(ap->ioaddr.device_addr, tmp);
-       ata_sff_pause(ap);
-}
-
-/**
- *     scc_set_devctl - Write device control reg
- *     @ap: port where the device is
- *     @ctl: value to write
- */
-
-static void scc_set_devctl(struct ata_port *ap, u8 ctl)
-{
-       out_be32(ap->ioaddr.ctl_addr, ctl);
-}
-
-/**
- *     scc_bmdma_setup - Set up PCI IDE BMDMA transaction
- *     @qc: Info associated with this ATA transaction.
- *
- *     Note: Original code is ata_bmdma_setup().
- */
-
-static void scc_bmdma_setup (struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
-       u8 dmactl;
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       /* load PRD table addr */
-       out_be32(mmio + SCC_DMA_TABLE_OFS, ap->bmdma_prd_dma);
-
-       /* specify data direction, triple-check start bit is clear */
-       dmactl = in_be32(mmio + SCC_DMA_CMD);
-       dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
-       if (!rw)
-               dmactl |= ATA_DMA_WR;
-       out_be32(mmio + SCC_DMA_CMD, dmactl);
-
-       /* issue r/w command */
-       ap->ops->sff_exec_command(ap, &qc->tf);
-}
-
-/**
- *     scc_bmdma_start - Start a PCI IDE BMDMA transaction
- *     @qc: Info associated with this ATA transaction.
- *
- *     Note: Original code is ata_bmdma_start().
- */
-
-static void scc_bmdma_start (struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       u8 dmactl;
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       /* start host DMA transaction */
-       dmactl = in_be32(mmio + SCC_DMA_CMD);
-       out_be32(mmio + SCC_DMA_CMD, dmactl | ATA_DMA_START);
-}
-
-/**
- *     scc_devchk - PATA device presence detection
- *     @ap: ATA channel to examine
- *     @device: Device to examine (starting at zero)
- *
- *     Note: Original code is ata_devchk().
- */
-
-static unsigned int scc_devchk (struct ata_port *ap,
-                               unsigned int device)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       u8 nsect, lbal;
-
-       ap->ops->sff_dev_select(ap, device);
-
-       out_be32(ioaddr->nsect_addr, 0x55);
-       out_be32(ioaddr->lbal_addr, 0xaa);
-
-       out_be32(ioaddr->nsect_addr, 0xaa);
-       out_be32(ioaddr->lbal_addr, 0x55);
-
-       out_be32(ioaddr->nsect_addr, 0x55);
-       out_be32(ioaddr->lbal_addr, 0xaa);
-
-       nsect = in_be32(ioaddr->nsect_addr);
-       lbal = in_be32(ioaddr->lbal_addr);
-
-       if ((nsect == 0x55) && (lbal == 0xaa))
-               return 1;       /* we found a device */
-
-       return 0;               /* nothing found */
-}
-
-/**
- *     scc_wait_after_reset - wait for devices to become ready after reset
- *
- *     Note: Original code is ata_sff_wait_after_reset
- */
-
-static int scc_wait_after_reset(struct ata_link *link, unsigned int devmask,
-                               unsigned long deadline)
-{
-       struct ata_port *ap = link->ap;
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int dev0 = devmask & (1 << 0);
-       unsigned int dev1 = devmask & (1 << 1);
-       int rc, ret = 0;
-
-       /* Spec mandates ">= 2ms" before checking status.  We wait
-        * 150ms, because that was the magic delay used for ATAPI
-        * devices in Hale Landis's ATADRVR, for the period of time
-        * between when the ATA command register is written, and then
-        * status is checked.  Because waiting for "a while" before
-        * checking status is fine, post SRST, we perform this magic
-        * delay here as well.
-        *
-        * Old drivers/ide uses the 2mS rule and then waits for ready.
-        */
-       ata_msleep(ap, 150);
-
-       /* always check readiness of the master device */
-       rc = ata_sff_wait_ready(link, deadline);
-       /* -ENODEV means the odd clown forgot the D7 pulldown resistor
-        * and TF status is 0xff, bail out on it too.
-        */
-       if (rc)
-               return rc;
-
-       /* if device 1 was found in ata_devchk, wait for register
-        * access briefly, then wait for BSY to clear.
-        */
-       if (dev1) {
-               int i;
-
-               ap->ops->sff_dev_select(ap, 1);
-
-               /* Wait for register access.  Some ATAPI devices fail
-                * to set nsect/lbal after reset, so don't waste too
-                * much time on it.  We're gonna wait for !BSY anyway.
-                */
-               for (i = 0; i < 2; i++) {
-                       u8 nsect, lbal;
-
-                       nsect = in_be32(ioaddr->nsect_addr);
-                       lbal = in_be32(ioaddr->lbal_addr);
-                       if ((nsect == 1) && (lbal == 1))
-                               break;
-                       ata_msleep(ap, 50);     /* give drive a breather */
-               }
-
-               rc = ata_sff_wait_ready(link, deadline);
-               if (rc) {
-                       if (rc != -ENODEV)
-                               return rc;
-                       ret = rc;
-               }
-       }
-
-       /* is all this really necessary? */
-       ap->ops->sff_dev_select(ap, 0);
-       if (dev1)
-               ap->ops->sff_dev_select(ap, 1);
-       if (dev0)
-               ap->ops->sff_dev_select(ap, 0);
-
-       return ret;
-}
-
-/**
- *     scc_bus_softreset - PATA device software reset
- *
- *     Note: Original code is ata_bus_softreset().
- */
-
-static int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
-                                      unsigned long deadline)
-{
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-
-       DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
-
-       /* software reset.  causes dev0 to be selected */
-       out_be32(ioaddr->ctl_addr, ap->ctl);
-       udelay(20);
-       out_be32(ioaddr->ctl_addr, ap->ctl | ATA_SRST);
-       udelay(20);
-       out_be32(ioaddr->ctl_addr, ap->ctl);
-
-       return scc_wait_after_reset(&ap->link, devmask, deadline);
-}
-
-/**
- *     scc_softreset - reset host port via ATA SRST
- *     @ap: port to reset
- *     @classes: resulting classes of attached devices
- *     @deadline: deadline jiffies for the operation
- *
- *     Note: Original code is ata_sff_softreset().
- */
-
-static int scc_softreset(struct ata_link *link, unsigned int *classes,
-                        unsigned long deadline)
-{
-       struct ata_port *ap = link->ap;
-       unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
-       unsigned int devmask = 0;
-       int rc;
-       u8 err;
-
-       DPRINTK("ENTER\n");
-
-       /* determine if device 0/1 are present */
-       if (scc_devchk(ap, 0))
-               devmask |= (1 << 0);
-       if (slave_possible && scc_devchk(ap, 1))
-               devmask |= (1 << 1);
-
-       /* select device 0 again */
-       ap->ops->sff_dev_select(ap, 0);
-
-       /* issue bus reset */
-       DPRINTK("about to softreset, devmask=%x\n", devmask);
-       rc = scc_bus_softreset(ap, devmask, deadline);
-       if (rc) {
-               ata_port_err(ap, "SRST failed (err_mask=0x%x)\n", rc);
-               return -EIO;
-       }
-
-       /* determine by signature whether we have ATA or ATAPI devices */
-       classes[0] = ata_sff_dev_classify(&ap->link.device[0],
-                                         devmask & (1 << 0), &err);
-       if (slave_possible && err != 0x81)
-               classes[1] = ata_sff_dev_classify(&ap->link.device[1],
-                                                 devmask & (1 << 1), &err);
-
-       DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
-       return 0;
-}
-
-/**
- *     scc_bmdma_stop - Stop PCI IDE BMDMA transfer
- *     @qc: Command we are ending DMA for
- */
-
-static void scc_bmdma_stop (struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       void __iomem *ctrl_base = ap->host->iomap[SCC_CTRL_BAR];
-       void __iomem *bmid_base = ap->host->iomap[SCC_BMID_BAR];
-       u32 reg;
-
-       while (1) {
-               reg = in_be32(bmid_base + SCC_DMA_INTST);
-
-               if (reg & INTSTS_SERROR) {
-                       printk(KERN_WARNING "%s: SERROR\n", DRV_NAME);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_SERROR|INTSTS_BMSINT);
-                       out_be32(bmid_base + SCC_DMA_CMD,
-                                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-                       continue;
-               }
-
-               if (reg & INTSTS_PRERR) {
-                       u32 maea0, maec0;
-                       maea0 = in_be32(ctrl_base + SCC_CTL_MAEA0);
-                       maec0 = in_be32(ctrl_base + SCC_CTL_MAEC0);
-                       printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", DRV_NAME, maea0, maec0);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_PRERR|INTSTS_BMSINT);
-                       out_be32(bmid_base + SCC_DMA_CMD,
-                                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-                       continue;
-               }
-
-               if (reg & INTSTS_RERR) {
-                       printk(KERN_WARNING "%s: Response Error\n", DRV_NAME);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_RERR|INTSTS_BMSINT);
-                       out_be32(bmid_base + SCC_DMA_CMD,
-                                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-                       continue;
-               }
-
-               if (reg & INTSTS_ICERR) {
-                       out_be32(bmid_base + SCC_DMA_CMD,
-                                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-                       printk(KERN_WARNING "%s: Illegal Configuration\n", DRV_NAME);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ICERR|INTSTS_BMSINT);
-                       continue;
-               }
-
-               if (reg & INTSTS_BMSINT) {
-                       unsigned int classes;
-                       unsigned long deadline = ata_deadline(jiffies, ATA_TMOUT_BOOT);
-                       printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
-                       /* TBD: SW reset */
-                       scc_softreset(&ap->link, &classes, deadline);
-                       continue;
-               }
-
-               if (reg & INTSTS_BMHE) {
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMHE);
-                       continue;
-               }
-
-               if (reg & INTSTS_ACTEINT) {
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_ACTEINT);
-                       continue;
-               }
-
-               if (reg & INTSTS_IOIRQS) {
-                       out_be32(bmid_base + SCC_DMA_INTST, INTSTS_IOIRQS);
-                       continue;
-               }
-               break;
-       }
-
-       /* clear start/stop bit */
-       out_be32(bmid_base + SCC_DMA_CMD,
-                in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
-
-       /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-       ata_sff_dma_pause(ap);  /* dummy read */
-}
-
-/**
- *     scc_bmdma_status - Read PCI IDE BMDMA status
- *     @ap: Port associated with this ATA transaction.
- */
-
-static u8 scc_bmdma_status (struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-       u8 host_stat = in_be32(mmio + SCC_DMA_STATUS);
-       u32 int_status = in_be32(mmio + SCC_DMA_INTST);
-       struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
-       static int retry = 0;
-
-       /* return if IOS_SS is cleared */
-       if (!(in_be32(mmio + SCC_DMA_CMD) & ATA_DMA_START))
-               return host_stat;
-
-       /* errata A252,A308 workaround: Step4 */
-       if ((scc_check_altstatus(ap) & ATA_ERR)
-                                       && (int_status & INTSTS_INTRQ))
-               return (host_stat | ATA_DMA_INTR);
-
-       /* errata A308 workaround Step5 */
-       if (int_status & INTSTS_IOIRQS) {
-               host_stat |= ATA_DMA_INTR;
-
-               /* We don't check ATAPI DMA because it is limited to UDMA4 */
-               if ((qc->tf.protocol == ATA_PROT_DMA &&
-                    qc->dev->xfer_mode > XFER_UDMA_4)) {
-                       if (!(int_status & INTSTS_ACTEINT)) {
-                               printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n",
-                                      ap->print_id);
-                               host_stat |= ATA_DMA_ERR;
-                               if (retry++)
-                                       ap->udma_mask &= ~(1 << qc->dev->xfer_mode);
-                       } else
-                               retry = 0;
-               }
-       }
-
-       return host_stat;
-}
-
-/**
- *     scc_data_xfer - Transfer data by PIO
- *     @dev: device for this I/O
- *     @buf: data buffer
- *     @buflen: buffer length
- *     @rw: read/write
- *
- *     Note: Original code is ata_sff_data_xfer().
- */
-
-static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf,
-                                  unsigned int buflen, int rw)
-{
-       struct ata_port *ap = dev->link->ap;
-       unsigned int words = buflen >> 1;
-       unsigned int i;
-       __le16 *buf16 = (__le16 *) buf;
-       void __iomem *mmio = ap->ioaddr.data_addr;
-
-       /* Transfer multiple of 2 bytes */
-       if (rw == READ)
-               for (i = 0; i < words; i++)
-                       buf16[i] = cpu_to_le16(in_be32(mmio));
-       else
-               for (i = 0; i < words; i++)
-                       out_be32(mmio, le16_to_cpu(buf16[i]));
-
-       /* Transfer trailing 1 byte, if any. */
-       if (unlikely(buflen & 0x01)) {
-               __le16 align_buf[1] = { 0 };
-               unsigned char *trailing_buf = buf + buflen - 1;
-
-               if (rw == READ) {
-                       align_buf[0] = cpu_to_le16(in_be32(mmio));
-                       memcpy(trailing_buf, align_buf, 1);
-               } else {
-                       memcpy(align_buf, trailing_buf, 1);
-                       out_be32(mmio, le16_to_cpu(align_buf[0]));
-               }
-               words++;
-       }
-
-       return words << 1;
-}
-
-/**
- *     scc_postreset - standard postreset callback
- *     @ap: the target ata_port
- *     @classes: classes of attached devices
- *
- *     Note: Original code is ata_sff_postreset().
- */
-
-static void scc_postreset(struct ata_link *link, unsigned int *classes)
-{
-       struct ata_port *ap = link->ap;
-
-       DPRINTK("ENTER\n");
-
-       /* is double-select really necessary? */
-       if (classes[0] != ATA_DEV_NONE)
-               ap->ops->sff_dev_select(ap, 1);
-       if (classes[1] != ATA_DEV_NONE)
-               ap->ops->sff_dev_select(ap, 0);
-
-       /* bail out if no device is present */
-       if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
-               DPRINTK("EXIT, no device\n");
-               return;
-       }
-
-       /* set up device control */
-       out_be32(ap->ioaddr.ctl_addr, ap->ctl);
-
-       DPRINTK("EXIT\n");
-}
-
-/**
- *     scc_irq_clear - Clear PCI IDE BMDMA interrupt.
- *     @ap: Port associated with this ATA transaction.
- *
- *     Note: Original code is ata_bmdma_irq_clear().
- */
-
-static void scc_irq_clear (struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       if (!mmio)
-               return;
-
-       out_be32(mmio + SCC_DMA_STATUS, in_be32(mmio + SCC_DMA_STATUS));
-}
-
-/**
- *     scc_port_start - Set port up for dma.
- *     @ap: Port to initialize
- *
- *     Allocate space for PRD table using ata_bmdma_port_start().
- *     Set PRD table address for PTERADD. (PRD Transfer End Read)
- */
-
-static int scc_port_start (struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-       int rc;
-
-       rc = ata_bmdma_port_start(ap);
-       if (rc)
-               return rc;
-
-       out_be32(mmio + SCC_DMA_PTERADD, ap->bmdma_prd_dma);
-       return 0;
-}
-
-/**
- *     scc_port_stop - Undo scc_port_start()
- *     @ap: Port to shut down
- *
- *     Reset PTERADD.
- */
-
-static void scc_port_stop (struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       out_be32(mmio + SCC_DMA_PTERADD, 0);
-}
-
-static struct scsi_host_template scc_sht = {
-       ATA_BMDMA_SHT(DRV_NAME),
-};
-
-static struct ata_port_operations scc_pata_ops = {
-       .inherits               = &ata_bmdma_port_ops,
-
-       .set_piomode            = scc_set_piomode,
-       .set_dmamode            = scc_set_dmamode,
-       .mode_filter            = scc_mode_filter,
-
-       .sff_tf_load            = scc_tf_load,
-       .sff_tf_read            = scc_tf_read,
-       .sff_exec_command       = scc_exec_command,
-       .sff_check_status       = scc_check_status,
-       .sff_check_altstatus    = scc_check_altstatus,
-       .sff_dev_select         = scc_dev_select,
-       .sff_set_devctl         = scc_set_devctl,
-
-       .bmdma_setup            = scc_bmdma_setup,
-       .bmdma_start            = scc_bmdma_start,
-       .bmdma_stop             = scc_bmdma_stop,
-       .bmdma_status           = scc_bmdma_status,
-       .sff_data_xfer          = scc_data_xfer,
-
-       .cable_detect           = ata_cable_80wire,
-       .softreset              = scc_softreset,
-       .postreset              = scc_postreset,
-
-       .sff_irq_clear          = scc_irq_clear,
-
-       .port_start             = scc_port_start,
-       .port_stop              = scc_port_stop,
-};
-
-static struct ata_port_info scc_port_info[] = {
-       {
-               .flags          = ATA_FLAG_SLAVE_POSS,
-               .pio_mask       = ATA_PIO4,
-               /* No MWDMA */
-               .udma_mask      = ATA_UDMA6,
-               .port_ops       = &scc_pata_ops,
-       },
-};
-
-/**
- *     scc_reset_controller - initialize SCC PATA controller.
- */
-
-static int scc_reset_controller(struct ata_host *host)
-{
-       void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR];
-       void __iomem *bmid_base = host->iomap[SCC_BMID_BAR];
-       void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
-       void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG;
-       void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE;
-       void __iomem *intmask_port = bmid_base + SCC_DMA_INTMASK;
-       void __iomem *dmastatus_port = bmid_base + SCC_DMA_STATUS;
-       u32 reg = 0;
-
-       out_be32(cckctrl_port, reg);
-       reg |= CCKCTRL_ATACLKOEN;
-       out_be32(cckctrl_port, reg);
-       reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
-       out_be32(cckctrl_port, reg);
-       reg |= CCKCTRL_CRST;
-       out_be32(cckctrl_port, reg);
-
-       for (;;) {
-               reg = in_be32(cckctrl_port);
-               if (reg & CCKCTRL_CRST)
-                       break;
-               udelay(5000);
-       }
-
-       reg |= CCKCTRL_ATARESET;
-       out_be32(cckctrl_port, reg);
-       out_be32(ecmode_port, ECMODE_VALUE);
-       out_be32(mode_port, MODE_JCUSFEN);
-       out_be32(intmask_port, INTMASK_MSK);
-
-       if (in_be32(dmastatus_port) & QCHSD_STPDIAG) {
-               printk(KERN_WARNING "%s: failed to detect 80c cable. (PDIAG# is high)\n", DRV_NAME);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-/**
- *     scc_setup_ports - initialize ioaddr with SCC PATA port offsets.
- *     @ioaddr: IO address structure to be initialized
- *     @base: base address of BMID region
- */
-
-static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base)
-{
-       ioaddr->cmd_addr = base + SCC_REG_CMD_ADDR;
-       ioaddr->altstatus_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS;
-       ioaddr->ctl_addr = ioaddr->cmd_addr + SCC_REG_ALTSTATUS;
-       ioaddr->bmdma_addr = base;
-       ioaddr->data_addr = ioaddr->cmd_addr + SCC_REG_DATA;
-       ioaddr->error_addr = ioaddr->cmd_addr + SCC_REG_ERR;
-       ioaddr->feature_addr = ioaddr->cmd_addr + SCC_REG_FEATURE;
-       ioaddr->nsect_addr = ioaddr->cmd_addr + SCC_REG_NSECT;
-       ioaddr->lbal_addr = ioaddr->cmd_addr + SCC_REG_LBAL;
-       ioaddr->lbam_addr = ioaddr->cmd_addr + SCC_REG_LBAM;
-       ioaddr->lbah_addr = ioaddr->cmd_addr + SCC_REG_LBAH;
-       ioaddr->device_addr = ioaddr->cmd_addr + SCC_REG_DEVICE;
-       ioaddr->status_addr = ioaddr->cmd_addr + SCC_REG_STATUS;
-       ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD;
-}
-
-static int scc_host_init(struct ata_host *host)
-{
-       struct pci_dev *pdev = to_pci_dev(host->dev);
-       int rc;
-
-       rc = scc_reset_controller(host);
-       if (rc)
-               return rc;
-
-       rc = dma_set_mask(&pdev->dev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-       rc = dma_set_coherent_mask(&pdev->dev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-
-       scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]);
-
-       pci_set_master(pdev);
-
-       return 0;
-}
-
-/**
- *     scc_init_one - Register SCC PATA device with kernel services
- *     @pdev: PCI device to register
- *     @ent: Entry in scc_pci_tbl matching with @pdev
- *
- *     LOCKING:
- *     Inherited from PCI layer (may sleep).
- *
- *     RETURNS:
- *     Zero on success, or -ERRNO value.
- */
-
-static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-       unsigned int board_idx = (unsigned int) ent->driver_data;
-       const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL };
-       struct ata_host *host;
-       int rc;
-
-       ata_print_version_once(&pdev->dev, DRV_VERSION);
-
-       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 1);
-       if (!host)
-               return -ENOMEM;
-
-       rc = pcim_enable_device(pdev);
-       if (rc)
-               return rc;
-
-       rc = pcim_iomap_regions(pdev, (1 << SCC_CTRL_BAR) | (1 << SCC_BMID_BAR), DRV_NAME);
-       if (rc == -EBUSY)
-               pcim_pin_device(pdev);
-       if (rc)
-               return rc;
-       host->iomap = pcim_iomap_table(pdev);
-
-       ata_port_pbar_desc(host->ports[0], SCC_CTRL_BAR, -1, "ctrl");
-       ata_port_pbar_desc(host->ports[0], SCC_BMID_BAR, -1, "bmid");
-
-       rc = scc_host_init(host);
-       if (rc)
-               return rc;
-
-       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
-                                IRQF_SHARED, &scc_sht);
-}
-
-static struct pci_driver scc_pci_driver = {
-       .name                   = DRV_NAME,
-       .id_table               = scc_pci_tbl,
-       .probe                  = scc_init_one,
-       .remove                 = ata_pci_remove_one,
-#ifdef CONFIG_PM_SLEEP
-       .suspend                = ata_pci_device_suspend,
-       .resume                 = ata_pci_device_resume,
-#endif
-};
-
-module_pci_driver(scc_pci_driver);
-
-MODULE_AUTHOR("Toshiba corp");
-MODULE_DESCRIPTION("SCSI low-level driver for Toshiba SCC PATA controller");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
-MODULE_VERSION(DRV_VERSION);
index 4f7e8d400bc01a178bcbfcf499340b40545fb54f..6de97b3871b0f8cffe4d2c9b2b78eb5e87c48247 100644 (file)
@@ -227,7 +227,6 @@ static void bt3c_receive(struct bt3c_info *info)
        iobase = info->p_dev->resource[0]->start;
 
        avail = bt3c_read(iobase, 0x7006);
-       //printk("bt3c_cs: receiving %d bytes\n", avail);
 
        bt3c_address(iobase, 0x7480);
        while (size < avail) {
@@ -250,7 +249,6 @@ static void bt3c_receive(struct bt3c_info *info)
 
                        bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
                        inb(iobase + DATA_H);
-                       //printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
 
                        switch (bt_cb(info->rx_skb)->pkt_type) {
 
@@ -364,7 +362,6 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
                        if (stat & 0x0001)
                                bt3c_receive(info);
                        if (stat & 0x0002) {
-                               //BT_ERR("Ack (stat=0x%04x)", stat);
                                clear_bit(XMIT_SENDING, &(info->tx_state));
                                bt3c_write_wakeup(info);
                        }
index d0741f3ed7ec36b49f1c50ff119fabc7368d3a9e..4bba86677adc64553fe8415d9b6812bfb3e1449d 100644 (file)
@@ -95,6 +95,78 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 }
 EXPORT_SYMBOL_GPL(btbcm_set_bdaddr);
 
+int btbcm_patchram(struct hci_dev *hdev, const char *firmware)
+{
+       const struct hci_command_hdr *cmd;
+       const struct firmware *fw;
+       const u8 *fw_ptr;
+       size_t fw_size;
+       struct sk_buff *skb;
+       u16 opcode;
+       int err;
+
+       err = request_firmware(&fw, firmware, &hdev->dev);
+       if (err < 0) {
+               BT_INFO("%s: BCM: Patch %s not found", hdev->name, firmware);
+               return err;
+       }
+
+       /* Start Download */
+       skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               err = PTR_ERR(skb);
+               BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
+                      hdev->name, err);
+               goto done;
+       }
+       kfree_skb(skb);
+
+       /* 50 msec delay after Download Minidrv completes */
+       msleep(50);
+
+       fw_ptr = fw->data;
+       fw_size = fw->size;
+
+       while (fw_size >= sizeof(*cmd)) {
+               const u8 *cmd_param;
+
+               cmd = (struct hci_command_hdr *)fw_ptr;
+               fw_ptr += sizeof(*cmd);
+               fw_size -= sizeof(*cmd);
+
+               if (fw_size < cmd->plen) {
+                       BT_ERR("%s: BCM: Patch %s is corrupted", hdev->name,
+                              firmware);
+                       err = -EINVAL;
+                       goto done;
+               }
+
+               cmd_param = fw_ptr;
+               fw_ptr += cmd->plen;
+               fw_size -= cmd->plen;
+
+               opcode = le16_to_cpu(cmd->opcode);
+
+               skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
+                                    HCI_INIT_TIMEOUT);
+               if (IS_ERR(skb)) {
+                       err = PTR_ERR(skb);
+                       BT_ERR("%s: BCM: Patch command %04x failed (%d)",
+                              hdev->name, opcode, err);
+                       goto done;
+               }
+               kfree_skb(skb);
+       }
+
+       /* 250 msec delay after Launch Ram completes */
+       msleep(250);
+
+done:
+       release_firmware(fw);
+       return err;
+}
+EXPORT_SYMBOL(btbcm_patchram);
+
 static int btbcm_reset(struct hci_dev *hdev)
 {
        struct sk_buff *skb;
@@ -198,12 +270,8 @@ static const struct {
 
 int btbcm_setup_patchram(struct hci_dev *hdev)
 {
-       const struct hci_command_hdr *cmd;
-       const struct firmware *fw;
-       const u8 *fw_ptr;
-       size_t fw_size;
        char fw_name[64];
-       u16 opcode, subver, rev, pid, vid;
+       u16 subver, rev, pid, vid;
        const char *hw_name = NULL;
        struct sk_buff *skb;
        struct hci_rp_read_local_version *ver;
@@ -273,74 +341,19 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
                hw_name ? : "BCM", (subver & 0x7000) >> 13,
                (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff);
 
-       err = request_firmware(&fw, fw_name, &hdev->dev);
-       if (err < 0) {
-               BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name);
+       err = btbcm_patchram(hdev, fw_name);
+       if (err == -ENOENT)
                return 0;
-       }
-
-       /* Start Download */
-       skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT);
-       if (IS_ERR(skb)) {
-               err = PTR_ERR(skb);
-               BT_ERR("%s: BCM: Download Minidrv command failed (%d)",
-                      hdev->name, err);
-               goto reset;
-       }
-       kfree_skb(skb);
-
-       /* 50 msec delay after Download Minidrv completes */
-       msleep(50);
-
-       fw_ptr = fw->data;
-       fw_size = fw->size;
-
-       while (fw_size >= sizeof(*cmd)) {
-               const u8 *cmd_param;
-
-               cmd = (struct hci_command_hdr *)fw_ptr;
-               fw_ptr += sizeof(*cmd);
-               fw_size -= sizeof(*cmd);
-
-               if (fw_size < cmd->plen) {
-                       BT_ERR("%s: BCM: patch %s is corrupted", hdev->name,
-                              fw_name);
-                       err = -EINVAL;
-                       goto reset;
-               }
 
-               cmd_param = fw_ptr;
-               fw_ptr += cmd->plen;
-               fw_size -= cmd->plen;
-
-               opcode = le16_to_cpu(cmd->opcode);
-
-               skb = __hci_cmd_sync(hdev, opcode, cmd->plen, cmd_param,
-                                    HCI_INIT_TIMEOUT);
-               if (IS_ERR(skb)) {
-                       err = PTR_ERR(skb);
-                       BT_ERR("%s: BCM: patch command %04x failed (%d)",
-                              hdev->name, opcode, err);
-                       goto reset;
-               }
-               kfree_skb(skb);
-       }
-
-       /* 250 msec delay after Launch Ram completes */
-       msleep(250);
-
-reset:
        /* Reset */
        err = btbcm_reset(hdev);
        if (err)
-               goto done;
+               return err;
 
        /* Read Local Version Info */
        skb = btbcm_read_local_version(hdev);
-       if (IS_ERR(skb)) {
-               err = PTR_ERR(skb);
-               goto done;
-       }
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
 
        ver = (struct hci_rp_read_local_version *)skb->data;
        rev = le16_to_cpu(ver->hci_rev);
@@ -355,10 +368,7 @@ reset:
 
        set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
 
-done:
-       release_firmware(fw);
-
-       return err;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(btbcm_setup_patchram);
 
index 34268ae3eb4607e16f5c9e017b23cb904a80b459..eb6ab5f9483d3b510ab6a2decfb1d694af8facb7 100644 (file)
@@ -25,6 +25,7 @@
 
 int btbcm_check_bdaddr(struct hci_dev *hdev);
 int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
+int btbcm_patchram(struct hci_dev *hdev, const char *firmware);
 
 int btbcm_setup_patchram(struct hci_dev *hdev);
 int btbcm_setup_apple(struct hci_dev *hdev);
@@ -41,6 +42,11 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
        return -EOPNOTSUPP;
 }
 
+static inline int btbcm_patchram(struct hci_dev *hdev, const char *firmware)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline int btbcm_setup_patchram(struct hci_dev *hdev)
 {
        return 0;
index de7b236eeae7777f71389ec42c233525d309aef2..d21f3b4176d3165f9541275964278db16dd24374 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
+#include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -57,6 +58,7 @@ static struct usb_driver btusb_driver;
 #define BTUSB_AMP              0x4000
 #define BTUSB_QCA_ROME         0x8000
 #define BTUSB_BCM_APPLE                0x10000
+#define BTUSB_REALTEK          0x20000
 
 static const struct usb_device_id btusb_table[] = {
        /* Generic Bluetooth USB device */
@@ -288,6 +290,28 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01),
          .driver_info = BTUSB_IGNORE },
 
+       /* Realtek Bluetooth devices */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
+         .driver_info = BTUSB_REALTEK },
+
+       /* Additional Realtek 8723AE Bluetooth devices */
+       { USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK },
+
+       /* Additional Realtek 8723BE Bluetooth devices */
+       { USB_DEVICE(0x0489, 0xe085), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x0489, 0xe08b), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK },
+
+       /* Additional Realtek 8821AE Bluetooth devices */
+       { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3458), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK },
+       { USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK },
+
        { }     /* Terminating entry */
 };
 
@@ -892,7 +916,7 @@ static int btusb_open(struct hci_dev *hdev)
         */
        if (data->setup_on_usb) {
                err = data->setup_on_usb(hdev);
-               if (err <0)
+               if (err < 0)
                        return err;
        }
 
@@ -1345,6 +1369,378 @@ static int btusb_setup_csr(struct hci_dev *hdev)
        return ret;
 }
 
+#define RTL_FRAG_LEN 252
+
+struct rtl_download_cmd {
+       __u8 index;
+       __u8 data[RTL_FRAG_LEN];
+} __packed;
+
+struct rtl_download_response {
+       __u8 status;
+       __u8 index;
+} __packed;
+
+struct rtl_rom_version_evt {
+       __u8 status;
+       __u8 version;
+} __packed;
+
+struct rtl_epatch_header {
+       __u8 signature[8];
+       __le32 fw_version;
+       __le16 num_patches;
+} __packed;
+
+#define RTL_EPATCH_SIGNATURE   "Realtech"
+#define RTL_ROM_LMP_3499       0x3499
+#define RTL_ROM_LMP_8723A      0x1200
+#define RTL_ROM_LMP_8723B      0x8723
+#define RTL_ROM_LMP_8821A      0x8821
+#define RTL_ROM_LMP_8761A      0x8761
+
+static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
+{
+       struct rtl_rom_version_evt *rom_version;
+       struct sk_buff *skb;
+       int ret;
+
+       /* Read RTL ROM version command */
+       skb = __hci_cmd_sync(hdev, 0xfc6d, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               BT_ERR("%s: Read ROM version failed (%ld)",
+                      hdev->name, PTR_ERR(skb));
+               return PTR_ERR(skb);
+       }
+
+       if (skb->len != sizeof(*rom_version)) {
+               BT_ERR("%s: RTL version event length mismatch", hdev->name);
+               kfree_skb(skb);
+               return -EIO;
+       }
+
+       rom_version = (struct rtl_rom_version_evt *)skb->data;
+       BT_INFO("%s: rom_version status=%x version=%x",
+               hdev->name, rom_version->status, rom_version->version);
+
+       ret = rom_version->status;
+       if (ret == 0)
+               *version = rom_version->version;
+
+       kfree_skb(skb);
+       return ret;
+}
+
+static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
+                                  const struct firmware *fw,
+                                  unsigned char **_buf)
+{
+       const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 };
+       struct rtl_epatch_header *epatch_info;
+       unsigned char *buf;
+       int i, ret, len;
+       size_t min_size;
+       u8 opcode, length, data, rom_version = 0;
+       int project_id = -1;
+       const unsigned char *fwptr, *chip_id_base;
+       const unsigned char *patch_length_base, *patch_offset_base;
+       u32 patch_offset = 0;
+       u16 patch_length, num_patches;
+       const u16 project_id_to_lmp_subver[] = {
+               RTL_ROM_LMP_8723A,
+               RTL_ROM_LMP_8723B,
+               RTL_ROM_LMP_8821A,
+               RTL_ROM_LMP_8761A
+       };
+
+       ret = rtl_read_rom_version(hdev, &rom_version);
+       if (ret)
+               return -bt_to_errno(ret);
+
+       min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
+       if (fw->size < min_size)
+               return -EINVAL;
+
+       fwptr = fw->data + fw->size - sizeof(extension_sig);
+       if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) {
+               BT_ERR("%s: extension section signature mismatch", hdev->name);
+               return -EINVAL;
+       }
+
+       /* Loop from the end of the firmware parsing instructions, until
+        * we find an instruction that identifies the "project ID" for the
+        * hardware supported by this firwmare file.
+        * Once we have that, we double-check that that project_id is suitable
+        * for the hardware we are working with.
+        */
+       while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) {
+               opcode = *--fwptr;
+               length = *--fwptr;
+               data = *--fwptr;
+
+               BT_DBG("check op=%x len=%x data=%x", opcode, length, data);
+
+               if (opcode == 0xff) /* EOF */
+                       break;
+
+               if (length == 0) {
+                       BT_ERR("%s: found instruction with length 0",
+                              hdev->name);
+                       return -EINVAL;
+               }
+
+               if (opcode == 0 && length == 1) {
+                       project_id = data;
+                       break;
+               }
+
+               fwptr -= length;
+       }
+
+       if (project_id < 0) {
+               BT_ERR("%s: failed to find version instruction", hdev->name);
+               return -EINVAL;
+       }
+
+       if (project_id >= ARRAY_SIZE(project_id_to_lmp_subver)) {
+               BT_ERR("%s: unknown project id %d", hdev->name, project_id);
+               return -EINVAL;
+       }
+
+       if (lmp_subver != project_id_to_lmp_subver[project_id]) {
+               BT_ERR("%s: firmware is for %x but this is a %x", hdev->name,
+                      project_id_to_lmp_subver[project_id], lmp_subver);
+               return -EINVAL;
+       }
+
+       epatch_info = (struct rtl_epatch_header *)fw->data;
+       if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) {
+               BT_ERR("%s: bad EPATCH signature", hdev->name);
+               return -EINVAL;
+       }
+
+       num_patches = le16_to_cpu(epatch_info->num_patches);
+       BT_DBG("fw_version=%x, num_patches=%d",
+              le32_to_cpu(epatch_info->fw_version), num_patches);
+
+       /* After the rtl_epatch_header there is a funky patch metadata section.
+        * Assuming 2 patches, the layout is:
+        * ChipID1 ChipID2 PatchLength1 PatchLength2 PatchOffset1 PatchOffset2
+        *
+        * Find the right patch for this chip.
+        */
+       min_size += 8 * num_patches;
+       if (fw->size < min_size)
+               return -EINVAL;
+
+       chip_id_base = fw->data + sizeof(struct rtl_epatch_header);
+       patch_length_base = chip_id_base + (sizeof(u16) * num_patches);
+       patch_offset_base = patch_length_base + (sizeof(u16) * num_patches);
+       for (i = 0; i < num_patches; i++) {
+               u16 chip_id = get_unaligned_le16(chip_id_base +
+                                                (i * sizeof(u16)));
+               if (chip_id == rom_version + 1) {
+                       patch_length = get_unaligned_le16(patch_length_base +
+                                                         (i * sizeof(u16)));
+                       patch_offset = get_unaligned_le32(patch_offset_base +
+                                                         (i * sizeof(u32)));
+                       break;
+               }
+       }
+
+       if (!patch_offset) {
+               BT_ERR("%s: didn't find patch for chip id %d",
+                      hdev->name, rom_version);
+               return -EINVAL;
+       }
+
+       BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i);
+       min_size = patch_offset + patch_length;
+       if (fw->size < min_size)
+               return -EINVAL;
+
+       /* Copy the firmware into a new buffer and write the version at
+        * the end.
+        */
+       len = patch_length;
+       buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4);
+
+       *_buf = buf;
+       return len;
+}
+
+static int rtl_download_firmware(struct hci_dev *hdev,
+                                const unsigned char *data, int fw_len)
+{
+       struct rtl_download_cmd *dl_cmd;
+       int frag_num = fw_len / RTL_FRAG_LEN + 1;
+       int frag_len = RTL_FRAG_LEN;
+       int ret = 0;
+       int i;
+
+       dl_cmd = kmalloc(sizeof(struct rtl_download_cmd), GFP_KERNEL);
+       if (!dl_cmd)
+               return -ENOMEM;
+
+       for (i = 0; i < frag_num; i++) {
+               struct rtl_download_response *dl_resp;
+               struct sk_buff *skb;
+
+               BT_DBG("download fw (%d/%d)", i, frag_num);
+
+               dl_cmd->index = i;
+               if (i == (frag_num - 1)) {
+                       dl_cmd->index |= 0x80; /* data end */
+                       frag_len = fw_len % RTL_FRAG_LEN;
+               }
+               memcpy(dl_cmd->data, data, frag_len);
+
+               /* Send download command */
+               skb = __hci_cmd_sync(hdev, 0xfc20, frag_len + 1, dl_cmd,
+                                    HCI_INIT_TIMEOUT);
+               if (IS_ERR(skb)) {
+                       BT_ERR("%s: download fw command failed (%ld)",
+                              hdev->name, PTR_ERR(skb));
+                       ret = -PTR_ERR(skb);
+                       goto out;
+               }
+
+               if (skb->len != sizeof(*dl_resp)) {
+                       BT_ERR("%s: download fw event length mismatch",
+                              hdev->name);
+                       kfree_skb(skb);
+                       ret = -EIO;
+                       goto out;
+               }
+
+               dl_resp = (struct rtl_download_response *)skb->data;
+               if (dl_resp->status != 0) {
+                       kfree_skb(skb);
+                       ret = bt_to_errno(dl_resp->status);
+                       goto out;
+               }
+
+               kfree_skb(skb);
+               data += RTL_FRAG_LEN;
+       }
+
+out:
+       kfree(dl_cmd);
+       return ret;
+}
+
+static int btusb_setup_rtl8723a(struct hci_dev *hdev)
+{
+       struct btusb_data *data = dev_get_drvdata(&hdev->dev);
+       struct usb_device *udev = interface_to_usbdev(data->intf);
+       const struct firmware *fw;
+       int ret;
+
+       BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name);
+       ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &udev->dev);
+       if (ret < 0) {
+               BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name);
+               return ret;
+       }
+
+       if (fw->size < 8) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* Check that the firmware doesn't have the epatch signature
+        * (which is only for RTL8723B and newer).
+        */
+       if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) {
+               BT_ERR("%s: unexpected EPATCH signature!", hdev->name);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = rtl_download_firmware(hdev, fw->data, fw->size);
+
+out:
+       release_firmware(fw);
+       return ret;
+}
+
+static int btusb_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver,
+                               const char *fw_name)
+{
+       struct btusb_data *data = dev_get_drvdata(&hdev->dev);
+       struct usb_device *udev = interface_to_usbdev(data->intf);
+       unsigned char *fw_data = NULL;
+       const struct firmware *fw;
+       int ret;
+
+       BT_INFO("%s: rtl: loading %s", hdev->name, fw_name);
+       ret = request_firmware(&fw, fw_name, &udev->dev);
+       if (ret < 0) {
+               BT_ERR("%s: Failed to load %s", hdev->name, fw_name);
+               return ret;
+       }
+
+       ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data);
+       if (ret < 0)
+               goto out;
+
+       ret = rtl_download_firmware(hdev, fw_data, ret);
+       kfree(fw_data);
+       if (ret < 0)
+               goto out;
+
+out:
+       release_firmware(fw);
+       return ret;
+}
+
+static int btusb_setup_realtek(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+       struct hci_rp_read_local_version *resp;
+       u16 lmp_subver;
+
+       skb = btusb_read_local_version(hdev);
+       if (IS_ERR(skb))
+               return -PTR_ERR(skb);
+
+       resp = (struct hci_rp_read_local_version *)skb->data;
+       BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x "
+               "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev,
+               resp->lmp_ver, resp->lmp_subver);
+
+       lmp_subver = le16_to_cpu(resp->lmp_subver);
+       kfree_skb(skb);
+
+       /* Match a set of subver values that correspond to stock firmware,
+        * which is not compatible with standard btusb.
+        * If matched, upload an alternative firmware that does conform to
+        * standard btusb. Once that firmware is uploaded, the subver changes
+        * to a different value.
+        */
+       switch (lmp_subver) {
+       case RTL_ROM_LMP_8723A:
+       case RTL_ROM_LMP_3499:
+               return btusb_setup_rtl8723a(hdev);
+       case RTL_ROM_LMP_8723B:
+               return btusb_setup_rtl8723b(hdev, lmp_subver,
+                                           "rtl_bt/rtl8723b_fw.bin");
+       case RTL_ROM_LMP_8821A:
+               return btusb_setup_rtl8723b(hdev, lmp_subver,
+                                           "rtl_bt/rtl8821a_fw.bin");
+       case RTL_ROM_LMP_8761A:
+               return btusb_setup_rtl8723b(hdev, lmp_subver,
+                                           "rtl_bt/rtl8761a_fw.bin");
+       default:
+               BT_INFO("rtl: assuming no firmware upload needed.");
+               return 0;
+       }
+}
+
 static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev,
                                                       struct intel_version *ver)
 {
@@ -2577,7 +2973,7 @@ static int btusb_setup_qca(struct hci_dev *hdev)
        int i, err;
 
        err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver,
-                                       sizeof(ver));
+                                       sizeof(ver));
        if (err < 0)
                return err;
 
@@ -2776,6 +3172,9 @@ static int btusb_probe(struct usb_interface *intf,
                hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
        }
 
+       if (id->driver_info & BTUSB_REALTEK)
+               hdev->setup = btusb_setup_realtek;
+
        if (id->driver_info & BTUSB_AMP) {
                /* AMP controllers do not support SCO packets */
                data->isoc = NULL;
index 1b3f8647ea2fd446e1a6f14979a27e399fb0dbf5..ec8fa0e0f03630c9646a60b831277477a249b010 100644 (file)
@@ -95,7 +95,6 @@ static void ath_hci_uart_work(struct work_struct *work)
        hci_uart_tx_wakeup(hu);
 }
 
-/* Initialize protocol */
 static int ath_open(struct hci_uart *hu)
 {
        struct ath_struct *ath;
@@ -116,8 +115,7 @@ static int ath_open(struct hci_uart *hu)
        return 0;
 }
 
-/* Flush protocol data */
-static int ath_flush(struct hci_uart *hu)
+static int ath_close(struct hci_uart *hu)
 {
        struct ath_struct *ath = hu->priv;
 
@@ -125,11 +123,17 @@ static int ath_flush(struct hci_uart *hu)
 
        skb_queue_purge(&ath->txq);
 
+       kfree_skb(ath->rx_skb);
+
+       cancel_work_sync(&ath->ctxtsw);
+
+       hu->priv = NULL;
+       kfree(ath);
+
        return 0;
 }
 
-/* Close protocol */
-static int ath_close(struct hci_uart *hu)
+static int ath_flush(struct hci_uart *hu)
 {
        struct ath_struct *ath = hu->priv;
 
@@ -137,19 +141,65 @@ static int ath_close(struct hci_uart *hu)
 
        skb_queue_purge(&ath->txq);
 
-       kfree_skb(ath->rx_skb);
+       return 0;
+}
 
-       cancel_work_sync(&ath->ctxtsw);
+static int ath_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+       struct sk_buff *skb;
+       u8 buf[10];
+       int err;
+
+       buf[0] = 0x01;
+       buf[1] = 0x01;
+       buf[2] = 0x00;
+       buf[3] = sizeof(bdaddr_t);
+       memcpy(buf + 4, bdaddr, sizeof(bdaddr_t));
+
+       skb = __hci_cmd_sync(hdev, 0xfc0b, sizeof(buf), buf, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               err = PTR_ERR(skb);
+               BT_ERR("%s: Change address command failed (%d)",
+                      hdev->name, err);
+               return err;
+       }
+       kfree_skb(skb);
 
-       hu->priv = NULL;
-       kfree(ath);
+       return 0;
+}
+
+static int ath_setup(struct hci_uart *hu)
+{
+       BT_DBG("hu %p", hu);
+
+       hu->hdev->set_bdaddr = ath_set_bdaddr;
 
        return 0;
 }
 
+static const struct h4_recv_pkt ath_recv_pkts[] = {
+       { H4_RECV_ACL,   .recv = hci_recv_frame },
+       { H4_RECV_SCO,   .recv = hci_recv_frame },
+       { H4_RECV_EVENT, .recv = hci_recv_frame },
+};
+
+static int ath_recv(struct hci_uart *hu, const void *data, int count)
+{
+       struct ath_struct *ath = hu->priv;
+
+       ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count,
+                                 ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts));
+       if (IS_ERR(ath->rx_skb)) {
+               int err = PTR_ERR(ath->rx_skb);
+               BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err);
+               return err;
+       }
+
+       return count;
+}
+
 #define HCI_OP_ATH_SLEEP 0xFC04
 
-/* Enqueue frame for transmittion */
 static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
 {
        struct ath_struct *ath = hu->priv;
@@ -159,8 +209,7 @@ static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
                return 0;
        }
 
-       /*
-        * Update power management enable flag with parameters of
+       /* Update power management enable flag with parameters of
         * HCI sleep enable vendor specific HCI command.
         */
        if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
@@ -190,37 +239,16 @@ static struct sk_buff *ath_dequeue(struct hci_uart *hu)
        return skb_dequeue(&ath->txq);
 }
 
-static const struct h4_recv_pkt ath_recv_pkts[] = {
-       { H4_RECV_ACL,   .recv = hci_recv_frame },
-       { H4_RECV_SCO,   .recv = hci_recv_frame },
-       { H4_RECV_EVENT, .recv = hci_recv_frame },
-};
-
-/* Recv data */
-static int ath_recv(struct hci_uart *hu, const void *data, int count)
-{
-       struct ath_struct *ath = hu->priv;
-
-       ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count,
-                                 ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts));
-       if (IS_ERR(ath->rx_skb)) {
-               int err = PTR_ERR(ath->rx_skb);
-               BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err);
-               return err;
-       }
-
-       return count;
-}
-
 static const struct hci_uart_proto athp = {
        .id             = HCI_UART_ATH3K,
        .name           = "ATH3K",
        .open           = ath_open,
        .close          = ath_close,
+       .flush          = ath_flush,
+       .setup          = ath_setup,
        .recv           = ath_recv,
        .enqueue        = ath_enqueue,
        .dequeue        = ath_dequeue,
-       .flush          = ath_flush,
 };
 
 int __init ath_init(void)
index 6e45a43ffe8476686bcaee1157a7acc641fc3e6b..97b1616aa391819c0579d12efcca286cfa1c7075 100644 (file)
@@ -499,19 +499,19 @@ static int __init dmi_present(const u8 *buf)
        buf += 16;
 
        if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
+               if (smbios_ver)
+                       dmi_ver = smbios_ver;
+               else
+                       dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F);
                dmi_num = get_unaligned_le16(buf + 12);
                dmi_len = get_unaligned_le16(buf + 6);
                dmi_base = get_unaligned_le32(buf + 8);
 
                if (dmi_walk_early(dmi_decode) == 0) {
                        if (smbios_ver) {
-                               dmi_ver = smbios_ver;
-                               pr_info("SMBIOS %d.%d%s present.\n",
-                                       dmi_ver >> 8, dmi_ver & 0xFF,
-                                       (dmi_ver < 0x0300) ? "" : ".x");
+                               pr_info("SMBIOS %d.%d present.\n",
+                                      dmi_ver >> 8, dmi_ver & 0xFF);
                        } else {
-                               dmi_ver = (buf[14] & 0xF0) << 4 |
-                                          (buf[14] & 0x0F);
                                pr_info("Legacy DMI %d.%d present.\n",
                                       dmi_ver >> 8, dmi_ver & 0xFF);
                        }
index c302ffb5a16814b41086abe52a25c7f7debd40a8..a19d2c71e20505aba9ca25158d6e5acd6ba6f920 100644 (file)
@@ -699,6 +699,16 @@ static int i915_drm_resume(struct drm_device *dev)
        intel_init_pch_refclk(dev);
        drm_mode_config_reset(dev);
 
+       /*
+        * Interrupts have to be enabled before any batches are run. If not the
+        * GPU will hang. i915_gem_init_hw() will initiate batches to
+        * update/restore the context.
+        *
+        * Modeset enabling in intel_modeset_init_hw() also needs working
+        * interrupts.
+        */
+       intel_runtime_pm_enable_interrupts(dev_priv);
+
        mutex_lock(&dev->struct_mutex);
        if (i915_gem_init_hw(dev)) {
                DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n");
@@ -706,9 +716,6 @@ static int i915_drm_resume(struct drm_device *dev)
        }
        mutex_unlock(&dev->struct_mutex);
 
-       /* We need working interrupts for modeset enabling ... */
-       intel_runtime_pm_enable_interrupts(dev_priv);
-
        intel_modeset_init_hw(dev);
 
        spin_lock_irq(&dev_priv->irq_lock);
index 28faea9996f9e111d6b35e547587025aa93c3089..a0c35bbc85462587be95048bd996aecb8ec481e2 100644 (file)
@@ -5822,7 +5822,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
               L2_CACHE_BIGK_FRAGMENT_SIZE(4));
        /* setup context0 */
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
                        (u32)(rdev->dummy_page.addr >> 12));
@@ -5837,7 +5837,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
        /* restore context1-15 */
        /* set vm size, must be a multiple of 4 */
        WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
-       WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
+       WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
        for (i = 1; i < 16; i++) {
                if (i < 8)
                        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
index f848acfd3fc8a94fb4674cf13d9442857e367567..05e6d6ef596385ecab450bbd1831e942186021d2 100644 (file)
@@ -2485,7 +2485,7 @@ static int evergreen_pcie_gart_enable(struct radeon_device *rdev)
        WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
        WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
                                RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
index e8a496ff007ee680d30a2bd688f30d094b58461c..aba2f428c0a895380a4a3251e51c6484fba4b3be 100644 (file)
@@ -1282,7 +1282,7 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev)
               L2_CACHE_BIGK_FRAGMENT_SIZE(6));
        /* setup context0 */
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
                        (u32)(rdev->dummy_page.addr >> 12));
@@ -1301,7 +1301,8 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev)
         */
        for (i = 1; i < 8; i++) {
                WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
-               WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn);
+               WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2),
+                       rdev->vm_manager.max_pfn - 1);
                WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
                       rdev->vm_manager.saved_table_addr[i]);
        }
index 8f6d862a188228101dc9070f5ab2ada5f819d1a6..25b4ac967742c034372caa1dbf67d6476fd6bb92 100644 (file)
@@ -1112,7 +1112,7 @@ static int r600_pcie_gart_enable(struct radeon_device *rdev)
        WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
        WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
                                RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
index 1017338a49d9f49aaad6dc594d6ec1bef8a5f111..2b98ed3e684d706a07e3c43b6da9f2232143e580 100644 (file)
@@ -666,6 +666,9 @@ radeon_dp_mst_probe(struct radeon_connector *radeon_connector)
        int ret;
        u8 msg[1];
 
+       if (!radeon_mst)
+               return 0;
+
        if (dig_connector->dpcd[DP_DPCD_REV] < 0x12)
                return 0;
 
index 01ee96acb3985ea65ec2470456381251d51f444e..c54d6313a46d243a226b5d969b597dcb062773ff 100644 (file)
@@ -921,7 +921,7 @@ static int rv770_pcie_gart_enable(struct radeon_device *rdev)
        WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
        WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
                                RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
index b1d74bc375d82f665dbb4455db5aa84db0c8d8dc..5326f753e10760ec04e27701e2eef4674139494f 100644 (file)
@@ -4303,7 +4303,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
               L2_CACHE_BIGK_FRAGMENT_SIZE(4));
        /* setup context0 */
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end >> 12) - 1);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
                        (u32)(rdev->dummy_page.addr >> 12));
@@ -4318,7 +4318,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
        /* empty context1-15 */
        /* set vm size, must be a multiple of 4 */
        WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
-       WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
+       WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
        /* Assign the pt base to something valid for now; the pts used for
         * the VMs are determined by the application and setup and assigned
         * on the fly in the vm part of radeon_gart.c
index a04c49f2a0118a887e22c16b9716656af6e87723..39ea67f9b066989ff901674cea38d2b1bb0ff2b3 100644 (file)
@@ -643,15 +643,6 @@ config BLK_DEV_TC86C001
        help
        This driver adds support for Toshiba TC86C001 GOKU-S chip.
 
-config BLK_DEV_CELLEB
-       tristate "Toshiba's Cell Reference Set IDE support"
-       depends on PPC_CELLEB
-       select BLK_DEV_IDEDMA_PCI
-       help
-         This driver provides support for the on-board IDE controller on
-         Toshiba Cell Reference Board.
-         If unsure, say Y.
-
 endif
 
 # TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF
index a04ee82f1c8f5bf5bd712f90dd73744a37762e2a..2a8c417d4081087daa50d154844bcb65f6cb55c0 100644 (file)
@@ -38,7 +38,6 @@ obj-$(CONFIG_BLK_DEV_AEC62XX)         += aec62xx.o
 obj-$(CONFIG_BLK_DEV_ALI15X3)          += alim15x3.o
 obj-$(CONFIG_BLK_DEV_AMD74XX)          += amd74xx.o
 obj-$(CONFIG_BLK_DEV_ATIIXP)           += atiixp.o
-obj-$(CONFIG_BLK_DEV_CELLEB)           += scc_pata.o
 obj-$(CONFIG_BLK_DEV_CMD64X)           += cmd64x.o
 obj-$(CONFIG_BLK_DEV_CS5520)           += cs5520.o
 obj-$(CONFIG_BLK_DEV_CS5530)           += cs5530.o
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
deleted file mode 100644 (file)
index 2a2d188..0000000
+++ /dev/null
@@ -1,887 +0,0 @@
-/*
- * Support for IDE interfaces on Celleb platform
- *
- * (C) Copyright 2006 TOSHIBA CORPORATION
- *
- * This code is based on drivers/ide/pci/siimage.c:
- * Copyright (C) 2001-2002     Andre Hedrick <andre@linux-ide.org>
- * Copyright (C) 2003          Red Hat
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA            0x01b4
-
-#define SCC_PATA_NAME           "scc IDE"
-
-#define TDVHSEL_MASTER          0x00000001
-#define TDVHSEL_SLAVE           0x00000004
-
-#define MODE_JCUSFEN            0x00000080
-
-#define CCKCTRL_ATARESET        0x00040000
-#define CCKCTRL_BUFCNT          0x00020000
-#define CCKCTRL_CRST            0x00010000
-#define CCKCTRL_OCLKEN          0x00000100
-#define CCKCTRL_ATACLKOEN       0x00000002
-#define CCKCTRL_LCLKEN          0x00000001
-
-#define QCHCD_IOS_SS           0x00000001
-
-#define QCHSD_STPDIAG          0x00020000
-
-#define INTMASK_MSK             0xD1000012
-#define INTSTS_SERROR          0x80000000
-#define INTSTS_PRERR           0x40000000
-#define INTSTS_RERR            0x10000000
-#define INTSTS_ICERR           0x01000000
-#define INTSTS_BMSINT          0x00000010
-#define INTSTS_BMHE            0x00000008
-#define INTSTS_IOIRQS           0x00000004
-#define INTSTS_INTRQ            0x00000002
-#define INTSTS_ACTEINT          0x00000001
-
-#define ECMODE_VALUE 0x01
-
-static struct scc_ports {
-       unsigned long ctl, dma;
-       struct ide_host *host;  /* for removing port from system */
-} scc_ports[MAX_HWIFS];
-
-/* PIO transfer mode  table */
-/* JCHST */
-static unsigned long JCHSTtbl[2][7] = {
-       {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00},   /* 100MHz */
-       {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00}    /* 133MHz */
-};
-
-/* JCHHT */
-static unsigned long JCHHTtbl[2][7] = {
-       {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00},   /* 100MHz */
-       {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00}    /* 133MHz */
-};
-
-/* JCHCT */
-static unsigned long JCHCTtbl[2][7] = {
-       {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00},   /* 100MHz */
-       {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00}    /* 133MHz */
-};
-
-
-/* DMA transfer mode  table */
-/* JCHDCTM/JCHDCTS */
-static unsigned long JCHDCTxtbl[2][7] = {
-       {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00},   /* 100MHz */
-       {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00}    /* 133MHz */
-};
-
-/* JCSTWTM/JCSTWTS  */
-static unsigned long JCSTWTxtbl[2][7] = {
-       {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00},   /* 100MHz */
-       {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02}    /* 133MHz */
-};
-
-/* JCTSS */
-static unsigned long JCTSStbl[2][7] = {
-       {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00},   /* 100MHz */
-       {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}    /* 133MHz */
-};
-
-/* JCENVT */
-static unsigned long JCENVTtbl[2][7] = {
-       {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00},   /* 100MHz */
-       {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}    /* 133MHz */
-};
-
-/* JCACTSELS/JCACTSELM */
-static unsigned long JCACTSELtbl[2][7] = {
-       {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00},   /* 100MHz */
-       {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}    /* 133MHz */
-};
-
-
-static u8 scc_ide_inb(unsigned long port)
-{
-       u32 data = in_be32((void*)port);
-       return (u8)data;
-}
-
-static void scc_exec_command(ide_hwif_t *hwif, u8 cmd)
-{
-       out_be32((void *)hwif->io_ports.command_addr, cmd);
-       eieio();
-       in_be32((void *)(hwif->dma_base + 0x01c));
-       eieio();
-}
-
-static u8 scc_read_status(ide_hwif_t *hwif)
-{
-       return (u8)in_be32((void *)hwif->io_ports.status_addr);
-}
-
-static u8 scc_read_altstatus(ide_hwif_t *hwif)
-{
-       return (u8)in_be32((void *)hwif->io_ports.ctl_addr);
-}
-
-static u8 scc_dma_sff_read_status(ide_hwif_t *hwif)
-{
-       return (u8)in_be32((void *)(hwif->dma_base + 4));
-}
-
-static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl)
-{
-       out_be32((void *)hwif->io_ports.ctl_addr, ctl);
-       eieio();
-       in_be32((void *)(hwif->dma_base + 0x01c));
-       eieio();
-}
-
-static void scc_ide_insw(unsigned long port, void *addr, u32 count)
-{
-       u16 *ptr = (u16 *)addr;
-       while (count--) {
-               *ptr++ = le16_to_cpu(in_be32((void*)port));
-       }
-}
-
-static void scc_ide_insl(unsigned long port, void *addr, u32 count)
-{
-       u16 *ptr = (u16 *)addr;
-       while (count--) {
-               *ptr++ = le16_to_cpu(in_be32((void*)port));
-               *ptr++ = le16_to_cpu(in_be32((void*)port));
-       }
-}
-
-static void scc_ide_outb(u8 addr, unsigned long port)
-{
-       out_be32((void*)port, addr);
-}
-
-static void
-scc_ide_outsw(unsigned long port, void *addr, u32 count)
-{
-       u16 *ptr = (u16 *)addr;
-       while (count--) {
-               out_be32((void*)port, cpu_to_le16(*ptr++));
-       }
-}
-
-static void
-scc_ide_outsl(unsigned long port, void *addr, u32 count)
-{
-       u16 *ptr = (u16 *)addr;
-       while (count--) {
-               out_be32((void*)port, cpu_to_le16(*ptr++));
-               out_be32((void*)port, cpu_to_le16(*ptr++));
-       }
-}
-
-/**
- *     scc_set_pio_mode        -       set host controller for PIO mode
- *     @hwif: port
- *     @drive: drive
- *
- *     Load the timing settings for this device mode into the
- *     controller.
- */
-
-static void scc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
-       struct scc_ports *ports = ide_get_hwifdata(hwif);
-       unsigned long ctl_base = ports->ctl;
-       unsigned long cckctrl_port = ctl_base + 0xff0;
-       unsigned long piosht_port = ctl_base + 0x000;
-       unsigned long pioct_port = ctl_base + 0x004;
-       unsigned long reg;
-       int offset;
-       const u8 pio = drive->pio_mode - XFER_PIO_0;
-
-       reg = in_be32((void __iomem *)cckctrl_port);
-       if (reg & CCKCTRL_ATACLKOEN) {
-               offset = 1; /* 133MHz */
-       } else {
-               offset = 0; /* 100MHz */
-       }
-       reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio];
-       out_be32((void __iomem *)piosht_port, reg);
-       reg = JCHCTtbl[offset][pio];
-       out_be32((void __iomem *)pioct_port, reg);
-}
-
-/**
- *     scc_set_dma_mode        -       set host controller for DMA mode
- *     @hwif: port
- *     @drive: drive
- *
- *     Load the timing settings for this device mode into the
- *     controller.
- */
-
-static void scc_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
-       struct scc_ports *ports = ide_get_hwifdata(hwif);
-       unsigned long ctl_base = ports->ctl;
-       unsigned long cckctrl_port = ctl_base + 0xff0;
-       unsigned long mdmact_port = ctl_base + 0x008;
-       unsigned long mcrcst_port = ctl_base + 0x00c;
-       unsigned long sdmact_port = ctl_base + 0x010;
-       unsigned long scrcst_port = ctl_base + 0x014;
-       unsigned long udenvt_port = ctl_base + 0x018;
-       unsigned long tdvhsel_port   = ctl_base + 0x020;
-       int is_slave = drive->dn & 1;
-       int offset, idx;
-       unsigned long reg;
-       unsigned long jcactsel;
-       const u8 speed = drive->dma_mode;
-
-       reg = in_be32((void __iomem *)cckctrl_port);
-       if (reg & CCKCTRL_ATACLKOEN) {
-               offset = 1; /* 133MHz */
-       } else {
-               offset = 0; /* 100MHz */
-       }
-
-       idx = speed - XFER_UDMA_0;
-
-       jcactsel = JCACTSELtbl[offset][idx];
-       if (is_slave) {
-               out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]);
-               out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]);
-               jcactsel = jcactsel << 2;
-               out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel);
-       } else {
-               out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]);
-               out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]);
-               out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel);
-       }
-       reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx];
-       out_be32((void __iomem *)udenvt_port, reg);
-}
-
-static void scc_dma_host_set(ide_drive_t *drive, int on)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 unit = drive->dn & 1;
-       u8 dma_stat = scc_dma_sff_read_status(hwif);
-
-       if (on)
-               dma_stat |= (1 << (5 + unit));
-       else
-               dma_stat &= ~(1 << (5 + unit));
-
-       scc_ide_outb(dma_stat, hwif->dma_base + 4);
-}
-
-/**
- *     scc_dma_setup   -       begin a DMA phase
- *     @drive: target device
- *     @cmd: command
- *
- *     Build an IDE DMA PRD (IDE speak for scatter gather table)
- *     and then set up the DMA transfer registers.
- *
- *     Returns 0 on success. If a PIO fallback is required then 1
- *     is returned.
- */
-
-static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
-       u8 dma_stat;
-
-       /* fall back to pio! */
-       if (ide_build_dmatable(drive, cmd) == 0)
-               return 1;
-
-       /* PRD table */
-       out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
-
-       /* specify r/w */
-       out_be32((void __iomem *)hwif->dma_base, rw);
-
-       /* read DMA status for INTR & ERROR flags */
-       dma_stat = scc_dma_sff_read_status(hwif);
-
-       /* clear INTR & ERROR flags */
-       out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
-
-       return 0;
-}
-
-static void scc_dma_start(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 dma_cmd = scc_ide_inb(hwif->dma_base);
-
-       /* start DMA */
-       scc_ide_outb(dma_cmd | 1, hwif->dma_base);
-}
-
-static int __scc_dma_end(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 dma_stat, dma_cmd;
-
-       /* get DMA command mode */
-       dma_cmd = scc_ide_inb(hwif->dma_base);
-       /* stop DMA */
-       scc_ide_outb(dma_cmd & ~1, hwif->dma_base);
-       /* get DMA status */
-       dma_stat = scc_dma_sff_read_status(hwif);
-       /* clear the INTR & ERROR bits */
-       scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
-       /* verify good DMA status */
-       return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
-}
-
-/**
- *     scc_dma_end     -       Stop DMA
- *     @drive: IDE drive
- *
- *     Check and clear INT Status register.
- *     Then call __scc_dma_end().
- */
-
-static int scc_dma_end(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       void __iomem *dma_base = (void __iomem *)hwif->dma_base;
-       unsigned long intsts_port = hwif->dma_base + 0x014;
-       u32 reg;
-       int dma_stat, data_loss = 0;
-       static int retry = 0;
-
-       /* errata A308 workaround: Step5 (check data loss) */
-       /* We don't check non ide_disk because it is limited to UDMA4 */
-       if (!(in_be32((void __iomem *)hwif->io_ports.ctl_addr)
-             & ATA_ERR) &&
-           drive->media == ide_disk && drive->current_speed > XFER_UDMA_4) {
-               reg = in_be32((void __iomem *)intsts_port);
-               if (!(reg & INTSTS_ACTEINT)) {
-                       printk(KERN_WARNING "%s: operation failed (transfer data loss)\n",
-                              drive->name);
-                       data_loss = 1;
-                       if (retry++) {
-                               struct request *rq = hwif->rq;
-                               ide_drive_t *drive;
-                               int i;
-
-                               /* ERROR_RESET and drive->crc_count are needed
-                                * to reduce DMA transfer mode in retry process.
-                                */
-                               if (rq)
-                                       rq->errors |= ERROR_RESET;
-
-                               ide_port_for_each_dev(i, drive, hwif)
-                                       drive->crc_count++;
-                       }
-               }
-       }
-
-       while (1) {
-               reg = in_be32((void __iomem *)intsts_port);
-
-               if (reg & INTSTS_SERROR) {
-                       printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME);
-                       out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT);
-
-                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
-                       continue;
-               }
-
-               if (reg & INTSTS_PRERR) {
-                       u32 maea0, maec0;
-                       unsigned long ctl_base = hwif->config_data;
-
-                       maea0 = in_be32((void __iomem *)(ctl_base + 0xF50));
-                       maec0 = in_be32((void __iomem *)(ctl_base + 0xF54));
-
-                       printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0);
-
-                       out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT);
-
-                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
-                       continue;
-               }
-
-               if (reg & INTSTS_RERR) {
-                       printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME);
-                       out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT);
-
-                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
-                       continue;
-               }
-
-               if (reg & INTSTS_ICERR) {
-                       out_be32(dma_base, in_be32(dma_base) & ~QCHCD_IOS_SS);
-
-                       printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME);
-                       out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT);
-                       continue;
-               }
-
-               if (reg & INTSTS_BMSINT) {
-                       printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME);
-                       out_be32((void __iomem *)intsts_port, INTSTS_BMSINT);
-
-                       ide_do_reset(drive);
-                       continue;
-               }
-
-               if (reg & INTSTS_BMHE) {
-                       out_be32((void __iomem *)intsts_port, INTSTS_BMHE);
-                       continue;
-               }
-
-               if (reg & INTSTS_ACTEINT) {
-                       out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT);
-                       continue;
-               }
-
-               if (reg & INTSTS_IOIRQS) {
-                       out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS);
-                       continue;
-               }
-               break;
-       }
-
-       dma_stat = __scc_dma_end(drive);
-       if (data_loss)
-               dma_stat |= 2; /* emulate DMA error (to retry command) */
-       return dma_stat;
-}
-
-/* returns 1 if dma irq issued, 0 otherwise */
-static int scc_dma_test_irq(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014);
-
-       /* SCC errata A252,A308 workaround: Step4 */
-       if ((in_be32((void __iomem *)hwif->io_ports.ctl_addr)
-            & ATA_ERR) &&
-           (int_stat & INTSTS_INTRQ))
-               return 1;
-
-       /* SCC errata A308 workaround: Step5 (polling IOIRQS) */
-       if (int_stat & INTSTS_IOIRQS)
-               return 1;
-
-       return 0;
-}
-
-static u8 scc_udma_filter(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       u8 mask = hwif->ultra_mask;
-
-       /* errata A308 workaround: limit non ide_disk drive to UDMA4 */
-       if ((drive->media != ide_disk) && (mask & 0xE0)) {
-               printk(KERN_INFO "%s: limit %s to UDMA4\n",
-                      SCC_PATA_NAME, drive->name);
-               mask = ATA_UDMA4;
-       }
-
-       return mask;
-}
-
-/**
- *     setup_mmio_scc  -       map CTRL/BMID region
- *     @dev: PCI device we are configuring
- *     @name: device name
- *
- */
-
-static int setup_mmio_scc (struct pci_dev *dev, const char *name)
-{
-       void __iomem *ctl_addr;
-       void __iomem *dma_addr;
-       int i, ret;
-
-       for (i = 0; i < MAX_HWIFS; i++) {
-               if (scc_ports[i].ctl == 0)
-                       break;
-       }
-       if (i >= MAX_HWIFS)
-               return -ENOMEM;
-
-       ret = pci_request_selected_regions(dev, (1 << 2) - 1, name);
-       if (ret < 0) {
-               printk(KERN_ERR "%s: can't reserve resources\n", name);
-               return ret;
-       }
-
-       ctl_addr = pci_ioremap_bar(dev, 0);
-       if (!ctl_addr)
-               goto fail_0;
-
-       dma_addr = pci_ioremap_bar(dev, 1);
-       if (!dma_addr)
-               goto fail_1;
-
-       pci_set_master(dev);
-       scc_ports[i].ctl = (unsigned long)ctl_addr;
-       scc_ports[i].dma = (unsigned long)dma_addr;
-       pci_set_drvdata(dev, (void *) &scc_ports[i]);
-
-       return 1;
-
- fail_1:
-       iounmap(ctl_addr);
- fail_0:
-       return -ENOMEM;
-}
-
-static int scc_ide_setup_pci_device(struct pci_dev *dev,
-                                   const struct ide_port_info *d)
-{
-       struct scc_ports *ports = pci_get_drvdata(dev);
-       struct ide_host *host;
-       struct ide_hw hw, *hws[] = { &hw };
-       int i, rc;
-
-       memset(&hw, 0, sizeof(hw));
-       for (i = 0; i <= 8; i++)
-               hw.io_ports_array[i] = ports->dma + 0x20 + i * 4;
-       hw.irq = dev->irq;
-       hw.dev = &dev->dev;
-
-       rc = ide_host_add(d, hws, 1, &host);
-       if (rc)
-               return rc;
-
-       ports->host = host;
-
-       return 0;
-}
-
-/**
- *     init_setup_scc  -       set up an SCC PATA Controller
- *     @dev: PCI device
- *     @d: IDE port info
- *
- *     Perform the initial set up for this device.
- */
-
-static int init_setup_scc(struct pci_dev *dev, const struct ide_port_info *d)
-{
-       unsigned long ctl_base;
-       unsigned long dma_base;
-       unsigned long cckctrl_port;
-       unsigned long intmask_port;
-       unsigned long mode_port;
-       unsigned long ecmode_port;
-       u32 reg = 0;
-       struct scc_ports *ports;
-       int rc;
-
-       rc = pci_enable_device(dev);
-       if (rc)
-               goto end;
-
-       rc = setup_mmio_scc(dev, d->name);
-       if (rc < 0)
-               goto end;
-
-       ports = pci_get_drvdata(dev);
-       ctl_base = ports->ctl;
-       dma_base = ports->dma;
-       cckctrl_port = ctl_base + 0xff0;
-       intmask_port = dma_base + 0x010;
-       mode_port = ctl_base + 0x024;
-       ecmode_port = ctl_base + 0xf00;
-
-       /* controller initialization */
-       reg = 0;
-       out_be32((void*)cckctrl_port, reg);
-       reg |= CCKCTRL_ATACLKOEN;
-       out_be32((void*)cckctrl_port, reg);
-       reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
-       out_be32((void*)cckctrl_port, reg);
-       reg |= CCKCTRL_CRST;
-       out_be32((void*)cckctrl_port, reg);
-
-       for (;;) {
-               reg = in_be32((void*)cckctrl_port);
-               if (reg & CCKCTRL_CRST)
-                       break;
-               udelay(5000);
-       }
-
-       reg |= CCKCTRL_ATARESET;
-       out_be32((void*)cckctrl_port, reg);
-
-       out_be32((void*)ecmode_port, ECMODE_VALUE);
-       out_be32((void*)mode_port, MODE_JCUSFEN);
-       out_be32((void*)intmask_port, INTMASK_MSK);
-
-       rc = scc_ide_setup_pci_device(dev, d);
-
- end:
-       return rc;
-}
-
-static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
-{
-       struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-
-       if (valid & IDE_VALID_FEATURE)
-               scc_ide_outb(tf->feature, io_ports->feature_addr);
-       if (valid & IDE_VALID_NSECT)
-               scc_ide_outb(tf->nsect, io_ports->nsect_addr);
-       if (valid & IDE_VALID_LBAL)
-               scc_ide_outb(tf->lbal, io_ports->lbal_addr);
-       if (valid & IDE_VALID_LBAM)
-               scc_ide_outb(tf->lbam, io_ports->lbam_addr);
-       if (valid & IDE_VALID_LBAH)
-               scc_ide_outb(tf->lbah, io_ports->lbah_addr);
-       if (valid & IDE_VALID_DEVICE)
-               scc_ide_outb(tf->device, io_ports->device_addr);
-}
-
-static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
-{
-       struct ide_io_ports *io_ports = &drive->hwif->io_ports;
-
-       if (valid & IDE_VALID_ERROR)
-               tf->error  = scc_ide_inb(io_ports->feature_addr);
-       if (valid & IDE_VALID_NSECT)
-               tf->nsect  = scc_ide_inb(io_ports->nsect_addr);
-       if (valid & IDE_VALID_LBAL)
-               tf->lbal   = scc_ide_inb(io_ports->lbal_addr);
-       if (valid & IDE_VALID_LBAM)
-               tf->lbam   = scc_ide_inb(io_ports->lbam_addr);
-       if (valid & IDE_VALID_LBAH)
-               tf->lbah   = scc_ide_inb(io_ports->lbah_addr);
-       if (valid & IDE_VALID_DEVICE)
-               tf->device = scc_ide_inb(io_ports->device_addr);
-}
-
-static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
-                          void *buf, unsigned int len)
-{
-       unsigned long data_addr = drive->hwif->io_ports.data_addr;
-
-       len++;
-
-       if (drive->io_32bit) {
-               scc_ide_insl(data_addr, buf, len / 4);
-
-               if ((len & 3) >= 2)
-                       scc_ide_insw(data_addr, (u8 *)buf + (len & ~3), 1);
-       } else
-               scc_ide_insw(data_addr, buf, len / 2);
-}
-
-static void scc_output_data(ide_drive_t *drive,  struct ide_cmd *cmd,
-                           void *buf, unsigned int len)
-{
-       unsigned long data_addr = drive->hwif->io_ports.data_addr;
-
-       len++;
-
-       if (drive->io_32bit) {
-               scc_ide_outsl(data_addr, buf, len / 4);
-
-               if ((len & 3) >= 2)
-                       scc_ide_outsw(data_addr, (u8 *)buf + (len & ~3), 1);
-       } else
-               scc_ide_outsw(data_addr, buf, len / 2);
-}
-
-/**
- *     init_mmio_iops_scc      -       set up the iops for MMIO
- *     @hwif: interface to set up
- *
- */
-
-static void init_mmio_iops_scc(ide_hwif_t *hwif)
-{
-       struct pci_dev *dev = to_pci_dev(hwif->dev);
-       struct scc_ports *ports = pci_get_drvdata(dev);
-       unsigned long dma_base = ports->dma;
-
-       ide_set_hwifdata(hwif, ports);
-
-       hwif->dma_base = dma_base;
-       hwif->config_data = ports->ctl;
-}
-
-/**
- *     init_iops_scc   -       set up iops
- *     @hwif: interface to set up
- *
- *     Do the basic setup for the SCC hardware interface
- *     and then do the MMIO setup.
- */
-
-static void init_iops_scc(ide_hwif_t *hwif)
-{
-       struct pci_dev *dev = to_pci_dev(hwif->dev);
-
-       hwif->hwif_data = NULL;
-       if (pci_get_drvdata(dev) == NULL)
-               return;
-       init_mmio_iops_scc(hwif);
-}
-
-static int scc_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
-{
-       return ide_allocate_dma_engine(hwif);
-}
-
-static u8 scc_cable_detect(ide_hwif_t *hwif)
-{
-       return ATA_CBL_PATA80;
-}
-
-/**
- *     init_hwif_scc   -       set up hwif
- *     @hwif: interface to set up
- *
- *     We do the basic set up of the interface structure. The SCC
- *     requires several custom handlers so we override the default
- *     ide DMA handlers appropriately.
- */
-
-static void init_hwif_scc(ide_hwif_t *hwif)
-{
-       /* PTERADD */
-       out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
-
-       if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN)
-               hwif->ultra_mask = ATA_UDMA6; /* 133MHz */
-       else
-               hwif->ultra_mask = ATA_UDMA5; /* 100MHz */
-}
-
-static const struct ide_tp_ops scc_tp_ops = {
-       .exec_command           = scc_exec_command,
-       .read_status            = scc_read_status,
-       .read_altstatus         = scc_read_altstatus,
-       .write_devctl           = scc_write_devctl,
-
-       .dev_select             = ide_dev_select,
-       .tf_load                = scc_tf_load,
-       .tf_read                = scc_tf_read,
-
-       .input_data             = scc_input_data,
-       .output_data            = scc_output_data,
-};
-
-static const struct ide_port_ops scc_port_ops = {
-       .set_pio_mode           = scc_set_pio_mode,
-       .set_dma_mode           = scc_set_dma_mode,
-       .udma_filter            = scc_udma_filter,
-       .cable_detect           = scc_cable_detect,
-};
-
-static const struct ide_dma_ops scc_dma_ops = {
-       .dma_host_set           = scc_dma_host_set,
-       .dma_setup              = scc_dma_setup,
-       .dma_start              = scc_dma_start,
-       .dma_end                = scc_dma_end,
-       .dma_test_irq           = scc_dma_test_irq,
-       .dma_lost_irq           = ide_dma_lost_irq,
-       .dma_timer_expiry       = ide_dma_sff_timer_expiry,
-       .dma_sff_read_status    = scc_dma_sff_read_status,
-};
-
-static const struct ide_port_info scc_chipset = {
-       .name           = "sccIDE",
-       .init_iops      = init_iops_scc,
-       .init_dma       = scc_init_dma,
-       .init_hwif      = init_hwif_scc,
-       .tp_ops         = &scc_tp_ops,
-       .port_ops       = &scc_port_ops,
-       .dma_ops        = &scc_dma_ops,
-       .host_flags     = IDE_HFLAG_SINGLE,
-       .irq_flags      = IRQF_SHARED,
-       .pio_mask       = ATA_PIO4,
-       .chipset        = ide_pci,
-};
-
-/**
- *     scc_init_one    -       pci layer discovery entry
- *     @dev: PCI device
- *     @id: ident table entry
- *
- *     Called by the PCI code when it finds an SCC PATA controller.
- *     We then use the IDE PCI generic helper to do most of the work.
- */
-
-static int scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       return init_setup_scc(dev, &scc_chipset);
-}
-
-/**
- *     scc_remove      -       pci layer remove entry
- *     @dev: PCI device
- *
- *     Called by the PCI code when it removes an SCC PATA controller.
- */
-
-static void scc_remove(struct pci_dev *dev)
-{
-       struct scc_ports *ports = pci_get_drvdata(dev);
-       struct ide_host *host = ports->host;
-
-       ide_host_remove(host);
-
-       iounmap((void*)ports->dma);
-       iounmap((void*)ports->ctl);
-       pci_release_selected_regions(dev, (1 << 2) - 1);
-       memset(ports, 0, sizeof(*ports));
-}
-
-static const struct pci_device_id scc_pci_tbl[] = {
-       { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0 },
-       { 0, },
-};
-MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
-
-static struct pci_driver scc_pci_driver = {
-       .name = "SCC IDE",
-       .id_table = scc_pci_tbl,
-       .probe = scc_init_one,
-       .remove = scc_remove,
-};
-
-static int __init scc_ide_init(void)
-{
-       return ide_pci_register_driver(&scc_pci_driver);
-}
-
-static void __exit scc_ide_exit(void)
-{
-       pci_unregister_driver(&scc_pci_driver);
-}
-
-module_init(scc_ide_init);
-module_exit(scc_ide_exit);
-
-MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
-MODULE_LICENSE("GPL");
index ab081702566fc47fd3fbbfe26a6ca7ef6bef58bc..e6ffa2e66c1ac54b7a2645f59bbb28c00bc91cc3 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "iwpm_util.h"
 
-static const char iwpm_ulib_name[] = "iWarpPortMapperUser";
+static const char iwpm_ulib_name[IWPM_ULIBNAME_SIZE] = "iWarpPortMapperUser";
 static int iwpm_ulib_version = 3;
 static int iwpm_user_pid = IWPM_PID_UNDEFINED;
 static atomic_t echo_nlmsg_seq;
index bb95a6c0477bb434cdcfd0e5e8f4408f6ec9e963..3ad8dc798f52c9101261882ac19138efb3905b94 100644 (file)
@@ -583,18 +583,18 @@ static void c4iw_record_pm_msg(struct c4iw_ep *ep,
                sizeof(ep->com.mapped_remote_addr));
 }
 
-static int get_remote_addr(struct c4iw_ep *ep)
+static int get_remote_addr(struct c4iw_ep *parent_ep, struct c4iw_ep *child_ep)
 {
        int ret;
 
-       print_addr(&ep->com, __func__, "get_remote_addr");
+       print_addr(&parent_ep->com, __func__, "get_remote_addr parent_ep ");
+       print_addr(&child_ep->com, __func__, "get_remote_addr child_ep ");
 
-       ret = iwpm_get_remote_info(&ep->com.mapped_local_addr,
-                                  &ep->com.mapped_remote_addr,
-                                  &ep->com.remote_addr, RDMA_NL_C4IW);
+       ret = iwpm_get_remote_info(&parent_ep->com.mapped_local_addr,
+                                  &child_ep->com.mapped_remote_addr,
+                                  &child_ep->com.remote_addr, RDMA_NL_C4IW);
        if (ret)
-               pr_info(MOD "Unable to find remote peer addr info - err %d\n",
-                       ret);
+               PDBG("Unable to find remote peer addr info - err %d\n", ret);
 
        return ret;
 }
@@ -2420,7 +2420,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
        }
        memcpy(&child_ep->com.remote_addr, &child_ep->com.mapped_remote_addr,
               sizeof(child_ep->com.remote_addr));
-       get_remote_addr(child_ep);
+       get_remote_addr(parent_ep, child_ep);
 
        c4iw_get_ep(&parent_ep->com);
        child_ep->parent_ep = parent_ep;
index cf54d6922dc47d18135253ffaf7d194bd1e39cc4..7e895d714b19e35a49ddd69f5a3432af5bcf1f71 100644 (file)
@@ -1386,7 +1386,7 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list)
                                          t4_sq_host_wq_pidx(&qp->wq),
                                          t4_sq_wq_size(&qp->wq));
                if (ret) {
-                       pr_err(KERN_ERR MOD "%s: Fatal error - "
+                       pr_err(MOD "%s: Fatal error - "
                               "DB overflow recovery failed - "
                               "error syncing SQ qid %u\n",
                               pci_name(ctx->lldi.pdev), qp->wq.sq.qid);
@@ -1402,7 +1402,7 @@ static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list)
                                          t4_rq_wq_size(&qp->wq));
 
                if (ret) {
-                       pr_err(KERN_ERR MOD "%s: Fatal error - "
+                       pr_err(MOD "%s: Fatal error - "
                               "DB overflow recovery failed - "
                               "error syncing RQ qid %u\n",
                               pci_name(ctx->lldi.pdev), qp->wq.rq.qid);
index 120aedf9f989a7a34839046a360dd9ad53816d64..cec1815329245cfa6573f39ce3f44f628175fea7 100644 (file)
@@ -77,7 +77,7 @@ int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
                return -EINVAL;
        }
 
-       memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
+       memcpy(&my_gid, gid->raw, sizeof(union ib_gid));
 
        subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
        interface_id = be64_to_cpu(my_gid.global.interface_id);
@@ -114,7 +114,7 @@ int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
                return -EINVAL;
        }
 
-       memcpy(&my_gid.raw, gid->raw, sizeof(union ib_gid));
+       memcpy(&my_gid, gid->raw, sizeof(union ib_gid));
 
        subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
        interface_id = be64_to_cpu(my_gid.global.interface_id);
index 57070c529dfb5ca038e2118212684dc54bb3d21b..cc64400d41ace3005c8a878b4c6811b0506726f9 100644 (file)
@@ -1569,8 +1569,7 @@ static void reset_gids_task(struct work_struct *work)
                               MLX4_CMD_TIME_CLASS_B,
                               MLX4_CMD_WRAPPED);
                if (err)
-                       pr_warn(KERN_WARNING
-                               "set port %d command failed\n", gw->port);
+                       pr_warn("set port %d command failed\n", gw->port);
        }
 
        mlx4_free_cmd_mailbox(dev, mailbox);
index 4d7024b899cb091a12aacfa9450af1e7750d4f45..d35f62d4f4c58ecce848cfb2d0544500c62dbfd3 100644 (file)
@@ -1392,7 +1392,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
 
        if (ah->ah_flags & IB_AH_GRH) {
                if (ah->grh.sgid_index >= gen->port[port - 1].gid_table_len) {
-                       pr_err(KERN_ERR "sgid_index (%u) too large. max is %d\n",
+                       pr_err("sgid_index (%u) too large. max is %d\n",
                               ah->grh.sgid_index, gen->port[port - 1].gid_table_len);
                        return -EINVAL;
                }
index ba5173e249738cb123560a29701bdacb496e9fc8..7df16f74bb4585e971e1208dd348911d142f78fb 100644 (file)
@@ -903,7 +903,7 @@ struct qib_devdata {
        /* PCI Device ID (here for NodeInfo) */
        u16 deviceid;
        /* for write combining settings */
-       unsigned long wc_cookie;
+       int wc_cookie;
        unsigned long wc_base;
        unsigned long wc_len;
 
index 6d61ef98721cb02f6b4baeead132cbe1d399753c..edd0ddbd44815d8e48ed49d3dec46e37545aa031 100644 (file)
@@ -118,7 +118,8 @@ int qib_enable_wc(struct qib_devdata *dd)
        if (!ret) {
                dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen);
                if (dd->wc_cookie < 0)
-                       ret = -EINVAL;
+                       /* use error from routine */
+                       ret = dd->wc_cookie;
        }
 
        return ret;
index a1cbba9056fdba15b1334bd923714c65957fc20c..3465faf1809e4cb1d6630e5cdc8f87cd4e405bd2 100644 (file)
@@ -266,6 +266,7 @@ static void put_pasid_state(struct pasid_state *pasid_state)
 
 static void put_pasid_state_wait(struct pasid_state *pasid_state)
 {
+       atomic_dec(&pasid_state->count);
        wait_event(pasid_state->wq, !atomic_read(&pasid_state->count));
        free_pasid_state(pasid_state);
 }
index 9f7e1d34a32bc8ec75c6470260c66f839419f502..66a803b9dd3af928024d853995ed31383e0a8dd2 100644 (file)
 #define RESUME_TERMINATE               (1 << 0)
 
 #define TTBCR2_SEP_SHIFT               15
-#define TTBCR2_SEP_MASK                        0x7
-
-#define TTBCR2_ADDR_32                 0
-#define TTBCR2_ADDR_36                 1
-#define TTBCR2_ADDR_40                 2
-#define TTBCR2_ADDR_42                 3
-#define TTBCR2_ADDR_44                 4
-#define TTBCR2_ADDR_48                 5
+#define TTBCR2_SEP_UPSTREAM            (0x7 << TTBCR2_SEP_SHIFT)
 
 #define TTBRn_HI_ASID_SHIFT            16
 
@@ -793,26 +786,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
                writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR);
                if (smmu->version > ARM_SMMU_V1) {
                        reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
-                       switch (smmu->va_size) {
-                       case 32:
-                               reg |= (TTBCR2_ADDR_32 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 36:
-                               reg |= (TTBCR2_ADDR_36 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 40:
-                               reg |= (TTBCR2_ADDR_40 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 42:
-                               reg |= (TTBCR2_ADDR_42 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 44:
-                               reg |= (TTBCR2_ADDR_44 << TTBCR2_SEP_SHIFT);
-                               break;
-                       case 48:
-                               reg |= (TTBCR2_ADDR_48 << TTBCR2_SEP_SHIFT);
-                               break;
-                       }
+                       reg |= TTBCR2_SEP_UPSTREAM;
                        writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR2);
                }
        } else {
index 4015560bf486db22e82f1652799731b90277b864..cab214544237cf6f89754c3878f0e57f66ba360d 100644 (file)
@@ -1004,20 +1004,18 @@ static int rk_iommu_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id rk_iommu_dt_ids[] = {
        { .compatible = "rockchip,iommu" },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, rk_iommu_dt_ids);
-#endif
 
 static struct platform_driver rk_iommu_driver = {
        .probe = rk_iommu_probe,
        .remove = rk_iommu_remove,
        .driver = {
                   .name = "rk_iommu",
-                  .of_match_table = of_match_ptr(rk_iommu_dt_ids),
+                  .of_match_table = rk_iommu_dt_ids,
        },
 };
 
index 51c485d9a87736bcf06cfdf67c089f81288bc8d8..f67bbd80433e8c90527a9b911a2656987b800b96 100644 (file)
@@ -264,7 +264,7 @@ static int tegra_ictlr_domain_alloc(struct irq_domain *domain,
 
                irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
                                              &tegra_ictlr_chip,
-                                             &info->base[ictlr]);
+                                             info->base[ictlr]);
        }
 
        parent_args = *args;
index 2cb59a641cd24417d996df89c2e2c81cc9eb087b..6a68ef5246d49962c5be7b152f8f121f61d4de04 100644 (file)
@@ -188,8 +188,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
                }
                dev[j] = rdev1;
 
-               disk_stack_limits(mddev->gendisk, rdev1->bdev,
-                                 rdev1->data_offset << 9);
+               if (mddev->queue)
+                       disk_stack_limits(mddev->gendisk, rdev1->bdev,
+                                         rdev1->data_offset << 9);
 
                if (rdev1->bdev->bd_disk->queue->merge_bvec_fn)
                        conf->has_merge_bvec = 1;
index 77dfd720aaa00ebc55d14234cd40b6e9b65bae5f..1ba97fdc6df1e3a6df76b42aa0e756c01644a385 100644 (file)
@@ -1078,9 +1078,6 @@ again:
                        pr_debug("skip op %ld on disc %d for sector %llu\n",
                                bi->bi_rw, i, (unsigned long long)sh->sector);
                        clear_bit(R5_LOCKED, &sh->dev[i].flags);
-                       if (sh->batch_head)
-                               set_bit(STRIPE_BATCH_ERR,
-                                       &sh->batch_head->state);
                        set_bit(STRIPE_HANDLE, &sh->state);
                }
 
@@ -1971,17 +1968,30 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
        put_cpu();
 }
 
+static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp)
+{
+       struct stripe_head *sh;
+
+       sh = kmem_cache_zalloc(sc, gfp);
+       if (sh) {
+               spin_lock_init(&sh->stripe_lock);
+               spin_lock_init(&sh->batch_lock);
+               INIT_LIST_HEAD(&sh->batch_list);
+               INIT_LIST_HEAD(&sh->lru);
+               atomic_set(&sh->count, 1);
+       }
+       return sh;
+}
 static int grow_one_stripe(struct r5conf *conf, gfp_t gfp)
 {
        struct stripe_head *sh;
-       sh = kmem_cache_zalloc(conf->slab_cache, gfp);
+
+       sh = alloc_stripe(conf->slab_cache, gfp);
        if (!sh)
                return 0;
 
        sh->raid_conf = conf;
 
-       spin_lock_init(&sh->stripe_lock);
-
        if (grow_buffers(sh, gfp)) {
                shrink_buffers(sh);
                kmem_cache_free(conf->slab_cache, sh);
@@ -1990,13 +2000,8 @@ static int grow_one_stripe(struct r5conf *conf, gfp_t gfp)
        sh->hash_lock_index =
                conf->max_nr_stripes % NR_STRIPE_HASH_LOCKS;
        /* we just created an active stripe so... */
-       atomic_set(&sh->count, 1);
        atomic_inc(&conf->active_stripes);
-       INIT_LIST_HEAD(&sh->lru);
 
-       spin_lock_init(&sh->batch_lock);
-       INIT_LIST_HEAD(&sh->batch_list);
-       sh->batch_head = NULL;
        release_stripe(sh);
        conf->max_nr_stripes++;
        return 1;
@@ -2060,6 +2065,35 @@ static struct flex_array *scribble_alloc(int num, int cnt, gfp_t flags)
        return ret;
 }
 
+static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
+{
+       unsigned long cpu;
+       int err = 0;
+
+       mddev_suspend(conf->mddev);
+       get_online_cpus();
+       for_each_present_cpu(cpu) {
+               struct raid5_percpu *percpu;
+               struct flex_array *scribble;
+
+               percpu = per_cpu_ptr(conf->percpu, cpu);
+               scribble = scribble_alloc(new_disks,
+                                         new_sectors / STRIPE_SECTORS,
+                                         GFP_NOIO);
+
+               if (scribble) {
+                       flex_array_free(percpu->scribble);
+                       percpu->scribble = scribble;
+               } else {
+                       err = -ENOMEM;
+                       break;
+               }
+       }
+       put_online_cpus();
+       mddev_resume(conf->mddev);
+       return err;
+}
+
 static int resize_stripes(struct r5conf *conf, int newsize)
 {
        /* Make all the stripes able to hold 'newsize' devices.
@@ -2088,7 +2122,6 @@ static int resize_stripes(struct r5conf *conf, int newsize)
        struct stripe_head *osh, *nsh;
        LIST_HEAD(newstripes);
        struct disk_info *ndisks;
-       unsigned long cpu;
        int err;
        struct kmem_cache *sc;
        int i;
@@ -2109,13 +2142,11 @@ static int resize_stripes(struct r5conf *conf, int newsize)
                return -ENOMEM;
 
        for (i = conf->max_nr_stripes; i; i--) {
-               nsh = kmem_cache_zalloc(sc, GFP_KERNEL);
+               nsh = alloc_stripe(sc, GFP_KERNEL);
                if (!nsh)
                        break;
 
                nsh->raid_conf = conf;
-               spin_lock_init(&nsh->stripe_lock);
-
                list_add(&nsh->lru, &newstripes);
        }
        if (i) {
@@ -2142,13 +2173,11 @@ static int resize_stripes(struct r5conf *conf, int newsize)
                                    lock_device_hash_lock(conf, hash));
                osh = get_free_stripe(conf, hash);
                unlock_device_hash_lock(conf, hash);
-               atomic_set(&nsh->count, 1);
+
                for(i=0; i<conf->pool_size; i++) {
                        nsh->dev[i].page = osh->dev[i].page;
                        nsh->dev[i].orig_page = osh->dev[i].page;
                }
-               for( ; i<newsize; i++)
-                       nsh->dev[i].page = NULL;
                nsh->hash_lock_index = hash;
                kmem_cache_free(conf->slab_cache, osh);
                cnt++;
@@ -2174,25 +2203,6 @@ static int resize_stripes(struct r5conf *conf, int newsize)
        } else
                err = -ENOMEM;
 
-       get_online_cpus();
-       for_each_present_cpu(cpu) {
-               struct raid5_percpu *percpu;
-               struct flex_array *scribble;
-
-               percpu = per_cpu_ptr(conf->percpu, cpu);
-               scribble = scribble_alloc(newsize, conf->chunk_sectors /
-                       STRIPE_SECTORS, GFP_NOIO);
-
-               if (scribble) {
-                       flex_array_free(percpu->scribble);
-                       percpu->scribble = scribble;
-               } else {
-                       err = -ENOMEM;
-                       break;
-               }
-       }
-       put_online_cpus();
-
        /* Step 4, return new stripes to service */
        while(!list_empty(&newstripes)) {
                nsh = list_entry(newstripes.next, struct stripe_head, lru);
@@ -2212,7 +2222,8 @@ static int resize_stripes(struct r5conf *conf, int newsize)
 
        conf->slab_cache = sc;
        conf->active_name = 1-conf->active_name;
-       conf->pool_size = newsize;
+       if (!err)
+               conf->pool_size = newsize;
        return err;
 }
 
@@ -2434,7 +2445,7 @@ static void raid5_end_write_request(struct bio *bi, int error)
        }
        rdev_dec_pending(rdev, conf->mddev);
 
-       if (sh->batch_head && !uptodate)
+       if (sh->batch_head && !uptodate && !replacement)
                set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state);
 
        if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags))
@@ -3278,7 +3289,9 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s,
                /* reconstruct-write isn't being forced */
                return 0;
        for (i = 0; i < s->failed; i++) {
-               if (!test_bit(R5_UPTODATE, &fdev[i]->flags) &&
+               if (s->failed_num[i] != sh->pd_idx &&
+                   s->failed_num[i] != sh->qd_idx &&
+                   !test_bit(R5_UPTODATE, &fdev[i]->flags) &&
                    !test_bit(R5_OVERWRITE, &fdev[i]->flags))
                        return 1;
        }
@@ -3298,6 +3311,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s,
                 */
                BUG_ON(test_bit(R5_Wantcompute, &dev->flags));
                BUG_ON(test_bit(R5_Wantread, &dev->flags));
+               BUG_ON(sh->batch_head);
                if ((s->uptodate == disks - 1) &&
                    (s->failed && (disk_idx == s->failed_num[0] ||
                                   disk_idx == s->failed_num[1]))) {
@@ -3366,7 +3380,6 @@ static void handle_stripe_fill(struct stripe_head *sh,
 {
        int i;
 
-       BUG_ON(sh->batch_head);
        /* look for blocks to read/compute, skip this if a compute
         * is already in flight, or if the stripe contents are in the
         * midst of changing due to a write
@@ -4198,15 +4211,9 @@ static void check_break_stripe_batch_list(struct stripe_head *sh)
                return;
 
        head_sh = sh;
-       do {
-               sh = list_first_entry(&sh->batch_list,
-                                     struct stripe_head, batch_list);
-               BUG_ON(sh == head_sh);
-       } while (!test_bit(STRIPE_DEGRADED, &sh->state));
 
-       while (sh != head_sh) {
-               next = list_first_entry(&sh->batch_list,
-                                       struct stripe_head, batch_list);
+       list_for_each_entry_safe(sh, next, &head_sh->batch_list, batch_list) {
+
                list_del_init(&sh->batch_list);
 
                set_mask_bits(&sh->state, ~STRIPE_EXPAND_SYNC_FLAG,
@@ -4226,8 +4233,6 @@ static void check_break_stripe_batch_list(struct stripe_head *sh)
 
                set_bit(STRIPE_HANDLE, &sh->state);
                release_stripe(sh);
-
-               sh = next;
        }
 }
 
@@ -6221,8 +6226,11 @@ static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu
                percpu->spare_page = alloc_page(GFP_KERNEL);
        if (!percpu->scribble)
                percpu->scribble = scribble_alloc(max(conf->raid_disks,
-                       conf->previous_raid_disks), conf->chunk_sectors /
-                       STRIPE_SECTORS, GFP_KERNEL);
+                                                     conf->previous_raid_disks),
+                                                 max(conf->chunk_sectors,
+                                                     conf->prev_chunk_sectors)
+                                                  / STRIPE_SECTORS,
+                                                 GFP_KERNEL);
 
        if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) {
                free_scratch_buffer(conf, percpu);
@@ -7198,6 +7206,15 @@ static int check_reshape(struct mddev *mddev)
        if (!check_stripe_cache(mddev))
                return -ENOSPC;
 
+       if (mddev->new_chunk_sectors > mddev->chunk_sectors ||
+           mddev->delta_disks > 0)
+               if (resize_chunks(conf,
+                                 conf->previous_raid_disks
+                                 + max(0, mddev->delta_disks),
+                                 max(mddev->new_chunk_sectors,
+                                     mddev->chunk_sectors)
+                           ) < 0)
+                       return -ENOMEM;
        return resize_stripes(conf, (conf->previous_raid_disks
                                     + mddev->delta_disks));
 }
index 6bddfe062b516467b6cc2be75a53c17c2040b2d7..fc55e8e0351dfe5f3ca436d8aed64bf6d660db84 100644 (file)
@@ -509,10 +509,11 @@ static int xcan_rx(struct net_device *ndev)
                        cf->can_id |= CAN_RTR_FLAG;
        }
 
-       if (!(id_xcan & XCAN_IDR_SRR_MASK)) {
-               data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET);
-               data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET);
+       /* DW1/DW2 must always be read to remove message from RXFIFO */
+       data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET);
+       data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET);
 
+       if (!(cf->can_id & CAN_RTR_FLAG)) {
                /* Change Xilinx CAN data format to socketCAN data format */
                if (cf->can_dlc > 0)
                        *(__be32 *)(cf->data) = cpu_to_be32(data[0]);
index af639ab4c55b64fd886df0413d090afd2fe618ba..cf309aa92802623ec0532b56b1dd10a88a234af1 100644 (file)
@@ -1469,6 +1469,9 @@ static void __exit mv88e6xxx_cleanup(void)
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
        unregister_switch_driver(&mv88e6171_switch_driver);
 #endif
+#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
+       unregister_switch_driver(&mv88e6352_switch_driver);
+#endif
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
        unregister_switch_driver(&mv88e6123_61_65_switch_driver);
 #endif
index 089c269637b725da7876db7e4988baa77b5ec171..426916036151649ca3a2cef4e69eb00735826c05 100644 (file)
@@ -180,6 +180,7 @@ config SUNLANCE
 config AMD_XGBE
        tristate "AMD 10GbE Ethernet driver"
        depends on (OF_NET || ACPI) && HAS_IOMEM && HAS_DMA
+       depends on ARM64 || COMPILE_TEST
        select PHYLIB
        select AMD_XGBE_PHY
        select BITREVERSE
index f4054d242f3c7ac6e52437c5cb795cac8e3da2dd..19e38afbc5ee3f5a015fd55ecba813c26a9bca1a 100644 (file)
@@ -1,6 +1,7 @@
 config NET_XGENE
        tristate "APM X-Gene SoC Ethernet Driver"
        depends on HAS_DMA
+       depends on ARCH_XGENE || COMPILE_TEST
        select PHYLIB
        help
          This is the Ethernet driver for the on-chip ethernet interface on the
index a8bb8f664d3d7f9a031158d5cac82820fbed7d6d..ec56a9b65dc3a313e1b0571e8a58047c161f6507 100644 (file)
@@ -4786,6 +4786,11 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct bnx2x *bp = netdev_priv(dev);
 
+       if (pci_num_vf(bp->pdev)) {
+               DP(BNX2X_MSG_IOV, "VFs are enabled, can not change MTU\n");
+               return -EPERM;
+       }
+
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
                BNX2X_ERR("Can't perform change MTU during parity recovery\n");
                return -EAGAIN;
@@ -4938,11 +4943,6 @@ int bnx2x_resume(struct pci_dev *pdev)
        }
        bp = netdev_priv(dev);
 
-       if (pci_num_vf(bp->pdev)) {
-               DP(BNX2X_MSG_IOV, "VFs are enabled, can not change MTU\n");
-               return -EPERM;
-       }
-
        if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
                BNX2X_ERR("Handling parity error recovery. Try again later\n");
                return -EAGAIN;
index 556dcc162a6252a36fe550110b4abbb3d1bbcf60..fd52ce95127ef98b7c0687594024357b05c1a848 100644 (file)
@@ -13371,8 +13371,13 @@ static int bnx2x_init_one(struct pci_dev *pdev,
        /* Management FW 'remembers' living interfaces. Allow it some time
         * to forget previously living interfaces, allowing a proper re-load.
         */
-       if (is_kdump_kernel())
-               msleep(5000);
+       if (is_kdump_kernel()) {
+               ktime_t now = ktime_get_boottime();
+               ktime_t fw_ready_time = ktime_set(5, 0);
+
+               if (ktime_before(now, fw_ready_time))
+                       msleep(ktime_ms_delta(fw_ready_time, now));
+       }
 
        /* An estimated maximum supported CoS number according to the chip
         * version.
index 4104d49f005d4a825eb14b99efeb5f158ab456d5..61aa570aad9a1b821613de323ef54701010fce53 100644 (file)
@@ -981,7 +981,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
        struct macb_queue *queue = dev_id;
        struct macb *bp = queue->bp;
        struct net_device *dev = bp->dev;
-       u32 status;
+       u32 status, ctrl;
 
        status = queue_readl(queue, ISR);
 
@@ -1037,6 +1037,15 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                 * add that if/when we get our hands on a full-blown MII PHY.
                 */
 
+               if (status & MACB_BIT(RXUBR)) {
+                       ctrl = macb_readl(bp, NCR);
+                       macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE));
+                       macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
+
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               macb_writel(bp, ISR, MACB_BIT(RXUBR));
+               }
+
                if (status & MACB_BIT(ISR_ROVR)) {
                        /* We missed at least one packet */
                        if (macb_is_gem(bp))
index 5d9ceb17b4cbad4f7e89cf0bb050e915f5b8d285..0abc942c966e4a377af222c1d876af6983edb91a 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/ptp_classify.h>
 #include <linux/mii.h>
 #include <linux/mdio.h>
+#include <linux/pm_qos.h>
 #include "hw.h"
 
 struct e1000_info;
index 1b0661e3573b78d73804ed59177420a4d6fde147..c754b2027281f8a2c0b18c079b31c2b7420eedbf 100644 (file)
@@ -610,7 +610,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
        unsigned int total_bytes = 0, total_packets = 0;
        u16 cleaned_count = fm10k_desc_unused(rx_ring);
 
-       do {
+       while (likely(total_packets < budget)) {
                union fm10k_rx_desc *rx_desc;
 
                /* return some buffers to hardware, one at a time is too slow */
@@ -659,7 +659,7 @@ static bool fm10k_clean_rx_irq(struct fm10k_q_vector *q_vector,
 
                /* update budget accounting */
                total_packets++;
-       } while (likely(total_packets < budget));
+       }
 
        /* place incomplete frames back on ring for completion */
        rx_ring->skb = skb;
index 8457d0306e3a76107c18ed524a3000d47b3ead6e..a0a9b1fcb5e8efcf4f7ebfe980459f64056e896f 100644 (file)
@@ -1036,7 +1036,7 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
                adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL;
 
        if (q_vector->rx.ring)
-               adapter->tx_ring[q_vector->rx.ring->queue_index] = NULL;
+               adapter->rx_ring[q_vector->rx.ring->queue_index] = NULL;
 
        netif_napi_del(&q_vector->napi);
 
@@ -1207,6 +1207,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
        q_vector = adapter->q_vector[v_idx];
        if (!q_vector)
                q_vector = kzalloc(size, GFP_KERNEL);
+       else
+               memset(q_vector, 0, size);
        if (!q_vector)
                return -ENOMEM;
 
index a16d267fbce4b0f6883c8cf5d43db1ad3bf7e458..e71cdde9cb017aecab834d2f2d9c5d4821c3d42e 100644 (file)
@@ -3612,7 +3612,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        u8 *dst_mac = skb_header_pointer(skb, 0, 0, NULL);
 
        if (!dst_mac || is_link_local_ether_addr(dst_mac)) {
-               dev_kfree_skb(skb);
+               dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
        }
 
index 54f0e5ab2e55ca87dc66a2ef8b4e27062a634ce4..0a56f010c8468d0734c3afd791605843d373b91a 100644 (file)
@@ -139,7 +139,7 @@ static unsigned long en_stats_adder(__be64 *start, __be64 *next, int num)
        int i;
        int offset = next - start;
 
-       for (i = 0; i <= num; i++) {
+       for (i = 0; i < num; i++) {
                ret += be64_to_cpu(*curr);
                curr += offset;
        }
index c7f28bf4b8e21436cc927c8212c5cc6b57706e51..92fce1b985589b993e3feccbf528e57c3a91fdb0 100644 (file)
@@ -2845,7 +2845,7 @@ int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave,
 {
        int err;
        int eqn = vhcr->in_modifier;
-       int res_id = (slave << 8) | eqn;
+       int res_id = (slave << 10) | eqn;
        struct mlx4_eq_context *eqc = inbox->buf;
        int mtt_base = eq_get_mtt_addr(eqc) / dev->caps.mtt_entry_sz;
        int mtt_size = eq_get_mtt_size(eqc);
@@ -3051,7 +3051,7 @@ int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev *dev, int slave,
                          struct mlx4_cmd_info *cmd)
 {
        int eqn = vhcr->in_modifier;
-       int res_id = eqn | (slave << 8);
+       int res_id = eqn | (slave << 10);
        struct res_eq *eq;
        int err;
 
@@ -3108,7 +3108,7 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe)
                return 0;
 
        mutex_lock(&priv->mfunc.master.gen_eqe_mutex[slave]);
-       res_id = (slave << 8) | event_eq->eqn;
+       res_id = (slave << 10) | event_eq->eqn;
        err = get_res(dev, slave, res_id, RES_EQ, &req);
        if (err)
                goto unlock;
@@ -3131,7 +3131,7 @@ int mlx4_GEN_EQE(struct mlx4_dev *dev, int slave, struct mlx4_eqe *eqe)
 
        memcpy(mailbox->buf, (u8 *) eqe, 28);
 
-       in_modifier = (slave & 0xff) | ((event_eq->eqn & 0xff) << 16);
+       in_modifier = (slave & 0xff) | ((event_eq->eqn & 0x3ff) << 16);
 
        err = mlx4_cmd(dev, mailbox->dma, in_modifier, 0,
                       MLX4_CMD_GEN_EQE, MLX4_CMD_TIME_CLASS_B,
@@ -3157,7 +3157,7 @@ int mlx4_QUERY_EQ_wrapper(struct mlx4_dev *dev, int slave,
                          struct mlx4_cmd_info *cmd)
 {
        int eqn = vhcr->in_modifier;
-       int res_id = eqn | (slave << 8);
+       int res_id = eqn | (slave << 10);
        struct res_eq *eq;
        int err;
 
@@ -4714,13 +4714,13 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
                                        break;
 
                                case RES_EQ_HW:
-                                       err = mlx4_cmd(dev, slave, eqn & 0xff,
+                                       err = mlx4_cmd(dev, slave, eqn & 0x3ff,
                                                       1, MLX4_CMD_HW2SW_EQ,
                                                       MLX4_CMD_TIME_CLASS_A,
                                                       MLX4_CMD_NATIVE);
                                        if (err)
                                                mlx4_dbg(dev, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n",
-                                                        slave, eqn);
+                                                        slave, eqn & 0x3ff);
                                        atomic_dec(&eq->mtt->ref_count);
                                        state = RES_EQ_RESERVED;
                                        break;
index 8da7c3faf8178c05576c74833fc828f197104f52..7b43a3b4abdcbc7bc1cdfd4d13c611563e2760a2 100644 (file)
@@ -1764,7 +1764,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
        int done = 0;
        struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
 
-       if (!spin_trylock(&adapter->tx_clean_lock))
+       if (!spin_trylock_bh(&adapter->tx_clean_lock))
                return 1;
 
        sw_consumer = tx_ring->sw_consumer;
@@ -1819,7 +1819,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
         */
        hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
        done = (sw_consumer == hw_consumer);
-       spin_unlock(&adapter->tx_clean_lock);
+       spin_unlock_bh(&adapter->tx_clean_lock);
 
        return done;
 }
index f66641d961e3bc18ae15a301323497ff9fb265e8..6af028d5f9bcbdcc3aae303a114fd64d87986eed 100644 (file)
@@ -912,6 +912,8 @@ qca_spi_probe(struct spi_device *spi_device)
        qca->spi_dev = spi_device;
        qca->legacy_mode = legacy_mode;
 
+       spi_set_drvdata(spi_device, qcaspi_devs);
+
        mac = of_get_mac_address(spi_device->dev.of_node);
 
        if (mac)
@@ -944,8 +946,6 @@ qca_spi_probe(struct spi_device *spi_device)
                return -EFAULT;
        }
 
-       spi_set_drvdata(spi_device, qcaspi_devs);
-
        qcaspi_init_device_debugfs(qca);
 
        return 0;
index c70ab40d86989974d54c9161bf7acd8558d93c74..3df51faf18ae3ba8ce6bb7f49e6f51e4da1be738 100644 (file)
@@ -6884,7 +6884,7 @@ static void r8169_csum_workaround(struct rtl8169_private *tp,
                        rtl8169_start_xmit(nskb, tp->dev);
                } while (segs);
 
-               dev_kfree_skb(skb);
+               dev_consume_skb_any(skb);
        } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
                if (skb_checksum_help(skb) < 0)
                        goto drop;
@@ -6896,7 +6896,7 @@ static void r8169_csum_workaround(struct rtl8169_private *tp,
 drop:
                stats = &tp->dev->stats;
                stats->tx_dropped++;
-               dev_kfree_skb(skb);
+               dev_kfree_skb_any(skb);
        }
 }
 
index 14b363a25c023c70f13b73e9c485bf28e9d533e2..630f0b7800e47e085c5ffb2db6ac23efef9ad08c 100644 (file)
@@ -2238,9 +2238,10 @@ static int smc_drv_probe(struct platform_device *pdev)
        const struct of_device_id *match = NULL;
        struct smc_local *lp;
        struct net_device *ndev;
-       struct resource *res, *ires;
+       struct resource *res;
        unsigned int __iomem *addr;
        unsigned long irq_flags = SMC_IRQ_FLAGS;
+       unsigned long irq_resflags;
        int ret;
 
        ndev = alloc_etherdev(sizeof(struct smc_local));
@@ -2332,16 +2333,19 @@ static int smc_drv_probe(struct platform_device *pdev)
                goto out_free_netdev;
        }
 
-       ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!ires) {
+       ndev->irq = platform_get_irq(pdev, 0);
+       if (ndev->irq <= 0) {
                ret = -ENODEV;
                goto out_release_io;
        }
-
-       ndev->irq = ires->start;
-
-       if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK)
-               irq_flags = ires->flags & IRQF_TRIGGER_MASK;
+       /*
+        * If this platform does not specify any special irqflags, or if
+        * the resource supplies a trigger, override the irqflags with
+        * the trigger flags from the resource.
+        */
+       irq_resflags = irqd_get_trigger_type(irq_get_irq_data(ndev->irq));
+       if (irq_flags == -1 || irq_resflags & IRQF_TRIGGER_MASK)
+               irq_flags = irq_resflags & IRQF_TRIGGER_MASK;
 
        ret = smc_request_attrib(pdev, ndev);
        if (ret)
index 41047c9143d0a66cde1441311fb5feb3ce0796d0..959aeeade0c97b8cbf5ee27024ecda185c6258b2 100644 (file)
@@ -2418,9 +2418,9 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
        struct net_device *dev;
        struct smsc911x_data *pdata;
        struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev);
-       struct resource *res, *irq_res;
+       struct resource *res;
        unsigned int intcfg = 0;
-       int res_size, irq_flags;
+       int res_size, irq, irq_flags;
        int retval;
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
@@ -2434,8 +2434,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
        }
        res_size = resource_size(res);
 
-       irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (!irq_res) {
+       irq = platform_get_irq(pdev, 0);
+       if (irq <= 0) {
                pr_warn("Could not allocate irq resource\n");
                retval = -ENODEV;
                goto out_0;
@@ -2455,8 +2455,8 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        pdata = netdev_priv(dev);
-       dev->irq = irq_res->start;
-       irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
+       dev->irq = irq;
+       irq_flags = irq_get_trigger_type(irq);
        pdata->ioaddr = ioremap_nocache(res->start, res_size);
 
        pdata->dev = dev;
index 705bbdf9394058944927fd575d1dfc47cdb283d5..68aec5c460db46c1378cdf122c3ad8f4eba15e86 100644 (file)
@@ -23,6 +23,7 @@
 *******************************************************************************/
 
 #include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_net.h>
index 690a4c36b3166c76b4d8ed63f9d21574ecac8bb3..af2694dc6f90146fc2afe9073a0dde7058731f59 100644 (file)
@@ -707,8 +707,8 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
        cur_p->app0 |= STS_CTRL_APP0_SOP;
        cur_p->len = skb_headlen(skb);
-       cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
-                                    DMA_TO_DEVICE);
+       cur_p->phys = dma_map_single(ndev->dev.parent, skb->data,
+                                    skb_headlen(skb), DMA_TO_DEVICE);
        cur_p->app4 = (unsigned long)skb;
 
        for (ii = 0; ii < num_frag; ii++) {
index 2d9ef533cc4837c5bd7b46c96958f9f1b9eda323..ea091bc5ff09dad379fde915fbb7ec073c613aa1 100644 (file)
@@ -826,7 +826,6 @@ int netvsc_send(struct hv_device *device,
        u16 q_idx = packet->q_idx;
        u32 pktlen = packet->total_data_buflen, msd_len = 0;
        unsigned int section_index = NETVSC_INVALID_INDEX;
-       struct sk_buff *skb = NULL;
        unsigned long flag;
        struct multi_send_data *msdp;
        struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL;
@@ -924,12 +923,8 @@ int netvsc_send(struct hv_device *device,
        if (cur_send)
                ret = netvsc_send_pkt(cur_send, net_device);
 
-       if (ret != 0) {
-               if (section_index != NETVSC_INVALID_INDEX)
-                       netvsc_free_send_slot(net_device, section_index);
-       } else if (skb) {
-               dev_kfree_skb_any(skb);
-       }
+       if (ret != 0 && section_index != NETVSC_INVALID_INDEX)
+               netvsc_free_send_slot(net_device, section_index);
 
        return ret;
 }
index 38026650c0387ecb101d085e24273bf24ded2783..67d00fbc2e0e29e7bd426ed8f7d21b22bf6772fc 100644 (file)
@@ -85,6 +85,7 @@ struct at86rf230_local {
        struct ieee802154_hw *hw;
        struct at86rf2xx_chip_data *data;
        struct regmap *regmap;
+       int slp_tr;
 
        struct completion state_complete;
        struct at86rf230_state_change state;
@@ -95,163 +96,164 @@ struct at86rf230_local {
        unsigned long cal_timeout;
        s8 max_frame_retries;
        bool is_tx;
+       bool is_tx_from_off;
        u8 tx_retry;
        struct sk_buff *tx_skb;
        struct at86rf230_state_change tx;
 };
 
-#define        RG_TRX_STATUS   (0x01)
-#define        SR_TRX_STATUS           0x01, 0x1f, 0
-#define        SR_RESERVED_01_3        0x01, 0x20, 5
-#define        SR_CCA_STATUS           0x01, 0x40, 6
-#define        SR_CCA_DONE             0x01, 0x80, 7
-#define        RG_TRX_STATE    (0x02)
-#define        SR_TRX_CMD              0x02, 0x1f, 0
-#define        SR_TRAC_STATUS          0x02, 0xe0, 5
-#define        RG_TRX_CTRL_0   (0x03)
-#define        SR_CLKM_CTRL            0x03, 0x07, 0
-#define        SR_CLKM_SHA_SEL         0x03, 0x08, 3
-#define        SR_PAD_IO_CLKM          0x03, 0x30, 4
-#define        SR_PAD_IO               0x03, 0xc0, 6
-#define        RG_TRX_CTRL_1   (0x04)
-#define        SR_IRQ_POLARITY         0x04, 0x01, 0
-#define        SR_IRQ_MASK_MODE        0x04, 0x02, 1
-#define        SR_SPI_CMD_MODE         0x04, 0x0c, 2
-#define        SR_RX_BL_CTRL           0x04, 0x10, 4
-#define        SR_TX_AUTO_CRC_ON       0x04, 0x20, 5
-#define        SR_IRQ_2_EXT_EN         0x04, 0x40, 6
-#define        SR_PA_EXT_EN            0x04, 0x80, 7
-#define        RG_PHY_TX_PWR   (0x05)
-#define        SR_TX_PWR               0x05, 0x0f, 0
-#define        SR_PA_LT                0x05, 0x30, 4
-#define        SR_PA_BUF_LT            0x05, 0xc0, 6
-#define        RG_PHY_RSSI     (0x06)
-#define        SR_RSSI                 0x06, 0x1f, 0
-#define        SR_RND_VALUE            0x06, 0x60, 5
-#define        SR_RX_CRC_VALID         0x06, 0x80, 7
-#define        RG_PHY_ED_LEVEL (0x07)
-#define        SR_ED_LEVEL             0x07, 0xff, 0
-#define        RG_PHY_CC_CCA   (0x08)
-#define        SR_CHANNEL              0x08, 0x1f, 0
-#define        SR_CCA_MODE             0x08, 0x60, 5
-#define        SR_CCA_REQUEST          0x08, 0x80, 7
-#define        RG_CCA_THRES    (0x09)
-#define        SR_CCA_ED_THRES         0x09, 0x0f, 0
-#define        SR_RESERVED_09_1        0x09, 0xf0, 4
-#define        RG_RX_CTRL      (0x0a)
-#define        SR_PDT_THRES            0x0a, 0x0f, 0
-#define        SR_RESERVED_0a_1        0x0a, 0xf0, 4
-#define        RG_SFD_VALUE    (0x0b)
-#define        SR_SFD_VALUE            0x0b, 0xff, 0
-#define        RG_TRX_CTRL_2   (0x0c)
-#define        SR_OQPSK_DATA_RATE      0x0c, 0x03, 0
-#define        SR_SUB_MODE             0x0c, 0x04, 2
-#define        SR_BPSK_QPSK            0x0c, 0x08, 3
-#define        SR_OQPSK_SUB1_RC_EN     0x0c, 0x10, 4
-#define        SR_RESERVED_0c_5        0x0c, 0x60, 5
-#define        SR_RX_SAFE_MODE         0x0c, 0x80, 7
-#define        RG_ANT_DIV      (0x0d)
-#define        SR_ANT_CTRL             0x0d, 0x03, 0
-#define        SR_ANT_EXT_SW_EN        0x0d, 0x04, 2
-#define        SR_ANT_DIV_EN           0x0d, 0x08, 3
-#define        SR_RESERVED_0d_2        0x0d, 0x70, 4
-#define        SR_ANT_SEL              0x0d, 0x80, 7
-#define        RG_IRQ_MASK     (0x0e)
-#define        SR_IRQ_MASK             0x0e, 0xff, 0
-#define        RG_IRQ_STATUS   (0x0f)
-#define        SR_IRQ_0_PLL_LOCK       0x0f, 0x01, 0
-#define        SR_IRQ_1_PLL_UNLOCK     0x0f, 0x02, 1
-#define        SR_IRQ_2_RX_START       0x0f, 0x04, 2
-#define        SR_IRQ_3_TRX_END        0x0f, 0x08, 3
-#define        SR_IRQ_4_CCA_ED_DONE    0x0f, 0x10, 4
-#define        SR_IRQ_5_AMI            0x0f, 0x20, 5
-#define        SR_IRQ_6_TRX_UR         0x0f, 0x40, 6
-#define        SR_IRQ_7_BAT_LOW        0x0f, 0x80, 7
-#define        RG_VREG_CTRL    (0x10)
-#define        SR_RESERVED_10_6        0x10, 0x03, 0
-#define        SR_DVDD_OK              0x10, 0x04, 2
-#define        SR_DVREG_EXT            0x10, 0x08, 3
-#define        SR_RESERVED_10_3        0x10, 0x30, 4
-#define        SR_AVDD_OK              0x10, 0x40, 6
-#define        SR_AVREG_EXT            0x10, 0x80, 7
-#define        RG_BATMON       (0x11)
-#define        SR_BATMON_VTH           0x11, 0x0f, 0
-#define        SR_BATMON_HR            0x11, 0x10, 4
-#define        SR_BATMON_OK            0x11, 0x20, 5
-#define        SR_RESERVED_11_1        0x11, 0xc0, 6
-#define        RG_XOSC_CTRL    (0x12)
-#define        SR_XTAL_TRIM            0x12, 0x0f, 0
-#define        SR_XTAL_MODE            0x12, 0xf0, 4
-#define        RG_RX_SYN       (0x15)
-#define        SR_RX_PDT_LEVEL         0x15, 0x0f, 0
-#define        SR_RESERVED_15_2        0x15, 0x70, 4
-#define        SR_RX_PDT_DIS           0x15, 0x80, 7
-#define        RG_XAH_CTRL_1   (0x17)
-#define        SR_RESERVED_17_8        0x17, 0x01, 0
-#define        SR_AACK_PROM_MODE       0x17, 0x02, 1
-#define        SR_AACK_ACK_TIME        0x17, 0x04, 2
-#define        SR_RESERVED_17_5        0x17, 0x08, 3
-#define        SR_AACK_UPLD_RES_FT     0x17, 0x10, 4
-#define        SR_AACK_FLTR_RES_FT     0x17, 0x20, 5
-#define        SR_CSMA_LBT_MODE        0x17, 0x40, 6
-#define        SR_RESERVED_17_1        0x17, 0x80, 7
-#define        RG_FTN_CTRL     (0x18)
-#define        SR_RESERVED_18_2        0x18, 0x7f, 0
-#define        SR_FTN_START            0x18, 0x80, 7
-#define        RG_PLL_CF       (0x1a)
-#define        SR_RESERVED_1a_2        0x1a, 0x7f, 0
-#define        SR_PLL_CF_START         0x1a, 0x80, 7
-#define        RG_PLL_DCU      (0x1b)
-#define        SR_RESERVED_1b_3        0x1b, 0x3f, 0
-#define        SR_RESERVED_1b_2        0x1b, 0x40, 6
-#define        SR_PLL_DCU_START        0x1b, 0x80, 7
-#define        RG_PART_NUM     (0x1c)
-#define        SR_PART_NUM             0x1c, 0xff, 0
-#define        RG_VERSION_NUM  (0x1d)
-#define        SR_VERSION_NUM          0x1d, 0xff, 0
-#define        RG_MAN_ID_0     (0x1e)
-#define        SR_MAN_ID_0             0x1e, 0xff, 0
-#define        RG_MAN_ID_1     (0x1f)
-#define        SR_MAN_ID_1             0x1f, 0xff, 0
-#define        RG_SHORT_ADDR_0 (0x20)
-#define        SR_SHORT_ADDR_0         0x20, 0xff, 0
-#define        RG_SHORT_ADDR_1 (0x21)
-#define        SR_SHORT_ADDR_1         0x21, 0xff, 0
-#define        RG_PAN_ID_0     (0x22)
-#define        SR_PAN_ID_0             0x22, 0xff, 0
-#define        RG_PAN_ID_1     (0x23)
-#define        SR_PAN_ID_1             0x23, 0xff, 0
-#define        RG_IEEE_ADDR_0  (0x24)
-#define        SR_IEEE_ADDR_0          0x24, 0xff, 0
-#define        RG_IEEE_ADDR_1  (0x25)
-#define        SR_IEEE_ADDR_1          0x25, 0xff, 0
-#define        RG_IEEE_ADDR_2  (0x26)
-#define        SR_IEEE_ADDR_2          0x26, 0xff, 0
-#define        RG_IEEE_ADDR_3  (0x27)
-#define        SR_IEEE_ADDR_3          0x27, 0xff, 0
-#define        RG_IEEE_ADDR_4  (0x28)
-#define        SR_IEEE_ADDR_4          0x28, 0xff, 0
-#define        RG_IEEE_ADDR_5  (0x29)
-#define        SR_IEEE_ADDR_5          0x29, 0xff, 0
-#define        RG_IEEE_ADDR_6  (0x2a)
-#define        SR_IEEE_ADDR_6          0x2a, 0xff, 0
-#define        RG_IEEE_ADDR_7  (0x2b)
-#define        SR_IEEE_ADDR_7          0x2b, 0xff, 0
-#define        RG_XAH_CTRL_0   (0x2c)
-#define        SR_SLOTTED_OPERATION    0x2c, 0x01, 0
-#define        SR_MAX_CSMA_RETRIES     0x2c, 0x0e, 1
-#define        SR_MAX_FRAME_RETRIES    0x2c, 0xf0, 4
-#define        RG_CSMA_SEED_0  (0x2d)
-#define        SR_CSMA_SEED_0          0x2d, 0xff, 0
-#define        RG_CSMA_SEED_1  (0x2e)
-#define        SR_CSMA_SEED_1          0x2e, 0x07, 0
-#define        SR_AACK_I_AM_COORD      0x2e, 0x08, 3
-#define        SR_AACK_DIS_ACK         0x2e, 0x10, 4
-#define        SR_AACK_SET_PD          0x2e, 0x20, 5
-#define        SR_AACK_FVN_MODE        0x2e, 0xc0, 6
-#define        RG_CSMA_BE      (0x2f)
-#define        SR_MIN_BE               0x2f, 0x0f, 0
-#define        SR_MAX_BE               0x2f, 0xf0, 4
+#define RG_TRX_STATUS  (0x01)
+#define SR_TRX_STATUS          0x01, 0x1f, 0
+#define SR_RESERVED_01_3       0x01, 0x20, 5
+#define SR_CCA_STATUS          0x01, 0x40, 6
+#define SR_CCA_DONE            0x01, 0x80, 7
+#define RG_TRX_STATE   (0x02)
+#define SR_TRX_CMD             0x02, 0x1f, 0
+#define SR_TRAC_STATUS         0x02, 0xe0, 5
+#define RG_TRX_CTRL_0  (0x03)
+#define SR_CLKM_CTRL           0x03, 0x07, 0
+#define SR_CLKM_SHA_SEL                0x03, 0x08, 3
+#define SR_PAD_IO_CLKM         0x03, 0x30, 4
+#define SR_PAD_IO              0x03, 0xc0, 6
+#define RG_TRX_CTRL_1  (0x04)
+#define SR_IRQ_POLARITY                0x04, 0x01, 0
+#define SR_IRQ_MASK_MODE       0x04, 0x02, 1
+#define SR_SPI_CMD_MODE                0x04, 0x0c, 2
+#define SR_RX_BL_CTRL          0x04, 0x10, 4
+#define SR_TX_AUTO_CRC_ON      0x04, 0x20, 5
+#define SR_IRQ_2_EXT_EN                0x04, 0x40, 6
+#define SR_PA_EXT_EN           0x04, 0x80, 7
+#define RG_PHY_TX_PWR  (0x05)
+#define SR_TX_PWR              0x05, 0x0f, 0
+#define SR_PA_LT               0x05, 0x30, 4
+#define SR_PA_BUF_LT           0x05, 0xc0, 6
+#define RG_PHY_RSSI    (0x06)
+#define SR_RSSI                        0x06, 0x1f, 0
+#define SR_RND_VALUE           0x06, 0x60, 5
+#define SR_RX_CRC_VALID                0x06, 0x80, 7
+#define RG_PHY_ED_LEVEL        (0x07)
+#define SR_ED_LEVEL            0x07, 0xff, 0
+#define RG_PHY_CC_CCA  (0x08)
+#define SR_CHANNEL             0x08, 0x1f, 0
+#define SR_CCA_MODE            0x08, 0x60, 5
+#define SR_CCA_REQUEST         0x08, 0x80, 7
+#define RG_CCA_THRES   (0x09)
+#define SR_CCA_ED_THRES                0x09, 0x0f, 0
+#define SR_RESERVED_09_1       0x09, 0xf0, 4
+#define RG_RX_CTRL     (0x0a)
+#define SR_PDT_THRES           0x0a, 0x0f, 0
+#define SR_RESERVED_0a_1       0x0a, 0xf0, 4
+#define RG_SFD_VALUE   (0x0b)
+#define SR_SFD_VALUE           0x0b, 0xff, 0
+#define RG_TRX_CTRL_2  (0x0c)
+#define SR_OQPSK_DATA_RATE     0x0c, 0x03, 0
+#define SR_SUB_MODE            0x0c, 0x04, 2
+#define SR_BPSK_QPSK           0x0c, 0x08, 3
+#define SR_OQPSK_SUB1_RC_EN    0x0c, 0x10, 4
+#define SR_RESERVED_0c_5       0x0c, 0x60, 5
+#define SR_RX_SAFE_MODE                0x0c, 0x80, 7
+#define RG_ANT_DIV     (0x0d)
+#define SR_ANT_CTRL            0x0d, 0x03, 0
+#define SR_ANT_EXT_SW_EN       0x0d, 0x04, 2
+#define SR_ANT_DIV_EN          0x0d, 0x08, 3
+#define SR_RESERVED_0d_2       0x0d, 0x70, 4
+#define SR_ANT_SEL             0x0d, 0x80, 7
+#define RG_IRQ_MASK    (0x0e)
+#define SR_IRQ_MASK            0x0e, 0xff, 0
+#define RG_IRQ_STATUS  (0x0f)
+#define SR_IRQ_0_PLL_LOCK      0x0f, 0x01, 0
+#define SR_IRQ_1_PLL_UNLOCK    0x0f, 0x02, 1
+#define SR_IRQ_2_RX_START      0x0f, 0x04, 2
+#define SR_IRQ_3_TRX_END       0x0f, 0x08, 3
+#define SR_IRQ_4_CCA_ED_DONE   0x0f, 0x10, 4
+#define SR_IRQ_5_AMI           0x0f, 0x20, 5
+#define SR_IRQ_6_TRX_UR                0x0f, 0x40, 6
+#define SR_IRQ_7_BAT_LOW       0x0f, 0x80, 7
+#define RG_VREG_CTRL   (0x10)
+#define SR_RESERVED_10_6       0x10, 0x03, 0
+#define SR_DVDD_OK             0x10, 0x04, 2
+#define SR_DVREG_EXT           0x10, 0x08, 3
+#define SR_RESERVED_10_3       0x10, 0x30, 4
+#define SR_AVDD_OK             0x10, 0x40, 6
+#define SR_AVREG_EXT           0x10, 0x80, 7
+#define RG_BATMON      (0x11)
+#define SR_BATMON_VTH          0x11, 0x0f, 0
+#define SR_BATMON_HR           0x11, 0x10, 4
+#define SR_BATMON_OK           0x11, 0x20, 5
+#define SR_RESERVED_11_1       0x11, 0xc0, 6
+#define RG_XOSC_CTRL   (0x12)
+#define SR_XTAL_TRIM           0x12, 0x0f, 0
+#define SR_XTAL_MODE           0x12, 0xf0, 4
+#define RG_RX_SYN      (0x15)
+#define SR_RX_PDT_LEVEL                0x15, 0x0f, 0
+#define SR_RESERVED_15_2       0x15, 0x70, 4
+#define SR_RX_PDT_DIS          0x15, 0x80, 7
+#define RG_XAH_CTRL_1  (0x17)
+#define SR_RESERVED_17_8       0x17, 0x01, 0
+#define SR_AACK_PROM_MODE      0x17, 0x02, 1
+#define SR_AACK_ACK_TIME       0x17, 0x04, 2
+#define SR_RESERVED_17_5       0x17, 0x08, 3
+#define SR_AACK_UPLD_RES_FT    0x17, 0x10, 4
+#define SR_AACK_FLTR_RES_FT    0x17, 0x20, 5
+#define SR_CSMA_LBT_MODE       0x17, 0x40, 6
+#define SR_RESERVED_17_1       0x17, 0x80, 7
+#define RG_FTN_CTRL    (0x18)
+#define SR_RESERVED_18_2       0x18, 0x7f, 0
+#define SR_FTN_START           0x18, 0x80, 7
+#define RG_PLL_CF      (0x1a)
+#define SR_RESERVED_1a_2       0x1a, 0x7f, 0
+#define SR_PLL_CF_START                0x1a, 0x80, 7
+#define RG_PLL_DCU     (0x1b)
+#define SR_RESERVED_1b_3       0x1b, 0x3f, 0
+#define SR_RESERVED_1b_2       0x1b, 0x40, 6
+#define SR_PLL_DCU_START       0x1b, 0x80, 7
+#define RG_PART_NUM    (0x1c)
+#define SR_PART_NUM            0x1c, 0xff, 0
+#define RG_VERSION_NUM (0x1d)
+#define SR_VERSION_NUM         0x1d, 0xff, 0
+#define RG_MAN_ID_0    (0x1e)
+#define SR_MAN_ID_0            0x1e, 0xff, 0
+#define RG_MAN_ID_1    (0x1f)
+#define SR_MAN_ID_1            0x1f, 0xff, 0
+#define RG_SHORT_ADDR_0        (0x20)
+#define SR_SHORT_ADDR_0                0x20, 0xff, 0
+#define RG_SHORT_ADDR_1        (0x21)
+#define SR_SHORT_ADDR_1                0x21, 0xff, 0
+#define RG_PAN_ID_0    (0x22)
+#define SR_PAN_ID_0            0x22, 0xff, 0
+#define RG_PAN_ID_1    (0x23)
+#define SR_PAN_ID_1            0x23, 0xff, 0
+#define RG_IEEE_ADDR_0 (0x24)
+#define SR_IEEE_ADDR_0         0x24, 0xff, 0
+#define RG_IEEE_ADDR_1 (0x25)
+#define SR_IEEE_ADDR_1         0x25, 0xff, 0
+#define RG_IEEE_ADDR_2 (0x26)
+#define SR_IEEE_ADDR_2         0x26, 0xff, 0
+#define RG_IEEE_ADDR_3 (0x27)
+#define SR_IEEE_ADDR_3         0x27, 0xff, 0
+#define RG_IEEE_ADDR_4 (0x28)
+#define SR_IEEE_ADDR_4         0x28, 0xff, 0
+#define RG_IEEE_ADDR_5 (0x29)
+#define SR_IEEE_ADDR_5         0x29, 0xff, 0
+#define RG_IEEE_ADDR_6 (0x2a)
+#define SR_IEEE_ADDR_6         0x2a, 0xff, 0
+#define RG_IEEE_ADDR_7 (0x2b)
+#define SR_IEEE_ADDR_7         0x2b, 0xff, 0
+#define RG_XAH_CTRL_0  (0x2c)
+#define SR_SLOTTED_OPERATION   0x2c, 0x01, 0
+#define SR_MAX_CSMA_RETRIES    0x2c, 0x0e, 1
+#define SR_MAX_FRAME_RETRIES   0x2c, 0xf0, 4
+#define RG_CSMA_SEED_0 (0x2d)
+#define SR_CSMA_SEED_0         0x2d, 0xff, 0
+#define RG_CSMA_SEED_1 (0x2e)
+#define SR_CSMA_SEED_1         0x2e, 0x07, 0
+#define SR_AACK_I_AM_COORD     0x2e, 0x08, 3
+#define SR_AACK_DIS_ACK                0x2e, 0x10, 4
+#define SR_AACK_SET_PD         0x2e, 0x20, 5
+#define SR_AACK_FVN_MODE       0x2e, 0xc0, 6
+#define RG_CSMA_BE     (0x2f)
+#define SR_MIN_BE              0x2f, 0x0f, 0
+#define SR_MAX_BE              0x2f, 0xf0, 4
 
 #define CMD_REG                0x80
 #define CMD_REG_MASK   0x3f
@@ -292,6 +294,8 @@ struct at86rf230_local {
 #define STATE_BUSY_RX_AACK_NOCLK 0x1E
 #define STATE_TRANSITION_IN_PROGRESS 0x1F
 
+#define TRX_STATE_MASK         (0x1F)
+
 #define AT86RF2XX_NUMREGS 0x3F
 
 static void
@@ -336,6 +340,14 @@ at86rf230_write_subreg(struct at86rf230_local *lp,
        return regmap_update_bits(lp->regmap, addr, mask, data << shift);
 }
 
+static inline void
+at86rf230_slp_tr_rising_edge(struct at86rf230_local *lp)
+{
+       gpio_set_value(lp->slp_tr, 1);
+       udelay(1);
+       gpio_set_value(lp->slp_tr, 0);
+}
+
 static bool
 at86rf230_reg_writeable(struct device *dev, unsigned int reg)
 {
@@ -509,7 +521,7 @@ at86rf230_async_state_assert(void *context)
        struct at86rf230_state_change *ctx = context;
        struct at86rf230_local *lp = ctx->lp;
        const u8 *buf = ctx->buf;
-       const u8 trx_state = buf[1] & 0x1f;
+       const u8 trx_state = buf[1] & TRX_STATE_MASK;
 
        /* Assert state change */
        if (trx_state != ctx->to_state) {
@@ -609,11 +621,17 @@ at86rf230_async_state_delay(void *context)
                switch (ctx->to_state) {
                case STATE_RX_AACK_ON:
                        tim = ktime_set(0, c->t_off_to_aack * NSEC_PER_USEC);
+                       /* state change from TRX_OFF to RX_AACK_ON to do a
+                        * calibration, we need to reset the timeout for the
+                        * next one.
+                        */
+                       lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
                        goto change;
+               case STATE_TX_ARET_ON:
                case STATE_TX_ON:
                        tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC);
-                       /* state change from TRX_OFF to TX_ON to do a
-                        * calibration, we need to reset the timeout for the
+                       /* state change from TRX_OFF to TX_ON or ARET_ON to do
+                        * calibration, we need to reset the timeout for the
                         * next one.
                         */
                        lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
@@ -667,7 +685,7 @@ at86rf230_async_state_change_start(void *context)
        struct at86rf230_state_change *ctx = context;
        struct at86rf230_local *lp = ctx->lp;
        u8 *buf = ctx->buf;
-       const u8 trx_state = buf[1] & 0x1f;
+       const u8 trx_state = buf[1] & TRX_STATE_MASK;
        int rc;
 
        /* Check for "possible" STATE_TRANSITION_IN_PROGRESS */
@@ -772,16 +790,6 @@ at86rf230_tx_on(void *context)
                                     at86rf230_tx_complete, true);
 }
 
-static void
-at86rf230_tx_trac_error(void *context)
-{
-       struct at86rf230_state_change *ctx = context;
-       struct at86rf230_local *lp = ctx->lp;
-
-       at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
-                                    at86rf230_tx_on, true);
-}
-
 static void
 at86rf230_tx_trac_check(void *context)
 {
@@ -791,12 +799,12 @@ at86rf230_tx_trac_check(void *context)
        const u8 trac = (buf[1] & 0xe0) >> 5;
 
        /* If trac status is different than zero we need to do a state change
-        * to STATE_FORCE_TRX_OFF then STATE_TX_ON to recover the transceiver
-        * state to TX_ON.
+        * to STATE_FORCE_TRX_OFF then STATE_RX_AACK_ON to recover the
+        * transceiver.
         */
        if (trac)
                at86rf230_async_state_change(lp, ctx, STATE_FORCE_TRX_OFF,
-                                            at86rf230_tx_trac_error, true);
+                                            at86rf230_tx_on, true);
        else
                at86rf230_tx_on(context);
 }
@@ -941,13 +949,18 @@ at86rf230_write_frame_complete(void *context)
        u8 *buf = ctx->buf;
        int rc;
 
-       buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
-       buf[1] = STATE_BUSY_TX;
        ctx->trx.len = 2;
-       ctx->msg.complete = NULL;
-       rc = spi_async(lp->spi, &ctx->msg);
-       if (rc)
-               at86rf230_async_error(lp, ctx, rc);
+
+       if (gpio_is_valid(lp->slp_tr)) {
+               at86rf230_slp_tr_rising_edge(lp);
+       } else {
+               buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
+               buf[1] = STATE_BUSY_TX;
+               ctx->msg.complete = NULL;
+               rc = spi_async(lp->spi, &ctx->msg);
+               if (rc)
+                       at86rf230_async_error(lp, ctx, rc);
+       }
 }
 
 static void
@@ -993,12 +1006,21 @@ at86rf230_xmit_start(void *context)
         * are in STATE_TX_ON. The pfad differs here, so we change
         * the complete handler.
         */
-       if (lp->tx_aret)
-               at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
-                                            at86rf230_xmit_tx_on, false);
-       else
+       if (lp->tx_aret) {
+               if (lp->is_tx_from_off) {
+                       lp->is_tx_from_off = false;
+                       at86rf230_async_state_change(lp, ctx, STATE_TX_ARET_ON,
+                                                    at86rf230_xmit_tx_on,
+                                                    false);
+               } else {
+                       at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
+                                                    at86rf230_xmit_tx_on,
+                                                    false);
+               }
+       } else {
                at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
                                             at86rf230_write_frame, false);
+       }
 }
 
 static int
@@ -1017,11 +1039,13 @@ at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
         * to TX_ON, the lp->cal_timeout should be reinit by state_delay
         * function then to start in the next 5 minutes.
         */
-       if (time_is_before_jiffies(lp->cal_timeout))
+       if (time_is_before_jiffies(lp->cal_timeout)) {
+               lp->is_tx_from_off = true;
                at86rf230_async_state_change(lp, ctx, STATE_TRX_OFF,
                                             at86rf230_xmit_start, false);
-       else
+       } else {
                at86rf230_xmit_start(ctx);
+       }
 
        return 0;
 }
@@ -1037,9 +1061,6 @@ at86rf230_ed(struct ieee802154_hw *hw, u8 *level)
 static int
 at86rf230_start(struct ieee802154_hw *hw)
 {
-       struct at86rf230_local *lp = hw->priv;
-
-       lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
        return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON);
 }
 
@@ -1673,6 +1694,7 @@ static int at86rf230_probe(struct spi_device *spi)
        lp = hw->priv;
        lp->hw = hw;
        lp->spi = spi;
+       lp->slp_tr = slp_tr;
        hw->parent = &spi->dev;
        hw->vif_data_size = sizeof(*lp);
        ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
index b227a13f6473404a5082a0a99d4e7067b3daeaf7..9f59f17dc317a254641bdc48973ce78e089761bc 100644 (file)
@@ -599,10 +599,18 @@ static int macvlan_open(struct net_device *dev)
                        goto del_unicast;
        }
 
+       if (dev->flags & IFF_PROMISC) {
+               err = dev_set_promiscuity(lowerdev, 1);
+               if (err < 0)
+                       goto clear_multi;
+       }
+
 hash_add:
        macvlan_hash_add(vlan);
        return 0;
 
+clear_multi:
+       dev_set_allmulti(lowerdev, -1);
 del_unicast:
        dev_uc_del(lowerdev, dev->dev_addr);
 out:
@@ -638,6 +646,9 @@ static int macvlan_stop(struct net_device *dev)
        if (dev->flags & IFF_ALLMULTI)
                dev_set_allmulti(lowerdev, -1);
 
+       if (dev->flags & IFF_PROMISC)
+               dev_set_promiscuity(lowerdev, -1);
+
        dev_uc_del(lowerdev, dev->dev_addr);
 
 hash_del:
@@ -696,6 +707,10 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change)
        if (dev->flags & IFF_UP) {
                if (change & IFF_ALLMULTI)
                        dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
+               if (change & IFF_PROMISC)
+                       dev_set_promiscuity(lowerdev,
+                                           dev->flags & IFF_PROMISC ? 1 : -1);
+
        }
 }
 
index 8fadaa14b9f0fbd97b689d7bab562eccd30d17bf..70641d2c042957e7e154b4a1d265f39fe3ffa386 100644 (file)
@@ -27,6 +27,7 @@ config AMD_PHY
 config AMD_XGBE_PHY
        tristate "Driver for the AMD 10GbE (amd-xgbe) PHYs"
        depends on (OF || ACPI) && HAS_IOMEM
+       depends on ARM64 || COMPILE_TEST
        ---help---
          Currently supports the AMD 10GbE PHY
 
index c9cb486c753d053c8b6da529a0c078d89f9c2a2f..53d18150f4e291bb4bb047a18a9877d3a82a08f4 100644 (file)
@@ -168,7 +168,10 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev,
                if (!new_bus->irq[i])
                        new_bus->irq[i] = PHY_POLL;
 
-       snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id);
+       if (bus_id != -1)
+               snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id);
+       else
+               strncpy(new_bus->id, "gpio", MII_BUS_ID_SIZE);
 
        if (devm_gpio_request(dev, bitbang->mdc, "mdc"))
                goto out_free_bus;
index 1190fd8f008862bc8f70f271575839d280a8f906..ebdc357c513167515baef710ba56d8b6b8e57cb9 100644 (file)
@@ -548,7 +548,8 @@ static int kszphy_probe(struct phy_device *phydev)
        }
 
        clk = devm_clk_get(&phydev->dev, "rmii-ref");
-       if (!IS_ERR(clk)) {
+       /* NOTE: clk may be NULL if building without CONFIG_HAVE_CLK */
+       if (!IS_ERR_OR_NULL(clk)) {
                unsigned long rate = clk_get_rate(clk);
                bool rmii_ref_clk_sel_25_mhz;
 
index aa1dd926623ad622e3a15f905733e3d585aca871..b62a5e3a1c652d27e2bbb0d2a8a88990c3fef027 100644 (file)
@@ -465,6 +465,10 @@ static void pppoe_unbind_sock_work(struct work_struct *work)
        struct sock *sk = sk_pppox(po);
 
        lock_sock(sk);
+       if (po->pppoe_dev) {
+               dev_put(po->pppoe_dev);
+               po->pppoe_dev = NULL;
+       }
        pppox_unbind_sock(sk);
        release_sock(sk);
        sock_put(sk);
index ac4d03b328b130ab918175b1fa5c8fe55a0cbc7b..aafa1a1898e43de0d3d06e7d8367751473f25142 100644 (file)
@@ -4116,6 +4116,7 @@ static struct usb_device_id rtl8152_table[] = {
        {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)},
        {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)},
        {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x7205)},
+       {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO,  0x304f)},
        {}
 };
 
index 733f4feb2ef3c5f11bbf99af962ecbb77253314b..3c86b107275a899f3748e4cfee82ab2bb43aff6b 100644 (file)
@@ -1285,7 +1285,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
                                     struct net_device *net)
 {
        struct usbnet           *dev = netdev_priv(net);
-       int                     length;
+       unsigned int                    length;
        struct urb              *urb = NULL;
        struct skb_data         *entry;
        struct driver_info      *info = dev->driver_info;
@@ -1413,7 +1413,7 @@ not_drop:
                }
        } else
                netif_dbg(dev, tx_queued, dev->net,
-                         "> tx, len %d, type 0x%x\n", length, skb->protocol);
+                         "> tx, len %u, type 0x%x\n", length, skb->protocol);
 #ifdef CONFIG_PM
 deferred:
 #endif
index 0acd079ba96bd3d2f60602ebf5f889f36da9f908..3ad79bb4f2c21c94b6c41c526a7e033e0937ed77 100644 (file)
@@ -1103,28 +1103,14 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
        struct sk_buff *skb;
        struct ath_frame_info *fi;
        struct ieee80211_tx_info *info;
-       struct ieee80211_vif *vif;
        struct ath_hw *ah = sc->sc_ah;
 
        if (sc->tx99_state || !ah->tpc_enabled)
                return MAX_RATE_POWER;
 
        skb = bf->bf_mpdu;
-       info = IEEE80211_SKB_CB(skb);
-       vif = info->control.vif;
-
-       if (!vif) {
-               max_power = sc->cur_chan->cur_txpower;
-               goto out;
-       }
-
-       if (vif->bss_conf.txpower_type != NL80211_TX_POWER_LIMITED) {
-               max_power = min_t(u8, sc->cur_chan->cur_txpower,
-                                 2 * vif->bss_conf.txpower);
-               goto out;
-       }
-
        fi = get_frame_info(skb);
+       info = IEEE80211_SKB_CB(skb);
 
        if (!AR_SREV_9300_20_OR_LATER(ah)) {
                int txpower = fi->tx_power;
@@ -1161,25 +1147,26 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
                        txpower -= 2;
 
                txpower = max(txpower, 0);
-               max_power = min_t(u8, ah->tx_power[rateidx],
-                                 2 * vif->bss_conf.txpower);
-               max_power = min_t(u8, max_power, txpower);
+               max_power = min_t(u8, ah->tx_power[rateidx], txpower);
+
+               /* XXX: clamp minimum TX power at 1 for AR9160 since if
+                * max_power is set to 0, frames are transmitted at max
+                * TX power
+                */
+               if (!max_power && !AR_SREV_9280_20_OR_LATER(ah))
+                       max_power = 1;
        } else if (!bf->bf_state.bfs_paprd) {
                if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC))
                        max_power = min_t(u8, ah->tx_power_stbc[rateidx],
-                                         2 * vif->bss_conf.txpower);
+                                         fi->tx_power);
                else
                        max_power = min_t(u8, ah->tx_power[rateidx],
-                                         2 * vif->bss_conf.txpower);
-               max_power = min(max_power, fi->tx_power);
+                                         fi->tx_power);
        } else {
                max_power = ah->paprd_training_power;
        }
-out:
-       /* XXX: clamp minimum TX power at 1 for AR9160 since if max_power
-        * is set to 0, frames are transmitted at max TX power
-        */
-       return (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) ? 1 : max_power;
+
+       return max_power;
 }
 
 static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
@@ -2129,6 +2116,7 @@ static void setup_frame_info(struct ieee80211_hw *hw,
        struct ath_node *an = NULL;
        enum ath9k_key_type keytype;
        bool short_preamble = false;
+       u8 txpower;
 
        /*
         * We check if Short Preamble is needed for the CTS rate by
@@ -2145,6 +2133,16 @@ static void setup_frame_info(struct ieee80211_hw *hw,
        if (sta)
                an = (struct ath_node *) sta->drv_priv;
 
+       if (tx_info->control.vif) {
+               struct ieee80211_vif *vif = tx_info->control.vif;
+
+               txpower = 2 * vif->bss_conf.txpower;
+       } else {
+               struct ath_softc *sc = hw->priv;
+
+               txpower = sc->cur_chan->cur_txpower;
+       }
+
        memset(fi, 0, sizeof(*fi));
        fi->txq = -1;
        if (hw_key)
@@ -2155,7 +2153,7 @@ static void setup_frame_info(struct ieee80211_hw *hw,
                fi->keyix = ATH9K_TXKEYIX_INVALID;
        fi->keytype = keytype;
        fi->framelen = framelen;
-       fi->tx_power = MAX_RATE_POWER;
+       fi->tx_power = txpower;
 
        if (!rate)
                return;
index bfdf3faa6c470dafbd9a66672b2f55e38b0872bc..62db2e5e45ebd51793c372e54832b21511057c58 100644 (file)
@@ -244,6 +244,7 @@ enum iwl_ucode_tlv_flag {
  *     longer than the passive one, which is essential for fragmented scan.
  * @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source.
  * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
+ * @IWL_UCODE_TLV_API_TX_POWER_DEV: new API for tx power.
  * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
  *     regardless of the band or the number of the probes. FW will calculate
  *     the actual dwell time.
@@ -260,6 +261,7 @@ enum iwl_ucode_tlv_api {
        IWL_UCODE_TLV_API_FRAGMENTED_SCAN       = BIT(8),
        IWL_UCODE_TLV_API_WIFI_MCC_UPDATE       = BIT(9),
        IWL_UCODE_TLV_API_HDC_PHASE_0           = BIT(10),
+       IWL_UCODE_TLV_API_TX_POWER_DEV          = BIT(11),
        IWL_UCODE_TLV_API_BASIC_DWELL           = BIT(13),
        IWL_UCODE_TLV_API_SCD_CFG               = BIT(15),
        IWL_UCODE_TLV_API_SINGLE_SCAN_EBS       = BIT(16),
index 6dfed1259260f06d23feb544d78ce6484c01fb36..56254a837214ffad421a7b7a14a9eaec3d7dc029 100644 (file)
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -421,8 +421,9 @@ struct iwl_trans_txq_scd_cfg {
  *
  * All the handlers MUST be implemented
  *
- * @start_hw: starts the HW- from that point on, the HW can send interrupts
- *     May sleep
+ * @start_hw: starts the HW. If low_power is true, the NIC needs to be taken
+ *     out of a low power state. From that point on, the HW can send
+ *     interrupts. May sleep.
  * @op_mode_leave: Turn off the HW RF kill indication if on
  *     May sleep
  * @start_fw: allocates and inits all the resources for the transport
@@ -432,10 +433,11 @@ struct iwl_trans_txq_scd_cfg {
  *     the SCD base address in SRAM, then provide it here, or 0 otherwise.
  *     May sleep
  * @stop_device: stops the whole device (embedded CPU put to reset) and stops
- *     the HW. From that point on, the HW will be in low power but will still
- *     issue interrupt if the HW RF kill is triggered. This callback must do
- *     the right thing and not crash even if start_hw() was called but not
- *     start_fw(). May sleep
+ *     the HW. If low_power is true, the NIC will be put in low power state.
+ *     From that point on, the HW will be stopped but will still issue an
+ *     interrupt if the HW RF kill switch is triggered.
+ *     This callback must do the right thing and not crash even if %start_hw()
+ *     was called but not &start_fw(). May sleep.
  * @d3_suspend: put the device into the correct mode for WoWLAN during
  *     suspend. This is optional, if not implemented WoWLAN will not be
  *     supported. This callback may sleep.
@@ -491,14 +493,14 @@ struct iwl_trans_txq_scd_cfg {
  */
 struct iwl_trans_ops {
 
-       int (*start_hw)(struct iwl_trans *iwl_trans);
+       int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power);
        void (*op_mode_leave)(struct iwl_trans *iwl_trans);
        int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
                        bool run_in_rfkill);
        int (*update_sf)(struct iwl_trans *trans,
                         struct iwl_sf_region *st_fwrd_space);
        void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
-       void (*stop_device)(struct iwl_trans *trans);
+       void (*stop_device)(struct iwl_trans *trans, bool low_power);
 
        void (*d3_suspend)(struct iwl_trans *trans, bool test);
        int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status,
@@ -652,11 +654,16 @@ static inline void iwl_trans_configure(struct iwl_trans *trans,
        trans->ops->configure(trans, trans_cfg);
 }
 
-static inline int iwl_trans_start_hw(struct iwl_trans *trans)
+static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power)
 {
        might_sleep();
 
-       return trans->ops->start_hw(trans);
+       return trans->ops->start_hw(trans, low_power);
+}
+
+static inline int iwl_trans_start_hw(struct iwl_trans *trans)
+{
+       return trans->ops->start_hw(trans, true);
 }
 
 static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans)
@@ -703,15 +710,21 @@ static inline int iwl_trans_update_sf(struct iwl_trans *trans,
        return 0;
 }
 
-static inline void iwl_trans_stop_device(struct iwl_trans *trans)
+static inline void _iwl_trans_stop_device(struct iwl_trans *trans,
+                                         bool low_power)
 {
        might_sleep();
 
-       trans->ops->stop_device(trans);
+       trans->ops->stop_device(trans, low_power);
 
        trans->state = IWL_TRANS_NO_FW;
 }
 
+static inline void iwl_trans_stop_device(struct iwl_trans *trans)
+{
+       _iwl_trans_stop_device(trans, true);
+}
+
 static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test)
 {
        might_sleep();
index a6c48c7b1e1683fdbdcb99fd0e4f971cf6ad66d2..1b1b2bf26819be1d09903f3c52957d274ee50ed7 100644 (file)
@@ -1726,7 +1726,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
        results->matched_profiles = le32_to_cpu(query->matched_profiles);
        memcpy(results->matches, query->matches, sizeof(results->matches));
 
-#ifdef CPTCFG_IWLWIFI_DEBUGFS
+#ifdef CONFIG_IWLWIFI_DEBUGFS
        mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done);
 #endif
 
index 4fc0938b3fb6d6c92464f63b3f206cbc798f92b7..b1baa33cc19b3228a8534af71ab69c7dede40520 100644 (file)
@@ -297,6 +297,40 @@ struct iwl_uapsd_misbehaving_ap_notif {
        u8 reserved[3];
 } __packed;
 
+/**
+ * struct iwl_reduce_tx_power_cmd - TX power reduction command
+ * REDUCE_TX_POWER_CMD = 0x9f
+ * @flags: (reserved for future implementation)
+ * @mac_context_id: id of the mac ctx for which we are reducing TX power.
+ * @pwr_restriction: TX power restriction in dBms.
+ */
+struct iwl_reduce_tx_power_cmd {
+       u8 flags;
+       u8 mac_context_id;
+       __le16 pwr_restriction;
+} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */
+
+/**
+ * struct iwl_dev_tx_power_cmd - TX power reduction command
+ * REDUCE_TX_POWER_CMD = 0x9f
+ * @set_mode: 0 - MAC tx power, 1 - device tx power
+ * @mac_context_id: id of the mac ctx for which we are reducing TX power.
+ * @pwr_restriction: TX power restriction in 1/8 dBms.
+ * @dev_24: device TX power restriction in 1/8 dBms
+ * @dev_52_low: device TX power restriction upper band - low
+ * @dev_52_high: device TX power restriction upper band - high
+ */
+struct iwl_dev_tx_power_cmd {
+       __le32 set_mode;
+       __le32 mac_context_id;
+       __le16 pwr_restriction;
+       __le16 dev_24;
+       __le16 dev_52_low;
+       __le16 dev_52_high;
+} __packed; /* TX_REDUCED_POWER_API_S_VER_2 */
+
+#define IWL_DEV_MAX_TX_POWER 0x7FFF
+
 /**
  * struct iwl_beacon_filter_cmd
  * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
index 4f81dcf57a736e7409087f4b3193809c3570db6f..d6cced47d561b9601a59166296a229facfd9014e 100644 (file)
@@ -122,46 +122,6 @@ enum iwl_scan_complete_status {
        SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C,
 };
 
-/**
- * struct iwl_scan_results_notif - scan results for one channel
- * ( SCAN_RESULTS_NOTIFICATION = 0x83 )
- * @channel: which channel the results are from
- * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
- * @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request
- * @num_probe_not_sent: # of request that weren't sent due to not enough time
- * @duration: duration spent in channel, in usecs
- * @statistics: statistics gathered for this channel
- */
-struct iwl_scan_results_notif {
-       u8 channel;
-       u8 band;
-       u8 probe_status;
-       u8 num_probe_not_sent;
-       __le32 duration;
-       __le32 statistics[SCAN_RESULTS_STATISTICS];
-} __packed; /* SCAN_RESULT_NTF_API_S_VER_2 */
-
-/**
- * struct iwl_scan_complete_notif - notifies end of scanning (all channels)
- * ( SCAN_COMPLETE_NOTIFICATION = 0x84 )
- * @scanned_channels: number of channels scanned (and number of valid results)
- * @status: one of SCAN_COMP_STATUS_*
- * @bt_status: BT on/off status
- * @last_channel: last channel that was scanned
- * @tsf_low: TSF timer (lower half) in usecs
- * @tsf_high: TSF timer (higher half) in usecs
- * @results: array of scan results, only "scanned_channels" of them are valid
- */
-struct iwl_scan_complete_notif {
-       u8 scanned_channels;
-       u8 status;
-       u8 bt_status;
-       u8 last_channel;
-       __le32 tsf_low;
-       __le32 tsf_high;
-       struct iwl_scan_results_notif results[];
-} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */
-
 /* scan offload */
 #define IWL_SCAN_MAX_BLACKLIST_LEN     64
 #define IWL_SCAN_SHORT_BLACKLIST_LEN   16
@@ -554,7 +514,7 @@ struct iwl_scan_req_unified_lmac {
 } __packed;
 
 /**
- * struct iwl_lmac_scan_results_notif - scan results for one channel -
+ * struct iwl_scan_results_notif - scan results for one channel -
  *     SCAN_RESULT_NTF_API_S_VER_3
  * @channel: which channel the results are from
  * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
@@ -562,7 +522,7 @@ struct iwl_scan_req_unified_lmac {
  * @num_probe_not_sent: # of request that weren't sent due to not enough time
  * @duration: duration spent in channel, in usecs
  */
-struct iwl_lmac_scan_results_notif {
+struct iwl_scan_results_notif {
        u8 channel;
        u8 band;
        u8 probe_status;
index aab68cbae754d547a9e1fe514c4c88de6877777f..01b1da6ad35977b349fc79336c15238706ca9078 100644 (file)
@@ -281,19 +281,6 @@ struct iwl_tx_ant_cfg_cmd {
        __le32 valid;
 } __packed;
 
-/**
- * struct iwl_reduce_tx_power_cmd - TX power reduction command
- * REDUCE_TX_POWER_CMD = 0x9f
- * @flags: (reserved for future implementation)
- * @mac_context_id: id of the mac ctx for which we are reducing TX power.
- * @pwr_restriction: TX power restriction in dBms.
- */
-struct iwl_reduce_tx_power_cmd {
-       u8 flags;
-       u8 mac_context_id;
-       __le16 pwr_restriction;
-} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */
-
 /*
  * Calibration control struct.
  * Sent as part of the phy configuration command.
index bc5eac4960e18a79a211da2a2bf6492b1a39e570..df869633f4dd976c9404e036ecf8a49a855fd0b4 100644 (file)
@@ -6,7 +6,7 @@
  * GPL LICENSE SUMMARY
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
  * BSD LICENSE
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -322,7 +322,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
 
        lockdep_assert_held(&mvm->mutex);
 
-       if (WARN_ON_ONCE(mvm->init_ucode_complete || mvm->calibrating))
+       if (WARN_ON_ONCE(mvm->calibrating))
                return 0;
 
        iwl_init_notification_wait(&mvm->notif_wait,
@@ -396,8 +396,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
         */
        ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
                        MVM_UCODE_CALIB_TIMEOUT);
-       if (!ret)
-               mvm->init_ucode_complete = true;
 
        if (ret && iwl_mvm_is_radio_killed(mvm)) {
                IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
@@ -494,15 +492,6 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
 
        mvm->fw_dump_desc = desc;
 
-       /* stop recording */
-       if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
-               iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
-       } else {
-               iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
-               /* wait before we collect the data till the DBGC stop */
-               udelay(100);
-       }
-
        queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay);
 
        return 0;
@@ -658,25 +647,24 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
         * module loading, load init ucode now
         * (for example, if we were in RFKILL)
         */
-       if (!mvm->init_ucode_complete) {
-               ret = iwl_run_init_mvm_ucode(mvm, false);
-               if (ret && !iwlmvm_mod_params.init_dbg) {
-                       IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
-                       /* this can't happen */
-                       if (WARN_ON(ret > 0))
-                               ret = -ERFKILL;
-                       goto error;
-               }
-               if (!iwlmvm_mod_params.init_dbg) {
-                       /*
-                        * should stop and start HW since that INIT
-                        * image just loaded
-                        */
-                       iwl_trans_stop_device(mvm->trans);
-                       ret = iwl_trans_start_hw(mvm->trans);
-                       if (ret)
-                               return ret;
-               }
+       ret = iwl_run_init_mvm_ucode(mvm, false);
+       if (ret && !iwlmvm_mod_params.init_dbg) {
+               IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
+               /* this can't happen */
+               if (WARN_ON(ret > 0))
+                       ret = -ERFKILL;
+               goto error;
+       }
+       if (!iwlmvm_mod_params.init_dbg) {
+               /*
+                * Stop and start the transport without entering low power
+                * mode. This will save the state of other components on the
+                * device that are triggered by the INIT firwmare (MFUART).
+                */
+               _iwl_trans_stop_device(mvm->trans, false);
+               _iwl_trans_start_hw(mvm->trans, false);
+               if (ret)
+                       return ret;
        }
 
        if (iwlmvm_mod_params.init_dbg)
index 84555170b6f751bb4f0925bf5c85319de76293b6..40265b9c66aeceedb6da22c05738628f7c289705 100644 (file)
@@ -1322,7 +1322,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
 
        clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
        iwl_mvm_d0i3_enable_tx(mvm, NULL);
-       ret = iwl_mvm_update_quotas(mvm, false, NULL);
+       ret = iwl_mvm_update_quotas(mvm, true, NULL);
        if (ret)
                IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
                        ret);
@@ -1471,8 +1471,8 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
        return NULL;
 }
 
-static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
-                               s8 tx_power)
+static int iwl_mvm_set_tx_power_old(struct iwl_mvm *mvm,
+                                   struct ieee80211_vif *vif, s8 tx_power)
 {
        /* FW is in charge of regulatory enforcement */
        struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = {
@@ -1485,6 +1485,26 @@ static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                                    &reduce_txpwr_cmd);
 }
 
+static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+                               s16 tx_power)
+{
+       struct iwl_dev_tx_power_cmd cmd = {
+               .set_mode = 0,
+               .mac_context_id =
+                       cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
+               .pwr_restriction = cpu_to_le16(8 * tx_power),
+       };
+
+       if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_TX_POWER_DEV))
+               return iwl_mvm_set_tx_power_old(mvm, vif, tx_power);
+
+       if (tx_power == IWL_DEFAULT_MAX_TX_POWER)
+               cmd.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
+
+       return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0,
+                                   sizeof(cmd), &cmd);
+}
+
 static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif)
 {
index d5522a16124292cd6cab36159851a8446b5e2d95..cf70f681d1acb7e271717091684ca805749e13ab 100644 (file)
@@ -603,7 +603,6 @@ struct iwl_mvm {
 
        enum iwl_ucode_type cur_ucode;
        bool ucode_loaded;
-       bool init_ucode_complete;
        bool calibrating;
        u32 error_event_table;
        u32 log_event_table;
index a08b03d58d4bf0f3ebd4773a7fdb6e07cc8406b8..1c66297d82c0a80dd0bb66c7148ea8ef42c5e099 100644 (file)
@@ -865,6 +865,16 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
                return;
 
        mutex_lock(&mvm->mutex);
+
+       /* stop recording */
+       if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+               iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
+       } else {
+               iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
+               /* wait before we collect the data till the DBGC stop */
+               udelay(100);
+       }
+
        iwl_mvm_fw_error_dump(mvm);
 
        /* start recording again if the firmware is not crashed */
index 78ec7db64ba59e886e2a7b18a3df64f70a4ea29c..d6314ddf57b5d9638fcfd2fcf6ba917bb136779f 100644 (file)
@@ -478,6 +478,11 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
        if (vif->type != NL80211_IFTYPE_STATION)
                return;
 
+       if (sig == 0) {
+               IWL_DEBUG_RX(mvm, "RSSI is 0 - skip signal based decision\n");
+               return;
+       }
+
        mvmvif->bf_data.ave_beacon_signal = sig;
 
        /* BT Coex */
index 74e1c86289dcbcedc1f5c7b963e468095de7cf25..1075a213bd6a87156e44ab410ac566cf18bdacc3 100644 (file)
@@ -319,7 +319,7 @@ int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
                                                struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
-       struct iwl_scan_complete_notif *notif = (void *)pkt->data;
+       struct iwl_lmac_scan_complete_notif *notif = (void *)pkt->data;
 
        IWL_DEBUG_SCAN(mvm,
                       "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
index 2de8fbfe4edf4d6c6997307fb91052177fd7e6e4..47bbf573fdc836c9e410bd58c8decbe7e91830c4 100644 (file)
@@ -5,8 +5,8 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -31,8 +31,8 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -104,7 +104,7 @@ static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
 static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       struct page *page;
+       struct page *page = NULL;
        dma_addr_t phys;
        u32 size;
        u8 power;
@@ -131,6 +131,7 @@ static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans)
                                    DMA_FROM_DEVICE);
                if (dma_mapping_error(trans->dev, phys)) {
                        __free_pages(page, order);
+                       page = NULL;
                        continue;
                }
                IWL_INFO(trans,
@@ -1020,7 +1021,7 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
        iwl_pcie_tx_start(trans, scd_addr);
 }
 
-static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
+static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        bool hw_rfkill, was_hw_rfkill;
@@ -1115,7 +1116,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
 void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
 {
        if (iwl_op_mode_hw_rf_kill(trans->op_mode, state))
-               iwl_trans_pcie_stop_device(trans);
+               iwl_trans_pcie_stop_device(trans, true);
 }
 
 static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test)
@@ -1200,7 +1201,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
        return 0;
 }
 
-static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
+static int iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
 {
        bool hw_rfkill;
        int err;
index f0188c83c79f7d6027bdee6372768d3657347a2a..2721cf89fb160f0d3f4e6106474c5da101707a18 100644 (file)
@@ -126,7 +126,7 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
 
        do {
                status = usb_control_msg(udev, pipe, request, reqtype, value,
-                                        index, pdata, len, 0); /*max. timeout*/
+                                        index, pdata, len, 1000);
                if (status < 0) {
                        /* firmware download is checksumed, don't retry */
                        if ((value >= FW_8192C_START_ADDRESS &&
index 8be2096c842390f5ecefc24186267e9ce4f61e2b..deeaed54422246dceb236f0a604696d5cddb2549 100644 (file)
@@ -348,7 +348,7 @@ int superio_fixup_irq(struct pci_dev *pcidev)
                BUG();
                return -1;
        }
-       printk("superio_fixup_irq(%s) ven 0x%x dev 0x%x from %pf\n",
+       printk(KERN_DEBUG "superio_fixup_irq(%s) ven 0x%x dev 0x%x from %ps\n",
                pci_name(pcidev),
                pcidev->vendor, pcidev->device,
                __builtin_return_address(0));
index ca1cc5a47eb1e02b9acd38f1aeff2abf93bbf6ac..bd1dbfee2515dda65c54176d9b2e547cb4e3beca 100644 (file)
@@ -1149,6 +1149,7 @@ static struct platform_driver axp288_fuel_gauge_driver = {
 
 module_platform_driver(axp288_fuel_gauge_driver);
 
+MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>");
 MODULE_AUTHOR("Todd Brandt <todd.e.brandt@linux.intel.com>");
 MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver");
 MODULE_LICENSE("GPL");
index a57433de5c249fa33e6fb4f59e7c2dbf3190208b..b6b98378faa32b50c0e1900c76ca4e26da3bd6c1 100644 (file)
@@ -1109,6 +1109,14 @@ static void __exit bq27x00_battery_exit(void)
 }
 module_exit(bq27x00_battery_exit);
 
+#ifdef CONFIG_BATTERY_BQ27X00_PLATFORM
+MODULE_ALIAS("platform:bq27000-battery");
+#endif
+
+#ifdef CONFIG_BATTERY_BQ27X00_I2C
+MODULE_ALIAS("i2c:bq27000-battery");
+#endif
+
 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
 MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
 MODULE_LICENSE("GPL");
index 2da9ed8ccbb5391f50c7137866b3fad5669dd2d7..8a971b3dbe583f0dc2640ddfa867f33c3e2c0ef4 100644 (file)
@@ -347,7 +347,7 @@ static int collie_bat_probe(struct ucb1x00_dev *dev)
                goto err_psy_reg_main;
        }
 
-       psy_main_cfg.drv_data = &collie_bat_bu;
+       psy_bu_cfg.drv_data = &collie_bat_bu;
        collie_bat_bu.psy = power_supply_register(&dev->ucb->dev,
                                                  &collie_bat_bu_desc,
                                                  &psy_bu_cfg);
index aad9c3318c02a271a864da8866b9b38c4623768c..17d93a73c5136e53ab2955d7aba02a7ef0c85d1f 100644 (file)
@@ -41,6 +41,7 @@ config POWER_RESET_AXXIA
 config POWER_RESET_BRCMSTB
        bool "Broadcom STB reset driver"
        depends on ARM || MIPS || COMPILE_TEST
+       depends on MFD_SYSCON
        default ARCH_BRCMSTB
        help
          This driver provides restart support for Broadcom STB boards.
index 01c7055c4200e3d9a7333ac7c0bcaccc3ac2d4a5..ca461ebc7ae8f73338059d6ce9547b850c269f1b 100644 (file)
@@ -212,9 +212,9 @@ static int at91_reset_platform_probe(struct platform_device *pdev)
                res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 );
                at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start,
                                                   resource_size(res));
-               if (IS_ERR(at91_ramc_base[idx])) {
+               if (!at91_ramc_base[idx]) {
                        dev_err(&pdev->dev, "Could not map ram controller address\n");
-                       return PTR_ERR(at91_ramc_base[idx]);
+                       return -ENOMEM;
                }
        }
 
index 7ef193b6f7fe81451c504797cec9bb4932879ee8..1e08195551fe7d505511a6dd92b07d1ab4300911 100644 (file)
@@ -120,18 +120,7 @@ static enum hrtimer_restart ltc2952_poweroff_timer_wde(struct hrtimer *timer)
 
 static void ltc2952_poweroff_start_wde(struct ltc2952_poweroff *data)
 {
-       if (hrtimer_start(&data->timer_wde, data->wde_interval,
-                         HRTIMER_MODE_REL)) {
-               /*
-                * The device will not toggle the watchdog reset,
-                * thus shut down is only safe if the PowerPath controller
-                * has a long enough time-off before triggering a hardware
-                * power-off.
-                *
-                * Only sending a warning as the system will power-off anyway
-                */
-               dev_err(data->dev, "unable to start the timer\n");
-       }
+       hrtimer_start(&data->timer_wde, data->wde_interval, HRTIMER_MODE_REL);
 }
 
 static enum hrtimer_restart
@@ -165,9 +154,8 @@ static irqreturn_t ltc2952_poweroff_handler(int irq, void *dev_id)
        }
 
        if (gpiod_get_value(data->gpio_trigger)) {
-               if (hrtimer_start(&data->timer_trigger, data->trigger_delay,
-                                 HRTIMER_MODE_REL))
-                       dev_err(data->dev, "unable to start the wait timer\n");
+               hrtimer_start(&data->timer_trigger, data->trigger_delay,
+                             HRTIMER_MODE_REL);
        } else {
                hrtimer_cancel(&data->timer_trigger);
                /* omitting return value check, timer should have been valid */
index cb70ced7e0db19771699a7b362d63b7c49e06d31..4b62d1a875e43eb09bf4631f7695f31dda9bfa6d 100644 (file)
@@ -64,7 +64,7 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
 static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct armada38x_rtc *rtc = dev_get_drvdata(dev);
-       unsigned long time, time_check, flags;
+       unsigned long time, time_check;
 
        mutex_lock(&rtc->mutex_time);
        time = readl(rtc->regs + RTC_TIME);
index 198f96b7fb45dab78845ba1fcde123ea680e2082..72b059081559356100aa68dea2c021b056b492e5 100644 (file)
@@ -78,6 +78,7 @@ config SPI_ATMEL
 config SPI_BCM2835
        tristate "BCM2835 SPI controller"
        depends on ARCH_BCM2835 || COMPILE_TEST
+       depends on GPIOLIB
        help
          This selects a driver for the Broadcom BCM2835 SPI master.
 
@@ -302,7 +303,7 @@ config SPI_FSL_SPI
 config SPI_FSL_DSPI
        tristate "Freescale DSPI controller"
        select REGMAP_MMIO
-       depends on SOC_VF610 || COMPILE_TEST
+       depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST
        help
          This enables support for the Freescale DSPI controller in master
          mode. VF610 platform uses the controller.
index f63864a893c520c40d9c79f1c8ca838b15dedc8c..37875cf942f7b928c5d31f44345b5c060f182b36 100644 (file)
@@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
                                         unsigned long xfer_time_us)
 {
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
-       unsigned long timeout = jiffies +
-               max(4 * xfer_time_us * HZ / 1000000, 2uL);
+       /* set timeout to 1 second of maximum polling */
+       unsigned long timeout = jiffies + HZ;
 
        /* enable HW block without interrupts */
        bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
 
-       /* set timeout to 4x the expected time, or 2 jiffies */
        /* loop until finished the transfer */
        while (bs->rx_len) {
                /* read from fifo as much as possible */
index 5ef6638d5e8a2698a6c8e85fad41c46d1f03fd06..840a4984d3650e27dcf98713235a67e040b8ca1a 100644 (file)
@@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi)
 {
        struct spi_bitbang_cs   *cs = spi->controller_state;
        struct spi_bitbang      *bitbang;
-       int                     retval;
        unsigned long           flags;
 
        bitbang = spi_master_get_devdata(spi->master);
@@ -197,9 +196,11 @@ int spi_bitbang_setup(struct spi_device *spi)
        if (!cs->txrx_word)
                return -EINVAL;
 
-       retval = bitbang->setup_transfer(spi, NULL);
-       if (retval < 0)
-               return retval;
+       if (bitbang->setup_transfer) {
+               int retval = bitbang->setup_transfer(spi, NULL);
+               if (retval < 0)
+                       return retval;
+       }
 
        dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs);
 
@@ -295,9 +296,11 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 
                /* init (-1) or override (1) transfer params */
                if (do_setup != 0) {
-                       status = bitbang->setup_transfer(spi, t);
-                       if (status < 0)
-                               break;
+                       if (bitbang->setup_transfer) {
+                               status = bitbang->setup_transfer(spi, t);
+                               if (status < 0)
+                                       break;
+                       }
                        if (do_setup == -1)
                                do_setup = 0;
                }
index 9c46a3058743b75228256f55e64b8419b49c1f3d..896add8cfd3b6c6bba311a335072e63a4060a3a4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/of_address.h>
 #include <linux/spi/spi.h>
 #include <linux/types.h>
+#include <linux/platform_device.h>
 
 #include "spi-fsl-cpm.h"
 #include "spi-fsl-lib.h"
@@ -269,17 +270,6 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
        if (mspi->flags & SPI_CPM2) {
                pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
                out_be16(spi_base, pram_ofs);
-       } else {
-               struct spi_pram __iomem *pram = spi_base;
-               u16 rpbase = in_be16(&pram->rpbase);
-
-               /* Microcode relocation patch applied? */
-               if (rpbase) {
-                       pram_ofs = rpbase;
-               } else {
-                       pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
-                       out_be16(spi_base, pram_ofs);
-               }
        }
 
        iounmap(spi_base);
@@ -292,7 +282,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
        struct device_node *np = dev->of_node;
        const u32 *iprop;
        int size;
-       unsigned long pram_ofs;
        unsigned long bds_ofs;
 
        if (!(mspi->flags & SPI_CPM_MODE))
@@ -319,8 +308,26 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
                }
        }
 
-       pram_ofs = fsl_spi_cpm_get_pram(mspi);
-       if (IS_ERR_VALUE(pram_ofs)) {
+       if (mspi->flags & SPI_CPM1) {
+               struct resource *res;
+               void *pram;
+
+               res = platform_get_resource(to_platform_device(dev),
+                                           IORESOURCE_MEM, 1);
+               pram = devm_ioremap_resource(dev, res);
+               if (IS_ERR(pram))
+                       mspi->pram = NULL;
+               else
+                       mspi->pram = pram;
+       } else {
+               unsigned long pram_ofs = fsl_spi_cpm_get_pram(mspi);
+
+               if (IS_ERR_VALUE(pram_ofs))
+                       mspi->pram = NULL;
+               else
+                       mspi->pram = cpm_muram_addr(pram_ofs);
+       }
+       if (mspi->pram == NULL) {
                dev_err(dev, "can't allocate spi parameter ram\n");
                goto err_pram;
        }
@@ -346,8 +353,6 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
                goto err_dummy_rx;
        }
 
-       mspi->pram = cpm_muram_addr(pram_ofs);
-
        mspi->tx_bd = cpm_muram_addr(bds_ofs);
        mspi->rx_bd = cpm_muram_addr(bds_ofs + sizeof(*mspi->tx_bd));
 
@@ -375,7 +380,8 @@ err_dummy_rx:
 err_dummy_tx:
        cpm_muram_free(bds_ofs);
 err_bds:
-       cpm_muram_free(pram_ofs);
+       if (!(mspi->flags & SPI_CPM1))
+               cpm_muram_free(cpm_muram_offset(mspi->pram));
 err_pram:
        fsl_spi_free_dummy_rx();
        return -ENOMEM;
index d0a73a09a9bd3e02371a30bc4b5ceb34f6b52e4e..80d245ac846fa366abf8d2b7511a1fb4ac25c03e 100644 (file)
@@ -359,14 +359,16 @@ static void fsl_espi_rw_trans(struct spi_message *m,
                                struct fsl_espi_transfer *trans, u8 *rx_buff)
 {
        struct fsl_espi_transfer *espi_trans = trans;
-       unsigned int n_tx = espi_trans->n_tx;
-       unsigned int n_rx = espi_trans->n_rx;
+       unsigned int total_len = espi_trans->len;
        struct spi_transfer *t;
        u8 *local_buf;
        u8 *rx_buf = rx_buff;
        unsigned int trans_len;
        unsigned int addr;
-       int i, pos, loop;
+       unsigned int tx_only;
+       unsigned int rx_pos = 0;
+       unsigned int pos;
+       int i, loop;
 
        local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL);
        if (!local_buf) {
@@ -374,36 +376,48 @@ static void fsl_espi_rw_trans(struct spi_message *m,
                return;
        }
 
-       for (pos = 0, loop = 0; pos < n_rx; pos += trans_len, loop++) {
-               trans_len = n_rx - pos;
-               if (trans_len > SPCOM_TRANLEN_MAX - n_tx)
-                       trans_len = SPCOM_TRANLEN_MAX - n_tx;
+       for (pos = 0, loop = 0; pos < total_len; pos += trans_len, loop++) {
+               trans_len = total_len - pos;
 
                i = 0;
+               tx_only = 0;
                list_for_each_entry(t, &m->transfers, transfer_list) {
                        if (t->tx_buf) {
                                memcpy(local_buf + i, t->tx_buf, t->len);
                                i += t->len;
+                               if (!t->rx_buf)
+                                       tx_only += t->len;
                        }
                }
 
+               /* Add additional TX bytes to compensate SPCOM_TRANLEN_MAX */
+               if (loop > 0)
+                       trans_len += tx_only;
+
+               if (trans_len > SPCOM_TRANLEN_MAX)
+                       trans_len = SPCOM_TRANLEN_MAX;
+
+               /* Update device offset */
                if (pos > 0) {
                        addr = fsl_espi_cmd2addr(local_buf);
-                       addr += pos;
+                       addr += rx_pos;
                        fsl_espi_addr2cmd(addr, local_buf);
                }
 
-               espi_trans->n_tx = n_tx;
-               espi_trans->n_rx = trans_len;
-               espi_trans->len = trans_len + n_tx;
+               espi_trans->len = trans_len;
                espi_trans->tx_buf = local_buf;
                espi_trans->rx_buf = local_buf;
                fsl_espi_do_trans(m, espi_trans);
 
-               memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len);
+               /* If there is at least one RX byte then copy it to rx_buf */
+               if (tx_only < SPCOM_TRANLEN_MAX)
+                       memcpy(rx_buf + rx_pos, espi_trans->rx_buf + tx_only,
+                                       trans_len - tx_only);
+
+               rx_pos += trans_len - tx_only;
 
                if (loop > 0)
-                       espi_trans->actual_length += espi_trans->len - n_tx;
+                       espi_trans->actual_length += espi_trans->len - tx_only;
                else
                        espi_trans->actual_length += espi_trans->len;
        }
@@ -418,6 +432,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
        u8 *rx_buf = NULL;
        unsigned int n_tx = 0;
        unsigned int n_rx = 0;
+       unsigned int xfer_len = 0;
        struct fsl_espi_transfer espi_trans;
 
        list_for_each_entry(t, &m->transfers, transfer_list) {
@@ -427,11 +442,13 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
                        n_rx += t->len;
                        rx_buf = t->rx_buf;
                }
+               if ((t->tx_buf) || (t->rx_buf))
+                       xfer_len += t->len;
        }
 
        espi_trans.n_tx = n_tx;
        espi_trans.n_rx = n_rx;
-       espi_trans.len = n_tx + n_rx;
+       espi_trans.len = xfer_len;
        espi_trans.actual_length = 0;
        espi_trans.status = 0;
 
index 4df8942058deed3928e61a4b2bc4061c56eec7d7..d1a5b9fc3eba22edaafd6155a5292ee108d97ac7 100644 (file)
@@ -1210,6 +1210,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
        struct omap2_mcspi      *mcspi;
        struct omap2_mcspi_dma  *mcspi_dma;
        struct spi_transfer     *t;
+       int status;
 
        spi = m->spi;
        mcspi = spi_master_get_devdata(master);
@@ -1229,7 +1230,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
                                        tx_buf ? "tx" : "",
                                        rx_buf ? "rx" : "",
                                        t->bits_per_word);
-                       return -EINVAL;
+                       status = -EINVAL;
+                       goto out;
                }
 
                if (m->is_dma_mapped || len < DMA_MIN_BYTES)
@@ -1241,7 +1243,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
                        if (dma_mapping_error(mcspi->dev, t->tx_dma)) {
                                dev_dbg(mcspi->dev, "dma %cX %d bytes error\n",
                                                'T', len);
-                               return -EINVAL;
+                               status = -EINVAL;
+                               goto out;
                        }
                }
                if (mcspi_dma->dma_rx && rx_buf != NULL) {
@@ -1253,14 +1256,19 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master,
                                if (tx_buf != NULL)
                                        dma_unmap_single(mcspi->dev, t->tx_dma,
                                                        len, DMA_TO_DEVICE);
-                               return -EINVAL;
+                               status = -EINVAL;
+                               goto out;
                        }
                }
        }
 
        omap2_mcspi_work(mcspi, m);
+       /* spi_finalize_current_message() changes the status inside the
+        * spi_message, save the status here. */
+       status = m->status;
+out:
        spi_finalize_current_message(master);
-       return 0;
+       return status;
 }
 
 static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
index d5d7d2235163f9ef8c6430d99544ec7f2c791c6b..50910d85df5af28d6f281485cc79d4b3e15bc7e5 100644 (file)
@@ -583,6 +583,15 @@ static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg)
        rx_dev = master->dma_rx->device->dev;
 
        list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+               /*
+                * Restore the original value of tx_buf or rx_buf if they are
+                * NULL.
+                */
+               if (xfer->tx_buf == master->dummy_tx)
+                       xfer->tx_buf = NULL;
+               if (xfer->rx_buf == master->dummy_rx)
+                       xfer->rx_buf = NULL;
+
                if (!master->can_dma(master, msg->spi, xfer))
                        continue;
 
index 12623bc02f46679674d9bd1c3f1574fc21b57c37..725718e97a0bc86f8d69d3fc112fba7670543402 100644 (file)
@@ -206,51 +206,57 @@ static void find_target_mwait(void)
 
 }
 
+struct pkg_cstate_info {
+       bool skip;
+       int msr_index;
+       int cstate_id;
+};
+
+#define PKG_CSTATE_INIT(id) {                          \
+               .msr_index = MSR_PKG_C##id##_RESIDENCY, \
+               .cstate_id = id                         \
+                       }
+
+static struct pkg_cstate_info pkg_cstates[] = {
+       PKG_CSTATE_INIT(2),
+       PKG_CSTATE_INIT(3),
+       PKG_CSTATE_INIT(6),
+       PKG_CSTATE_INIT(7),
+       PKG_CSTATE_INIT(8),
+       PKG_CSTATE_INIT(9),
+       PKG_CSTATE_INIT(10),
+       {NULL},
+};
+
 static bool has_pkg_state_counter(void)
 {
-       u64 tmp;
-       return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) ||
-              !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) ||
-              !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) ||
-              !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp);
+       u64 val;
+       struct pkg_cstate_info *info = pkg_cstates;
+
+       /* check if any one of the counter msrs exists */
+       while (info->msr_index) {
+               if (!rdmsrl_safe(info->msr_index, &val))
+                       return true;
+               info++;
+       }
+
+       return false;
 }
 
 static u64 pkg_state_counter(void)
 {
        u64 val;
        u64 count = 0;
-
-       static bool skip_c2;
-       static bool skip_c3;
-       static bool skip_c6;
-       static bool skip_c7;
-
-       if (!skip_c2) {
-               if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val))
-                       count += val;
-               else
-                       skip_c2 = true;
-       }
-
-       if (!skip_c3) {
-               if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val))
-                       count += val;
-               else
-                       skip_c3 = true;
-       }
-
-       if (!skip_c6) {
-               if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val))
-                       count += val;
-               else
-                       skip_c6 = true;
-       }
-
-       if (!skip_c7) {
-               if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val))
-                       count += val;
-               else
-                       skip_c7 = true;
+       struct pkg_cstate_info *info = pkg_cstates;
+
+       while (info->msr_index) {
+               if (!info->skip) {
+                       if (!rdmsrl_safe(info->msr_index, &val))
+                               count += val;
+                       else
+                               info->skip = true;
+               }
+               info++;
        }
 
        return count;
@@ -667,7 +673,7 @@ static struct thermal_cooling_device_ops powerclamp_cooling_ops = {
 };
 
 /* runs on Nehalem and later */
-static const struct x86_cpu_id intel_powerclamp_ids[] = {
+static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = {
        { X86_VENDOR_INTEL, 6, 0x1a},
        { X86_VENDOR_INTEL, 6, 0x1c},
        { X86_VENDOR_INTEL, 6, 0x1e},
@@ -689,12 +695,13 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = {
        { X86_VENDOR_INTEL, 6, 0x46},
        { X86_VENDOR_INTEL, 6, 0x4c},
        { X86_VENDOR_INTEL, 6, 0x4d},
+       { X86_VENDOR_INTEL, 6, 0x4f},
        { X86_VENDOR_INTEL, 6, 0x56},
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
 
-static int powerclamp_probe(void)
+static int __init powerclamp_probe(void)
 {
        if (!x86_match_cpu(intel_powerclamp_ids)) {
                pr_err("Intel powerclamp does not run on family %d model %d\n",
@@ -760,7 +767,7 @@ file_error:
        debugfs_remove_recursive(debug_dir);
 }
 
-static int powerclamp_init(void)
+static int __init powerclamp_init(void)
 {
        int retval;
        int bitmap_size;
@@ -809,7 +816,7 @@ exit_free:
 }
 module_init(powerclamp_init);
 
-static void powerclamp_exit(void)
+static void __exit powerclamp_exit(void)
 {
        unregister_hotcpu_notifier(&powerclamp_cpu_notifier);
        end_power_clamp();
index 3aa46ac7cdbc33765a90279da09fd84507a09d6c..cd8f5f93b42c45aa4cde0f8c4aa346836006f6da 100644 (file)
@@ -529,7 +529,7 @@ static int rockchip_thermal_probe(struct platform_device *pdev)
 
        thermal->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
        if (IS_ERR(thermal->pclk)) {
-               error = PTR_ERR(thermal->clk);
+               error = PTR_ERR(thermal->pclk);
                dev_err(&pdev->dev, "failed to get apb_pclk clock: %d\n",
                        error);
                return error;
index 0531c752fbbb6680c40e939ad2a14fdc1830f357..8e391812e50377664f079cb83f61c380b16e6d93 100644 (file)
@@ -103,7 +103,7 @@ static inline int of_thermal_get_ntrips(struct thermal_zone_device *tz)
 static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz,
                                            int trip)
 {
-       return 0;
+       return false;
 }
 static inline const struct thermal_trip *
 of_thermal_get_trip_points(struct thermal_zone_device *tz)
index 49a1c61433b73722683cad25eef1fb92045e265a..1977c2a553aca711ba145d1670ea9a84fd45ea84 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -659,6 +659,9 @@ int setup_arg_pages(struct linux_binprm *bprm,
        if (stack_base > STACK_SIZE_MAX)
                stack_base = STACK_SIZE_MAX;
 
+       /* Add space for stack randomization. */
+       stack_base += (STACK_RND_MASK << PAGE_SHIFT);
+
        /* Make sure we didn't let the argument array grow too large. */
        if (vma->vm_end - vma->vm_start > stack_base)
                return -ENOMEM;
index f131fc23ffc4c18f03a9764973fa998bf0e5f79e..fffca9517321c88ee1e0128b864b257c56e2350d 100644 (file)
@@ -518,7 +518,14 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
        if (!kn)
                goto err_out1;
 
-       ret = ida_simple_get(&root->ino_ida, 1, 0, GFP_KERNEL);
+       /*
+        * If the ino of the sysfs entry created for a kmem cache gets
+        * allocated from an ida layer, which is accounted to the memcg that
+        * owns the cache, the memcg will get pinned forever. So do not account
+        * ino ida allocations.
+        */
+       ret = ida_simple_get(&root->ino_ida, 1, 0,
+                            GFP_KERNEL | __GFP_NOACCOUNT);
        if (ret < 0)
                goto err_out2;
        kn->ino = ret;
index 03d647bf195d78bb3d6611553c9ad3e6fa4385a2..cdefaa331a0719e88df91ef7c04c32706ae199a1 100644 (file)
@@ -181,6 +181,17 @@ nfsd4_block_proc_layoutcommit(struct inode *inode,
 }
 
 const struct nfsd4_layout_ops bl_layout_ops = {
+       /*
+        * Pretend that we send notification to the client.  This is a blatant
+        * lie to force recent Linux clients to cache our device IDs.
+        * We rarely ever change the device ID, so the harm of leaking deviceids
+        * for a while isn't too bad.  Unfortunately RFC5661 is a complete mess
+        * in this regard, but I filed errata 4119 for this a while ago, and
+        * hopefully the Linux client will eventually start caching deviceids
+        * without this again.
+        */
+       .notify_types           =
+                       NOTIFY_DEVICEID4_DELETE | NOTIFY_DEVICEID4_CHANGE,
        .proc_getdeviceinfo     = nfsd4_block_proc_getdeviceinfo,
        .encode_getdeviceinfo   = nfsd4_block_encode_getdeviceinfo,
        .proc_layoutget         = nfsd4_block_proc_layoutget,
index 58277859a467d878cf5cd5d947d7361f8b3396cf..5694cfb7a47b73a0d7128ed987cf1aaba6ea8859 100644 (file)
@@ -224,7 +224,7 @@ static int nfs_cb_stat_to_errno(int status)
 }
 
 static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
-                              enum nfsstat4 *status)
+                              int *status)
 {
        __be32 *p;
        u32 op;
@@ -235,7 +235,7 @@ static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
        op = be32_to_cpup(p++);
        if (unlikely(op != expected))
                goto out_unexpected;
-       *status = be32_to_cpup(p);
+       *status = nfs_cb_stat_to_errno(be32_to_cpup(p));
        return 0;
 out_overflow:
        print_overflow_msg(__func__, xdr);
@@ -446,22 +446,16 @@ out_overflow:
 static int decode_cb_sequence4res(struct xdr_stream *xdr,
                                  struct nfsd4_callback *cb)
 {
-       enum nfsstat4 nfserr;
        int status;
 
        if (cb->cb_minorversion == 0)
                return 0;
 
-       status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &nfserr);
-       if (unlikely(status))
-               goto out;
-       if (unlikely(nfserr != NFS4_OK))
-               goto out_default;
-       status = decode_cb_sequence4resok(xdr, cb);
-out:
-       return status;
-out_default:
-       return nfs_cb_stat_to_errno(nfserr);
+       status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &cb->cb_status);
+       if (unlikely(status || cb->cb_status))
+               return status;
+
+       return decode_cb_sequence4resok(xdr, cb);
 }
 
 /*
@@ -524,26 +518,19 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp,
                                  struct nfsd4_callback *cb)
 {
        struct nfs4_cb_compound_hdr hdr;
-       enum nfsstat4 nfserr;
        int status;
 
        status = decode_cb_compound4res(xdr, &hdr);
        if (unlikely(status))
-               goto out;
+               return status;
 
        if (cb != NULL) {
                status = decode_cb_sequence4res(xdr, cb);
-               if (unlikely(status))
-                       goto out;
+               if (unlikely(status || cb->cb_status))
+                       return status;
        }
 
-       status = decode_cb_op_status(xdr, OP_CB_RECALL, &nfserr);
-       if (unlikely(status))
-               goto out;
-       if (unlikely(nfserr != NFS4_OK))
-               status = nfs_cb_stat_to_errno(nfserr);
-out:
-       return status;
+       return decode_cb_op_status(xdr, OP_CB_RECALL, &cb->cb_status);
 }
 
 #ifdef CONFIG_NFSD_PNFS
@@ -621,24 +608,18 @@ static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp,
                                  struct nfsd4_callback *cb)
 {
        struct nfs4_cb_compound_hdr hdr;
-       enum nfsstat4 nfserr;
        int status;
 
        status = decode_cb_compound4res(xdr, &hdr);
        if (unlikely(status))
-               goto out;
+               return status;
+
        if (cb) {
                status = decode_cb_sequence4res(xdr, cb);
-               if (unlikely(status))
-                       goto out;
+               if (unlikely(status || cb->cb_status))
+                       return status;
        }
-       status = decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &nfserr);
-       if (unlikely(status))
-               goto out;
-       if (unlikely(nfserr != NFS4_OK))
-               status = nfs_cb_stat_to_errno(nfserr);
-out:
-       return status;
+       return decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &cb->cb_status);
 }
 #endif /* CONFIG_NFSD_PNFS */
 
@@ -898,13 +879,6 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
                if (!nfsd41_cb_get_slot(clp, task))
                        return;
        }
-       spin_lock(&clp->cl_lock);
-       if (list_empty(&cb->cb_per_client)) {
-               /* This is the first call, not a restart */
-               cb->cb_done = false;
-               list_add(&cb->cb_per_client, &clp->cl_callbacks);
-       }
-       spin_unlock(&clp->cl_lock);
        rpc_call_start(task);
 }
 
@@ -918,22 +892,33 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
 
        if (clp->cl_minorversion) {
                /* No need for lock, access serialized in nfsd4_cb_prepare */
-               ++clp->cl_cb_session->se_cb_seq_nr;
+               if (!task->tk_status)
+                       ++clp->cl_cb_session->se_cb_seq_nr;
                clear_bit(0, &clp->cl_cb_slot_busy);
                rpc_wake_up_next(&clp->cl_cb_waitq);
                dprintk("%s: freed slot, new seqid=%d\n", __func__,
                        clp->cl_cb_session->se_cb_seq_nr);
        }
 
-       if (clp->cl_cb_client != task->tk_client) {
-               /* We're shutting down or changing cl_cb_client; leave
-                * it to nfsd4_process_cb_update to restart the call if
-                * necessary. */
+       /*
+        * If the backchannel connection was shut down while this
+        * task was queued, we need to resubmit it after setting up
+        * a new backchannel connection.
+        *
+        * Note that if we lost our callback connection permanently
+        * the submission code will error out, so we don't need to
+        * handle that case here.
+        */
+       if (task->tk_flags & RPC_TASK_KILLED) {
+               task->tk_status = 0;
+               cb->cb_need_restart = true;
                return;
        }
 
-       if (cb->cb_done)
-               return;
+       if (cb->cb_status) {
+               WARN_ON_ONCE(task->tk_status);
+               task->tk_status = cb->cb_status;
+       }
 
        switch (cb->cb_ops->done(cb, task)) {
        case 0:
@@ -949,21 +934,17 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
        default:
                BUG();
        }
-       cb->cb_done = true;
 }
 
 static void nfsd4_cb_release(void *calldata)
 {
        struct nfsd4_callback *cb = calldata;
-       struct nfs4_client *clp = cb->cb_clp;
-
-       if (cb->cb_done) {
-               spin_lock(&clp->cl_lock);
-               list_del(&cb->cb_per_client);
-               spin_unlock(&clp->cl_lock);
 
+       if (cb->cb_need_restart)
+               nfsd4_run_cb(cb);
+       else
                cb->cb_ops->release(cb);
-       }
+
 }
 
 static const struct rpc_call_ops nfsd4_cb_ops = {
@@ -1058,9 +1039,6 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
                nfsd4_mark_cb_down(clp, err);
                return;
        }
-       /* Yay, the callback channel's back! Restart any callbacks: */
-       list_for_each_entry(cb, &clp->cl_callbacks, cb_per_client)
-               queue_work(callback_wq, &cb->cb_work);
 }
 
 static void
@@ -1071,8 +1049,12 @@ nfsd4_run_cb_work(struct work_struct *work)
        struct nfs4_client *clp = cb->cb_clp;
        struct rpc_clnt *clnt;
 
-       if (cb->cb_ops && cb->cb_ops->prepare)
-               cb->cb_ops->prepare(cb);
+       if (cb->cb_need_restart) {
+               cb->cb_need_restart = false;
+       } else {
+               if (cb->cb_ops && cb->cb_ops->prepare)
+                       cb->cb_ops->prepare(cb);
+       }
 
        if (clp->cl_flags & NFSD4_CLIENT_CB_FLAG_MASK)
                nfsd4_process_cb_update(cb);
@@ -1084,6 +1066,15 @@ nfsd4_run_cb_work(struct work_struct *work)
                        cb->cb_ops->release(cb);
                return;
        }
+
+       /*
+        * Don't send probe messages for 4.1 or later.
+        */
+       if (!cb->cb_ops && clp->cl_minorversion) {
+               clp->cl_cb_state = NFSD4_CB_UP;
+               return;
+       }
+
        cb->cb_msg.rpc_cred = clp->cl_cb_cred;
        rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
                        cb->cb_ops ? &nfsd4_cb_ops : &nfsd4_cb_probe_ops, cb);
@@ -1098,8 +1089,8 @@ void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
        cb->cb_msg.rpc_resp = cb;
        cb->cb_ops = ops;
        INIT_WORK(&cb->cb_work, nfsd4_run_cb_work);
-       INIT_LIST_HEAD(&cb->cb_per_client);
-       cb->cb_done = true;
+       cb->cb_status = 0;
+       cb->cb_need_restart = false;
 }
 
 void nfsd4_run_cb(struct nfsd4_callback *cb)
index 38f2d7abe3a707061c3f860ce8042649bf5109eb..039f9c8a95e84289c7296e9b78973efbea9d6e5a 100644 (file)
@@ -94,6 +94,7 @@ static struct kmem_cache *lockowner_slab;
 static struct kmem_cache *file_slab;
 static struct kmem_cache *stateid_slab;
 static struct kmem_cache *deleg_slab;
+static struct kmem_cache *odstate_slab;
 
 static void free_session(struct nfsd4_session *);
 
@@ -281,6 +282,7 @@ put_nfs4_file(struct nfs4_file *fi)
        if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) {
                hlist_del_rcu(&fi->fi_hash);
                spin_unlock(&state_lock);
+               WARN_ON_ONCE(!list_empty(&fi->fi_clnt_odstate));
                WARN_ON_ONCE(!list_empty(&fi->fi_delegations));
                call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu);
        }
@@ -471,6 +473,86 @@ static void nfs4_file_put_access(struct nfs4_file *fp, u32 access)
                __nfs4_file_put_access(fp, O_RDONLY);
 }
 
+/*
+ * Allocate a new open/delegation state counter. This is needed for
+ * pNFS for proper return on close semantics.
+ *
+ * Note that we only allocate it for pNFS-enabled exports, otherwise
+ * all pointers to struct nfs4_clnt_odstate are always NULL.
+ */
+static struct nfs4_clnt_odstate *
+alloc_clnt_odstate(struct nfs4_client *clp)
+{
+       struct nfs4_clnt_odstate *co;
+
+       co = kmem_cache_zalloc(odstate_slab, GFP_KERNEL);
+       if (co) {
+               co->co_client = clp;
+               atomic_set(&co->co_odcount, 1);
+       }
+       return co;
+}
+
+static void
+hash_clnt_odstate_locked(struct nfs4_clnt_odstate *co)
+{
+       struct nfs4_file *fp = co->co_file;
+
+       lockdep_assert_held(&fp->fi_lock);
+       list_add(&co->co_perfile, &fp->fi_clnt_odstate);
+}
+
+static inline void
+get_clnt_odstate(struct nfs4_clnt_odstate *co)
+{
+       if (co)
+               atomic_inc(&co->co_odcount);
+}
+
+static void
+put_clnt_odstate(struct nfs4_clnt_odstate *co)
+{
+       struct nfs4_file *fp;
+
+       if (!co)
+               return;
+
+       fp = co->co_file;
+       if (atomic_dec_and_lock(&co->co_odcount, &fp->fi_lock)) {
+               list_del(&co->co_perfile);
+               spin_unlock(&fp->fi_lock);
+
+               nfsd4_return_all_file_layouts(co->co_client, fp);
+               kmem_cache_free(odstate_slab, co);
+       }
+}
+
+static struct nfs4_clnt_odstate *
+find_or_hash_clnt_odstate(struct nfs4_file *fp, struct nfs4_clnt_odstate *new)
+{
+       struct nfs4_clnt_odstate *co;
+       struct nfs4_client *cl;
+
+       if (!new)
+               return NULL;
+
+       cl = new->co_client;
+
+       spin_lock(&fp->fi_lock);
+       list_for_each_entry(co, &fp->fi_clnt_odstate, co_perfile) {
+               if (co->co_client == cl) {
+                       get_clnt_odstate(co);
+                       goto out;
+               }
+       }
+       co = new;
+       co->co_file = fp;
+       hash_clnt_odstate_locked(new);
+out:
+       spin_unlock(&fp->fi_lock);
+       return co;
+}
+
 struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl,
                                         struct kmem_cache *slab)
 {
@@ -606,7 +688,8 @@ static void block_delegations(struct knfsd_fh *fh)
 }
 
 static struct nfs4_delegation *
-alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh)
+alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh,
+                struct nfs4_clnt_odstate *odstate)
 {
        struct nfs4_delegation *dp;
        long n;
@@ -631,6 +714,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct svc_fh *current_fh)
        INIT_LIST_HEAD(&dp->dl_perfile);
        INIT_LIST_HEAD(&dp->dl_perclnt);
        INIT_LIST_HEAD(&dp->dl_recall_lru);
+       dp->dl_clnt_odstate = odstate;
+       get_clnt_odstate(odstate);
        dp->dl_type = NFS4_OPEN_DELEGATE_READ;
        dp->dl_retries = 1;
        nfsd4_init_cb(&dp->dl_recall, dp->dl_stid.sc_client,
@@ -714,6 +799,7 @@ static void destroy_delegation(struct nfs4_delegation *dp)
        spin_lock(&state_lock);
        unhash_delegation_locked(dp);
        spin_unlock(&state_lock);
+       put_clnt_odstate(dp->dl_clnt_odstate);
        nfs4_put_deleg_lease(dp->dl_stid.sc_file);
        nfs4_put_stid(&dp->dl_stid);
 }
@@ -724,6 +810,7 @@ static void revoke_delegation(struct nfs4_delegation *dp)
 
        WARN_ON(!list_empty(&dp->dl_recall_lru));
 
+       put_clnt_odstate(dp->dl_clnt_odstate);
        nfs4_put_deleg_lease(dp->dl_stid.sc_file);
 
        if (clp->cl_minorversion == 0)
@@ -933,6 +1020,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
 {
        struct nfs4_ol_stateid *stp = openlockstateid(stid);
 
+       put_clnt_odstate(stp->st_clnt_odstate);
        release_all_access(stp);
        if (stp->st_stateowner)
                nfs4_put_stateowner(stp->st_stateowner);
@@ -1538,7 +1626,6 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
        INIT_LIST_HEAD(&clp->cl_openowners);
        INIT_LIST_HEAD(&clp->cl_delegations);
        INIT_LIST_HEAD(&clp->cl_lru);
-       INIT_LIST_HEAD(&clp->cl_callbacks);
        INIT_LIST_HEAD(&clp->cl_revoked);
 #ifdef CONFIG_NFSD_PNFS
        INIT_LIST_HEAD(&clp->cl_lo_states);
@@ -1634,6 +1721,7 @@ __destroy_client(struct nfs4_client *clp)
        while (!list_empty(&reaplist)) {
                dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
                list_del_init(&dp->dl_recall_lru);
+               put_clnt_odstate(dp->dl_clnt_odstate);
                nfs4_put_deleg_lease(dp->dl_stid.sc_file);
                nfs4_put_stid(&dp->dl_stid);
        }
@@ -3057,6 +3145,7 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval,
        spin_lock_init(&fp->fi_lock);
        INIT_LIST_HEAD(&fp->fi_stateids);
        INIT_LIST_HEAD(&fp->fi_delegations);
+       INIT_LIST_HEAD(&fp->fi_clnt_odstate);
        fh_copy_shallow(&fp->fi_fhandle, fh);
        fp->fi_deleg_file = NULL;
        fp->fi_had_conflict = false;
@@ -3073,6 +3162,7 @@ static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval,
 void
 nfsd4_free_slabs(void)
 {
+       kmem_cache_destroy(odstate_slab);
        kmem_cache_destroy(openowner_slab);
        kmem_cache_destroy(lockowner_slab);
        kmem_cache_destroy(file_slab);
@@ -3103,8 +3193,14 @@ nfsd4_init_slabs(void)
                        sizeof(struct nfs4_delegation), 0, 0, NULL);
        if (deleg_slab == NULL)
                goto out_free_stateid_slab;
+       odstate_slab = kmem_cache_create("nfsd4_odstate",
+                       sizeof(struct nfs4_clnt_odstate), 0, 0, NULL);
+       if (odstate_slab == NULL)
+               goto out_free_deleg_slab;
        return 0;
 
+out_free_deleg_slab:
+       kmem_cache_destroy(deleg_slab);
 out_free_stateid_slab:
        kmem_cache_destroy(stateid_slab);
 out_free_file_slab:
@@ -3581,6 +3677,14 @@ alloc_stateid:
        open->op_stp = nfs4_alloc_open_stateid(clp);
        if (!open->op_stp)
                return nfserr_jukebox;
+
+       if (nfsd4_has_session(cstate) &&
+           (cstate->current_fh.fh_export->ex_flags & NFSEXP_PNFS)) {
+               open->op_odstate = alloc_clnt_odstate(clp);
+               if (!open->op_odstate)
+                       return nfserr_jukebox;
+       }
+
        return nfs_ok;
 }
 
@@ -3869,7 +3973,7 @@ out_fput:
 
 static struct nfs4_delegation *
 nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
-                   struct nfs4_file *fp)
+                   struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate)
 {
        int status;
        struct nfs4_delegation *dp;
@@ -3877,7 +3981,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
        if (fp->fi_had_conflict)
                return ERR_PTR(-EAGAIN);
 
-       dp = alloc_init_deleg(clp, fh);
+       dp = alloc_init_deleg(clp, fh, odstate);
        if (!dp)
                return ERR_PTR(-ENOMEM);
 
@@ -3903,6 +4007,7 @@ out_unlock:
        spin_unlock(&state_lock);
 out:
        if (status) {
+               put_clnt_odstate(dp->dl_clnt_odstate);
                nfs4_put_stid(&dp->dl_stid);
                return ERR_PTR(status);
        }
@@ -3980,7 +4085,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open,
                default:
                        goto out_no_deleg;
        }
-       dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file);
+       dp = nfs4_set_delegation(clp, fh, stp->st_stid.sc_file, stp->st_clnt_odstate);
        if (IS_ERR(dp))
                goto out_no_deleg;
 
@@ -4069,6 +4174,11 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
                        release_open_stateid(stp);
                        goto out;
                }
+
+               stp->st_clnt_odstate = find_or_hash_clnt_odstate(fp,
+                                                       open->op_odstate);
+               if (stp->st_clnt_odstate == open->op_odstate)
+                       open->op_odstate = NULL;
        }
        update_stateid(&stp->st_stid.sc_stateid);
        memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
@@ -4129,6 +4239,8 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate,
                kmem_cache_free(file_slab, open->op_file);
        if (open->op_stp)
                nfs4_put_stid(&open->op_stp->st_stid);
+       if (open->op_odstate)
+               kmem_cache_free(odstate_slab, open->op_odstate);
 }
 
 __be32
@@ -4385,10 +4497,17 @@ static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_s
        return nfserr_old_stateid;
 }
 
+static __be32 nfsd4_check_openowner_confirmed(struct nfs4_ol_stateid *ols)
+{
+       if (ols->st_stateowner->so_is_open_owner &&
+           !(openowner(ols->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
+               return nfserr_bad_stateid;
+       return nfs_ok;
+}
+
 static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
 {
        struct nfs4_stid *s;
-       struct nfs4_ol_stateid *ols;
        __be32 status = nfserr_bad_stateid;
 
        if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
@@ -4418,13 +4537,7 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
                break;
        case NFS4_OPEN_STID:
        case NFS4_LOCK_STID:
-               ols = openlockstateid(s);
-               if (ols->st_stateowner->so_is_open_owner
-                               && !(openowner(ols->st_stateowner)->oo_flags
-                                               & NFS4_OO_CONFIRMED))
-                       status = nfserr_bad_stateid;
-               else
-                       status = nfs_ok;
+               status = nfsd4_check_openowner_confirmed(openlockstateid(s));
                break;
        default:
                printk("unknown stateid type %x\n", s->sc_type);
@@ -4516,8 +4629,8 @@ nfs4_preprocess_stateid_op(struct net *net, struct nfsd4_compound_state *cstate,
                status = nfs4_check_fh(current_fh, stp);
                if (status)
                        goto out;
-               if (stp->st_stateowner->so_is_open_owner
-                   && !(openowner(stp->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
+               status = nfsd4_check_openowner_confirmed(stp);
+               if (status)
                        goto out;
                status = nfs4_check_openmode(stp, flags);
                if (status)
@@ -4852,9 +4965,6 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        update_stateid(&stp->st_stid.sc_stateid);
        memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
 
-       nfsd4_return_all_file_layouts(stp->st_stateowner->so_client,
-                                     stp->st_stid.sc_file);
-
        nfsd4_close_open_stateid(stp);
 
        /* put reference from nfs4_preprocess_seqid_op */
@@ -6488,6 +6598,7 @@ nfs4_state_shutdown_net(struct net *net)
        list_for_each_safe(pos, next, &reaplist) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
                list_del_init(&dp->dl_recall_lru);
+               put_clnt_odstate(dp->dl_clnt_odstate);
                nfs4_put_deleg_lease(dp->dl_stid.sc_file);
                nfs4_put_stid(&dp->dl_stid);
        }
index 4f3bfeb1176662ce5c7eb6f59f9440c95c8cf68e..dbc4f85a500825a2c80b21a9a92b52ff1631b8fb 100644 (file)
@@ -63,12 +63,12 @@ typedef struct {
 
 struct nfsd4_callback {
        struct nfs4_client *cb_clp;
-       struct list_head cb_per_client;
        u32 cb_minorversion;
        struct rpc_message cb_msg;
        struct nfsd4_callback_ops *cb_ops;
        struct work_struct cb_work;
-       bool cb_done;
+       int cb_status;
+       bool cb_need_restart;
 };
 
 struct nfsd4_callback_ops {
@@ -126,6 +126,7 @@ struct nfs4_delegation {
        struct list_head        dl_perfile;
        struct list_head        dl_perclnt;
        struct list_head        dl_recall_lru;  /* delegation recalled */
+       struct nfs4_clnt_odstate *dl_clnt_odstate;
        u32                     dl_type;
        time_t                  dl_time;
 /* For recall: */
@@ -332,7 +333,6 @@ struct nfs4_client {
        int                     cl_cb_state;
        struct nfsd4_callback   cl_cb_null;
        struct nfsd4_session    *cl_cb_session;
-       struct list_head        cl_callbacks; /* list of in-progress callbacks */
 
        /* for all client information that callback code might need: */
        spinlock_t              cl_lock;
@@ -464,6 +464,17 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so)
        return container_of(so, struct nfs4_lockowner, lo_owner);
 }
 
+/*
+ * Per-client state indicating no. of opens and outstanding delegations
+ * on a file from a particular client.'od' stands for 'open & delegation'
+ */
+struct nfs4_clnt_odstate {
+       struct nfs4_client      *co_client;
+       struct nfs4_file        *co_file;
+       struct list_head        co_perfile;
+       atomic_t                co_odcount;
+};
+
 /*
  * nfs4_file: a file opened by some number of (open) nfs4_stateowners.
  *
@@ -485,6 +496,7 @@ struct nfs4_file {
                struct list_head        fi_delegations;
                struct rcu_head         fi_rcu;
        };
+       struct list_head        fi_clnt_odstate;
        /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
        struct file *           fi_fds[3];
        /*
@@ -526,6 +538,7 @@ struct nfs4_ol_stateid {
        struct list_head              st_perstateowner;
        struct list_head              st_locks;
        struct nfs4_stateowner      * st_stateowner;
+       struct nfs4_clnt_odstate    * st_clnt_odstate;
        unsigned char                 st_access_bmap;
        unsigned char                 st_deny_bmap;
        struct nfs4_ol_stateid         * st_openstp;
index f982ae84f0cd2303df5275086a3a05ce519bbd86..2f8c092be2b3344901f07f2f16e0ee239034ccdf 100644 (file)
@@ -247,6 +247,7 @@ struct nfsd4_open {
        struct nfs4_openowner *op_openowner; /* used during processing */
        struct nfs4_file *op_file;          /* used during processing */
        struct nfs4_ol_stateid *op_stp;     /* used during processing */
+       struct nfs4_clnt_odstate *op_odstate; /* used during processing */
        struct nfs4_acl *op_acl;
        struct xdr_netobj op_label;
 };
index 2dd405c9be78d474fe4c1c11a70651b6741ab396..45c39a37f9249562761dc9615ffecf12ec194846 100644 (file)
        {0x1002, 0x6658, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x665c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x665d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x665f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BONAIRE|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x6664, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HAINAN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
index 97a9373e61e80d048ee6259eb4962bd831cac822..15928f0647e44187eb00ae7e128f4047519b093b 100644 (file)
@@ -30,6 +30,7 @@ struct vm_area_struct;
 #define ___GFP_HARDWALL                0x20000u
 #define ___GFP_THISNODE                0x40000u
 #define ___GFP_RECLAIMABLE     0x80000u
+#define ___GFP_NOACCOUNT       0x100000u
 #define ___GFP_NOTRACK         0x200000u
 #define ___GFP_NO_KSWAPD       0x400000u
 #define ___GFP_OTHER_NODE      0x800000u
@@ -87,6 +88,7 @@ struct vm_area_struct;
 #define __GFP_HARDWALL   ((__force gfp_t)___GFP_HARDWALL) /* Enforce hardwall cpuset memory allocs */
 #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */
 #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
+#define __GFP_NOACCOUNT        ((__force gfp_t)___GFP_NOACCOUNT) /* Don't account to kmemcg */
 #define __GFP_NOTRACK  ((__force gfp_t)___GFP_NOTRACK)  /* Don't track with kmemcheck */
 
 #define __GFP_NO_KSWAPD        ((__force gfp_t)___GFP_NO_KSWAPD)
index 8dad4a307bb8c4b086e8f6f62211d91d8c05a53a..28aeae46f355fdfdc96f28dd5a091dacbc85e9b8 100644 (file)
@@ -205,6 +205,7 @@ enum {
        ATA_LFLAG_SW_ACTIVITY   = (1 << 7), /* keep activity stats */
        ATA_LFLAG_NO_LPM        = (1 << 8), /* disable LPM on this link */
        ATA_LFLAG_RST_ONCE      = (1 << 9), /* limit recovery to one reset */
+       ATA_LFLAG_CHANGED       = (1 << 10), /* LPM state changed on this link */
 
        /* struct ata_port flags */
        ATA_FLAG_SLAVE_POSS     = (1 << 0), /* host supports slave dev */
@@ -309,6 +310,12 @@ enum {
         */
        ATA_TMOUT_PMP_SRST_WAIT = 5000,
 
+       /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might
+        * be a spurious PHY event, so ignore the first PHY event that
+        * occurs within 10s after the policy change.
+        */
+       ATA_TMOUT_SPURIOUS_PHY  = 10000,
+
        /* ATA bus states */
        BUS_UNKNOWN             = 0,
        BUS_DMA                 = 1,
@@ -788,6 +795,8 @@ struct ata_link {
        struct ata_eh_context   eh_context;
 
        struct ata_device       device[ATA_MAX_DEVICES];
+
+       unsigned long           last_lpm_change; /* when last LPM change happened */
 };
 #define ATA_LINK_CLEAR_BEGIN           offsetof(struct ata_link, active_tag)
 #define ATA_LINK_CLEAR_END             offsetof(struct ata_link, device[0])
@@ -1201,6 +1210,7 @@ extern struct ata_device *ata_dev_pair(struct ata_device *adev);
 extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
 extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap);
 extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q);
+extern bool sata_lpm_ignore_phy_events(struct ata_link *link);
 
 extern int ata_cable_40wire(struct ata_port *ap);
 extern int ata_cable_80wire(struct ata_port *ap);
index 72dff5fb0d0ceaf0386d80f1cba83c7bb2c7632f..6c8918114804fda89d00ed3e6b1482539f2dd4ee 100644 (file)
@@ -463,6 +463,8 @@ memcg_kmem_newpage_charge(gfp_t gfp, struct mem_cgroup **memcg, int order)
        if (!memcg_kmem_enabled())
                return true;
 
+       if (gfp & __GFP_NOACCOUNT)
+               return true;
        /*
         * __GFP_NOFAIL allocations will move on even if charging is not
         * possible. Therefore we don't even try, and have this allocation
@@ -522,6 +524,8 @@ memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp)
 {
        if (!memcg_kmem_enabled())
                return cachep;
+       if (gfp & __GFP_NOACCOUNT)
+               return cachep;
        if (gfp & __GFP_NOFAIL)
                return cachep;
        if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD))
index 1899c74a712791ba33f7e17f2d139da21da70c42..05b9a694e21312ad26beec7dfa0f32f719cc8c87 100644 (file)
@@ -25,7 +25,6 @@
 #ifndef _LINUX_NETDEVICE_H
 #define _LINUX_NETDEVICE_H
 
-#include <linux/pm_qos.h>
 #include <linux/timer.h>
 #include <linux/bug.h>
 #include <linux/delay.h>
@@ -1499,8 +1498,6 @@ enum netdev_priv_flags {
  *
  *     @qdisc_tx_busylock:     XXX: need comments on this one
  *
- *     @pm_qos_req:    Power Management QoS object
- *
  *     FIXME: cleanup struct net_device such that network protocol info
  *     moves out.
  */
index 6341f5be6e2474c0a7e30fdd75e3eae5b4286bf3..a30b172df6e1a760905f83c2136ac35f4611320f 100644 (file)
@@ -18,7 +18,7 @@ static inline int rt_task(struct task_struct *p)
 #ifdef CONFIG_RT_MUTEXES
 extern int rt_mutex_getprio(struct task_struct *p);
 extern void rt_mutex_setprio(struct task_struct *p, int prio);
-extern int rt_mutex_check_prio(struct task_struct *task, int newprio);
+extern int rt_mutex_get_effective_prio(struct task_struct *task, int newprio);
 extern struct task_struct *rt_mutex_get_top_task(struct task_struct *task);
 extern void rt_mutex_adjust_pi(struct task_struct *p);
 static inline bool tsk_is_pi_blocked(struct task_struct *tsk)
@@ -31,9 +31,10 @@ static inline int rt_mutex_getprio(struct task_struct *p)
        return p->normal_prio;
 }
 
-static inline int rt_mutex_check_prio(struct task_struct *task, int newprio)
+static inline int rt_mutex_get_effective_prio(struct task_struct *task,
+                                             int newprio)
 {
-       return 0;
+       return newprio;
 }
 
 static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *task)
index 0caa3a2d4106eab0137d20ac75518af7964281ba..3b2911502a8cf4a6e3eaf721e0e0105937ad456e 100644 (file)
@@ -145,11 +145,19 @@ struct tcp_sock {
  *     read the code and the spec side by side (and laugh ...)
  *     See RFC793 and RFC1122. The RFC writes these in capitals.
  */
+       u64     bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived
+                                * sum(delta(rcv_nxt)), or how many bytes
+                                * were acked.
+                                */
        u32     rcv_nxt;        /* What we want to receive next         */
        u32     copied_seq;     /* Head of yet unread data              */
        u32     rcv_wup;        /* rcv_nxt on last window update sent   */
        u32     snd_nxt;        /* Next sequence we send                */
 
+       u64     bytes_acked;    /* RFC4898 tcpEStatsAppHCThruOctetsAcked
+                                * sum(delta(snd_una)), or how many bytes
+                                * were acked.
+                                */
        u32     snd_una;        /* First byte we want an ack for        */
        u32     snd_sml;        /* Last byte of the most recently transmitted small packet */
        u32     rcv_tstamp;     /* timestamp of last received ACK (for keepalives) */
index 0ee05da3889946c10dd8fabaeb50e59cc20739c3..03835522dfcb68ab830a9d38768c374a99ec131d 100644 (file)
@@ -109,12 +109,12 @@ static inline bool gid_lte(kgid_t left, kgid_t right)
 
 static inline bool uid_valid(kuid_t uid)
 {
-       return !uid_eq(uid, INVALID_UID);
+       return __kuid_val(uid) != (uid_t) -1;
 }
 
 static inline bool gid_valid(kgid_t gid)
 {
-       return !gid_eq(gid, INVALID_GID);
+       return __kgid_val(gid) != (gid_t) -1;
 }
 
 #ifdef CONFIG_USER_NS
index eeda67652766a9979478de97105322b5ee6a7977..6ea16c84293b0cdcb981df77481a4fa5e509fdde 100644 (file)
@@ -30,11 +30,13 @@ struct wpan_phy_cca;
 struct cfg802154_ops {
        struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
                                                           const char *name,
+                                                          unsigned char name_assign_type,
                                                           int type);
        void    (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
                                               struct net_device *dev);
        int     (*add_virtual_intf)(struct wpan_phy *wpan_phy,
                                    const char *name,
+                                   unsigned char name_assign_type,
                                    enum nl802154_iftype type,
                                    __le64 extended_addr);
        int     (*del_virtual_intf)(struct wpan_phy *wpan_phy,
index aeee28081245c9215f10badd611f58ba0124fcd0..1e18005f7f65f061f6084ea1823a8d37368a57e4 100644 (file)
@@ -120,11 +120,13 @@ static inline u32 codel_time_to_us(codel_time_t val)
  * struct codel_params - contains codel parameters
  * @target:    target queue size (in time units)
  * @interval:  width of moving time window
+ * @mtu:       device mtu, or minimal queue backlog in bytes.
  * @ecn:       is Explicit Congestion Notification enabled
  */
 struct codel_params {
        codel_time_t    target;
        codel_time_t    interval;
+       u32             mtu;
        bool            ecn;
 };
 
@@ -166,10 +168,12 @@ struct codel_stats {
        u32             ecn_mark;
 };
 
-static void codel_params_init(struct codel_params *params)
+static void codel_params_init(struct codel_params *params,
+                             const struct Qdisc *sch)
 {
        params->interval = MS2TIME(100);
        params->target = MS2TIME(5);
+       params->mtu = psched_mtu(qdisc_dev(sch));
        params->ecn = false;
 }
 
@@ -180,7 +184,7 @@ static void codel_vars_init(struct codel_vars *vars)
 
 static void codel_stats_init(struct codel_stats *stats)
 {
-       stats->maxpacket = 256;
+       stats->maxpacket = 0;
 }
 
 /*
@@ -234,7 +238,7 @@ static bool codel_should_drop(const struct sk_buff *skb,
                stats->maxpacket = qdisc_pkt_len(skb);
 
        if (codel_time_before(vars->ldelay, params->target) ||
-           sch->qstats.backlog <= stats->maxpacket) {
+           sch->qstats.backlog <= params->mtu) {
                /* went below - stay below for at least interval */
                vars->first_above_time = 0;
                return false;
index b4bef1152c05c52b87dc877e9d4e8b09050842f7..8e3668b44c2984aeb3531d14927dd2bf6b9f88a3 100644 (file)
@@ -1666,6 +1666,8 @@ struct ieee80211_tx_control {
  * @sta: station table entry, %NULL for per-vif queue
  * @tid: the TID for this queue (unused for per-vif queue)
  * @ac: the AC for this queue
+ * @drv_priv: data area for driver use, will always be aligned to
+ *     sizeof(void *).
  *
  * The driver can obtain packets from this queue by calling
  * ieee80211_tx_dequeue().
index e18e7fd43f47d996613b0c1e7dfe6bc0e636c476..7df28a4c23f98793626371d1e2334ad91f7ebf87 100644 (file)
@@ -247,19 +247,109 @@ static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src)
        __put_unaligned_memmove64(swab64p(le64_src), be64_dst);
 }
 
-/* Basic interface to register ieee802154 device */
+/**
+ * ieee802154_alloc_hw - Allocate a new hardware device
+ *
+ * This must be called once for each hardware device. The returned pointer
+ * must be used to refer to this device when calling other functions.
+ * mac802154 allocates a private data area for the driver pointed to by
+ * @priv in &struct ieee802154_hw, the size of this area is given as
+ * @priv_data_len.
+ *
+ * @priv_data_len: length of private data
+ * @ops: callbacks for this device
+ *
+ * Return: A pointer to the new hardware device, or %NULL on error.
+ */
 struct ieee802154_hw *
 ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops);
+
+/**
+ * ieee802154_free_hw - free hardware descriptor
+ *
+ * This function frees everything that was allocated, including the
+ * private data for the driver. You must call ieee802154_unregister_hw()
+ * before calling this function.
+ *
+ * @hw: the hardware to free
+ */
 void ieee802154_free_hw(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_register_hw - Register hardware device
+ *
+ * You must call this function before any other functions in
+ * mac802154. Note that before a hardware can be registered, you
+ * need to fill the contained wpan_phy's information.
+ *
+ * @hw: the device to register as returned by ieee802154_alloc_hw()
+ *
+ * Return: 0 on success. An error code otherwise.
+ */
 int ieee802154_register_hw(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_unregister_hw - Unregister a hardware device
+ *
+ * This function instructs mac802154 to free allocated resources
+ * and unregister netdevices from the networking subsystem.
+ *
+ * @hw: the hardware to unregister
+ */
 void ieee802154_unregister_hw(struct ieee802154_hw *hw);
 
+/**
+ * ieee802154_rx - receive frame
+ *
+ * Use this function to hand received frames to mac802154. The receive
+ * buffer in @skb must start with an IEEE 802.15.4 header. In case of a
+ * paged @skb is used, the driver is recommended to put the ieee802154
+ * header of the frame on the linear part of the @skb to avoid memory
+ * allocation and/or memcpy by the stack.
+ *
+ * This function may not be called in IRQ context. Calls to this function
+ * for a single hardware must be synchronized against each other.
+ *
+ * @hw: the hardware this frame came in on
+ * @skb: the buffer to receive, owned by mac802154 after this call
+ */
 void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb);
+
+/**
+ * ieee802154_rx_irqsafe - receive frame
+ *
+ * Like ieee802154_rx() but can be called in IRQ context
+ * (internally defers to a tasklet.)
+ *
+ * @hw: the hardware this frame came in on
+ * @skb: the buffer to receive, owned by mac802154 after this call
+ * @lqi: link quality indicator
+ */
 void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb,
                           u8 lqi);
-
+/**
+ * ieee802154_wake_queue - wake ieee802154 queue
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ *
+ * Drivers should use this function instead of netif_wake_queue.
+ */
 void ieee802154_wake_queue(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_stop_queue - stop ieee802154 queue
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ *
+ * Drivers should use this function instead of netif_stop_queue.
+ */
 void ieee802154_stop_queue(struct ieee802154_hw *hw);
+
+/**
+ * ieee802154_xmit_complete - frame transmission complete
+ *
+ * @hw: pointer as obtained from ieee802154_alloc_hw().
+ * @skb: buffer for transmission
+ * @ifs_handling: indicate interframe space handling
+ */
 void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
                              bool ifs_handling);
 
index 051dc5c2802d3296f8b49d4b40911c0c22345262..6d204f3f9df8cafb82d856db08769a7d24dfd79e 100644 (file)
@@ -576,7 +576,7 @@ static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
 }
 
 /* tcp.c */
-void tcp_get_info(const struct sock *, struct tcp_info *);
+void tcp_get_info(struct sock *, struct tcp_info *);
 
 /* Read 'sendfile()'-style from a TCP socket */
 typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *,
@@ -804,6 +804,8 @@ enum tcp_ca_ack_event_flags {
 /* Requires ECN/ECT set on all packets */
 #define TCP_CONG_NEEDS_ECN     0x2
 
+union tcp_cc_info;
+
 struct tcp_congestion_ops {
        struct list_head        list;
        u32 key;
@@ -829,7 +831,8 @@ struct tcp_congestion_ops {
        /* hook for packet ack accounting (optional) */
        void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us);
        /* get info for inet_diag (optional) */
-       int (*get_info)(struct sock *sk, u32 ext, struct sk_buff *skb);
+       size_t (*get_info)(struct sock *sk, u32 ext, int *attr,
+                          union tcp_cc_info *info);
 
        char            name[TCP_CA_NAME_MAX];
        struct module   *owner;
index d65c0a09efd32041e3dd07ff80d0a421f0de6ae8..c7093c75bdd6b70a53c1c35a0950a92ad49722da 100644 (file)
@@ -143,4 +143,8 @@ struct tcp_dctcp_info {
        __u32   dctcp_ab_tot;
 };
 
+union tcp_cc_info {
+       struct tcpvegas_info    vegas;
+       struct tcp_dctcp_info   dctcp;
+};
 #endif /* _UAPI_INET_DIAG_H_ */
index bc9abfe88c9a0e1ba4a80f7f16af038c5cd1f2ac..139d4dd1cab83f1cee0399e9924138a24d350ba7 100644 (file)
@@ -31,4 +31,14 @@ struct mpls_label {
 #define MPLS_LS_TTL_MASK        0x000000FF
 #define MPLS_LS_TTL_SHIFT       0
 
+/* Reserved labels */
+#define MPLS_LABEL_IPV4NULL            0 /* RFC3032 */
+#define MPLS_LABEL_RTALERT             1 /* RFC3032 */
+#define MPLS_LABEL_IPV6NULL            2 /* RFC3032 */
+#define MPLS_LABEL_IMPLNULL            3 /* RFC3032 */
+#define MPLS_LABEL_ENTROPY             7 /* RFC6790 */
+#define MPLS_LABEL_GAL                 13 /* RFC5586 */
+#define MPLS_LABEL_OAMALERT            14 /* RFC3429 */
+#define MPLS_LABEL_EXTENSION           15 /* RFC7274 */
+
 #endif /* _UAPI_MPLS_H */
index 3b9718328d8bf7732a73a13a4811b98ff667f000..faa72f4fa547bcfe643b9cfd32b83b62caf6b973 100644 (file)
@@ -112,6 +112,7 @@ enum {
 #define TCP_FASTOPEN           23      /* Enable FastOpen on listeners */
 #define TCP_TIMESTAMP          24
 #define TCP_NOTSENT_LOWAT      25      /* limit number of unsent bytes in write queue */
+#define TCP_CC_INFO            26      /* Get Congestion Control (optional) info */
 
 struct tcp_repair_opt {
        __u32   opt_code;
@@ -189,6 +190,8 @@ struct tcp_info {
 
        __u64   tcpi_pacing_rate;
        __u64   tcpi_max_pacing_rate;
+       __u64   tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
+       __u64   tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
 };
 
 /* for TCP_MD5SIG socket option */
index 81aa3a4ece9f787038027bb4e5a1e456312c1182..1a3bf48743ce1c62c26077d642084cbdc8b40d6b 100644 (file)
@@ -913,10 +913,30 @@ static void put_ctx(struct perf_event_context *ctx)
  * Those places that change perf_event::ctx will hold both
  * perf_event_ctx::mutex of the 'old' and 'new' ctx value.
  *
- * Lock ordering is by mutex address. There is one other site where
- * perf_event_context::mutex nests and that is put_event(). But remember that
- * that is a parent<->child context relation, and migration does not affect
- * children, therefore these two orderings should not interact.
+ * Lock ordering is by mutex address. There are two other sites where
+ * perf_event_context::mutex nests and those are:
+ *
+ *  - perf_event_exit_task_context()   [ child , 0 ]
+ *      __perf_event_exit_task()
+ *        sync_child_event()
+ *          put_event()                        [ parent, 1 ]
+ *
+ *  - perf_event_init_context()                [ parent, 0 ]
+ *      inherit_task_group()
+ *        inherit_group()
+ *          inherit_event()
+ *            perf_event_alloc()
+ *              perf_init_event()
+ *                perf_try_init_event()        [ child , 1 ]
+ *
+ * While it appears there is an obvious deadlock here -- the parent and child
+ * nesting levels are inverted between the two. This is in fact safe because
+ * life-time rules separate them. That is an exiting task cannot fork, and a
+ * spawning task cannot (yet) exit.
+ *
+ * But remember that that these are parent<->child context relations, and
+ * migration does not affect children, therefore these two orderings should not
+ * interact.
  *
  * The change in perf_event::ctx does not affect children (as claimed above)
  * because the sys_perf_event_open() case will install a new event and break
@@ -3657,9 +3677,6 @@ static void perf_remove_from_owner(struct perf_event *event)
        }
 }
 
-/*
- * Called when the last reference to the file is gone.
- */
 static void put_event(struct perf_event *event)
 {
        struct perf_event_context *ctx;
@@ -3697,6 +3714,9 @@ int perf_event_release_kernel(struct perf_event *event)
 }
 EXPORT_SYMBOL_GPL(perf_event_release_kernel);
 
+/*
+ * Called when the last reference to the file is gone.
+ */
 static int perf_release(struct inode *inode, struct file *file)
 {
        put_event(file->private_data);
@@ -7364,7 +7384,12 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
                return -ENODEV;
 
        if (event->group_leader != event) {
-               ctx = perf_event_ctx_lock(event->group_leader);
+               /*
+                * This ctx->mutex can nest when we're called through
+                * inheritance. See the perf_event_ctx_lock_nested() comment.
+                */
+               ctx = perf_event_ctx_lock_nested(event->group_leader,
+                                                SINGLE_DEPTH_NESTING);
                BUG_ON(!ctx);
        }
 
index b73279367087ca779072b79a784f69224929c149..b025295f49662469d1f3b4257f3835d2f40f01e1 100644 (file)
@@ -265,15 +265,17 @@ struct task_struct *rt_mutex_get_top_task(struct task_struct *task)
 }
 
 /*
- * Called by sched_setscheduler() to check whether the priority change
- * is overruled by a possible priority boosting.
+ * Called by sched_setscheduler() to get the priority which will be
+ * effective after the change.
  */
-int rt_mutex_check_prio(struct task_struct *task, int newprio)
+int rt_mutex_get_effective_prio(struct task_struct *task, int newprio)
 {
        if (!task_has_pi_waiters(task))
-               return 0;
+               return newprio;
 
-       return task_top_pi_waiter(task)->task->prio <= newprio;
+       if (task_top_pi_waiter(task)->task->prio <= newprio)
+               return task_top_pi_waiter(task)->task->prio;
+       return newprio;
 }
 
 /*
index fe22f7510bceab3fad0f008379a91f34db074d37..57bd333bc4ab3e070356e7a3b9b9b2a5e742c91f 100644 (file)
@@ -3300,15 +3300,18 @@ static void __setscheduler_params(struct task_struct *p,
 
 /* Actually do priority change: must hold pi & rq lock. */
 static void __setscheduler(struct rq *rq, struct task_struct *p,
-                          const struct sched_attr *attr)
+                          const struct sched_attr *attr, bool keep_boost)
 {
        __setscheduler_params(p, attr);
 
        /*
-        * If we get here, there was no pi waiters boosting the
-        * task. It is safe to use the normal prio.
+        * Keep a potential priority boosting if called from
+        * sched_setscheduler().
         */
-       p->prio = normal_prio(p);
+       if (keep_boost)
+               p->prio = rt_mutex_get_effective_prio(p, normal_prio(p));
+       else
+               p->prio = normal_prio(p);
 
        if (dl_prio(p->prio))
                p->sched_class = &dl_sched_class;
@@ -3408,7 +3411,7 @@ static int __sched_setscheduler(struct task_struct *p,
        int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 :
                      MAX_RT_PRIO - 1 - attr->sched_priority;
        int retval, oldprio, oldpolicy = -1, queued, running;
-       int policy = attr->sched_policy;
+       int new_effective_prio, policy = attr->sched_policy;
        unsigned long flags;
        const struct sched_class *prev_class;
        struct rq *rq;
@@ -3590,15 +3593,14 @@ change:
        oldprio = p->prio;
 
        /*
-        * Special case for priority boosted tasks.
-        *
-        * If the new priority is lower or equal (user space view)
-        * than the current (boosted) priority, we just store the new
+        * Take priority boosted tasks into account. If the new
+        * effective priority is unchanged, we just store the new
         * normal parameters and do not touch the scheduler class and
         * the runqueue. This will be done when the task deboost
         * itself.
         */
-       if (rt_mutex_check_prio(p, newprio)) {
+       new_effective_prio = rt_mutex_get_effective_prio(p, newprio);
+       if (new_effective_prio == oldprio) {
                __setscheduler_params(p, attr);
                task_rq_unlock(rq, p, &flags);
                return 0;
@@ -3612,7 +3614,7 @@ change:
                put_prev_task(rq, p);
 
        prev_class = p->sched_class;
-       __setscheduler(rq, p, attr);
+       __setscheduler(rq, p, attr, true);
 
        if (running)
                p->sched_class->set_curr_task(rq);
@@ -6997,27 +6999,23 @@ static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
        unsigned long flags;
        long cpu = (long)hcpu;
        struct dl_bw *dl_b;
+       bool overflow;
+       int cpus;
 
-       switch (action & ~CPU_TASKS_FROZEN) {
+       switch (action) {
        case CPU_DOWN_PREPARE:
-               /* explicitly allow suspend */
-               if (!(action & CPU_TASKS_FROZEN)) {
-                       bool overflow;
-                       int cpus;
-
-                       rcu_read_lock_sched();
-                       dl_b = dl_bw_of(cpu);
+               rcu_read_lock_sched();
+               dl_b = dl_bw_of(cpu);
 
-                       raw_spin_lock_irqsave(&dl_b->lock, flags);
-                       cpus = dl_bw_cpus(cpu);
-                       overflow = __dl_overflow(dl_b, cpus, 0, 0);
-                       raw_spin_unlock_irqrestore(&dl_b->lock, flags);
+               raw_spin_lock_irqsave(&dl_b->lock, flags);
+               cpus = dl_bw_cpus(cpu);
+               overflow = __dl_overflow(dl_b, cpus, 0, 0);
+               raw_spin_unlock_irqrestore(&dl_b->lock, flags);
 
-                       rcu_read_unlock_sched();
+               rcu_read_unlock_sched();
 
-                       if (overflow)
-                               return notifier_from_errno(-EBUSY);
-               }
+               if (overflow)
+                       return notifier_from_errno(-EBUSY);
                cpuset_update_active_cpus(false);
                break;
        case CPU_DOWN_PREPARE_FROZEN:
@@ -7346,7 +7344,7 @@ static void normalize_task(struct rq *rq, struct task_struct *p)
        queued = task_on_rq_queued(p);
        if (queued)
                dequeue_task(rq, p, 0);
-       __setscheduler(rq, p, &attr);
+       __setscheduler(rq, p, &attr, false);
        if (queued) {
                enqueue_task(rq, p, 0);
                resched_curr(rq);
index 5405aff5a590c370d3c8ca37c0f9a0c19cb46775..f0fe4f2c1fa7aa865055731834cdd78e0684cca5 100644 (file)
 #define BYTES_PER_POINTER      sizeof(void *)
 
 /* GFP bitmask for kmemleak internal allocations */
-#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \
+#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC | \
+                                          __GFP_NOACCOUNT)) | \
                                 __GFP_NORETRY | __GFP_NOMEMALLOC | \
                                 __GFP_NOWARN)
 
index ede26291d4aa92ad120bfd006786414fd6d45c56..747743237d9f4d3ead6117d4ee152c00659cd362 100644 (file)
@@ -2518,7 +2518,7 @@ static void __init check_numabalancing_enable(void)
        if (numabalancing_override)
                set_numabalancing_state(numabalancing_override == 1);
 
-       if (nr_node_ids > 1 && !numabalancing_override) {
+       if (num_online_nodes() > 1 && !numabalancing_override) {
                pr_info("%s automatic NUMA balancing. "
                        "Configure with numa_balancing= or the "
                        "kernel.numa_balancing sysctl",
index 755a42c76eb4747623da51acdeb780b322b5ac06..303c908790efca6f7d0b30cc6d8a9db918085e10 100644 (file)
@@ -101,7 +101,8 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype)
                        buddy_idx = __find_buddy_index(page_idx, order);
                        buddy = page + (buddy_idx - page_idx);
 
-                       if (!is_migrate_isolate_page(buddy)) {
+                       if (pfn_valid_within(page_to_pfn(buddy)) &&
+                           !is_migrate_isolate_page(buddy)) {
                                __isolate_free_page(page, order);
                                kernel_map_pages(page, (1 << order), 1);
                                set_page_refcounted(page);
index 476709bd068a474f7edcac83a4869849ccfb4b17..4663c3dad3f5f676e913cbc9f6a79d5efcecde4e 100644 (file)
@@ -1557,7 +1557,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 {
        BT_DBG("%s %p", hdev->name, hdev);
 
-       if (!hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+       if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
+           test_bit(HCI_UP, &hdev->flags)) {
                /* Execute vendor specific shutdown routine */
                if (hdev->shutdown)
                        hdev->shutdown(hdev);
index c7ba0388f1be8e37e780f27e0b3bd95f45dd0ade..2c1c67fad64d57f3d744c89843816b2d64f5b834 100644 (file)
@@ -5209,7 +5209,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
        if (__netdev_find_adj(upper_dev, dev, &upper_dev->all_adj_list.upper))
                return -EBUSY;
 
-       if (__netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper))
+       if (__netdev_find_adj(dev, upper_dev, &dev->adj_list.upper))
                return -EEXIST;
 
        if (master && netdev_master_upper_dev_get(dev))
index 78fc04ad36fc03a0f1737ee484a08e1824b324dc..572af0011997a2057f30ba0b5022760e11493d98 100644 (file)
@@ -601,7 +601,7 @@ static int rtnl_net_getid(struct sk_buff *skb, struct nlmsghdr *nlh)
        }
 
        err = rtnl_net_fill(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
-                           RTM_GETNSID, net, peer, -1);
+                           RTM_NEWNSID, net, peer, -1);
        if (err < 0)
                goto err_out;
 
index e891bcf325ca759c9b7498f29ec76aa946198d5e..292f42228bfb361b5748998bbcc538b1e16a2f22 100644 (file)
@@ -1474,8 +1474,8 @@ void sk_release_kernel(struct sock *sk)
                return;
 
        sock_hold(sk);
-       sock_net_set(sk, get_net(&init_net));
        sock_release(sk->sk_socket);
+       sock_net_set(sk, get_net(&init_net));
        sock_put(sk);
 }
 EXPORT_SYMBOL(sk_release_kernel);
index 05dab2957cd49e9be95c6bbe1cef1eb9f35ab8a2..4adfd4d5471b83c254313a887687cb497ce7ad3a 100644 (file)
@@ -3,7 +3,9 @@ obj-$(CONFIG_IEEE802154_SOCKET) += ieee802154_socket.o
 obj-y += 6lowpan/
 
 ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \
-                header_ops.o sysfs.o nl802154.o
+                header_ops.o sysfs.o nl802154.o trace.o
 ieee802154_socket-y := socket.o
 
+CFLAGS_trace.o := -I$(src)
+
 ccflags-y += -D__CHECK_ENDIAN__
index 1b9d25f6e898616d7972950692bcd1eab71ddb26..346c6665d25e59bf372bacedc5a2ae6df30d227c 100644 (file)
@@ -175,6 +175,7 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
        int rc = -ENOBUFS;
        struct net_device *dev;
        int type = __IEEE802154_DEV_INVALID;
+       unsigned char name_assign_type;
 
        pr_debug("%s\n", __func__);
 
@@ -190,8 +191,10 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
                if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1]
                                != '\0')
                        return -EINVAL; /* phy name should be null-terminated */
+               name_assign_type = NET_NAME_USER;
        } else  {
                devname = "wpan%d";
+               name_assign_type = NET_NAME_ENUM;
        }
 
        if (strlen(devname) >= IFNAMSIZ)
@@ -221,7 +224,7 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
        }
 
        dev = rdev_add_virtual_intf_deprecated(wpan_phy_to_rdev(phy), devname,
-                                              type);
+                                              name_assign_type, type);
        if (IS_ERR(dev)) {
                rc = PTR_ERR(dev);
                goto nla_put_failure;
index a4daf91b8d0a395d6964dad93cf292e566dee22c..f3c12f6a4a392ad301e5a79fcabb2bb9f8521431 100644 (file)
@@ -589,7 +589,7 @@ static int nl802154_new_interface(struct sk_buff *skb, struct genl_info *info)
 
        return rdev_add_virtual_intf(rdev,
                                     nla_data(info->attrs[NL802154_ATTR_IFNAME]),
-                                    type, extended_addr);
+                                    NET_NAME_USER, type, extended_addr);
 }
 
 static int nl802154_del_interface(struct sk_buff *skb, struct genl_info *info)
index 7c46732fad2bdd3f6778fce066cb89330b5aeaa3..7b5a9dd94fe5a2b55d01103aa529261141ece521 100644 (file)
@@ -4,13 +4,16 @@
 #include <net/cfg802154.h>
 
 #include "core.h"
+#include "trace.h"
 
 static inline struct net_device *
 rdev_add_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
-                                const char *name, int type)
+                                const char *name,
+                                unsigned char name_assign_type,
+                                int type)
 {
        return rdev->ops->add_virtual_intf_deprecated(&rdev->wpan_phy, name,
-                                                     type);
+                                                     name_assign_type, type);
 }
 
 static inline void
@@ -22,75 +25,131 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
 
 static inline int
 rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name,
+                     unsigned char name_assign_type,
                      enum nl802154_iftype type, __le64 extended_addr)
 {
-       return rdev->ops->add_virtual_intf(&rdev->wpan_phy, name, type,
+       int ret;
+
+       trace_802154_rdev_add_virtual_intf(&rdev->wpan_phy, name, type,
                                           extended_addr);
+       ret = rdev->ops->add_virtual_intf(&rdev->wpan_phy, name,
+                                         name_assign_type, type,
+                                         extended_addr);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_del_virtual_intf(struct cfg802154_registered_device *rdev,
                      struct wpan_dev *wpan_dev)
 {
-       return rdev->ops->del_virtual_intf(&rdev->wpan_phy, wpan_dev);
+       int ret;
+
+       trace_802154_rdev_del_virtual_intf(&rdev->wpan_phy, wpan_dev);
+       ret = rdev->ops->del_virtual_intf(&rdev->wpan_phy, wpan_dev);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_channel(struct cfg802154_registered_device *rdev, u8 page, u8 channel)
 {
-       return rdev->ops->set_channel(&rdev->wpan_phy, page, channel);
+       int ret;
+
+       trace_802154_rdev_set_channel(&rdev->wpan_phy, page, channel);
+       ret = rdev->ops->set_channel(&rdev->wpan_phy, page, channel);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_cca_mode(struct cfg802154_registered_device *rdev,
                  const struct wpan_phy_cca *cca)
 {
-       return rdev->ops->set_cca_mode(&rdev->wpan_phy, cca);
+       int ret;
+
+       trace_802154_rdev_set_cca_mode(&rdev->wpan_phy, cca);
+       ret = rdev->ops->set_cca_mode(&rdev->wpan_phy, cca);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_pan_id(struct cfg802154_registered_device *rdev,
                struct wpan_dev *wpan_dev, __le16 pan_id)
 {
-       return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
+       int ret;
+
+       trace_802154_rdev_set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
+       ret = rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_short_addr(struct cfg802154_registered_device *rdev,
                    struct wpan_dev *wpan_dev, __le16 short_addr)
 {
-       return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr);
+       int ret;
+
+       trace_802154_rdev_set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr);
+       ret = rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev,
                          struct wpan_dev *wpan_dev, u8 min_be, u8 max_be)
 {
-       return rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev,
+       int ret;
+
+       trace_802154_rdev_set_backoff_exponent(&rdev->wpan_phy, wpan_dev,
                                               min_be, max_be);
+       ret = rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev,
+                                             min_be, max_be);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev,
                           struct wpan_dev *wpan_dev, u8 max_csma_backoffs)
 {
-       return rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev,
-                                               max_csma_backoffs);
+       int ret;
+
+       trace_802154_rdev_set_csma_backoffs(&rdev->wpan_phy, wpan_dev,
+                                           max_csma_backoffs);
+       ret = rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev,
+                                              max_csma_backoffs);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev,
                           struct wpan_dev *wpan_dev, s8 max_frame_retries)
 {
-       return rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev,
+       int ret;
+
+       trace_802154_rdev_set_max_frame_retries(&rdev->wpan_phy, wpan_dev,
                                                max_frame_retries);
+       ret = rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev,
+                                              max_frame_retries);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 static inline int
 rdev_set_lbt_mode(struct cfg802154_registered_device *rdev,
                  struct wpan_dev *wpan_dev, bool mode)
 {
-       return rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode);
+       int ret;
+
+       trace_802154_rdev_set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode);
+       ret = rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode);
+       trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+       return ret;
 }
 
 #endif /* __CFG802154_RDEV_OPS */
diff --git a/net/ieee802154/trace.c b/net/ieee802154/trace.c
new file mode 100644 (file)
index 0000000..95f997f
--- /dev/null
@@ -0,0 +1,7 @@
+#include <linux/module.h>
+
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
+#endif
diff --git a/net/ieee802154/trace.h b/net/ieee802154/trace.h
new file mode 100644 (file)
index 0000000..5ac25eb
--- /dev/null
@@ -0,0 +1,247 @@
+/* Based on net/wireless/tracing.h */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM cfg802154
+
+#if !defined(__RDEV_CFG802154_OPS_TRACE) || defined(TRACE_HEADER_MULTI_READ)
+#define __RDEV_CFG802154_OPS_TRACE
+
+#include <linux/tracepoint.h>
+
+#include <net/cfg802154.h>
+
+#define MAXNAME                32
+#define WPAN_PHY_ENTRY __array(char, wpan_phy_name, MAXNAME)
+#define WPAN_PHY_ASSIGN        strlcpy(__entry->wpan_phy_name,  \
+                               wpan_phy_name(wpan_phy), \
+                               MAXNAME)
+#define WPAN_PHY_PR_FMT        "%s"
+#define WPAN_PHY_PR_ARG        __entry->wpan_phy_name
+
+#define WPAN_DEV_ENTRY __field(u32, identifier)
+#define WPAN_DEV_ASSIGN        (__entry->identifier) = (!IS_ERR_OR_NULL(wpan_dev) \
+                                        ? wpan_dev->identifier : 0)
+#define WPAN_DEV_PR_FMT        "wpan_dev(%u)"
+#define WPAN_DEV_PR_ARG        (__entry->identifier)
+
+#define WPAN_CCA_ENTRY __field(enum nl802154_cca_modes, cca_mode) \
+                       __field(enum nl802154_cca_opts, cca_opt)
+#define WPAN_CCA_ASSIGN \
+       do {                                     \
+               (__entry->cca_mode) = cca->mode; \
+               (__entry->cca_opt) = cca->opt;   \
+       } while (0)
+#define WPAN_CCA_PR_FMT        "cca_mode: %d, cca_opt: %d"
+#define WPAN_CCA_PR_ARG __entry->cca_mode, __entry->cca_opt
+
+#define BOOL_TO_STR(bo) (bo) ? "true" : "false"
+
+/*************************************************************
+ *                     rdev->ops traces                     *
+ *************************************************************/
+
+TRACE_EVENT(802154_rdev_add_virtual_intf,
+       TP_PROTO(struct wpan_phy *wpan_phy, char *name,
+                enum nl802154_iftype type, __le64 extended_addr),
+       TP_ARGS(wpan_phy, name, type, extended_addr),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               __string(vir_intf_name, name ? name : "<noname>")
+               __field(enum nl802154_iftype, type)
+               __field(__le64, extended_addr)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               __assign_str(vir_intf_name, name ? name : "<noname>");
+               __entry->type = type;
+               __entry->extended_addr = extended_addr;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", virtual intf name: %s, type: %d, ea %llx",
+                 WPAN_PHY_PR_ARG, __get_str(vir_intf_name), __entry->type,
+                 __le64_to_cpu(__entry->extended_addr))
+);
+
+TRACE_EVENT(802154_rdev_del_virtual_intf,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev),
+       TP_ARGS(wpan_phy, wpan_dev),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT, WPAN_PHY_PR_ARG,
+                 WPAN_DEV_PR_ARG)
+);
+
+TRACE_EVENT(802154_rdev_set_channel,
+       TP_PROTO(struct wpan_phy *wpan_phy, u8 page, u8 channel),
+       TP_ARGS(wpan_phy, page, channel),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               __field(u8, page)
+               __field(u8, channel)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               __entry->page = page;
+               __entry->channel = channel;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", page: %d, channel: %d", WPAN_PHY_PR_ARG,
+                 __entry->page, __entry->channel)
+);
+
+TRACE_EVENT(802154_rdev_set_cca_mode,
+       TP_PROTO(struct wpan_phy *wpan_phy, const struct wpan_phy_cca *cca),
+       TP_ARGS(wpan_phy, cca),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_CCA_ENTRY
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_CCA_ASSIGN;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_CCA_PR_FMT, WPAN_PHY_PR_ARG,
+                 WPAN_CCA_PR_ARG)
+);
+
+DECLARE_EVENT_CLASS(802154_le16_template,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                __le16 le16arg),
+       TP_ARGS(wpan_phy, wpan_dev, le16arg),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(__le16, le16arg)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->le16arg = le16arg;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT ", pan id: 0x%04x",
+                 WPAN_PHY_PR_ARG, WPAN_DEV_PR_ARG,
+                 __le16_to_cpu(__entry->le16arg))
+);
+
+DEFINE_EVENT(802154_le16_template, 802154_rdev_set_pan_id,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                __le16 le16arg),
+       TP_ARGS(wpan_phy, wpan_dev, le16arg)
+);
+
+DEFINE_EVENT_PRINT(802154_le16_template, 802154_rdev_set_short_addr,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                __le16 le16arg),
+       TP_ARGS(wpan_phy, wpan_dev, le16arg),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT ", sa: 0x%04x",
+                 WPAN_PHY_PR_ARG, WPAN_DEV_PR_ARG,
+                 __le16_to_cpu(__entry->le16arg))
+);
+
+TRACE_EVENT(802154_rdev_set_backoff_exponent,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                u8 min_be, u8 max_be),
+       TP_ARGS(wpan_phy, wpan_dev, min_be, max_be),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(u8, min_be)
+               __field(u8, max_be)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->min_be = min_be;
+               __entry->max_be = max_be;
+       ),
+
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT
+                 ", min be: %d, max_be: %d", WPAN_PHY_PR_ARG,
+                 WPAN_DEV_PR_ARG, __entry->min_be, __entry->max_be)
+);
+
+TRACE_EVENT(802154_rdev_set_csma_backoffs,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                u8 max_csma_backoffs),
+       TP_ARGS(wpan_phy, wpan_dev, max_csma_backoffs),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(u8, max_csma_backoffs)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->max_csma_backoffs = max_csma_backoffs;
+       ),
+
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT
+                 ", max csma backoffs: %d", WPAN_PHY_PR_ARG,
+                 WPAN_DEV_PR_ARG, __entry->max_csma_backoffs)
+);
+
+TRACE_EVENT(802154_rdev_set_max_frame_retries,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                s8 max_frame_retries),
+       TP_ARGS(wpan_phy, wpan_dev, max_frame_retries),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(s8, max_frame_retries)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->max_frame_retries = max_frame_retries;
+       ),
+
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT
+                 ", max frame retries: %d", WPAN_PHY_PR_ARG,
+                 WPAN_DEV_PR_ARG, __entry->max_frame_retries)
+);
+
+TRACE_EVENT(802154_rdev_set_lbt_mode,
+       TP_PROTO(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+                bool mode),
+       TP_ARGS(wpan_phy, wpan_dev, mode),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               WPAN_DEV_ENTRY
+               __field(bool, mode)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               WPAN_DEV_ASSIGN;
+               __entry->mode = mode;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", " WPAN_DEV_PR_FMT
+               ", lbt mode: %s", WPAN_PHY_PR_ARG,
+               WPAN_DEV_PR_ARG, BOOL_TO_STR(__entry->mode))
+);
+
+TRACE_EVENT(802154_rdev_return_int,
+       TP_PROTO(struct wpan_phy *wpan_phy, int ret),
+       TP_ARGS(wpan_phy, ret),
+       TP_STRUCT__entry(
+               WPAN_PHY_ENTRY
+               __field(int, ret)
+       ),
+       TP_fast_assign(
+               WPAN_PHY_ASSIGN;
+               __entry->ret = ret;
+       ),
+       TP_printk(WPAN_PHY_PR_FMT ", returned: %d", WPAN_PHY_PR_ARG,
+                 __entry->ret)
+);
+
+#endif /* !__RDEV_CFG802154_OPS_TRACE || TRACE_HEADER_MULTI_READ */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+#include <trace/define_trace.h>
index bb77ebdae3b31bcacbfc4fdb350d4282e400e2e8..4d32262c7502cc22d13a9f3bd47ca72e8ee355e8 100644 (file)
@@ -224,14 +224,16 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
        handler->idiag_get_info(sk, r, info);
 
        if (sk->sk_state < TCP_TIME_WAIT) {
-               int err = 0;
+               union tcp_cc_info info;
+               size_t sz = 0;
+               int attr;
 
                rcu_read_lock();
                ca_ops = READ_ONCE(icsk->icsk_ca_ops);
                if (ca_ops && ca_ops->get_info)
-                       err = ca_ops->get_info(sk, ext, skb);
+                       sz = ca_ops->get_info(sk, ext, &attr, &info);
                rcu_read_unlock();
-               if (err < 0)
+               if (sz && nla_put(skb, attr, sz, &info) < 0)
                        goto errout;
        }
 
index 8c5cd9efebbcfa877fedb49dda67e3d098ccbbc1..46efa03d2b11352913654fc336a2ad5e6b957e01 100644 (file)
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/poll.h>
+#include <linux/inet_diag.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/skbuff.h>
@@ -2592,7 +2593,7 @@ EXPORT_SYMBOL(compat_tcp_setsockopt);
 #endif
 
 /* Return information about state of tcp endpoint in API format. */
-void tcp_get_info(const struct sock *sk, struct tcp_info *info)
+void tcp_get_info(struct sock *sk, struct tcp_info *info)
 {
        const struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2663,6 +2664,11 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info)
 
        rate = READ_ONCE(sk->sk_max_pacing_rate);
        info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL;
+
+       spin_lock_bh(&sk->sk_lock.slock);
+       info->tcpi_bytes_acked = tp->bytes_acked;
+       info->tcpi_bytes_received = tp->bytes_received;
+       spin_unlock_bh(&sk->sk_lock.slock);
 }
 EXPORT_SYMBOL_GPL(tcp_get_info);
 
@@ -2734,6 +2740,26 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
                        return -EFAULT;
                return 0;
        }
+       case TCP_CC_INFO: {
+               const struct tcp_congestion_ops *ca_ops;
+               union tcp_cc_info info;
+               size_t sz = 0;
+               int attr;
+
+               if (get_user(len, optlen))
+                       return -EFAULT;
+
+               ca_ops = icsk->icsk_ca_ops;
+               if (ca_ops && ca_ops->get_info)
+                       sz = ca_ops->get_info(sk, ~0U, &attr, &info);
+
+               len = min_t(unsigned int, len, sz);
+               if (put_user(len, optlen))
+                       return -EFAULT;
+               if (copy_to_user(optval, &info, len))
+                       return -EFAULT;
+               return 0;
+       }
        case TCP_QUICKACK:
                val = !icsk->icsk_ack.pingpong;
                break;
index 4376016f7fa5cf84a3114d1551da623442c9c713..4c41c1287197eb4748198ae9532d1f6233aa7f6a 100644 (file)
@@ -277,7 +277,8 @@ static void dctcp_cwnd_event(struct sock *sk, enum tcp_ca_event ev)
        }
 }
 
-static int dctcp_get_info(struct sock *sk, u32 ext, struct sk_buff *skb)
+static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr,
+                            union tcp_cc_info *info)
 {
        const struct dctcp *ca = inet_csk_ca(sk);
 
@@ -286,18 +287,17 @@ static int dctcp_get_info(struct sock *sk, u32 ext, struct sk_buff *skb)
         */
        if (ext & (1 << (INET_DIAG_DCTCPINFO - 1)) ||
            ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-               struct tcp_dctcp_info info;
-
-               memset(&info, 0, sizeof(info));
+               memset(info, 0, sizeof(struct tcp_dctcp_info));
                if (inet_csk(sk)->icsk_ca_ops != &dctcp_reno) {
-                       info.dctcp_enabled = 1;
-                       info.dctcp_ce_state = (u16) ca->ce_state;
-                       info.dctcp_alpha = ca->dctcp_alpha;
-                       info.dctcp_ab_ecn = ca->acked_bytes_ecn;
-                       info.dctcp_ab_tot = ca->acked_bytes_total;
+                       info->dctcp.dctcp_enabled = 1;
+                       info->dctcp.dctcp_ce_state = (u16) ca->ce_state;
+                       info->dctcp.dctcp_alpha = ca->dctcp_alpha;
+                       info->dctcp.dctcp_ab_ecn = ca->acked_bytes_ecn;
+                       info->dctcp.dctcp_ab_tot = ca->acked_bytes_total;
                }
 
-               return nla_put(skb, INET_DIAG_DCTCPINFO, sizeof(info), &info);
+               *attr = INET_DIAG_DCTCPINFO;
+               return sizeof(*info);
        }
        return 0;
 }
index e3d87aca6be8fafe02bec5a8f862a88a6fe79d50..3c673d5e6cff02df9416df8c5b9a9ede91f9bf99 100644 (file)
@@ -206,6 +206,7 @@ static bool tcp_fastopen_create_child(struct sock *sk,
                        skb_set_owner_r(skb2, child);
                        __skb_queue_tail(&child->sk_receive_queue, skb2);
                        tp->syn_data_acked = 1;
+                       tp->bytes_received = end_seq - TCP_SKB_CB(skb)->seq - 1;
                } else {
                        end_seq = TCP_SKB_CB(skb)->seq + 1;
                }
index 67476f085e4843dacaeb1b4d6b71ecc160c99b97..f71002e4db0ba7fe8dfe35bb2196bbaae751ed59 100644 (file)
@@ -300,24 +300,25 @@ static u32 tcp_illinois_ssthresh(struct sock *sk)
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
-static int tcp_illinois_info(struct sock *sk, u32 ext, struct sk_buff *skb)
+static size_t tcp_illinois_info(struct sock *sk, u32 ext, int *attr,
+                               union tcp_cc_info *info)
 {
        const struct illinois *ca = inet_csk_ca(sk);
 
        if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-               struct tcpvegas_info info = {
-                       .tcpv_enabled = 1,
-                       .tcpv_rttcnt = ca->cnt_rtt,
-                       .tcpv_minrtt = ca->base_rtt,
-               };
+               info->vegas.tcpv_enabled = 1;
+               info->vegas.tcpv_rttcnt = ca->cnt_rtt;
+               info->vegas.tcpv_minrtt = ca->base_rtt;
+               info->vegas.tcpv_rtt = 0;
 
-               if (info.tcpv_rttcnt > 0) {
+               if (info->vegas.tcpv_rttcnt > 0) {
                        u64 t = ca->sum_rtt;
 
-                       do_div(t, info.tcpv_rttcnt);
-                       info.tcpv_rtt = t;
+                       do_div(t, info->vegas.tcpv_rttcnt);
+                       info->vegas.tcpv_rtt = t;
                }
-               return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
+               *attr = INET_DIAG_VEGASINFO;
+               return sizeof(struct tcpvegas_info);
        }
        return 0;
 }
index 3a4d9b34bed44a2f6b77b2be0e753867bad32292..bc790ea9960f952281285934d7b0678e79ad6313 100644 (file)
@@ -1820,14 +1820,12 @@ advance_sp:
        for (j = 0; j < used_sacks; j++)
                tp->recv_sack_cache[i++] = sp[j];
 
-       tcp_mark_lost_retrans(sk);
-
-       tcp_verify_left_out(tp);
-
        if ((state.reord < tp->fackets_out) &&
            ((inet_csk(sk)->icsk_ca_state != TCP_CA_Loss) || tp->undo_marker))
                tcp_update_reordering(sk, tp->fackets_out - state.reord, 0);
 
+       tcp_mark_lost_retrans(sk);
+       tcp_verify_left_out(tp);
 out:
 
 #if FASTRETRANS_DEBUG > 0
@@ -3280,6 +3278,24 @@ static inline bool tcp_may_update_window(const struct tcp_sock *tp,
                (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd);
 }
 
+/* If we update tp->snd_una, also update tp->bytes_acked */
+static void tcp_snd_una_update(struct tcp_sock *tp, u32 ack)
+{
+       u32 delta = ack - tp->snd_una;
+
+       tp->bytes_acked += delta;
+       tp->snd_una = ack;
+}
+
+/* If we update tp->rcv_nxt, also update tp->bytes_received */
+static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq)
+{
+       u32 delta = seq - tp->rcv_nxt;
+
+       tp->bytes_received += delta;
+       tp->rcv_nxt = seq;
+}
+
 /* Update our send window.
  *
  * Window update algorithm, described in RFC793/RFC1122 (used in linux-2.2
@@ -3315,7 +3331,7 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32
                }
        }
 
-       tp->snd_una = ack;
+       tcp_snd_una_update(tp, ack);
 
        return flag;
 }
@@ -3497,7 +3513,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
                 * Note, we use the fact that SND.UNA>=SND.WL2.
                 */
                tcp_update_wl(tp, ack_seq);
-               tp->snd_una = ack;
+               tcp_snd_una_update(tp, ack);
                flag |= FLAG_WIN_UPDATE;
 
                tcp_in_ack_event(sk, CA_ACK_WIN_UPDATE);
@@ -4236,7 +4252,7 @@ static void tcp_ofo_queue(struct sock *sk)
 
                tail = skb_peek_tail(&sk->sk_receive_queue);
                eaten = tail && tcp_try_coalesce(sk, tail, skb, &fragstolen);
-               tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+               tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq);
                if (!eaten)
                        __skb_queue_tail(&sk->sk_receive_queue, skb);
                if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
@@ -4404,7 +4420,7 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int
        __skb_pull(skb, hdrlen);
        eaten = (tail &&
                 tcp_try_coalesce(sk, tail, skb, fragstolen)) ? 1 : 0;
-       tcp_sk(sk)->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+       tcp_rcv_nxt_update(tcp_sk(sk), TCP_SKB_CB(skb)->end_seq);
        if (!eaten) {
                __skb_queue_tail(&sk->sk_receive_queue, skb);
                skb_set_owner_r(skb, sk);
@@ -4497,7 +4513,7 @@ queue_and_out:
 
                        eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen);
                }
-               tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+               tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq);
                if (skb->len)
                        tcp_event_data_recv(sk, skb);
                if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
@@ -5245,7 +5261,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                        tcp_rcv_rtt_measure_ts(sk, skb);
 
                                        __skb_pull(skb, tcp_header_len);
-                                       tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
+                                       tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq);
                                        NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITSTOUSER);
                                        eaten = 1;
                                }
index c71a1b8f7bde3082a6520128bb6f47d3081de8ac..a6cea1d5e20d47f06eab95f3344a3e3b7c44da89 100644 (file)
@@ -286,18 +286,19 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 acked)
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
-int tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb)
+size_t tcp_vegas_get_info(struct sock *sk, u32 ext, int *attr,
+                         union tcp_cc_info *info)
 {
        const struct vegas *ca = inet_csk_ca(sk);
+
        if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-               struct tcpvegas_info info = {
-                       .tcpv_enabled = ca->doing_vegas_now,
-                       .tcpv_rttcnt = ca->cntRTT,
-                       .tcpv_rtt = ca->baseRTT,
-                       .tcpv_minrtt = ca->minRTT,
-               };
-
-               return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
+               info->vegas.tcpv_enabled = ca->doing_vegas_now,
+               info->vegas.tcpv_rttcnt = ca->cntRTT,
+               info->vegas.tcpv_rtt = ca->baseRTT,
+               info->vegas.tcpv_minrtt = ca->minRTT,
+
+               *attr = INET_DIAG_VEGASINFO;
+               return sizeof(struct tcpvegas_info);
        }
        return 0;
 }
index e8a6b33cc61dd7c4d58ea7d3ebd1dd1f35041de9..ef9da5306c685b269cc1efe64ee40196faf11e66 100644 (file)
@@ -19,6 +19,7 @@ void tcp_vegas_init(struct sock *sk);
 void tcp_vegas_state(struct sock *sk, u8 ca_state);
 void tcp_vegas_pkts_acked(struct sock *sk, u32 cnt, s32 rtt_us);
 void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event);
-int tcp_vegas_get_info(struct sock *sk, u32 ext, struct sk_buff *skb);
+size_t tcp_vegas_get_info(struct sock *sk, u32 ext, int *attr,
+                         union tcp_cc_info *info);
 
 #endif /* __TCP_VEGAS_H */
index b3c57cceb9907fe9d79f33f33369a96b647b5f26..c10732e39837872c724b801700f627a7fb1c9390 100644 (file)
@@ -256,18 +256,19 @@ static void tcp_westwood_event(struct sock *sk, enum tcp_ca_event event)
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
-static int tcp_westwood_info(struct sock *sk, u32 ext, struct sk_buff *skb)
+static size_t tcp_westwood_info(struct sock *sk, u32 ext, int *attr,
+                               union tcp_cc_info *info)
 {
        const struct westwood *ca = inet_csk_ca(sk);
 
        if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
-               struct tcpvegas_info info = {
-                       .tcpv_enabled = 1,
-                       .tcpv_rtt = jiffies_to_usecs(ca->rtt),
-                       .tcpv_minrtt = jiffies_to_usecs(ca->rtt_min),
-               };
+               info->vegas.tcpv_enabled = 1;
+               info->vegas.tcpv_rttcnt = 0;
+               info->vegas.tcpv_rtt    = jiffies_to_usecs(ca->rtt),
+               info->vegas.tcpv_minrtt = jiffies_to_usecs(ca->rtt_min),
 
-               return nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
+               *attr = INET_DIAG_VEGASINFO;
+               return sizeof(struct tcpvegas_info);
        }
        return 0;
 }
index 7fde1f265c90e90f16291e6c861b6e242111c25b..c21777565c58cabd7649cc48b790ff21c88498b5 100644 (file)
@@ -886,22 +886,45 @@ static int ip6_dst_lookup_tail(struct sock *sk,
 #endif
        int err;
 
-       if (!*dst)
-               *dst = ip6_route_output(net, sk, fl6);
-
-       err = (*dst)->error;
-       if (err)
-               goto out_err_release;
+       /* The correct way to handle this would be to do
+        * ip6_route_get_saddr, and then ip6_route_output; however,
+        * the route-specific preferred source forces the
+        * ip6_route_output call _before_ ip6_route_get_saddr.
+        *
+        * In source specific routing (no src=any default route),
+        * ip6_route_output will fail given src=any saddr, though, so
+        * that's why we try it again later.
+        */
+       if (ipv6_addr_any(&fl6->saddr) && (!*dst || !(*dst)->error)) {
+               struct rt6_info *rt;
+               bool had_dst = *dst != NULL;
 
-       if (ipv6_addr_any(&fl6->saddr)) {
-               struct rt6_info *rt = (struct rt6_info *) *dst;
+               if (!had_dst)
+                       *dst = ip6_route_output(net, sk, fl6);
+               rt = (*dst)->error ? NULL : (struct rt6_info *)*dst;
                err = ip6_route_get_saddr(net, rt, &fl6->daddr,
                                          sk ? inet6_sk(sk)->srcprefs : 0,
                                          &fl6->saddr);
                if (err)
                        goto out_err_release;
+
+               /* If we had an erroneous initial result, pretend it
+                * never existed and let the SA-enabled version take
+                * over.
+                */
+               if (!had_dst && (*dst)->error) {
+                       dst_release(*dst);
+                       *dst = NULL;
+               }
        }
 
+       if (!*dst)
+               *dst = ip6_route_output(net, sk, fl6);
+
+       err = (*dst)->error;
+       if (err)
+               goto out_err_release;
+
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
        /*
         * Here if the dst entry we've looked up
index 5c48293ff06235e72f586007ff1e7bb568733b92..d3588885f09705278b745c43b86563c85a0d3dea 100644 (file)
@@ -2245,9 +2245,10 @@ int ip6_route_get_saddr(struct net *net,
                        unsigned int prefs,
                        struct in6_addr *saddr)
 {
-       struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt);
+       struct inet6_dev *idev =
+               rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
        int err = 0;
-       if (rt->rt6i_prefsrc.plen)
+       if (rt && rt->rt6i_prefsrc.plen)
                *saddr = rt->rt6i_prefsrc.addr;
        else
                err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
index b4ac596a7cb76205cf39d935708d3383490c2b73..bab5c63c0bad798529b3c5a964db995be4eef6b0 100644 (file)
@@ -819,13 +819,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
         * (because if we remove a STA after ops->remove_interface()
         * the driver will have removed the vif info already!)
         *
-        * This is relevant only in WDS mode, in all other modes we've
-        * already removed all stations when disconnecting or similar,
-        * so warn otherwise.
+        * In WDS mode a station must exist here and be flushed, for
+        * AP_VLANs stations may exist since there's nothing else that
+        * would have removed them, but in other modes there shouldn't
+        * be any stations.
         */
        flushed = sta_info_flush(sdata);
-       WARN_ON_ONCE((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
-                    (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1));
+       WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+                    ((sdata->vif.type != NL80211_IFTYPE_WDS && flushed > 0) ||
+                     (sdata->vif.type == NL80211_IFTYPE_WDS && flushed != 1)));
 
        /* don't count this interface for promisc/allmulti while it is down */
        if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
index 12971b71d0fa1ea8ce69dbdc09314c1c1641d7c8..2880f2ae99abe3a05b6421f53340a42e11a9ca30 100644 (file)
@@ -66,6 +66,7 @@
 
 static const struct rhashtable_params sta_rht_params = {
        .nelem_hint = 3, /* start small */
+       .automatic_shrinking = true,
        .head_offset = offsetof(struct sta_info, hash_node),
        .key_offset = offsetof(struct sta_info, sta.addr),
        .key_len = ETH_ALEN,
@@ -157,8 +158,24 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
                              const u8 *addr)
 {
        struct ieee80211_local *local = sdata->local;
+       struct sta_info *sta;
+       struct rhash_head *tmp;
+       const struct bucket_table *tbl;
+
+       rcu_read_lock();
+       tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
 
-       return rhashtable_lookup_fast(&local->sta_hash, addr, sta_rht_params);
+       for_each_sta_info(local, tbl, addr, sta, tmp) {
+               if (sta->sdata == sdata) {
+                       rcu_read_unlock();
+                       /* this is safe as the caller must already hold
+                        * another rcu read section or the mutex
+                        */
+                       return sta;
+               }
+       }
+       rcu_read_unlock();
+       return NULL;
 }
 
 /*
index 5d9f68c75e5f8f68c5884d467e5a9d16db0edaac..70be9c799f8a81596a4e753b239849549d792dd0 100644 (file)
 
 static struct net_device *
 ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
-                               const char *name, int type)
+                               const char *name,
+                               unsigned char name_assign_type, int type)
 {
        struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
        struct net_device *dev;
 
        rtnl_lock();
-       dev = ieee802154_if_add(local, name, type,
+       dev = ieee802154_if_add(local, name, name_assign_type, type,
                                cpu_to_le64(0x0000000000000000ULL));
        rtnl_unlock();
 
@@ -45,12 +46,14 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
 
 static int
 ieee802154_add_iface(struct wpan_phy *phy, const char *name,
+                    unsigned char name_assign_type,
                     enum nl802154_iftype type, __le64 extended_addr)
 {
        struct ieee802154_local *local = wpan_phy_priv(phy);
        struct net_device *err;
 
-       err = ieee802154_if_add(local, name, type, extended_addr);
+       err = ieee802154_if_add(local, name, name_assign_type, type,
+                               extended_addr);
        return PTR_ERR_OR_ZERO(err);
 }
 
index bebd70ffc7a3d101551f023e515db24033883f0b..127ba18386fc639aac4ccda482ebe4be11b8e6ee 100644 (file)
@@ -182,7 +182,8 @@ void ieee802154_iface_exit(void);
 void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata);
 struct net_device *
 ieee802154_if_add(struct ieee802154_local *local, const char *name,
-                 enum nl802154_iftype type, __le64 extended_addr);
+                 unsigned char name_assign_type, enum nl802154_iftype type,
+                 __le64 extended_addr);
 void ieee802154_remove_interfaces(struct ieee802154_local *local);
 
 #endif /* __IEEE802154_I_H */
index 38b56f9d9386a4821e50cfdd6059fa115c5e4358..91b75abbd1a1d05b3219b9089232d9f67eb73ccd 100644 (file)
@@ -522,7 +522,8 @@ ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata,
 
 struct net_device *
 ieee802154_if_add(struct ieee802154_local *local, const char *name,
-                 enum nl802154_iftype type, __le64 extended_addr)
+                 unsigned char name_assign_type, enum nl802154_iftype type,
+                 __le64 extended_addr)
 {
        struct net_device *ndev = NULL;
        struct ieee802154_sub_if_data *sdata = NULL;
@@ -531,7 +532,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
        ASSERT_RTNL();
 
        ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, name,
-                           NET_NAME_UNKNOWN, ieee802154_if_setup);
+                           name_assign_type, ieee802154_if_setup);
        if (!ndev)
                return ERR_PTR(-ENOMEM);
 
index dcf73958133a0d6d0c28f825f648b13cc9ef478b..5b2be12832e65fca351dec5a61619c1042de9004 100644 (file)
@@ -134,7 +134,7 @@ llsec_key_alloc(const struct ieee802154_llsec_key *template)
        for (i = 0; i < ARRAY_SIZE(key->tfm); i++) {
                key->tfm[i] = crypto_alloc_aead("ccm(aes)", 0,
                                                CRYPTO_ALG_ASYNC);
-               if (!key->tfm[i])
+               if (IS_ERR(key->tfm[i]))
                        goto err_tfm;
                if (crypto_aead_setkey(key->tfm[i], template->key,
                                       IEEE802154_LLSEC_KEY_SIZE))
@@ -144,7 +144,7 @@ llsec_key_alloc(const struct ieee802154_llsec_key *template)
        }
 
        key->tfm0 = crypto_alloc_blkcipher("ctr(aes)", 0, CRYPTO_ALG_ASYNC);
-       if (!key->tfm0)
+       if (IS_ERR(key->tfm0))
                goto err_tfm;
 
        if (crypto_blkcipher_setkey(key->tfm0, template->key,
index 8500378c8318cd3b5b7e3a368f44080b40c5900f..08cb32dc8fd33e892e53f7f87f601b10ede8c38d 100644 (file)
@@ -161,18 +161,21 @@ int ieee802154_register_hw(struct ieee802154_hw *hw)
 
        rtnl_lock();
 
-       dev = ieee802154_if_add(local, "wpan%d", NL802154_IFTYPE_NODE,
+       dev = ieee802154_if_add(local, "wpan%d", NET_NAME_ENUM,
+                               NL802154_IFTYPE_NODE,
                                cpu_to_le64(0x0000000000000000ULL));
        if (IS_ERR(dev)) {
                rtnl_unlock();
                rc = PTR_ERR(dev);
-               goto out_wq;
+               goto out_phy;
        }
 
        rtnl_unlock();
 
        return 0;
 
+out_phy:
+       wpan_phy_unregister(local->phy);
 out_wq:
        destroy_workqueue(local->workqueue);
 out:
index 954810c76a8650d87ec4bddc62fa5618e48c1341..7b3f732269e43bb33dc1a6584eaa91b74eab9b64 100644 (file)
@@ -647,7 +647,7 @@ int nla_get_labels(const struct nlattr *nla,
                        return -EINVAL;
 
                switch (dec.label) {
-               case LABEL_IMPLICIT_NULL:
+               case MPLS_LABEL_IMPLNULL:
                        /* RFC3032: This is a label that an LSR may
                         * assign and distribute, but which never
                         * actually appears in the encapsulation.
@@ -935,7 +935,7 @@ static int resize_platform_label_table(struct net *net, size_t limit)
        }
 
        /* In case the predefined labels need to be populated */
-       if (limit > LABEL_IPV4_EXPLICIT_NULL) {
+       if (limit > MPLS_LABEL_IPV4NULL) {
                struct net_device *lo = net->loopback_dev;
                rt0 = mpls_rt_alloc(lo->addr_len);
                if (!rt0)
@@ -945,7 +945,7 @@ static int resize_platform_label_table(struct net *net, size_t limit)
                rt0->rt_via_table = NEIGH_LINK_TABLE;
                memcpy(rt0->rt_via, lo->dev_addr, lo->addr_len);
        }
-       if (limit > LABEL_IPV6_EXPLICIT_NULL) {
+       if (limit > MPLS_LABEL_IPV6NULL) {
                struct net_device *lo = net->loopback_dev;
                rt2 = mpls_rt_alloc(lo->addr_len);
                if (!rt2)
@@ -973,15 +973,15 @@ static int resize_platform_label_table(struct net *net, size_t limit)
        memcpy(labels, old, cp_size);
 
        /* If needed set the predefined labels */
-       if ((old_limit <= LABEL_IPV6_EXPLICIT_NULL) &&
-           (limit > LABEL_IPV6_EXPLICIT_NULL)) {
-               RCU_INIT_POINTER(labels[LABEL_IPV6_EXPLICIT_NULL], rt2);
+       if ((old_limit <= MPLS_LABEL_IPV6NULL) &&
+           (limit > MPLS_LABEL_IPV6NULL)) {
+               RCU_INIT_POINTER(labels[MPLS_LABEL_IPV6NULL], rt2);
                rt2 = NULL;
        }
 
-       if ((old_limit <= LABEL_IPV4_EXPLICIT_NULL) &&
-           (limit > LABEL_IPV4_EXPLICIT_NULL)) {
-               RCU_INIT_POINTER(labels[LABEL_IPV4_EXPLICIT_NULL], rt0);
+       if ((old_limit <= MPLS_LABEL_IPV4NULL) &&
+           (limit > MPLS_LABEL_IPV4NULL)) {
+               RCU_INIT_POINTER(labels[MPLS_LABEL_IPV4NULL], rt0);
                rt0 = NULL;
        }
 
index 693877d69606a1ecdab02dd78dc74eefdaf26f3f..b064c345042c17ccd9ec841535857fb29041a8a3 100644 (file)
@@ -1,16 +1,6 @@
 #ifndef MPLS_INTERNAL_H
 #define MPLS_INTERNAL_H
 
-#define LABEL_IPV4_EXPLICIT_NULL       0 /* RFC3032 */
-#define LABEL_ROUTER_ALERT_LABEL       1 /* RFC3032 */
-#define LABEL_IPV6_EXPLICIT_NULL       2 /* RFC3032 */
-#define LABEL_IMPLICIT_NULL            3 /* RFC3032 */
-#define LABEL_ENTROPY_INDICATOR                7 /* RFC6790 */
-#define LABEL_GAL                      13 /* RFC5586 */
-#define LABEL_OAM_ALERT                        14 /* RFC3429 */
-#define LABEL_EXTENSION                        15 /* RFC7274 */
-
-
 struct mpls_shim_hdr {
        __be32 label_stack_entry;
 };
index ec4adbdcb9b4a9926b4d992906f51787c57dc6a2..daa0b818174bdc2c7b5e15e5e0dbd6b287014ba6 100644 (file)
@@ -3139,7 +3139,6 @@ static const struct rhashtable_params netlink_rhashtable_params = {
        .key_len = netlink_compare_arg_len,
        .obj_hashfn = netlink_hash,
        .obj_cmpfn = netlink_compare,
-       .max_size = 65536,
        .automatic_shrinking = true,
 };
 
index 5102c3cc4eec4ecec6698859935d7769d37a174c..b5989c6ee5513904127a8ffec31d09589094c8f6 100644 (file)
@@ -2311,11 +2311,14 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
                tlen = dev->needed_tailroom;
                skb = sock_alloc_send_skb(&po->sk,
                                hlen + tlen + sizeof(struct sockaddr_ll),
-                               0, &err);
+                               !need_wait, &err);
 
-               if (unlikely(skb == NULL))
+               if (unlikely(skb == NULL)) {
+                       /* we assume the socket was initially writeable ... */
+                       if (likely(len_sum > 0))
+                               err = len_sum;
                        goto out_status;
-
+               }
                tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto,
                                          addr, hlen);
                if (tp_len > dev->mtu + dev->hard_header_len) {
index 14f041398ca1744ea7596decaad7145184c7df0c..da6da57e5f36b5cc13a5bc92abfedb6a5ccea45d 100644 (file)
@@ -126,7 +126,10 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
        struct rds_transport *loop_trans;
        unsigned long flags;
        int ret;
+       struct rds_transport *otrans = trans;
 
+       if (!is_outgoing && otrans->t_type == RDS_TRANS_TCP)
+               goto new_conn;
        rcu_read_lock();
        conn = rds_conn_lookup(head, laddr, faddr, trans);
        if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport &&
@@ -142,6 +145,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
        if (conn)
                goto out;
 
+new_conn:
        conn = kmem_cache_zalloc(rds_conn_slab, gfp);
        if (!conn) {
                conn = ERR_PTR(-ENOMEM);
@@ -230,13 +234,22 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
                /* Creating normal conn */
                struct rds_connection *found;
 
-               found = rds_conn_lookup(head, laddr, faddr, trans);
+               if (!is_outgoing && otrans->t_type == RDS_TRANS_TCP)
+                       found = NULL;
+               else
+                       found = rds_conn_lookup(head, laddr, faddr, trans);
                if (found) {
                        trans->conn_free(conn->c_transport_data);
                        kmem_cache_free(rds_conn_slab, conn);
                        conn = found;
                } else {
-                       hlist_add_head_rcu(&conn->c_hash_node, head);
+                       if ((is_outgoing && otrans->t_type == RDS_TRANS_TCP) ||
+                           (otrans->t_type != RDS_TRANS_TCP)) {
+                               /* Only the active side should be added to
+                                * reconnect list for TCP.
+                                */
+                               hlist_add_head_rcu(&conn->c_hash_node, head);
+                       }
                        rds_cong_add_conn(conn);
                        rds_conn_count++;
                }
index 31b74f5e61adbd37535b636b1499c384bdd992f5..8a09ee7db3c13bdd833784c4ee311e048a7c2789 100644 (file)
@@ -183,8 +183,17 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
 
        /* If the peer gave us the last packet it saw, process this as if
         * we had received a regular ACK. */
-       if (dp && dp->dp_ack_seq)
-               rds_send_drop_acked(conn, be64_to_cpu(dp->dp_ack_seq), NULL);
+       if (dp) {
+               /* dp structure start is not guaranteed to be 8 bytes aligned.
+                * Since dp_ack_seq is 64-bit extended load operations can be
+                * used so go through get_unaligned to avoid unaligned errors.
+                */
+               __be64 dp_ack_seq = get_unaligned(&dp->dp_ack_seq);
+
+               if (dp_ack_seq)
+                       rds_send_drop_acked(conn, be64_to_cpu(dp_ack_seq),
+                                           NULL);
+       }
 
        rds_connect_complete(conn);
 }
index f9f564a6c960e47b3c243d11a3e11317c5a56353..973109c7b8e86f21bec783eb9e4e118e6e8ebb8b 100644 (file)
@@ -62,6 +62,7 @@ void rds_tcp_state_change(struct sock *sk)
                case TCP_ESTABLISHED:
                        rds_connect_complete(conn);
                        break;
+               case TCP_CLOSE_WAIT:
                case TCP_CLOSE:
                        rds_conn_drop(conn);
                default:
index 23ab4dcd1d9f03942aa4d70bc7f6d9aa401f7707..0da49e34495f1e974bf466b83ba1144ec8965f61 100644 (file)
@@ -45,12 +45,45 @@ static void rds_tcp_accept_worker(struct work_struct *work);
 static DECLARE_WORK(rds_tcp_listen_work, rds_tcp_accept_worker);
 static struct socket *rds_tcp_listen_sock;
 
+static int rds_tcp_keepalive(struct socket *sock)
+{
+       /* values below based on xs_udp_default_timeout */
+       int keepidle = 5; /* send a probe 'keepidle' secs after last data */
+       int keepcnt = 5; /* number of unack'ed probes before declaring dead */
+       int keepalive = 1;
+       int ret = 0;
+
+       ret = kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+                               (char *)&keepalive, sizeof(keepalive));
+       if (ret < 0)
+               goto bail;
+
+       ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT,
+                               (char *)&keepcnt, sizeof(keepcnt));
+       if (ret < 0)
+               goto bail;
+
+       ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE,
+                               (char *)&keepidle, sizeof(keepidle));
+       if (ret < 0)
+               goto bail;
+
+       /* KEEPINTVL is the interval between successive probes. We follow
+        * the model in xs_tcp_finish_connecting() and re-use keepidle.
+        */
+       ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL,
+                               (char *)&keepidle, sizeof(keepidle));
+bail:
+       return ret;
+}
+
 static int rds_tcp_accept_one(struct socket *sock)
 {
        struct socket *new_sock = NULL;
        struct rds_connection *conn;
        int ret;
        struct inet_sock *inet;
+       struct rds_tcp_connection *rs_tcp;
 
        ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type,
                               sock->sk->sk_protocol, &new_sock);
@@ -63,6 +96,10 @@ static int rds_tcp_accept_one(struct socket *sock)
        if (ret < 0)
                goto out;
 
+       ret = rds_tcp_keepalive(new_sock);
+       if (ret < 0)
+               goto out;
+
        rds_tcp_tune(new_sock);
 
        inet = inet_sk(new_sock->sk);
@@ -77,6 +114,15 @@ static int rds_tcp_accept_one(struct socket *sock)
                ret = PTR_ERR(conn);
                goto out;
        }
+       /* An incoming SYN request came in, and TCP just accepted it.
+        * We always create a new conn for listen side of TCP, and do not
+        * add it to the c_hash_list.
+        *
+        * If the client reboots, this conn will need to be cleaned up.
+        * rds_tcp_state_change() will do that cleanup
+        */
+       rs_tcp = (struct rds_tcp_connection *)conn->c_transport_data;
+       WARN_ON(!rs_tcp || rs_tcp->t_sock);
 
        /*
         * see the comment above rds_queue_delayed_reconnect()
index 8b0470e418dc6e9475464768d629969087e66b37..b6ef9a04de06f411b844b055102b12ca49877707 100644 (file)
@@ -308,12 +308,11 @@ replay:
                case RTM_DELTFILTER:
                        err = tp->ops->delete(tp, fh);
                        if (err == 0) {
-                               tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
-                               if (tcf_destroy(tp, false)) {
-                                       struct tcf_proto *next = rtnl_dereference(tp->next);
+                               struct tcf_proto *next = rtnl_dereference(tp->next);
 
+                               tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
+                               if (tcf_destroy(tp, false))
                                        RCU_INIT_POINTER(*back, next);
-                               }
                        }
                        goto errout;
                case RTM_GETTFILTER:
index de28f8e968e8176ac7630a1e6fcccb45ad295f5d..7a0bdb16ac92fd0a20f565295392bed8674c8d90 100644 (file)
@@ -164,7 +164,7 @@ static int codel_init(struct Qdisc *sch, struct nlattr *opt)
 
        sch->limit = DEFAULT_CODEL_LIMIT;
 
-       codel_params_init(&q->params);
+       codel_params_init(&q->params, sch);
        codel_vars_init(&q->vars);
        codel_stats_init(&q->stats);
 
index 1e52decb7b59cf0b4173d0f17efdab8fefee5f26..c244c45b78d7feca32fda3b925f7605aebf0a5b6 100644 (file)
@@ -391,7 +391,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt)
        q->perturbation = prandom_u32();
        INIT_LIST_HEAD(&q->new_flows);
        INIT_LIST_HEAD(&q->old_flows);
-       codel_params_init(&q->cparams);
+       codel_params_init(&q->cparams, sch);
        codel_stats_init(&q->cstats);
        q->cparams.ecn = true;
 
index a4ca4517cdc82843e21e5245989a59e89aa53702..634529e0ce6bddc44b48161b6f76bd79af0a2a8e 100644 (file)
@@ -229,7 +229,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                break;
        }
 
-       if (q->backlog + qdisc_pkt_len(skb) <= q->limit) {
+       if (gred_backlog(t, q, sch) + qdisc_pkt_len(skb) <= q->limit) {
                q->backlog += qdisc_pkt_len(skb);
                return qdisc_enqueue_tail(skb, sch);
        }
@@ -553,7 +553,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
 
                opt.limit       = q->limit;
                opt.DP          = q->DP;
-               opt.backlog     = q->backlog;
+               opt.backlog     = gred_backlog(table, q, sch);
                opt.prio        = q->prio;
                opt.qth_min     = q->parms.qth_min >> q->parms.Wlog;
                opt.qth_max     = q->parms.qth_max >> q->parms.Wlog;
index 1ec19f6f0c2b9fe71ee9a7110873873274b9ab62..eeeba5adee6d939ab3429100d231a46e82b1ff94 100644 (file)
@@ -793,20 +793,26 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
 {
        u32 value_follows;
        int err;
+       struct page *scratch;
+
+       scratch = alloc_page(GFP_KERNEL);
+       if (!scratch)
+               return -ENOMEM;
+       xdr_set_scratch_buffer(xdr, page_address(scratch), PAGE_SIZE);
 
        /* res->status */
        err = gssx_dec_status(xdr, &res->status);
        if (err)
-               return err;
+               goto out_free;
 
        /* res->context_handle */
        err = gssx_dec_bool(xdr, &value_follows);
        if (err)
-               return err;
+               goto out_free;
        if (value_follows) {
                err = gssx_dec_ctx(xdr, res->context_handle);
                if (err)
-                       return err;
+                       goto out_free;
        } else {
                res->context_handle = NULL;
        }
@@ -814,11 +820,11 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
        /* res->output_token */
        err = gssx_dec_bool(xdr, &value_follows);
        if (err)
-               return err;
+               goto out_free;
        if (value_follows) {
                err = gssx_dec_buffer(xdr, res->output_token);
                if (err)
-                       return err;
+                       goto out_free;
        } else {
                res->output_token = NULL;
        }
@@ -826,14 +832,17 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,
        /* res->delegated_cred_handle */
        err = gssx_dec_bool(xdr, &value_follows);
        if (err)
-               return err;
+               goto out_free;
        if (value_follows) {
                /* we do not support upcall servers sending this data. */
-               return -EINVAL;
+               err = -EINVAL;
+               goto out_free;
        }
 
        /* res->options */
        err = gssx_dec_option_array(xdr, &res->options);
 
+out_free:
+       __free_page(scratch);
        return err;
 }
index 0c356fb650220c6cd5d452d68a22eeb286d40d13..18ffccf004264d202632990d40227c27c41d27ad 100644 (file)
@@ -14,9 +14,10 @@ define allow-override
     $(eval $(1) = $(2)))
 endef
 
-# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
+# Allow setting CC and AR and LD, or setting CROSS_COMPILE as a prefix.
 $(call allow-override,CC,$(CROSS_COMPILE)gcc)
 $(call allow-override,AR,$(CROSS_COMPILE)ar)
+$(call allow-override,LD,$(CROSS_COMPILE)ld)
 
 INSTALL = install
 
index a11e3c357be7f8fb00720694324f26adae0402c5..cd2cc59a5da7900e53084fe19e650438e13af0a2 100644 (file)
@@ -28,6 +28,9 @@
 #define __init
 #define noinline
 #define list_add_tail_rcu list_add_tail
+#define list_for_each_entry_rcu list_for_each_entry
+#define barrier() 
+#define synchronize_sched()
 
 #ifndef CALLER_ADDR0
 #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
index c699dc35eef9cbd1bc96427f453acc23a2e9c103..d31a7bbd7cee8610db236c7842cfb5ec63dc56b0 100644 (file)
@@ -24,7 +24,7 @@ unexport MAKEFLAGS
 # (To override it, run 'make JOBS=1' and similar.)
 #
 ifeq ($(JOBS),)
-  JOBS := $(shell egrep -c '^processor|^CPU' /proc/cpuinfo 2>/dev/null)
+  JOBS := $(shell (getconf _NPROCESSORS_ONLN || egrep -c '^processor|^CPU[0-9]' /proc/cpuinfo) 2>/dev/null)
   ifeq ($(JOBS),0)
     JOBS := 1
   endif
index ddf63569df5ae166e466901aa1a60e1b194fe508..5bdb781163d1f2d0eb6a69fea8a976fa2873f3b1 100644 (file)
@@ -1,4 +1,8 @@
-.PHONY: all all_32 all_64 check_build32 clean run_tests
+all:
+
+include ../lib.mk
+
+.PHONY: all all_32 all_64 warn_32bit_failure clean
 
 TARGETS_C_BOTHBITS := sigreturn single_step_syscall
 
@@ -7,42 +11,47 @@ BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64)
 
 CFLAGS := -O2 -g -std=gnu99 -pthread -Wall
 
-UNAME_P := $(shell uname -p)
+UNAME_M := $(shell uname -m)
+CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32)
+CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c)
 
-# Always build 32-bit tests
+ifeq ($(CAN_BUILD_I386),1)
 all: all_32
+TEST_PROGS += $(BINARIES_32)
+endif
 
-# If we're on a 64-bit host, build 64-bit tests as well
-ifeq ($(shell uname -p),x86_64)
+ifeq ($(CAN_BUILD_X86_64),1)
 all: all_64
+TEST_PROGS += $(BINARIES_64)
 endif
 
-all_32: check_build32 $(BINARIES_32)
+all_32: $(BINARIES_32)
 
 all_64: $(BINARIES_64)
 
 clean:
        $(RM) $(BINARIES_32) $(BINARIES_64)
 
-run_tests:
-       ./run_x86_tests.sh
-
 $(TARGETS_C_BOTHBITS:%=%_32): %_32: %.c
        $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
 
 $(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c
        $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
 
-check_build32:
-       @if ! $(CC) -m32 -o /dev/null trivial_32bit_program.c; then     \
-         echo "Warning: you seem to have a broken 32-bit build" 2>&1;  \
-         echo "environment.  If you are using a Debian-like";          \
-         echo " distribution, try:";                                   \
-         echo "";                                                      \
-         echo "  apt-get install gcc-multilib libc6-i386 libc6-dev-i386"; \
-         echo "";                                                      \
-         echo "If you are using a Fedora-like distribution, try:";     \
-         echo "";                                                      \
-         echo "  yum install glibc-devel.*i686";                       \
-         exit 1;                                                       \
-       fi
+# x86_64 users should be encouraged to install 32-bit libraries
+ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),01)
+all: warn_32bit_failure
+
+warn_32bit_failure:
+       @echo "Warning: you seem to have a broken 32-bit build" 2>&1;   \
+       echo "environment.  This will reduce test coverage of 64-bit" 2>&1; \
+       echo "kernels.  If you are using a Debian-like distribution," 2>&1; \
+       echo "try:"; 2>&1; \
+       echo "";                                                        \
+       echo "  apt-get install gcc-multilib libc6-i386 libc6-dev-i386"; \
+       echo "";                                                        \
+       echo "If you are using a Fedora-like distribution, try:";       \
+       echo "";                                                        \
+       echo "  yum install glibc-devel.*i686";                         \
+       exit 0;
+endif
diff --git a/tools/testing/selftests/x86/check_cc.sh b/tools/testing/selftests/x86/check_cc.sh
new file mode 100755 (executable)
index 0000000..172d329
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+# check_cc.sh - Helper to test userspace compilation support
+# Copyright (c) 2015 Andrew Lutomirski
+# GPL v2
+
+CC="$1"
+TESTPROG="$2"
+shift 2
+
+if "$CC" -o /dev/null "$TESTPROG" -O0 "$@" 2>/dev/null; then
+    echo 1
+else
+    echo 0
+fi
+
+exit 0
diff --git a/tools/testing/selftests/x86/run_x86_tests.sh b/tools/testing/selftests/x86/run_x86_tests.sh
deleted file mode 100644 (file)
index 3fc19b3..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-# This is deliberately minimal.  IMO kselftests should provide a standard
-# script here.
-./sigreturn_32 || exit 1
-./single_step_syscall_32 || exit 1
-
-if [[ "$uname -p" -eq "x86_64" ]]; then
-    ./sigreturn_64 || exit 1
-    ./single_step_syscall_64 || exit 1
-fi
-
-exit 0
index 2e231beb0a39e7c4b1571dc6ee746941ff069705..fabdf0f51621e30a850c510ffcce8841115c10f2 100644 (file)
@@ -4,6 +4,10 @@
  * GPL v2
  */
 
+#ifndef __i386__
+# error wrong architecture
+#endif
+
 #include <stdio.h>
 
 int main()
diff --git a/tools/testing/selftests/x86/trivial_64bit_program.c b/tools/testing/selftests/x86/trivial_64bit_program.c
new file mode 100644 (file)
index 0000000..b994946
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Trivial program to check that we have a valid 32-bit build environment.
+ * Copyright (c) 2015 Andy Lutomirski
+ * GPL v2
+ */
+
+#ifndef __x86_64__
+# error wrong architecture
+#endif
+
+#include <stdio.h>
+
+int main()
+{
+       printf("\n");
+
+       return 0;
+}
index 0788621c8d760f01f714d377a18c6a390a990fde..2e83dd3655a28ae606a0a2c8c4b80a58331ef24e 100644 (file)
@@ -12,10 +12,6 @@ TARGET=tmon
 INSTALL_PROGRAM=install -m 755 -p
 DEL_FILE=rm -f
 
-INSTALL_CONFIGFILE=install -m 644 -p
-CONFIG_FILE=
-CONFIG_PATH=
-
 # Static builds might require -ltinfo, for instance
 ifneq ($(findstring -static, $(LDFLAGS)),)
 STATIC := --static
@@ -38,13 +34,9 @@ valgrind: tmon
 install:
        - mkdir -p $(INSTALL_ROOT)/$(BINDIR)
        - $(INSTALL_PROGRAM) "$(TARGET)" "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)"
-       - mkdir -p $(INSTALL_ROOT)/$(CONFIG_PATH)
-       - $(INSTALL_CONFIGFILE) "$(CONFIG_FILE)" "$(INSTALL_ROOT)/$(CONFIG_PATH)"
 
 uninstall:
        $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)"
-       $(CONFIG_FILE) "$(CONFIG_PATH)"
-
 
 clean:
        find . -name "*.o" | xargs $(DEL_FILE)
index ac884b65a0725fc9b4e2ed46a490996524fd96a3..93aadaf7ff63d66afab325a67bd09fba982de947 100644 (file)
@@ -3,7 +3,7 @@
 TARGETS=page-types slabinfo page_owner_sort
 
 LIB_DIR = ../lib/api
-LIBS = $(LIB_DIR)/libapikfs.a
+LIBS = $(LIB_DIR)/libapi.a
 
 CC = $(CROSS_COMPILE)gcc
 CFLAGS = -Wall -Wextra -I../lib/