Unified · Split
| @@ -1,4 +1,4 @@ | ||
| 1 | −What: state | |
| 1 | +What: /sys/devices/system/ibm_rtl/state | |
| 2 | 2 | Date: Sep 2010 |
| 3 | 3 | KernelVersion: 2.6.37 |
| 4 | 4 | Contact: Vernon Mauery <vernux@us.ibm.com> |
| @@ -10,7 +10,7 @@ Description: The state file allows a means by which to change in and · 5 unmodified lines | ||
| 10 | 10 | Users: The ibm-prtm userspace daemon uses this interface. |
| 11 | 11 | |
| 12 | 12 | |
| 13 | −What: version | |
| 13 | +What: /sys/devices/system/ibm_rtl/version | |
| 14 | 14 | Date: Sep 2010 |
| 15 | 15 | KernelVersion: 2.6.37 |
| 16 | 16 | Contact: Vernon Mauery <vernux@us.ibm.com> |
| @@ -6,7 +6,7 @@ perform in-band IPMI communication with their host. · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | Required properties: |
| 8 | 8 | |
| 9 | −- compatible : should be "aspeed,ast2400-bt-bmc" | |
| 9 | +- compatible : should be "aspeed,ast2400-ibt-bmc" | |
| 10 | 10 | - reg: physical address and size of the registers |
| 11 | 11 | |
| 12 | 12 | Optional properties: |
| @@ -17,7 +17,7 @@ Optional properties: · 4 unmodified lines | ||
| 17 | 17 | Example: |
| 18 | 18 | |
| 19 | 19 | ibt@1e789140 { |
| 20 | − compatible = "aspeed,ast2400-bt-bmc"; | |
| 20 | + compatible = "aspeed,ast2400-ibt-bmc"; | |
| 21 | 21 | reg = <0x1e789140 0x18>; |
| 22 | 22 | interrupts = <8>; |
| 23 | 23 | }; |
| @@ -43,6 +43,9 @@ Optional properties: · 42 unmodified lines | ||
| 43 | 43 | reset signal present internally in some host controller IC designs. |
| 44 | 44 | See Documentation/devicetree/bindings/reset/reset.txt for details. |
| 45 | 45 | |
| 46 | +* reset-names: request name for using "resets" property. Must be "reset". | |
| 47 | + (It will be used together with "resets" property.) | |
| 48 | + | |
| 46 | 49 | * clocks: from common clock binding: handle to biu and ciu clocks for the |
| 47 | 50 | bus interface unit clock and the card interface unit clock. |
| 48 | 51 | |
| @@ -103,6 +106,8 @@ board specific portions as listed below. · 54 unmodified lines | ||
| 103 | 106 | interrupts = <0 75 0>; |
| 104 | 107 | #address-cells = <1>; |
| 105 | 108 | #size-cells = <0>; |
| 109 | + resets = <&rst 20>; | |
| 110 | + reset-names = "reset"; | |
| 106 | 111 | }; |
| 107 | 112 | |
| 108 | 113 | [board specific internal DMA resources] |
| @@ -26,13 +26,16 @@ Required properties: · 25 unmodified lines | ||
| 26 | 26 | - "sys" |
| 27 | 27 | - "legacy" |
| 28 | 28 | - "client" |
| 29 | −- resets: Must contain five entries for each entry in reset-names. | |
| 29 | +- resets: Must contain seven entries for each entry in reset-names. | |
| 30 | 30 | See ../reset/reset.txt for details. |
| 31 | 31 | - reset-names: Must include the following names |
| 32 | 32 | - "core" |
| 33 | 33 | - "mgmt" |
| 34 | 34 | - "mgmt-sticky" |
| 35 | 35 | - "pipe" |
| 36 | + - "pm" | |
| 37 | + - "aclk" | |
| 38 | + - "pclk" | |
| 36 | 39 | - pinctrl-names : The pin control state names |
| 37 | 40 | - pinctrl-0: The "default" pinctrl state |
| 38 | 41 | - #interrupt-cells: specifies the number of cells needed to encode an |
| @@ -86,8 +89,10 @@ pcie0: pcie@f8000000 { · 47 unmodified lines | ||
| 86 | 89 | reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; |
| 87 | 90 | reg-names = "axi-base", "apb-base"; |
| 88 | 91 | resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, |
| 89 | − <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>; | |
| 90 | − reset-names = "core", "mgmt", "mgmt-sticky", "pipe"; | |
| 92 | + <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE> , | |
| 93 | + <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>; | |
| 94 | + reset-names = "core", "mgmt", "mgmt-sticky", "pipe", | |
| 95 | + "pm", "pclk", "aclk"; | |
| 91 | 96 | phys = <&pcie_phy>; |
| 92 | 97 | phy-names = "pcie-phy"; |
| 93 | 98 | pinctrl-names = "default"; |
| @@ -14,11 +14,6 @@ Required properies: · 13 unmodified lines | ||
| 14 | 14 | - #size-cells : The value of this property must be 1 |
| 15 | 15 | - ranges : defines mapping between pin controller node (parent) to |
| 16 | 16 | gpio-bank node (children). |
| 17 | − - interrupt-parent: phandle of the interrupt parent to which the external | |
| 18 | − GPIO interrupts are forwarded to. | |
| 19 | − - st,syscfg: Should be phandle/offset pair. The phandle to the syscon node | |
| 20 | − which includes IRQ mux selection register, and the offset of the IRQ mux | |
| 21 | − selection register. | |
| 22 | 17 | - pins-are-numbered: Specify the subnodes are using numbered pinmux to |
| 23 | 18 | specify pins. |
| 24 | 19 | |
| @@ -37,6 +32,11 @@ Required properties: · 12 unmodified lines | ||
| 37 | 32 | |
| 38 | 33 | Optional properties: |
| 39 | 34 | - reset: : Reference to the reset controller |
| 35 | + - interrupt-parent: phandle of the interrupt parent to which the external | |
| 36 | + GPIO interrupts are forwarded to. | |
| 37 | + - st,syscfg: Should be phandle/offset pair. The phandle to the syscon node | |
| 38 | + which includes IRQ mux selection register, and the offset of the IRQ mux | |
| 39 | + selection register. | |
| 40 | 40 | |
| 41 | 41 | Example: |
| 42 | 42 | #include <dt-bindings/pinctrl/stm32f429-pinfunc.h> |
| @@ -12,7 +12,7 @@ Required properties: · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | Optional properties: |
| 14 | 14 | - ti,dmic: phandle for the OMAP dmic node if the machine have it connected |
| 15 | −- ti,jack_detection: Need to be present if the board capable to detect jack | |
| 15 | +- ti,jack-detection: Need to be present if the board capable to detect jack | |
| 16 | 16 | insertion, removal. |
| 17 | 17 | |
| 18 | 18 | Available audio endpoints for the audio-routing table: |
| @@ -447,7 +447,6 @@ prototypes: · 446 unmodified lines | ||
| 447 | 447 | int (*flush) (struct file *); |
| 448 | 448 | int (*release) (struct inode *, struct file *); |
| 449 | 449 | int (*fsync) (struct file *, loff_t start, loff_t end, int datasync); |
| 450 | − int (*aio_fsync) (struct kiocb *, int datasync); | |
| 451 | 450 | int (*fasync) (int, struct file *, int); |
| 452 | 451 | int (*lock) (struct file *, int, struct file_lock *); |
| 453 | 452 | ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, |
| @@ -828,7 +828,6 @@ struct file_operations { · 827 unmodified lines | ||
| 828 | 828 | int (*flush) (struct file *, fl_owner_t id); |
| 829 | 829 | int (*release) (struct inode *, struct file *); |
| 830 | 830 | int (*fsync) (struct file *, loff_t, loff_t, int datasync); |
| 831 | − int (*aio_fsync) (struct kiocb *, int datasync); | |
| 832 | 831 | int (*fasync) (int, struct file *, int); |
| 833 | 832 | int (*lock) (struct file *, int, struct file_lock *); |
| 834 | 833 | ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); |
| @@ -326,7 +326,7 @@ Two parent-locked sibling muxes · 325 unmodified lines | ||
| 326 | 326 | |
| 327 | 327 | This is a good topology. |
| 328 | 328 | |
| 329 | − .--------. | |
| 329 | + .--------. | |
| 330 | 330 | .----------. .--| dev D1 | |
| 331 | 331 | | parent- |--' '--------' |
| 332 | 332 | .--| locked | .--------. |
| @@ -350,7 +350,7 @@ Mux-locked and parent-locked sibling muxes · 17 unmodified lines | ||
| 350 | 350 | |
| 351 | 351 | This is a good topology. |
| 352 | 352 | |
| 353 | − .--------. | |
| 353 | + .--------. | |
| 354 | 354 | .----------. .--| dev D1 | |
| 355 | 355 | | mux- |--' '--------' |
| 356 | 356 | .--| locked | .--------. |
| @@ -67,13 +67,14 @@ Note that DSA does not currently create network interfaces for the "cpu" and · 66 unmodified lines | ||
| 67 | 67 | Switch tagging protocols |
| 68 | 68 | ------------------------ |
| 69 | 69 | |
| 70 | −DSA currently supports 4 different tagging protocols, and a tag-less mode as | |
| 70 | +DSA currently supports 5 different tagging protocols, and a tag-less mode as | |
| 71 | 71 | well. The different protocols are implemented in: |
| 72 | 72 | |
| 73 | 73 | net/dsa/tag_trailer.c: Marvell's 4 trailer tag mode (legacy) |
| 74 | 74 | net/dsa/tag_dsa.c: Marvell's original DSA tag |
| 75 | 75 | net/dsa/tag_edsa.c: Marvell's enhanced DSA tag |
| 76 | 76 | net/dsa/tag_brcm.c: Broadcom's 4 bytes tag |
| 77 | +net/dsa/tag_qca.c: Qualcomm's 2 bytes tag | |
| 77 | 78 | |
| 78 | 79 | The exact format of the tag protocol is vendor specific, but in general, they |
| 79 | 80 | all contain something which: |
| @@ -777,6 +777,17 @@ Gets the current timestamp of kvmclock as seen by the current guest. In · 776 unmodified lines | ||
| 777 | 777 | conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios |
| 778 | 778 | such as migration. |
| 779 | 779 | |
| 780 | +When KVM_CAP_ADJUST_CLOCK is passed to KVM_CHECK_EXTENSION, it returns the | |
| 781 | +set of bits that KVM can return in struct kvm_clock_data's flag member. | |
| 782 | + | |
| 783 | +The only flag defined now is KVM_CLOCK_TSC_STABLE. If set, the returned | |
| 784 | +value is the exact kvmclock value seen by all VCPUs at the instant | |
| 785 | +when KVM_GET_CLOCK was called. If clear, the returned value is simply | |
| 786 | +CLOCK_MONOTONIC plus a constant offset; the offset can be modified | |
| 787 | +with KVM_SET_CLOCK. KVM will try to make all VCPUs follow this clock, | |
| 788 | +but the exact value read by each VCPU could differ, because the host | |
| 789 | +TSC is not stable. | |
| 790 | + | |
| 780 | 791 | struct kvm_clock_data { |
| 781 | 792 | __u64 clock; /* kvmclock current value */ |
| 782 | 793 | __u32 flags; |
| @@ -7084,6 +7084,7 @@ F: drivers/scsi/53c700* · 7083 unmodified lines | ||
| 7084 | 7084 | LED SUBSYSTEM |
| 7085 | 7085 | M: Richard Purdie <rpurdie@rpsys.net> |
| 7086 | 7086 | M: Jacek Anaszewski <j.anaszewski@samsung.com> |
| 7087 | +M: Pavel Machek <pavel@ucw.cz> | |
| 7087 | 7088 | L: linux-leds@vger.kernel.org |
| 7088 | 7089 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git |
| 7089 | 7090 | S: Maintained |
| @@ -8057,6 +8058,7 @@ F: drivers/infiniband/hw/mlx4/ · 967 unmodified lines | ||
| 8057 | 8058 | F: include/linux/mlx4/ |
| 8058 | 8059 | |
| 8059 | 8060 | MELLANOX MLX5 core VPI driver |
| 8061 | +M: Saeed Mahameed <saeedm@mellanox.com> | |
| 8060 | 8062 | M: Matan Barak <matanb@mellanox.com> |
| 8061 | 8063 | M: Leon Romanovsky <leonro@mellanox.com> |
| 8062 | 8064 | L: netdev@vger.kernel.org |
| @@ -9335,7 +9337,7 @@ PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) · 1272 unmodified lines | ||
| 9335 | 9337 | M: Keith Busch <keith.busch@intel.com> |
| 9336 | 9338 | L: linux-pci@vger.kernel.org |
| 9337 | 9339 | S: Supported |
| 9338 | −F: arch/x86/pci/vmd.c | |
| 9340 | +F: drivers/pci/host/vmd.c | |
| 9339 | 9341 | |
| 9340 | 9342 | PCIE DRIVER FOR ST SPEAR13XX |
| 9341 | 9343 | M: Pratyush Anand <pratyush.anand@gmail.com> |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 4 |
| 2 | 2 | PATCHLEVEL = 9 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc4 | |
| 4 | +EXTRAVERSION = -rc6 | |
| 5 | 5 | NAME = Psychotic Stoned Sheep |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -370,7 +370,7 @@ LDFLAGS_MODULE = · 362 unmodified lines | ||
| 370 | 370 | CFLAGS_KERNEL = |
| 371 | 371 | AFLAGS_KERNEL = |
| 372 | 372 | LDFLAGS_vmlinux = |
| 373 | −CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im | |
| 373 | +CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized | |
| 374 | 374 | CFLAGS_KCOV := $(call cc-option,-fsanitize-coverage=trace-pc,) |
| 375 | 375 | |
| 376 | 376 | |
| @@ -399,11 +399,12 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ · 22 unmodified lines | ||
| 399 | 399 | -fno-strict-aliasing -fno-common \ |
| 400 | 400 | -Werror-implicit-function-declaration \ |
| 401 | 401 | -Wno-format-security \ |
| 402 | − -std=gnu89 | |
| 402 | + -std=gnu89 $(call cc-option,-fno-PIE) | |
| 403 | + | |
| 403 | 404 | |
| 404 | 405 | KBUILD_AFLAGS_KERNEL := |
| 405 | 406 | KBUILD_CFLAGS_KERNEL := |
| 406 | −KBUILD_AFLAGS := -D__ASSEMBLY__ | |
| 407 | +KBUILD_AFLAGS := -D__ASSEMBLY__ $(call cc-option,-fno-PIE) | |
| 407 | 408 | KBUILD_AFLAGS_MODULE := -DMODULE |
| 408 | 409 | KBUILD_CFLAGS_MODULE := -DMODULE |
| 409 | 410 | KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds |
| @@ -620,7 +621,6 @@ ARCH_CFLAGS := · 210 unmodified lines | ||
| 620 | 621 | include arch/$(SRCARCH)/Makefile |
| 621 | 622 | |
| 622 | 623 | KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,) |
| 623 | −KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,) | |
| 624 | 624 | KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,) |
| 625 | 625 | |
| 626 | 626 | ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION |
| @@ -629,15 +629,18 @@ KBUILD_CFLAGS += $(call cc-option,-fdata-sections,) · 2 unmodified lines | ||
| 629 | 629 | endif |
| 630 | 630 | |
| 631 | 631 | ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE |
| 632 | −KBUILD_CFLAGS += -Os | |
| 632 | +KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,) | |
| 633 | 633 | else |
| 634 | 634 | ifdef CONFIG_PROFILE_ALL_BRANCHES |
| 635 | −KBUILD_CFLAGS += -O2 | |
| 635 | +KBUILD_CFLAGS += -O2 $(call cc-disable-warning,maybe-uninitialized,) | |
| 636 | 636 | else |
| 637 | 637 | KBUILD_CFLAGS += -O2 |
| 638 | 638 | endif |
| 639 | 639 | endif |
| 640 | 640 | |
| 641 | +KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0409, \ | |
| 642 | + $(call cc-disable-warning,maybe-uninitialized,)) | |
| 643 | + | |
| 641 | 644 | # Tell gcc to never replace conditional load with a non-conditional one |
| 642 | 645 | KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) |
| 643 | 646 | |
| @@ -50,6 +50,9 @@ atleast_gcc44 := $(call cc-ifversion, -ge, 0404, y) · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | cflags-$(atleast_gcc44) += -fsection-anchors |
| 52 | 52 | |
| 53 | +cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock | |
| 54 | +cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape | |
| 55 | + | |
| 53 | 56 | ifdef CONFIG_ISA_ARCV2 |
| 54 | 57 | |
| 55 | 58 | ifndef CONFIG_ARC_HAS_LL64 |
| @@ -68,7 +71,9 @@ cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables $(cfi) · 12 unmodified lines | ||
| 68 | 71 | ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE |
| 69 | 72 | # Generic build system uses -O2, we want -O3 |
| 70 | 73 | # Note: No need to add to cflags-y as that happens anyways |
| 71 | −ARCH_CFLAGS += -O3 | |
| 74 | +# | |
| 75 | +# Disable the false maybe-uninitialized warings gcc spits out at -O3 | |
| 76 | +ARCH_CFLAGS += -O3 $(call cc-disable-warning,maybe-uninitialized,) | |
| 72 | 77 | endif |
| 73 | 78 | |
| 74 | 79 | # small data is default for elf32 tool-chain. If not usable, disable it |
| @@ -71,7 +71,7 @@ · 70 unmodified lines | ||
| 71 | 71 | reg-io-width = <4>; |
| 72 | 72 | }; |
| 73 | 73 | |
| 74 | − arcpmu0: pmu { | |
| 74 | + arcpct0: pct { | |
| 75 | 75 | compatible = "snps,arc700-pct"; |
| 76 | 76 | }; |
| 77 | 77 | }; |
| @@ -69,7 +69,7 @@ · 68 unmodified lines | ||
| 69 | 69 | }; |
| 70 | 70 | }; |
| 71 | 71 | |
| 72 | − arcpmu0: pmu { | |
| 72 | + arcpct0: pct { | |
| 73 | 73 | compatible = "snps,arc700-pct"; |
| 74 | 74 | }; |
| 75 | 75 | }; |
| @@ -83,5 +83,9 @@ · 82 unmodified lines | ||
| 83 | 83 | reg = <0xf0003000 0x44>; |
| 84 | 84 | interrupts = <7>; |
| 85 | 85 | }; |
| 86 | + | |
| 87 | + arcpct0: pct { | |
| 88 | + compatible = "snps,arc700-pct"; | |
| 89 | + }; | |
| 86 | 90 | }; |
| 87 | 91 | }; |
| @@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y · 13 unmodified lines | ||
| 14 | 14 | CONFIG_INITRAMFS_SOURCE="../arc_initramfs/" |
| 15 | 15 | CONFIG_KALLSYMS_ALL=y |
| 16 | 16 | CONFIG_EMBEDDED=y |
| 17 | +CONFIG_PERF_EVENTS=y | |
| 17 | 18 | # CONFIG_SLUB_DEBUG is not set |
| 18 | 19 | # CONFIG_COMPAT_BRK is not set |
| 19 | 20 | CONFIG_KPROBES=y |
| @@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y · 13 unmodified lines | ||
| 14 | 14 | CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/" |
| 15 | 15 | CONFIG_KALLSYMS_ALL=y |
| 16 | 16 | CONFIG_EMBEDDED=y |
| 17 | +CONFIG_PERF_EVENTS=y | |
| 17 | 18 | # CONFIG_SLUB_DEBUG is not set |
| 18 | 19 | # CONFIG_COMPAT_BRK is not set |
| 19 | 20 | CONFIG_KPROBES=y |
| @@ -12,6 +12,7 @@ CONFIG_BLK_DEV_INITRD=y · 11 unmodified lines | ||
| 12 | 12 | CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/" |
| 13 | 13 | CONFIG_KALLSYMS_ALL=y |
| 14 | 14 | CONFIG_EMBEDDED=y |
| 15 | +CONFIG_PERF_EVENTS=y | |
| 15 | 16 | # CONFIG_SLUB_DEBUG is not set |
| 16 | 17 | # CONFIG_COMPAT_BRK is not set |
| 17 | 18 | CONFIG_KPROBES=y |
| @@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y · 13 unmodified lines | ||
| 14 | 14 | CONFIG_INITRAMFS_SOURCE="../arc_initramfs/" |
| 15 | 15 | CONFIG_KALLSYMS_ALL=y |
| 16 | 16 | CONFIG_EMBEDDED=y |
| 17 | +CONFIG_PERF_EVENTS=y | |
| 17 | 18 | # CONFIG_SLUB_DEBUG is not set |
| 18 | 19 | # CONFIG_COMPAT_BRK is not set |
| 19 | 20 | CONFIG_KPROBES=y |
| @@ -14,6 +14,7 @@ CONFIG_BLK_DEV_INITRD=y · 13 unmodified lines | ||
| 14 | 14 | CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/" |
| 15 | 15 | CONFIG_KALLSYMS_ALL=y |
| 16 | 16 | CONFIG_EMBEDDED=y |
| 17 | +CONFIG_PERF_EVENTS=y | |
| 17 | 18 | # CONFIG_SLUB_DEBUG is not set |
| 18 | 19 | # CONFIG_COMPAT_BRK is not set |
| 19 | 20 | CONFIG_KPROBES=y |
| @@ -10,6 +10,7 @@ CONFIG_IKCONFIG_PROC=y · 9 unmodified lines | ||
| 10 | 10 | # CONFIG_PID_NS is not set |
| 11 | 11 | CONFIG_BLK_DEV_INITRD=y |
| 12 | 12 | CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/" |
| 13 | +CONFIG_PERF_EVENTS=y | |
| 13 | 14 | # CONFIG_COMPAT_BRK is not set |
| 14 | 15 | CONFIG_KPROBES=y |
| 15 | 16 | CONFIG_MODULES=y |
| @@ -34,7 +35,6 @@ CONFIG_INET=y · 18 unmodified lines | ||
| 34 | 35 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set |
| 35 | 36 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set |
| 36 | 37 | # CONFIG_INET_XFRM_MODE_BEET is not set |
| 37 | −# CONFIG_INET_LRO is not set | |
| 38 | 38 | # CONFIG_IPV6 is not set |
| 39 | 39 | # CONFIG_WIRELESS is not set |
| 40 | 40 | CONFIG_DEVTMPFS=y |
| @@ -72,7 +72,6 @@ CONFIG_SERIAL_OF_PLATFORM=y · 31 unmodified lines | ||
| 72 | 72 | # CONFIG_HWMON is not set |
| 73 | 73 | CONFIG_DRM=y |
| 74 | 74 | CONFIG_DRM_ARCPGU=y |
| 75 | −CONFIG_FRAMEBUFFER_CONSOLE=y | |
| 76 | 75 | CONFIG_LOGO=y |
| 77 | 76 | # CONFIG_HID is not set |
| 78 | 77 | # CONFIG_USB_SUPPORT is not set |
| @@ -43,12 +43,14 @@ · 42 unmodified lines | ||
| 43 | 43 | #define STATUS_AE_BIT 5 /* Exception active */ |
| 44 | 44 | #define STATUS_DE_BIT 6 /* PC is in delay slot */ |
| 45 | 45 | #define STATUS_U_BIT 7 /* User/Kernel mode */ |
| 46 | +#define STATUS_Z_BIT 11 | |
| 46 | 47 | #define STATUS_L_BIT 12 /* Loop inhibit */ |
| 47 | 48 | |
| 48 | 49 | /* These masks correspond to the status word(STATUS_32) bits */ |
| 49 | 50 | #define STATUS_AE_MASK (1<<STATUS_AE_BIT) |
| 50 | 51 | #define STATUS_DE_MASK (1<<STATUS_DE_BIT) |
| 51 | 52 | #define STATUS_U_MASK (1<<STATUS_U_BIT) |
| 53 | +#define STATUS_Z_MASK (1<<STATUS_Z_BIT) | |
| 52 | 54 | #define STATUS_L_MASK (1<<STATUS_L_BIT) |
| 53 | 55 | |
| 54 | 56 | /* |
| @@ -37,9 +37,9 @@ extern const char *arc_platform_smp_cpuinfo(void); · 36 unmodified lines | ||
| 37 | 37 | * API expected BY platform smp code (FROM arch smp code) |
| 38 | 38 | * |
| 39 | 39 | * smp_ipi_irq_setup: |
| 40 | − * Takes @cpu and @irq to which the arch-common ISR is hooked up | |
| 40 | + * Takes @cpu and @hwirq to which the arch-common ISR is hooked up | |
| 41 | 41 | */ |
| 42 | −extern int smp_ipi_irq_setup(int cpu, int irq); | |
| 42 | +extern int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq); | |
| 43 | 43 | |
| 44 | 44 | /* |
| 45 | 45 | * struct plat_smp_ops - SMP callbacks provided by platform to ARC SMP |
| @@ -31,6 +31,8 @@ static void __init arc_set_early_base_baud(unsigned long dt_root) · 30 unmodified lines | ||
| 31 | 31 | arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */ |
| 32 | 32 | else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp")) |
| 33 | 33 | arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */ |
| 34 | + else if (of_flat_dt_is_compatible(dt_root, "ezchip,arc-nps")) | |
| 35 | + arc_base_baud = 800000000; /* Fixed 800MHz clk (NPS) */ | |
| 34 | 36 | else |
| 35 | 37 | arc_base_baud = 50000000; /* Fixed default 50MHz */ |
| 36 | 38 | } |
| @@ -181,6 +181,8 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask, · 180 unmodified lines | ||
| 181 | 181 | { |
| 182 | 182 | unsigned long flags; |
| 183 | 183 | cpumask_t online; |
| 184 | + unsigned int destination_bits; | |
| 185 | + unsigned int distribution_mode; | |
| 184 | 186 | |
| 185 | 187 | /* errout if no online cpu per @cpumask */ |
| 186 | 188 | if (!cpumask_and(&online, cpumask, cpu_online_mask)) |
| @@ -188,8 +190,15 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask, · 1 unmodified line | ||
| 188 | 190 | |
| 189 | 191 | raw_spin_lock_irqsave(&mcip_lock, flags); |
| 190 | 192 | |
| 191 | − idu_set_dest(data->hwirq, cpumask_bits(&online)[0]); | |
| 192 | − idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_RR); | |
| 193 | + destination_bits = cpumask_bits(&online)[0]; | |
| 194 | + idu_set_dest(data->hwirq, destination_bits); | |
| 195 | + | |
| 196 | + if (ffs(destination_bits) == fls(destination_bits)) | |
| 197 | + distribution_mode = IDU_M_DISTRI_DEST; | |
| 198 | + else | |
| 199 | + distribution_mode = IDU_M_DISTRI_RR; | |
| 200 | + | |
| 201 | + idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode); | |
| 193 | 202 | |
| 194 | 203 | raw_spin_unlock_irqrestore(&mcip_lock, flags); |
| 195 | 204 | |
| @@ -207,16 +216,15 @@ static struct irq_chip idu_irq_chip = { · 11 unmodified lines | ||
| 207 | 216 | |
| 208 | 217 | }; |
| 209 | 218 | |
| 210 | −static int idu_first_irq; | |
| 219 | +static irq_hw_number_t idu_first_hwirq; | |
| 211 | 220 | |
| 212 | 221 | static void idu_cascade_isr(struct irq_desc *desc) |
| 213 | 222 | { |
| 214 | − struct irq_domain *domain = irq_desc_get_handler_data(desc); | |
| 215 | − unsigned int core_irq = irq_desc_get_irq(desc); | |
| 216 | − unsigned int idu_irq; | |
| 223 | + struct irq_domain *idu_domain = irq_desc_get_handler_data(desc); | |
| 224 | + irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc)); | |
| 225 | + irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq; | |
| 217 | 226 | |
| 218 | − idu_irq = core_irq - idu_first_irq; | |
| 219 | − generic_handle_irq(irq_find_mapping(domain, idu_irq)); | |
| 227 | + generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq)); | |
| 220 | 228 | } |
| 221 | 229 | |
| 222 | 230 | static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) |
| @@ -282,7 +290,7 @@ idu_of_init(struct device_node *intc, struct device_node *parent) · 59 unmodified lines | ||
| 282 | 290 | struct irq_domain *domain; |
| 283 | 291 | /* Read IDU BCR to confirm nr_irqs */ |
| 284 | 292 | int nr_irqs = of_irq_count(intc); |
| 285 | − int i, irq; | |
| 293 | + int i, virq; | |
| 286 | 294 | struct mcip_bcr mp; |
| 287 | 295 | |
| 288 | 296 | READ_BCR(ARC_REG_MCIP_BCR, mp); |
| @@ -303,11 +311,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent) · 14 unmodified lines | ||
| 303 | 311 | * however we need it to get the parent virq and set IDU handler |
| 304 | 312 | * as first level isr |
| 305 | 313 | */ |
| 306 | − irq = irq_of_parse_and_map(intc, i); | |
| 314 | + virq = irq_of_parse_and_map(intc, i); | |
| 307 | 315 | if (!i) |
| 308 | − idu_first_irq = irq; | |
| 316 | + idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq)); | |
| 309 | 317 | |
| 310 | − irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain); | |
| 318 | + irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain); | |
| 311 | 319 | } |
| 312 | 320 | |
| 313 | 321 | __mcip_cmd(CMD_IDU_ENABLE, 0); |
| @@ -43,8 +43,8 @@ SYSCALL_DEFINE0(arc_gettls) · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new) |
| 45 | 45 | { |
| 46 | − int uval; | |
| 47 | − int ret; | |
| 46 | + struct pt_regs *regs = current_pt_regs(); | |
| 47 | + int uval = -EFAULT; | |
| 48 | 48 | |
| 49 | 49 | /* |
| 50 | 50 | * This is only for old cores lacking LLOCK/SCOND, which by defintion |
| @@ -54,24 +54,26 @@ SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new) · 3 unmodified lines | ||
| 54 | 54 | */ |
| 55 | 55 | WARN_ON_ONCE(IS_ENABLED(CONFIG_SMP)); |
| 56 | 56 | |
| 57 | + /* Z indicates to userspace if operation succeded */ | |
| 58 | + regs->status32 &= ~STATUS_Z_MASK; | |
| 59 | + | |
| 57 | 60 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) |
| 58 | 61 | return -EFAULT; |
| 59 | 62 | |
| 60 | 63 | preempt_disable(); |
| 61 | 64 | |
| 62 | − ret = __get_user(uval, uaddr); | |
| 63 | − if (ret) | |
| 65 | + if (__get_user(uval, uaddr)) | |
| 64 | 66 | goto done; |
| 65 | 67 | |
| 66 | − if (uval != expected) | |
| 67 | − ret = -EAGAIN; | |
| 68 | − else | |
| 69 | − ret = __put_user(new, uaddr); | |
| 68 | + if (uval == expected) { | |
| 69 | + if (!__put_user(new, uaddr)) | |
| 70 | + regs->status32 |= STATUS_Z_MASK; | |
| 71 | + } | |
| 70 | 72 | |
| 71 | 73 | done: |
| 72 | 74 | preempt_enable(); |
| 73 | 75 | |
| 74 | − return ret; | |
| 76 | + return uval; | |
| 75 | 77 | } |
| 76 | 78 | |
| 77 | 79 | void arch_cpu_idle(void) |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/atomic.h> |
| 23 | 23 | #include <linux/cpumask.h> |
| 24 | 24 | #include <linux/reboot.h> |
| 25 | +#include <linux/irqdomain.h> | |
| 25 | 26 | #include <asm/processor.h> |
| 26 | 27 | #include <asm/setup.h> |
| 27 | 28 | #include <asm/mach_desc.h> |
| @@ -67,11 +68,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) · 39 unmodified lines | ||
| 67 | 68 | int i; |
| 68 | 69 | |
| 69 | 70 | /* |
| 70 | − * Initialise the present map, which describes the set of CPUs | |
| 71 | − * actually populated at the present time. | |
| 71 | + * if platform didn't set the present map already, do it now | |
| 72 | + * boot cpu is set to present already by init/main.c | |
| 72 | 73 | */ |
| 73 | − for (i = 0; i < max_cpus; i++) | |
| 74 | − set_cpu_present(i, true); | |
| 74 | + if (num_present_cpus() <= 1) { | |
| 75 | + for (i = 0; i < max_cpus; i++) | |
| 76 | + set_cpu_present(i, true); | |
| 77 | + } | |
| 75 | 78 | } |
| 76 | 79 | |
| 77 | 80 | void __init smp_cpus_done(unsigned int max_cpus) |
| @@ -351,20 +354,24 @@ irqreturn_t do_IPI(int irq, void *dev_id) · 273 unmodified lines | ||
| 351 | 354 | */ |
| 352 | 355 | static DEFINE_PER_CPU(int, ipi_dev); |
| 353 | 356 | |
| 354 | −int smp_ipi_irq_setup(int cpu, int irq) | |
| 357 | +int smp_ipi_irq_setup(int cpu, irq_hw_number_t hwirq) | |
| 355 | 358 | { |
| 356 | 359 | int *dev = per_cpu_ptr(&ipi_dev, cpu); |
| 360 | + unsigned int virq = irq_find_mapping(NULL, hwirq); | |
| 361 | + | |
| 362 | + if (!virq) | |
| 363 | + panic("Cannot find virq for root domain and hwirq=%lu", hwirq); | |
| 357 | 364 | |
| 358 | 365 | /* Boot cpu calls request, all call enable */ |
| 359 | 366 | if (!cpu) { |
| 360 | 367 | int rc; |
| 361 | 368 | |
| 362 | − rc = request_percpu_irq(irq, do_IPI, "IPI Interrupt", dev); | |
| 369 | + rc = request_percpu_irq(virq, do_IPI, "IPI Interrupt", dev); | |
| 363 | 370 | if (rc) |
| 364 | − panic("Percpu IRQ request failed for %d\n", irq); | |
| 371 | + panic("Percpu IRQ request failed for %u\n", virq); | |
| 365 | 372 | } |
| 366 | 373 | |
| 367 | − enable_percpu_irq(irq, 0); | |
| 374 | + enable_percpu_irq(virq, 0); | |
| 368 | 375 | |
| 369 | 376 | return 0; |
| 370 | 377 | } |
| @@ -152,14 +152,17 @@ static cycle_t arc_read_rtc(struct clocksource *cs) · 151 unmodified lines | ||
| 152 | 152 | cycle_t full; |
| 153 | 153 | } stamp; |
| 154 | 154 | |
| 155 | − | |
| 156 | − __asm__ __volatile( | |
| 157 | − "1: \n" | |
| 158 | − " lr %0, [AUX_RTC_LOW] \n" | |
| 159 | − " lr %1, [AUX_RTC_HIGH] \n" | |
| 160 | − " lr %2, [AUX_RTC_CTRL] \n" | |
| 161 | − " bbit0.nt %2, 31, 1b \n" | |
| 162 | − : "=r" (stamp.low), "=r" (stamp.high), "=r" (status)); | |
| 155 | + /* | |
| 156 | + * hardware has an internal state machine which tracks readout of | |
| 157 | + * low/high and updates the CTRL.status if | |
| 158 | + * - interrupt/exception taken between the two reads | |
| 159 | + * - high increments after low has been read | |
| 160 | + */ | |
| 161 | + do { | |
| 162 | + stamp.low = read_aux_reg(AUX_RTC_LOW); | |
| 163 | + stamp.high = read_aux_reg(AUX_RTC_HIGH); | |
| 164 | + status = read_aux_reg(AUX_RTC_CTRL); | |
| 165 | + } while (!(status & _BITUL(31))); | |
| 163 | 166 | |
| 164 | 167 | return stamp.full; |
| 165 | 168 | } |
| @@ -105,6 +105,31 @@ static void arc_dma_free(struct device *dev, size_t size, void *vaddr, · 104 unmodified lines | ||
| 105 | 105 | __free_pages(page, get_order(size)); |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | +static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma, | |
| 109 | + void *cpu_addr, dma_addr_t dma_addr, size_t size, | |
| 110 | + unsigned long attrs) | |
| 111 | +{ | |
| 112 | + unsigned long user_count = vma_pages(vma); | |
| 113 | + unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; | |
| 114 | + unsigned long pfn = __phys_to_pfn(plat_dma_to_phys(dev, dma_addr)); | |
| 115 | + unsigned long off = vma->vm_pgoff; | |
| 116 | + int ret = -ENXIO; | |
| 117 | + | |
| 118 | + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | |
| 119 | + | |
| 120 | + if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) | |
| 121 | + return ret; | |
| 122 | + | |
| 123 | + if (off < count && user_count <= (count - off)) { | |
| 124 | + ret = remap_pfn_range(vma, vma->vm_start, | |
| 125 | + pfn + off, | |
| 126 | + user_count << PAGE_SHIFT, | |
| 127 | + vma->vm_page_prot); | |
| 128 | + } | |
| 129 | + | |
| 130 | + return ret; | |
| 131 | +} | |
| 132 | + | |
| 108 | 133 | /* |
| 109 | 134 | * streaming DMA Mapping API... |
| 110 | 135 | * CPU accesses page via normal paddr, thus needs to explicitly made |
| @@ -193,6 +218,7 @@ static int arc_dma_supported(struct device *dev, u64 dma_mask) · 82 unmodified lines | ||
| 193 | 218 | struct dma_map_ops arc_dma_ops = { |
| 194 | 219 | .alloc = arc_dma_alloc, |
| 195 | 220 | .free = arc_dma_free, |
| 221 | + .mmap = arc_dma_mmap, | |
| 196 | 222 | .map_page = arc_dma_map_page, |
| 197 | 223 | .map_sg = arc_dma_map_sg, |
| 198 | 224 | .sync_single_for_device = arc_dma_sync_single_for_device, |
| @@ -140,16 +140,10 @@ static void eznps_init_per_cpu(int cpu) · 139 unmodified lines | ||
| 140 | 140 | mtm_enable_core(cpu); |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | −static void eznps_ipi_clear(int irq) | |
| 144 | −{ | |
| 145 | − write_aux_reg(CTOP_AUX_IACK, 1 << irq); | |
| 146 | −} | |
| 147 | − | |
| 148 | 143 | struct plat_smp_ops plat_smp_ops = { |
| 149 | 144 | .info = smp_cpuinfo_buf, |
| 150 | 145 | .init_early_smp = eznps_init_cpumasks, |
| 151 | 146 | .cpu_kick = eznps_smp_wakeup_cpu, |
| 152 | 147 | .ipi_send = eznps_ipi_send, |
| 153 | 148 | .init_per_cpu = eznps_init_per_cpu, |
| 154 | − .ipi_clear = eznps_ipi_clear, | |
| 155 | 149 | }; |
| @@ -64,8 +64,8 @@ · 63 unmodified lines | ||
| 64 | 64 | }; |
| 65 | 65 | |
| 66 | 66 | ldo3_reg: ldo3 { |
| 67 | − regulator-min-microvolt = <600000>; | |
| 68 | − regulator-max-microvolt = <1800000>; | |
| 67 | + regulator-min-microvolt = <1725000>; | |
| 68 | + regulator-max-microvolt = <3300000>; | |
| 69 | 69 | regulator-always-on; |
| 70 | 70 | }; |
| 71 | 71 | |
| @@ -76,8 +76,8 @@ · 4 unmodified lines | ||
| 76 | 76 | }; |
| 77 | 77 | |
| 78 | 78 | ldo5_reg: ldo5 { |
| 79 | − regulator-min-microvolt = <1725000>; | |
| 80 | − regulator-max-microvolt = <3300000>; | |
| 79 | + regulator-min-microvolt = <1200000>; | |
| 80 | + regulator-max-microvolt = <3600000>; | |
| 81 | 81 | regulator-always-on; |
| 82 | 82 | }; |
| 83 | 83 | |
| @@ -100,14 +100,14 @@ · 16 unmodified lines | ||
| 100 | 100 | }; |
| 101 | 101 | |
| 102 | 102 | ldo9_reg: ldo9 { |
| 103 | − regulator-min-microvolt = <1200000>; | |
| 103 | + regulator-min-microvolt = <1250000>; | |
| 104 | 104 | regulator-max-microvolt = <3600000>; |
| 105 | 105 | regulator-always-on; |
| 106 | 106 | }; |
| 107 | 107 | |
| 108 | 108 | ldo10_reg: ldo10 { |
| 109 | − regulator-min-microvolt = <1250000>; | |
| 110 | − regulator-max-microvolt = <3650000>; | |
| 109 | + regulator-min-microvolt = <1200000>; | |
| 110 | + regulator-max-microvolt = <3600000>; | |
| 111 | 111 | regulator-always-on; |
| 112 | 112 | }; |
| 113 | 113 | }; |
| @@ -13,6 +13,11 @@ · 12 unmodified lines | ||
| 13 | 13 | }; |
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | + memory@80000000 { | |
| 17 | + device_type = "memory"; | |
| 18 | + reg = <0x80000000 0>; | |
| 19 | + }; | |
| 20 | + | |
| 16 | 21 | wl12xx_vmmc: wl12xx_vmmc { |
| 17 | 22 | compatible = "regulator-fixed"; |
| 18 | 23 | regulator-name = "vwl1271"; |
| @@ -13,9 +13,9 @@ · 12 unmodified lines | ||
| 13 | 13 | }; |
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | − memory@0 { | |
| 16 | + memory@80000000 { | |
| 17 | 17 | device_type = "memory"; |
| 18 | − reg = <0 0>; | |
| 18 | + reg = <0x80000000 0>; | |
| 19 | 19 | }; |
| 20 | 20 | |
| 21 | 21 | leds { |
| @@ -124,6 +124,7 @@ · 123 unmodified lines | ||
| 124 | 124 | compatible = "ti,abe-twl6040"; |
| 125 | 125 | ti,model = "omap5-uevm"; |
| 126 | 126 | |
| 127 | + ti,jack-detection; | |
| 127 | 128 | ti,mclk-freq = <19200000>; |
| 128 | 129 | |
| 129 | 130 | ti,mcpdm = <&mcpdm>; |
| @@ -415,7 +416,7 @@ · 285 unmodified lines | ||
| 415 | 416 | ti,backup-battery-charge-high-current; |
| 416 | 417 | }; |
| 417 | 418 | |
| 418 | − gpadc { | |
| 419 | + gpadc: gpadc { | |
| 419 | 420 | compatible = "ti,palmas-gpadc"; |
| 420 | 421 | interrupts = <18 0 |
| 421 | 422 | 16 0 |
| @@ -475,8 +476,8 @@ · 53 unmodified lines | ||
| 475 | 476 | smps6_reg: smps6 { |
| 476 | 477 | /* VDD_DDR3 - over VDD_SMPS6 */ |
| 477 | 478 | regulator-name = "smps6"; |
| 478 | − regulator-min-microvolt = <1200000>; | |
| 479 | − regulator-max-microvolt = <1200000>; | |
| 479 | + regulator-min-microvolt = <1350000>; | |
| 480 | + regulator-max-microvolt = <1350000>; | |
| 480 | 481 | regulator-always-on; |
| 481 | 482 | regulator-boot-on; |
| 482 | 483 | }; |
| @@ -74,7 +74,7 @@ · 73 unmodified lines | ||
| 74 | 74 | /* Low speed expansion connector */ |
| 75 | 75 | spi0: spi@9844000 { |
| 76 | 76 | label = "LS-SPI0"; |
| 77 | − cs-gpio = <&pio30 3 0>; | |
| 77 | + cs-gpios = <&pio30 3 0>; | |
| 78 | 78 | status = "okay"; |
| 79 | 79 | }; |
| 80 | 80 | |
| @@ -282,11 +282,15 @@ · 281 unmodified lines | ||
| 282 | 282 | uart1_pins_a: uart1@0 { |
| 283 | 283 | allwinner,pins = "PG6", "PG7"; |
| 284 | 284 | allwinner,function = "uart1"; |
| 285 | + allwinner,drive = <SUN4I_PINCTRL_10_MA>; | |
| 286 | + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; | |
| 285 | 287 | }; |
| 286 | 288 | |
| 287 | 289 | uart1_pins_cts_rts_a: uart1-cts-rts@0 { |
| 288 | 290 | allwinner,pins = "PG8", "PG9"; |
| 289 | 291 | allwinner,function = "uart1"; |
| 292 | + allwinner,drive = <SUN4I_PINCTRL_10_MA>; | |
| 293 | + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; | |
| 290 | 294 | }; |
| 291 | 295 | |
| 292 | 296 | mmc0_pins_a: mmc0@0 { |
| @@ -66,6 +66,7 @@ extern char __kvm_hyp_vector[]; · 65 unmodified lines | ||
| 66 | 66 | extern void __kvm_flush_vm_context(void); |
| 67 | 67 | extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); |
| 68 | 68 | extern void __kvm_tlb_flush_vmid(struct kvm *kvm); |
| 69 | +extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu); | |
| 69 | 70 | |
| 70 | 71 | extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); |
| 71 | 72 | |
| @@ -57,6 +57,9 @@ struct kvm_arch { · 56 unmodified lines | ||
| 57 | 57 | /* VTTBR value associated with below pgd and vmid */ |
| 58 | 58 | u64 vttbr; |
| 59 | 59 | |
| 60 | + /* The last vcpu id that ran on each physical CPU */ | |
| 61 | + int __percpu *last_vcpu_ran; | |
| 62 | + | |
| 60 | 63 | /* Timer */ |
| 61 | 64 | struct arch_timer_kvm timer; |
| 62 | 65 | |
| @@ -71,6 +71,7 @@ · 70 unmodified lines | ||
| 71 | 71 | #define ICIALLUIS __ACCESS_CP15(c7, 0, c1, 0) |
| 72 | 72 | #define ATS1CPR __ACCESS_CP15(c7, 0, c8, 0) |
| 73 | 73 | #define TLBIALLIS __ACCESS_CP15(c8, 0, c3, 0) |
| 74 | +#define TLBIALL __ACCESS_CP15(c8, 0, c7, 0) | |
| 74 | 75 | #define TLBIALLNSNHIS __ACCESS_CP15(c8, 4, c3, 4) |
| 75 | 76 | #define PRRR __ACCESS_CP15(c10, 0, c2, 0) |
| 76 | 77 | #define NMRR __ACCESS_CP15(c10, 0, c2, 1) |
| @@ -74,6 +74,26 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long · 73 unmodified lines | ||
| 74 | 74 | dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | +void dump_backtrace_stm(u32 *stack, u32 instruction) | |
| 78 | +{ | |
| 79 | + char str[80], *p; | |
| 80 | + unsigned int x; | |
| 81 | + int reg; | |
| 82 | + | |
| 83 | + for (reg = 10, x = 0, p = str; reg >= 0; reg--) { | |
| 84 | + if (instruction & BIT(reg)) { | |
| 85 | + p += sprintf(p, " r%d:%08x", reg, *stack--); | |
| 86 | + if (++x == 6) { | |
| 87 | + x = 0; | |
| 88 | + p = str; | |
| 89 | + printk("%s\n", str); | |
| 90 | + } | |
| 91 | + } | |
| 92 | + } | |
| 93 | + if (p != str) | |
| 94 | + printk("%s\n", str); | |
| 95 | +} | |
| 96 | + | |
| 77 | 97 | #ifndef CONFIG_ARM_UNWIND |
| 78 | 98 | /* |
| 79 | 99 | * Stack pointers should always be within the kernels view of |
| @@ -3,6 +3,9 @@ · 2 unmodified lines | ||
| 3 | 3 | * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | +/* No __ro_after_init data in the .rodata section - which will always be ro */ | |
| 7 | +#define RO_AFTER_INIT_DATA | |
| 8 | + | |
| 6 | 9 | #include <asm-generic/vmlinux.lds.h> |
| 7 | 10 | #include <asm/cache.h> |
| 8 | 11 | #include <asm/thread_info.h> |
| @@ -223,6 +226,8 @@ SECTIONS · 214 unmodified lines | ||
| 223 | 226 | . = ALIGN(PAGE_SIZE); |
| 224 | 227 | __init_end = .; |
| 225 | 228 | |
| 229 | + *(.data..ro_after_init) | |
| 230 | + | |
| 226 | 231 | NOSAVE_DATA |
| 227 | 232 | CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) |
| 228 | 233 | READ_MOSTLY_DATA(L1_CACHE_BYTES) |
| @@ -114,11 +114,18 @@ void kvm_arch_check_processor_compat(void *rtn) · 113 unmodified lines | ||
| 114 | 114 | */ |
| 115 | 115 | int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) |
| 116 | 116 | { |
| 117 | − int ret = 0; | |
| 117 | + int ret, cpu; | |
| 118 | 118 | |
| 119 | 119 | if (type) |
| 120 | 120 | return -EINVAL; |
| 121 | 121 | |
| 122 | + kvm->arch.last_vcpu_ran = alloc_percpu(typeof(*kvm->arch.last_vcpu_ran)); | |
| 123 | + if (!kvm->arch.last_vcpu_ran) | |
| 124 | + return -ENOMEM; | |
| 125 | + | |
| 126 | + for_each_possible_cpu(cpu) | |
| 127 | + *per_cpu_ptr(kvm->arch.last_vcpu_ran, cpu) = -1; | |
| 128 | + | |
| 122 | 129 | ret = kvm_alloc_stage2_pgd(kvm); |
| 123 | 130 | if (ret) |
| 124 | 131 | goto out_fail_alloc; |
| @@ -141,6 +148,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) · 16 unmodified lines | ||
| 141 | 148 | out_free_stage2_pgd: |
| 142 | 149 | kvm_free_stage2_pgd(kvm); |
| 143 | 150 | out_fail_alloc: |
| 151 | + free_percpu(kvm->arch.last_vcpu_ran); | |
| 152 | + kvm->arch.last_vcpu_ran = NULL; | |
| 144 | 153 | return ret; |
| 145 | 154 | } |
| 146 | 155 | |
| @@ -168,6 +177,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm) · 21 unmodified lines | ||
| 168 | 177 | { |
| 169 | 178 | int i; |
| 170 | 179 | |
| 180 | + free_percpu(kvm->arch.last_vcpu_ran); | |
| 181 | + kvm->arch.last_vcpu_ran = NULL; | |
| 182 | + | |
| 171 | 183 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { |
| 172 | 184 | if (kvm->vcpus[i]) { |
| 173 | 185 | kvm_arch_vcpu_free(kvm->vcpus[i]); |
| @@ -312,6 +324,19 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) · 138 unmodified lines | ||
| 312 | 324 | |
| 313 | 325 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
| 314 | 326 | { |
| 327 | + int *last_ran; | |
| 328 | + | |
| 329 | + last_ran = this_cpu_ptr(vcpu->kvm->arch.last_vcpu_ran); | |
| 330 | + | |
| 331 | + /* | |
| 332 | + * We might get preempted before the vCPU actually runs, but | |
| 333 | + * over-invalidation doesn't affect correctness. | |
| 334 | + */ | |
| 335 | + if (*last_ran != vcpu->vcpu_id) { | |
| 336 | + kvm_call_hyp(__kvm_tlb_flush_local_vmid, vcpu); | |
| 337 | + *last_ran = vcpu->vcpu_id; | |
| 338 | + } | |
| 339 | + | |
| 315 | 340 | vcpu->cpu = cpu; |
| 316 | 341 | vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state); |
| 317 | 342 | |
| @@ -55,6 +55,21 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) · 54 unmodified lines | ||
| 55 | 55 | __kvm_tlb_flush_vmid(kvm); |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | +void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) | |
| 59 | +{ | |
| 60 | + struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); | |
| 61 | + | |
| 62 | + /* Switch to requested VMID */ | |
| 63 | + write_sysreg(kvm->arch.vttbr, VTTBR); | |
| 64 | + isb(); | |
| 65 | + | |
| 66 | + write_sysreg(0, TLBIALL); | |
| 67 | + dsb(nsh); | |
| 68 | + isb(); | |
| 69 | + | |
| 70 | + write_sysreg(0, VTTBR); | |
| 71 | +} | |
| 72 | + | |
| 58 | 73 | void __hyp_text __kvm_flush_vm_context(void) |
| 59 | 74 | { |
| 60 | 75 | write_sysreg(0, TLBIALLNSNHIS); |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | * 27/03/03 Ian Molton Clean up CONFIG_CPU |
| 11 | 11 | * |
| 12 | 12 | */ |
| 13 | +#include <linux/kern_levels.h> | |
| 13 | 14 | #include <linux/linkage.h> |
| 14 | 15 | #include <asm/assembler.h> |
| 15 | 16 | .text |
| @@ -83,13 +84,13 @@ for_each_frame: tst frame, mask @ Check for address exceptions · 67 unmodified lines | ||
| 83 | 84 | teq r3, r1, lsr #11 |
| 84 | 85 | ldreq r0, [frame, #-8] @ get sp |
| 85 | 86 | subeq r0, r0, #4 @ point at the last arg |
| 86 | − bleq .Ldumpstm @ dump saved registers | |
| 87 | + bleq dump_backtrace_stm @ dump saved registers | |
| 87 | 88 | |
| 88 | 89 | 1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc} |
| 89 | 90 | ldr r3, .Ldsi @ instruction exists, |
| 90 | 91 | teq r3, r1, lsr #11 |
| 91 | 92 | subeq r0, frame, #16 |
| 92 | − bleq .Ldumpstm @ dump saved registers | |
| 93 | + bleq dump_backtrace_stm @ dump saved registers | |
| 93 | 94 | |
| 94 | 95 | teq sv_fp, #0 @ zero saved fp means |
| 95 | 96 | beq no_frame @ no further frames |
| @@ -112,38 +113,6 @@ ENDPROC(c_backtrace) · 16 unmodified lines | ||
| 112 | 113 | .long 1004b, 1006b |
| 113 | 114 | .popsection |
| 114 | 115 | |
| 115 | −#define instr r4 | |
| 116 | −#define reg r5 | |
| 117 | −#define stack r6 | |
| 118 | − | |
| 119 | −.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} | |
| 120 | − mov stack, r0 | |
| 121 | − mov instr, r1 | |
| 122 | − mov reg, #10 | |
| 123 | − mov r7, #0 | |
| 124 | −1: mov r3, #1 | |
| 125 | − ARM( tst instr, r3, lsl reg ) | |
| 126 | − THUMB( lsl r3, reg ) | |
| 127 | − THUMB( tst instr, r3 ) | |
| 128 | − beq 2f | |
| 129 | − add r7, r7, #1 | |
| 130 | − teq r7, #6 | |
| 131 | − moveq r7, #0 | |
| 132 | − adr r3, .Lcr | |
| 133 | − addne r3, r3, #1 @ skip newline | |
| 134 | − ldr r2, [stack], #-4 | |
| 135 | − mov r1, reg | |
| 136 | − adr r0, .Lfp | |
| 137 | − bl printk | |
| 138 | −2: subs reg, reg, #1 | |
| 139 | − bpl 1b | |
| 140 | − teq r7, #0 | |
| 141 | − adrne r0, .Lcr | |
| 142 | − blne printk | |
| 143 | − ldmfd sp!, {instr, reg, stack, r7, pc} | |
| 144 | − | |
| 145 | −.Lfp: .asciz " r%d:%08x%s" | |
| 146 | −.Lcr: .asciz "\n" | |
| 147 | 116 | .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" |
| 148 | 117 | .align |
| 149 | 118 | .Ldsi: .word 0xe92dd800 >> 11 @ stmfd sp!, {... fp, ip, lr, pc} |
| @@ -71,6 +71,7 @@ config SOC_AM43XX · 70 unmodified lines | ||
| 71 | 71 | select HAVE_ARM_TWD |
| 72 | 72 | select ARM_ERRATA_754322 |
| 73 | 73 | select ARM_ERRATA_775420 |
| 74 | + select OMAP_INTERCONNECT | |
| 74 | 75 | |
| 75 | 76 | config SOC_DRA7XX |
| 76 | 77 | bool "TI DRA7XX" |
| @@ -205,11 +205,15 @@ void __init omap2xxx_check_revision(void) · 204 unmodified lines | ||
| 205 | 205 | |
| 206 | 206 | #define OMAP3_SHOW_FEATURE(feat) \ |
| 207 | 207 | if (omap3_has_ ##feat()) \ |
| 208 | − printk(#feat" "); | |
| 208 | + n += scnprintf(buf + n, sizeof(buf) - n, #feat " "); | |
| 209 | 209 | |
| 210 | 210 | static void __init omap3_cpuinfo(void) |
| 211 | 211 | { |
| 212 | 212 | const char *cpu_name; |
| 213 | + char buf[64]; | |
| 214 | + int n = 0; | |
| 215 | + | |
| 216 | + memset(buf, 0, sizeof(buf)); | |
| 213 | 217 | |
| 214 | 218 | /* |
| 215 | 219 | * OMAP3430 and OMAP3530 are assumed to be same. |
| @@ -241,10 +245,10 @@ static void __init omap3_cpuinfo(void) · 25 unmodified lines | ||
| 241 | 245 | cpu_name = "OMAP3503"; |
| 242 | 246 | } |
| 243 | 247 | |
| 244 | − sprintf(soc_name, "%s", cpu_name); | |
| 248 | + scnprintf(soc_name, sizeof(soc_name), "%s", cpu_name); | |
| 245 | 249 | |
| 246 | 250 | /* Print verbose information */ |
| 247 | − pr_info("%s %s (", soc_name, soc_rev); | |
| 251 | + n += scnprintf(buf, sizeof(buf) - n, "%s %s (", soc_name, soc_rev); | |
| 248 | 252 | |
| 249 | 253 | OMAP3_SHOW_FEATURE(l2cache); |
| 250 | 254 | OMAP3_SHOW_FEATURE(iva); |
| @@ -252,8 +256,10 @@ static void __init omap3_cpuinfo(void) · 1 unmodified line | ||
| 252 | 256 | OMAP3_SHOW_FEATURE(neon); |
| 253 | 257 | OMAP3_SHOW_FEATURE(isp); |
| 254 | 258 | OMAP3_SHOW_FEATURE(192mhz_clk); |
| 255 | − | |
| 256 | − printk(")\n"); | |
| 259 | + if (*(buf + n - 1) == ' ') | |
| 260 | + n--; | |
| 261 | + n += scnprintf(buf + n, sizeof(buf) - n, ")\n"); | |
| 262 | + pr_info("%s", buf); | |
| 257 | 263 | } |
| 258 | 264 | |
| 259 | 265 | #define OMAP3_CHECK_FEATURE(status,feat) \ |
| @@ -319,6 +319,9 @@ void __init omap3_prm_init_pm(bool has_uart4, bool has_iva) · 318 unmodified lines | ||
| 319 | 319 | if (has_uart4) { |
| 320 | 320 | en_uart4_mask = OMAP3630_EN_UART4_MASK; |
| 321 | 321 | grpsel_uart4_mask = OMAP3630_GRPSEL_UART4_MASK; |
| 322 | + } else { | |
| 323 | + en_uart4_mask = 0; | |
| 324 | + grpsel_uart4_mask = 0; | |
| 322 | 325 | } |
| 323 | 326 | |
| 324 | 327 | /* Enable wakeups in PER */ |
| @@ -87,6 +87,12 @@ int voltdm_scale(struct voltagedomain *voltdm, · 86 unmodified lines | ||
| 87 | 87 | return -ENODATA; |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | + if (!voltdm->volt_data) { | |
| 91 | + pr_err("%s: No voltage data defined for vdd_%s\n", | |
| 92 | + __func__, voltdm->name); | |
| 93 | + return -ENODATA; | |
| 94 | + } | |
| 95 | + | |
| 90 | 96 | /* Adjust voltage to the exact voltage from the OPP table */ |
| 91 | 97 | for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) { |
| 92 | 98 | if (voltdm->volt_data[i].volt_nominal >= target_volt) { |
| @@ -1167,7 +1167,7 @@ static int __init dma_debug_do_init(void) · 1166 unmodified lines | ||
| 1167 | 1167 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); |
| 1168 | 1168 | return 0; |
| 1169 | 1169 | } |
| 1170 | −fs_initcall(dma_debug_do_init); | |
| 1170 | +core_initcall(dma_debug_do_init); | |
| 1171 | 1171 | |
| 1172 | 1172 | #ifdef CONFIG_ARM_DMA_USE_IOMMU |
| 1173 | 1173 | |
| @@ -96,7 +96,7 @@ ENTRY(cpu_cm7_proc_fin) · 95 unmodified lines | ||
| 96 | 96 | ret lr |
| 97 | 97 | ENDPROC(cpu_cm7_proc_fin) |
| 98 | 98 | |
| 99 | − .section ".text.init", #alloc, #execinstr | |
| 99 | + .section ".init.text", #alloc, #execinstr | |
| 100 | 100 | |
| 101 | 101 | __v7m_cm7_setup: |
| 102 | 102 | mov r8, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC| V7M_SCB_CCR_BP) |
| @@ -105,7 +105,7 @@ · 104 unmodified lines | ||
| 105 | 105 | status = "disabled"; |
| 106 | 106 | }; |
| 107 | 107 | |
| 108 | − nb_perih_clk: nb-periph-clk@13000{ | |
| 108 | + nb_periph_clk: nb-periph-clk@13000 { | |
| 109 | 109 | compatible = "marvell,armada-3700-periph-clock-nb"; |
| 110 | 110 | reg = <0x13000 0x100>; |
| 111 | 111 | clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, |
| @@ -113,7 +113,7 @@ · 1 unmodified line | ||
| 113 | 113 | #clock-cells = <1>; |
| 114 | 114 | }; |
| 115 | 115 | |
| 116 | − sb_perih_clk: sb-periph-clk@18000{ | |
| 116 | + sb_periph_clk: sb-periph-clk@18000 { | |
| 117 | 117 | compatible = "marvell,armada-3700-periph-clock-sb"; |
| 118 | 118 | reg = <0x18000 0x100>; |
| 119 | 119 | clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, |
| @@ -130,8 +130,8 @@ · 129 unmodified lines | ||
| 130 | 130 | reg = <0x700600 0x50>; |
| 131 | 131 | #address-cells = <0x1>; |
| 132 | 132 | #size-cells = <0x0>; |
| 133 | − cell-index = <1>; | |
| 134 | − clocks = <&cps_syscon0 0 3>; | |
| 133 | + cell-index = <3>; | |
| 134 | + clocks = <&cps_syscon0 1 21>; | |
| 135 | 135 | status = "disabled"; |
| 136 | 136 | }; |
| 137 | 137 | |
| @@ -140,7 +140,7 @@ · 2 unmodified lines | ||
| 140 | 140 | reg = <0x700680 0x50>; |
| 141 | 141 | #address-cells = <1>; |
| 142 | 142 | #size-cells = <0>; |
| 143 | − cell-index = <2>; | |
| 143 | + cell-index = <4>; | |
| 144 | 144 | clocks = <&cps_syscon0 1 21>; |
| 145 | 145 | status = "disabled"; |
| 146 | 146 | }; |
| @@ -300,8 +300,11 @@ · 299 unmodified lines | ||
| 300 | 300 | ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x600000 |
| 301 | 301 | 0x81000000 0x0 0xfa600000 0x0 0xfa600000 0x0 0x100000>; |
| 302 | 302 | resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, |
| 303 | − <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>; | |
| 304 | − reset-names = "core", "mgmt", "mgmt-sticky", "pipe"; | |
| 303 | + <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>, | |
| 304 | + <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, | |
| 305 | + <&cru SRST_A_PCIE>; | |
| 306 | + reset-names = "core", "mgmt", "mgmt-sticky", "pipe", | |
| 307 | + "pm", "pclk", "aclk"; | |
| 305 | 308 | status = "disabled"; |
| 306 | 309 | |
| 307 | 310 | pcie0_intc: interrupt-controller { |
| @@ -54,6 +54,7 @@ extern char __kvm_hyp_vector[]; · 53 unmodified lines | ||
| 54 | 54 | extern void __kvm_flush_vm_context(void); |
| 55 | 55 | extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); |
| 56 | 56 | extern void __kvm_tlb_flush_vmid(struct kvm *kvm); |
| 57 | +extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu); | |
| 57 | 58 | |
| 58 | 59 | extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); |
| 59 | 60 | |
| @@ -62,6 +62,9 @@ struct kvm_arch { · 61 unmodified lines | ||
| 62 | 62 | /* VTTBR value associated with above pgd and vmid */ |
| 63 | 63 | u64 vttbr; |
| 64 | 64 | |
| 65 | + /* The last vcpu id that ran on each physical CPU */ | |
| 66 | + int __percpu *last_vcpu_ran; | |
| 67 | + | |
| 65 | 68 | /* The maximum number of vCPUs depends on the used GIC model */ |
| 66 | 69 | int max_vcpus; |
| 67 | 70 | |
| @@ -128,7 +128,7 @@ static inline unsigned long __kern_hyp_va(unsigned long v) · 127 unmodified lines | ||
| 128 | 128 | return v; |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | −#define kern_hyp_va(v) (typeof(v))(__kern_hyp_va((unsigned long)(v))) | |
| 131 | +#define kern_hyp_va(v) ((typeof(v))(__kern_hyp_va((unsigned long)(v)))) | |
| 132 | 132 | |
| 133 | 133 | /* |
| 134 | 134 | * We currently only support a 40bit IPA. |
| @@ -46,7 +46,15 @@ · 45 unmodified lines | ||
| 46 | 46 | #define ARMV8_PMU_EVTYPE_MASK 0xc800ffff /* Mask for writable bits */ |
| 47 | 47 | #define ARMV8_PMU_EVTYPE_EVENT 0xffff /* Mask for EVENT bits */ |
| 48 | 48 | |
| 49 | −#define ARMV8_PMU_EVTYPE_EVENT_SW_INCR 0 /* Software increment event */ | |
| 49 | +/* | |
| 50 | + * PMUv3 event types: required events | |
| 51 | + */ | |
| 52 | +#define ARMV8_PMUV3_PERFCTR_SW_INCR 0x00 | |
| 53 | +#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL 0x03 | |
| 54 | +#define ARMV8_PMUV3_PERFCTR_L1D_CACHE 0x04 | |
| 55 | +#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED 0x10 | |
| 56 | +#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES 0x11 | |
| 57 | +#define ARMV8_PMUV3_PERFCTR_BR_PRED 0x12 | |
| 50 | 58 | |
| 51 | 59 | /* |
| 52 | 60 | * Event filters for PMUv3 |
| @@ -31,17 +31,9 @@ · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | /* |
| 33 | 33 | * ARMv8 PMUv3 Performance Events handling code. |
| 34 | − * Common event types. | |
| 34 | + * Common event types (some are defined in asm/perf_event.h). | |
| 35 | 35 | */ |
| 36 | 36 | |
| 37 | −/* Required events. */ | |
| 38 | −#define ARMV8_PMUV3_PERFCTR_SW_INCR 0x00 | |
| 39 | −#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL 0x03 | |
| 40 | −#define ARMV8_PMUV3_PERFCTR_L1D_CACHE 0x04 | |
| 41 | −#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED 0x10 | |
| 42 | −#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES 0x11 | |
| 43 | −#define ARMV8_PMUV3_PERFCTR_BR_PRED 0x12 | |
| 44 | − | |
| 45 | 37 | /* At least one of the following is required. */ |
| 46 | 38 | #define ARMV8_PMUV3_PERFCTR_INST_RETIRED 0x08 |
| 47 | 39 | #define ARMV8_PMUV3_PERFCTR_INST_SPEC 0x1B |
| @@ -64,6 +64,21 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm) · 63 unmodified lines | ||
| 64 | 64 | write_sysreg(0, vttbr_el2); |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | +void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) | |
| 68 | +{ | |
| 69 | + struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); | |
| 70 | + | |
| 71 | + /* Switch to requested VMID */ | |
| 72 | + write_sysreg(kvm->arch.vttbr, vttbr_el2); | |
| 73 | + isb(); | |
| 74 | + | |
| 75 | + asm volatile("tlbi vmalle1" : : ); | |
| 76 | + dsb(nsh); | |
| 77 | + isb(); | |
| 78 | + | |
| 79 | + write_sysreg(0, vttbr_el2); | |
| 80 | +} | |
| 81 | + | |
| 67 | 82 | void __hyp_text __kvm_flush_vm_context(void) |
| 68 | 83 | { |
| 69 | 84 | dsb(ishst); |
| @@ -597,8 +597,14 @@ static bool access_pmu_evcntr(struct kvm_vcpu *vcpu, · 596 unmodified lines | ||
| 597 | 597 | |
| 598 | 598 | idx = ARMV8_PMU_CYCLE_IDX; |
| 599 | 599 | } else { |
| 600 | − BUG(); | |
| 600 | + return false; | |
| 601 | 601 | } |
| 602 | + } else if (r->CRn == 0 && r->CRm == 9) { | |
| 603 | + /* PMCCNTR */ | |
| 604 | + if (pmu_access_event_counter_el0_disabled(vcpu)) | |
| 605 | + return false; | |
| 606 | + | |
| 607 | + idx = ARMV8_PMU_CYCLE_IDX; | |
| 602 | 608 | } else if (r->CRn == 14 && (r->CRm & 12) == 8) { |
| 603 | 609 | /* PMEVCNTRn_EL0 */ |
| 604 | 610 | if (pmu_access_event_counter_el0_disabled(vcpu)) |
| @@ -606,7 +612,7 @@ static bool access_pmu_evcntr(struct kvm_vcpu *vcpu, · 1 unmodified line | ||
| 606 | 612 | |
| 607 | 613 | idx = ((r->CRm & 3) << 3) | (r->Op2 & 7); |
| 608 | 614 | } else { |
| 609 | − BUG(); | |
| 615 | + return false; | |
| 610 | 616 | } |
| 611 | 617 | |
| 612 | 618 | if (!pmu_counter_idx_valid(vcpu, idx)) |
| @@ -324,6 +324,7 @@ static int __init nios2_time_init(struct device_node *timer) · 323 unmodified lines | ||
| 324 | 324 | ret = nios2_clocksource_init(timer); |
| 325 | 325 | break; |
| 326 | 326 | default: |
| 327 | + ret = 0; | |
| 327 | 328 | break; |
| 328 | 329 | } |
| 329 | 330 | |
| @@ -91,7 +91,7 @@ · 90 unmodified lines | ||
| 91 | 91 | */ |
| 92 | 92 | #define LOAD_HANDLER(reg, label) \ |
| 93 | 93 | ld reg,PACAKBASE(r13); /* get high part of &label */ \ |
| 94 | − ori reg,reg,(FIXED_SYMBOL_ABS_ADDR(label))@l; | |
| 94 | + ori reg,reg,FIXED_SYMBOL_ABS_ADDR(label); | |
| 95 | 95 | |
| 96 | 96 | #define __LOAD_HANDLER(reg, label) \ |
| 97 | 97 | ld reg,PACAKBASE(r13); \ |
| @@ -158,14 +158,17 @@ BEGIN_FTR_SECTION_NESTED(943) \ · 60 unmodified lines | ||
| 158 | 158 | std ra,offset(r13); \ |
| 159 | 159 | END_FTR_SECTION_NESTED(ftr,ftr,943) |
| 160 | 160 | |
| 161 | −#define EXCEPTION_PROLOG_0(area) \ | |
| 162 | − GET_PACA(r13); \ | |
| 161 | +#define EXCEPTION_PROLOG_0_PACA(area) \ | |
| 163 | 162 | std r9,area+EX_R9(r13); /* save r9 */ \ |
| 164 | 163 | OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR); \ |
| 165 | 164 | HMT_MEDIUM; \ |
| 166 | 165 | std r10,area+EX_R10(r13); /* save r10 - r12 */ \ |
| 167 | 166 | OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) |
| 168 | 167 | |
| 168 | +#define EXCEPTION_PROLOG_0(area) \ | |
| 169 | + GET_PACA(r13); \ | |
| 170 | + EXCEPTION_PROLOG_0_PACA(area) | |
| 171 | + | |
| 169 | 172 | #define __EXCEPTION_PROLOG_1(area, extra, vec) \ |
| 170 | 173 | OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \ |
| 171 | 174 | OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \ |
| @@ -196,6 +199,12 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) · 24 unmodified lines | ||
| 196 | 199 | EXCEPTION_PROLOG_1(area, extra, vec); \ |
| 197 | 200 | EXCEPTION_PROLOG_PSERIES_1(label, h); |
| 198 | 201 | |
| 202 | +/* Have the PACA in r13 already */ | |
| 203 | +#define EXCEPTION_PROLOG_PSERIES_PACA(area, label, h, extra, vec) \ | |
| 204 | + EXCEPTION_PROLOG_0_PACA(area); \ | |
| 205 | + EXCEPTION_PROLOG_1(area, extra, vec); \ | |
| 206 | + EXCEPTION_PROLOG_PSERIES_1(label, h); | |
| 207 | + | |
| 199 | 208 | #define __KVMTEST(h, n) \ |
| 200 | 209 | lbz r10,HSTATE_IN_GUEST(r13); \ |
| 201 | 210 | cmpwi r10,0; \ |
| @@ -460,5 +460,6 @@ · 459 unmodified lines | ||
| 460 | 460 | |
| 461 | 461 | #define PPC_SLBIA(IH) stringify_in_c(.long PPC_INST_SLBIA | \ |
| 462 | 462 | ((IH & 0x7) << 21)) |
| 463 | +#define PPC_INVALIDATE_ERAT PPC_SLBIA(7) | |
| 463 | 464 | |
| 464 | 465 | #endif /* _ASM_POWERPC_PPC_OPCODE_H */ |
| @@ -116,7 +116,9 @@ EXC_VIRT_NONE(0x4000, 0x4100) · 115 unmodified lines | ||
| 116 | 116 | |
| 117 | 117 | EXC_REAL_BEGIN(system_reset, 0x100, 0x200) |
| 118 | 118 | SET_SCRATCH0(r13) |
| 119 | − EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD, | |
| 119 | + GET_PACA(r13) | |
| 120 | + clrrdi r13,r13,1 /* Last bit of HSPRG0 is set if waking from winkle */ | |
| 121 | + EXCEPTION_PROLOG_PSERIES_PACA(PACA_EXGEN, system_reset_common, EXC_STD, | |
| 120 | 122 | IDLETEST, 0x100) |
| 121 | 123 | |
| 122 | 124 | EXC_REAL_END(system_reset, 0x100, 0x200) |
| @@ -124,6 +126,9 @@ EXC_VIRT_NONE(0x4100, 0x4200) · 1 unmodified line | ||
| 124 | 126 | |
| 125 | 127 | #ifdef CONFIG_PPC_P7_NAP |
| 126 | 128 | EXC_COMMON_BEGIN(system_reset_idle_common) |
| 129 | +BEGIN_FTR_SECTION | |
| 130 | + GET_PACA(r13) /* Restore HSPRG0 to get the winkle bit in r13 */ | |
| 131 | +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) | |
| 127 | 132 | bl pnv_restore_hyp_resource |
| 128 | 133 | |
| 129 | 134 | li r0,PNV_THREAD_RUNNING |
| @@ -169,7 +174,7 @@ EXC_REAL_BEGIN(machine_check, 0x200, 0x300) · 39 unmodified lines | ||
| 169 | 174 | SET_SCRATCH0(r13) /* save r13 */ |
| 170 | 175 | /* |
| 171 | 176 | * Running native on arch 2.06 or later, we may wakeup from winkle |
| 172 | − * inside machine check. If yes, then last bit of HSPGR0 would be set | |
| 177 | + * inside machine check. If yes, then last bit of HSPRG0 would be set | |
| 173 | 178 | * to 1. Hence clear it unconditionally. |
| 174 | 179 | */ |
| 175 | 180 | GET_PACA(r13) |
| @@ -388,7 +393,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) · 212 unmodified lines | ||
| 388 | 393 | /* |
| 389 | 394 | * Go back to winkle. Please note that this thread was woken up in |
| 390 | 395 | * machine check from winkle and have not restored the per-subcore |
| 391 | − * state. Hence before going back to winkle, set last bit of HSPGR0 | |
| 396 | + * state. Hence before going back to winkle, set last bit of HSPRG0 | |
| 392 | 397 | * to 1. This will make sure that if this thread gets woken up |
| 393 | 398 | * again at reset vector 0x100 then it will get chance to restore |
| 394 | 399 | * the subcore state. |
| @@ -1215,7 +1215,7 @@ static void show_instructions(struct pt_regs *regs) · 1214 unmodified lines | ||
| 1215 | 1215 | int instr; |
| 1216 | 1216 | |
| 1217 | 1217 | if (!(i % 8)) |
| 1218 | − printk("\n"); | |
| 1218 | + pr_cont("\n"); | |
| 1219 | 1219 | |
| 1220 | 1220 | #if !defined(CONFIG_BOOKE) |
| 1221 | 1221 | /* If executing with the IMMU off, adjust pc rather |
| @@ -1227,18 +1227,18 @@ static void show_instructions(struct pt_regs *regs) · 5 unmodified lines | ||
| 1227 | 1227 | |
| 1228 | 1228 | if (!__kernel_text_address(pc) || |
| 1229 | 1229 | probe_kernel_address((unsigned int __user *)pc, instr)) { |
| 1230 | − printk(KERN_CONT "XXXXXXXX "); | |
| 1230 | + pr_cont("XXXXXXXX "); | |
| 1231 | 1231 | } else { |
| 1232 | 1232 | if (regs->nip == pc) |
| 1233 | − printk(KERN_CONT "<%08x> ", instr); | |
| 1233 | + pr_cont("<%08x> ", instr); | |
| 1234 | 1234 | else |
| 1235 | − printk(KERN_CONT "%08x ", instr); | |
| 1235 | + pr_cont("%08x ", instr); | |
| 1236 | 1236 | } |
| 1237 | 1237 | |
| 1238 | 1238 | pc += sizeof(int); |
| 1239 | 1239 | } |
| 1240 | 1240 | |
| 1241 | − printk("\n"); | |
| 1241 | + pr_cont("\n"); | |
| 1242 | 1242 | } |
| 1243 | 1243 | |
| 1244 | 1244 | struct regbit { |
| @@ -1282,7 +1282,7 @@ static void print_bits(unsigned long val, struct regbit *bits, const char *sep) · 37 unmodified lines | ||
| 1282 | 1282 | |
| 1283 | 1283 | for (; bits->bit; ++bits) |
| 1284 | 1284 | if (val & bits->bit) { |
| 1285 | − printk("%s%s", s, bits->name); | |
| 1285 | + pr_cont("%s%s", s, bits->name); | |
| 1286 | 1286 | s = sep; |
| 1287 | 1287 | } |
| 1288 | 1288 | } |
| @@ -1305,9 +1305,9 @@ static void print_tm_bits(unsigned long val) · 16 unmodified lines | ||
| 1305 | 1305 | * T: Transactional (bit 34) |
| 1306 | 1306 | */ |
| 1307 | 1307 | if (val & (MSR_TM | MSR_TS_S | MSR_TS_T)) { |
| 1308 | − printk(",TM["); | |
| 1308 | + pr_cont(",TM["); | |
| 1309 | 1309 | print_bits(val, msr_tm_bits, ""); |
| 1310 | − printk("]"); | |
| 1310 | + pr_cont("]"); | |
| 1311 | 1311 | } |
| 1312 | 1312 | } |
| 1313 | 1313 | #else |
| @@ -1316,10 +1316,10 @@ static void print_tm_bits(unsigned long val) {} · 2 unmodified lines | ||
| 1316 | 1316 | |
| 1317 | 1317 | static void print_msr_bits(unsigned long val) |
| 1318 | 1318 | { |
| 1319 | − printk("<"); | |
| 1319 | + pr_cont("<"); | |
| 1320 | 1320 | print_bits(val, msr_bits, ","); |
| 1321 | 1321 | print_tm_bits(val); |
| 1322 | − printk(">"); | |
| 1322 | + pr_cont(">"); | |
| 1323 | 1323 | } |
| 1324 | 1324 | |
| 1325 | 1325 | #ifdef CONFIG_PPC64 |
| @@ -1347,29 +1347,29 @@ void show_regs(struct pt_regs * regs) · 21 unmodified lines | ||
| 1347 | 1347 | printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); |
| 1348 | 1348 | trap = TRAP(regs); |
| 1349 | 1349 | if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) |
| 1350 | − printk("CFAR: "REG" ", regs->orig_gpr3); | |
| 1350 | + pr_cont("CFAR: "REG" ", regs->orig_gpr3); | |
| 1351 | 1351 | if (trap == 0x200 || trap == 0x300 || trap == 0x600) |
| 1352 | 1352 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) |
| 1353 | − printk("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr); | |
| 1353 | + pr_cont("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr); | |
| 1354 | 1354 | #else |
| 1355 | − printk("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr); | |
| 1355 | + pr_cont("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr); | |
| 1356 | 1356 | #endif |
| 1357 | 1357 | #ifdef CONFIG_PPC64 |
| 1358 | − printk("SOFTE: %ld ", regs->softe); | |
| 1358 | + pr_cont("SOFTE: %ld ", regs->softe); | |
| 1359 | 1359 | #endif |
| 1360 | 1360 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
| 1361 | 1361 | if (MSR_TM_ACTIVE(regs->msr)) |
| 1362 | − printk("\nPACATMSCRATCH: %016llx ", get_paca()->tm_scratch); | |
| 1362 | + pr_cont("\nPACATMSCRATCH: %016llx ", get_paca()->tm_scratch); | |
| 1363 | 1363 | #endif |
| 1364 | 1364 | |
| 1365 | 1365 | for (i = 0; i < 32; i++) { |
| 1366 | 1366 | if ((i % REGS_PER_LINE) == 0) |
| 1367 | − printk("\nGPR%02d: ", i); | |
| 1368 | − printk(REG " ", regs->gpr[i]); | |
| 1367 | + pr_cont("\nGPR%02d: ", i); | |
| 1368 | + pr_cont(REG " ", regs->gpr[i]); | |
| 1369 | 1369 | if (i == LAST_VOLATILE && !FULL_REGS(regs)) |
| 1370 | 1370 | break; |
| 1371 | 1371 | } |
| 1372 | − printk("\n"); | |
| 1372 | + pr_cont("\n"); | |
| 1373 | 1373 | #ifdef CONFIG_KALLSYMS |
| 1374 | 1374 | /* |
| 1375 | 1375 | * Lookup NIP late so we have the best change of getting the |
| @@ -1900,14 +1900,14 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) · 524 unmodified lines | ||
| 1900 | 1900 | printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); |
| 1901 | 1901 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 1902 | 1902 | if ((ip == rth) && curr_frame >= 0) { |
| 1903 | − printk(" (%pS)", | |
| 1903 | + pr_cont(" (%pS)", | |
| 1904 | 1904 | (void *)current->ret_stack[curr_frame].ret); |
| 1905 | 1905 | curr_frame--; |
| 1906 | 1906 | } |
| 1907 | 1907 | #endif |
| 1908 | 1908 | if (firstframe) |
| 1909 | − printk(" (unreliable)"); | |
| 1910 | − printk("\n"); | |
| 1909 | + pr_cont(" (unreliable)"); | |
| 1910 | + pr_cont("\n"); | |
| 1911 | 1911 | } |
| 1912 | 1912 | firstframe = 0; |
| 1913 | 1913 | |
| @@ -226,17 +226,25 @@ static void __init configure_exceptions(void) · 225 unmodified lines | ||
| 226 | 226 | if (firmware_has_feature(FW_FEATURE_OPAL)) |
| 227 | 227 | opal_configure_cores(); |
| 228 | 228 | |
| 229 | − /* Enable AIL if supported, and we are in hypervisor mode */ | |
| 230 | − if (early_cpu_has_feature(CPU_FTR_HVMODE) && | |
| 231 | − early_cpu_has_feature(CPU_FTR_ARCH_207S)) { | |
| 232 | − unsigned long lpcr = mfspr(SPRN_LPCR); | |
| 233 | − mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); | |
| 234 | − } | |
| 229 | + /* AIL on native is done in cpu_ready_for_interrupts() */ | |
| 235 | 230 | } |
| 236 | 231 | } |
| 237 | 232 | |
| 238 | 233 | static void cpu_ready_for_interrupts(void) |
| 239 | 234 | { |
| 235 | + /* | |
| 236 | + * Enable AIL if supported, and we are in hypervisor mode. This | |
| 237 | + * is called once for every processor. | |
| 238 | + * | |
| 239 | + * If we are not in hypervisor mode the job is done once for | |
| 240 | + * the whole partition in configure_exceptions(). | |
| 241 | + */ | |
| 242 | + if (early_cpu_has_feature(CPU_FTR_HVMODE) && | |
| 243 | + early_cpu_has_feature(CPU_FTR_ARCH_207S)) { | |
| 244 | + unsigned long lpcr = mfspr(SPRN_LPCR); | |
| 245 | + mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); | |
| 246 | + } | |
| 247 | + | |
| 240 | 248 | /* Set IR and DR in PACA MSR */ |
| 241 | 249 | get_paca()->kernel_msr = MSR_KERNEL; |
| 242 | 250 | } |
| @@ -1029,6 +1029,10 @@ void hash__early_init_mmu_secondary(void) · 1028 unmodified lines | ||
| 1029 | 1029 | { |
| 1030 | 1030 | /* Initialize hash table for that CPU */ |
| 1031 | 1031 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { |
| 1032 | + | |
| 1033 | + if (cpu_has_feature(CPU_FTR_POWER9_DD1)) | |
| 1034 | + update_hid_for_hash(); | |
| 1035 | + | |
| 1032 | 1036 | if (!cpu_has_feature(CPU_FTR_ARCH_300)) |
| 1033 | 1037 | mtspr(SPRN_SDR1, _SDR1); |
| 1034 | 1038 | else |
| @@ -388,6 +388,10 @@ void radix__early_init_mmu_secondary(void) · 387 unmodified lines | ||
| 388 | 388 | * update partition table control register and UPRT |
| 389 | 389 | */ |
| 390 | 390 | if (!firmware_has_feature(FW_FEATURE_LPAR)) { |
| 391 | + | |
| 392 | + if (cpu_has_feature(CPU_FTR_POWER9_DD1)) | |
| 393 | + update_hid_for_radix(); | |
| 394 | + | |
| 391 | 395 | lpcr = mfspr(SPRN_LPCR); |
| 392 | 396 | mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR); |
| 393 | 397 | |
| @@ -50,6 +50,8 @@ static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) · 49 unmodified lines | ||
| 50 | 50 | for (set = 0; set < POWER9_TLB_SETS_RADIX ; set++) { |
| 51 | 51 | __tlbiel_pid(pid, set, ric); |
| 52 | 52 | } |
| 53 | + if (cpu_has_feature(CPU_FTR_POWER9_DD1)) | |
| 54 | + asm volatile(PPC_INVALIDATE_ERAT : : :"memory"); | |
| 53 | 55 | return; |
| 54 | 56 | } |
| 55 | 57 | |
| @@ -83,6 +85,8 @@ static inline void _tlbiel_va(unsigned long va, unsigned long pid, · 27 unmodified lines | ||
| 83 | 85 | asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) |
| 84 | 86 | : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); |
| 85 | 87 | asm volatile("ptesync": : :"memory"); |
| 88 | + if (cpu_has_feature(CPU_FTR_POWER9_DD1)) | |
| 89 | + asm volatile(PPC_INVALIDATE_ERAT : : :"memory"); | |
| 86 | 90 | } |
| 87 | 91 | |
| 88 | 92 | static inline void _tlbie_va(unsigned long va, unsigned long pid, |
| @@ -62,9 +62,11 @@ SECTIONS · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | . = ALIGN(PAGE_SIZE); |
| 64 | 64 | __start_ro_after_init = .; |
| 65 | + __start_data_ro_after_init = .; | |
| 65 | 66 | .data..ro_after_init : { |
| 66 | 67 | *(.data..ro_after_init) |
| 67 | 68 | } |
| 69 | + __end_data_ro_after_init = .; | |
| 68 | 70 | EXCEPTION_TABLE(16) |
| 69 | 71 | . = ALIGN(PAGE_SIZE); |
| 70 | 72 | __end_ro_after_init = .; |
| @@ -423,7 +423,7 @@ static int __s390_dma_map_sg(struct device *dev, struct scatterlist *sg, · 422 unmodified lines | ||
| 423 | 423 | dma_addr_t dma_addr_base, dma_addr; |
| 424 | 424 | int flags = ZPCI_PTE_VALID; |
| 425 | 425 | struct scatterlist *s; |
| 426 | − unsigned long pa; | |
| 426 | + unsigned long pa = 0; | |
| 427 | 427 | int ret; |
| 428 | 428 | |
| 429 | 429 | size = PAGE_ALIGN(size); |
| @@ -43,6 +43,7 @@ config SPARC · 42 unmodified lines | ||
| 43 | 43 | select ARCH_HAS_SG_CHAIN |
| 44 | 44 | select CPU_NO_EFFICIENT_FFS |
| 45 | 45 | select HAVE_ARCH_HARDENED_USERCOPY |
| 46 | + select PROVE_LOCKING_SMALL if PROVE_LOCKING | |
| 46 | 47 | |
| 47 | 48 | config SPARC32 |
| 48 | 49 | def_bool !64BIT |
| @@ -89,6 +90,14 @@ config ARCH_DEFCONFIG · 40 unmodified lines | ||
| 89 | 90 | config ARCH_PROC_KCORE_TEXT |
| 90 | 91 | def_bool y |
| 91 | 92 | |
| 93 | +config ARCH_ATU | |
| 94 | + bool | |
| 95 | + default y if SPARC64 | |
| 96 | + | |
| 97 | +config ARCH_DMA_ADDR_T_64BIT | |
| 98 | + bool | |
| 99 | + default y if ARCH_ATU | |
| 100 | + | |
| 92 | 101 | config IOMMU_HELPER |
| 93 | 102 | bool |
| 94 | 103 | default y if SPARC64 |
| @@ -304,6 +313,20 @@ config ARCH_SPARSEMEM_ENABLE · 209 unmodified lines | ||
| 304 | 313 | config ARCH_SPARSEMEM_DEFAULT |
| 305 | 314 | def_bool y if SPARC64 |
| 306 | 315 | |
| 316 | +config FORCE_MAX_ZONEORDER | |
| 317 | + int "Maximum zone order" | |
| 318 | + default "13" | |
| 319 | + help | |
| 320 | + The kernel memory allocator divides physically contiguous memory | |
| 321 | + blocks into "zones", where each zone is a power of two number of | |
| 322 | + pages. This option selects the largest power of two that the kernel | |
| 323 | + keeps in the memory allocator. If you need to allocate very large | |
| 324 | + blocks of physically contiguous memory, then you may need to | |
| 325 | + increase this value. | |
| 326 | + | |
| 327 | + This config option is actually maximum order plus one. For example, | |
| 328 | + a value of 13 means that the largest free memory block is 2^12 pages. | |
| 329 | + | |
| 307 | 330 | source "mm/Kconfig" |
| 308 | 331 | |
| 309 | 332 | if SPARC64 |
| @@ -2335,6 +2335,348 @@ unsigned long sun4v_vintr_set_target(unsigned long dev_handle, · 2334 unmodified lines | ||
| 2335 | 2335 | */ |
| 2336 | 2336 | #define HV_FAST_PCI_MSG_SETVALID 0xd3 |
| 2337 | 2337 | |
| 2338 | +/* PCI IOMMU v2 definitions and services | |
| 2339 | + * | |
| 2340 | + * While the PCI IO definitions above is valid IOMMU v2 adds new PCI IO | |
| 2341 | + * definitions and services. | |
| 2342 | + * | |
| 2343 | + * CTE Clump Table Entry. First level table entry in the ATU. | |
| 2344 | + * | |
| 2345 | + * pci_device_list | |
| 2346 | + * A 32-bit aligned list of pci_devices. | |
| 2347 | + * | |
| 2348 | + * pci_device_listp | |
| 2349 | + * real address of a pci_device_list. 32-bit aligned. | |
| 2350 | + * | |
| 2351 | + * iotte IOMMU translation table entry. | |
| 2352 | + * | |
| 2353 | + * iotte_attributes | |
| 2354 | + * IO Attributes for IOMMU v2 mappings. In addition to | |
| 2355 | + * read, write IOMMU v2 supports relax ordering | |
| 2356 | + * | |
| 2357 | + * io_page_list A 64-bit aligned list of real addresses. Each real | |
| 2358 | + * address in an io_page_list must be properly aligned | |
| 2359 | + * to the pagesize of the given IOTSB. | |
| 2360 | + * | |
| 2361 | + * io_page_list_p Real address of an io_page_list, 64-bit aligned. | |
| 2362 | + * | |
| 2363 | + * IOTSB IO Translation Storage Buffer. An aligned table of | |
| 2364 | + * IOTTEs. Each IOTSB has a pagesize, table size, and | |
| 2365 | + * virtual address associated with it that must match | |
| 2366 | + * a pagesize and table size supported by the un-derlying | |
| 2367 | + * hardware implementation. The alignment requirements | |
| 2368 | + * for an IOTSB depend on the pagesize used for that IOTSB. | |
| 2369 | + * Each IOTTE in an IOTSB maps one pagesize-sized page. | |
| 2370 | + * The size of the IOTSB dictates how large of a virtual | |
| 2371 | + * address space the IOTSB is capable of mapping. | |
| 2372 | + * | |
| 2373 | + * iotsb_handle An opaque identifier for an IOTSB. A devhandle plus | |
| 2374 | + * iotsb_handle represents a binding of an IOTSB to a | |
| 2375 | + * PCI root complex. | |
| 2376 | + * | |
| 2377 | + * iotsb_index Zero-based IOTTE number within an IOTSB. | |
| 2378 | + */ | |
| 2379 | + | |
| 2380 | +/* The index_count argument consists of two fields: | |
| 2381 | + * bits 63:48 #iottes and bits 47:0 iotsb_index | |
| 2382 | + */ | |
| 2383 | +#define HV_PCI_IOTSB_INDEX_COUNT(__iottes, __iotsb_index) \ | |
| 2384 | + (((u64)(__iottes) << 48UL) | ((u64)(__iotsb_index))) | |
| 2385 | + | |
| 2386 | +/* pci_iotsb_conf() | |
| 2387 | + * TRAP: HV_FAST_TRAP | |
| 2388 | + * FUNCTION: HV_FAST_PCI_IOTSB_CONF | |
| 2389 | + * ARG0: devhandle | |
| 2390 | + * ARG1: r_addr | |
| 2391 | + * ARG2: size | |
| 2392 | + * ARG3: pagesize | |
| 2393 | + * ARG4: iova | |
| 2394 | + * RET0: status | |
| 2395 | + * RET1: iotsb_handle | |
| 2396 | + * ERRORS: EINVAL Invalid devhandle, size, iova, or pagesize | |
| 2397 | + * EBADALIGN r_addr is not properly aligned | |
| 2398 | + * ENORADDR r_addr is not a valid real address | |
| 2399 | + * ETOOMANY No further IOTSBs may be configured | |
| 2400 | + * EBUSY Duplicate devhandle, raddir, iova combination | |
| 2401 | + * | |
| 2402 | + * Create an IOTSB suitable for the PCI root complex identified by devhandle, | |
| 2403 | + * for the DMA virtual address defined by the argument iova. | |
| 2404 | + * | |
| 2405 | + * r_addr is the properly aligned base address of the IOTSB and size is the | |
| 2406 | + * IOTSB (table) size in bytes.The IOTSB is required to be zeroed prior to | |
| 2407 | + * being configured. If it contains any values other than zeros then the | |
| 2408 | + * behavior is undefined. | |
| 2409 | + * | |
| 2410 | + * pagesize is the size of each page in the IOTSB. Note that the combination of | |
| 2411 | + * size (table size) and pagesize must be valid. | |
| 2412 | + * | |
| 2413 | + * virt is the DMA virtual address this IOTSB will map. | |
| 2414 | + * | |
| 2415 | + * If successful, the opaque 64-bit handle iotsb_handle is returned in ret1. | |
| 2416 | + * Once configured, privileged access to the IOTSB memory is prohibited and | |
| 2417 | + * creates undefined behavior. The only permitted access is indirect via these | |
| 2418 | + * services. | |
| 2419 | + */ | |
| 2420 | +#define HV_FAST_PCI_IOTSB_CONF 0x190 | |
| 2421 | + | |
| 2422 | +/* pci_iotsb_info() | |
| 2423 | + * TRAP: HV_FAST_TRAP | |
| 2424 | + * FUNCTION: HV_FAST_PCI_IOTSB_INFO | |
| 2425 | + * ARG0: devhandle | |
| 2426 | + * ARG1: iotsb_handle | |
| 2427 | + * RET0: status | |
| 2428 | + * RET1: r_addr | |
| 2429 | + * RET2: size | |
| 2430 | + * RET3: pagesize | |
| 2431 | + * RET4: iova | |
| 2432 | + * RET5: #bound | |
| 2433 | + * ERRORS: EINVAL Invalid devhandle or iotsb_handle | |
| 2434 | + * | |
| 2435 | + * This service returns configuration information about an IOTSB previously | |
| 2436 | + * created with pci_iotsb_conf. | |
| 2437 | + * | |
| 2438 | + * iotsb_handle value 0 may be used with this service to inquire about the | |
| 2439 | + * legacy IOTSB that may or may not exist. If the service succeeds, the return | |
| 2440 | + * values describe the legacy IOTSB and I/O virtual addresses mapped by that | |
| 2441 | + * table. However, the table base address r_addr may contain the value -1 which | |
| 2442 | + * indicates a memory range that cannot be accessed or be reclaimed. | |
| 2443 | + * | |
| 2444 | + * The return value #bound contains the number of PCI devices that iotsb_handle | |
| 2445 | + * is currently bound to. | |
| 2446 | + */ | |
| 2447 | +#define HV_FAST_PCI_IOTSB_INFO 0x191 | |
| 2448 | + | |
| 2449 | +/* pci_iotsb_unconf() | |
| 2450 | + * TRAP: HV_FAST_TRAP | |
| 2451 | + * FUNCTION: HV_FAST_PCI_IOTSB_UNCONF | |
| 2452 | + * ARG0: devhandle | |
| 2453 | + * ARG1: iotsb_handle | |
| 2454 | + * RET0: status | |
| 2455 | + * ERRORS: EINVAL Invalid devhandle or iotsb_handle | |
| 2456 | + * EBUSY The IOTSB is bound and may not be unconfigured | |
| 2457 | + * | |
| 2458 | + * This service unconfigures the IOTSB identified by the devhandle and | |
| 2459 | + * iotsb_handle arguments, previously created with pci_iotsb_conf. | |
| 2460 | + * The IOTSB must not be currently bound to any device or the service will fail | |
| 2461 | + * | |
| 2462 | + * If the call succeeds, iotsb_handle is no longer valid. | |
| 2463 | + */ | |
| 2464 | +#define HV_FAST_PCI_IOTSB_UNCONF 0x192 | |
| 2465 | + | |
| 2466 | +/* pci_iotsb_bind() | |
| 2467 | + * TRAP: HV_FAST_TRAP | |
| 2468 | + * FUNCTION: HV_FAST_PCI_IOTSB_BIND | |
| 2469 | + * ARG0: devhandle | |
| 2470 | + * ARG1: iotsb_handle | |
| 2471 | + * ARG2: pci_device | |
| 2472 | + * RET0: status | |
| 2473 | + * ERRORS: EINVAL Invalid devhandle, iotsb_handle, or pci_device | |
| 2474 | + * EBUSY A PCI function is already bound to an IOTSB at the same | |
| 2475 | + * address range as specified by devhandle, iotsb_handle. | |
| 2476 | + * | |
| 2477 | + * This service binds the PCI function specified by the argument pci_device to | |
| 2478 | + * the IOTSB specified by the arguments devhandle and iotsb_handle. | |
| 2479 | + * | |
| 2480 | + * The PCI device function is bound to the specified IOTSB with the IOVA range | |
| 2481 | + * specified when the IOTSB was configured via pci_iotsb_conf. If the function | |
| 2482 | + * is already bound then it is unbound first. | |
| 2483 | + */ | |
| 2484 | +#define HV_FAST_PCI_IOTSB_BIND 0x193 | |
| 2485 | + | |
| 2486 | +/* pci_iotsb_unbind() | |
| 2487 | + * TRAP: HV_FAST_TRAP | |
| 2488 | + * FUNCTION: HV_FAST_PCI_IOTSB_UNBIND | |
| 2489 | + * ARG0: devhandle | |
| 2490 | + * ARG1: iotsb_handle | |
| 2491 | + * ARG2: pci_device | |
| 2492 | + * RET0: status | |
| 2493 | + * ERRORS: EINVAL Invalid devhandle, iotsb_handle, or pci_device | |
| 2494 | + * ENOMAP The PCI function was not bound to the specified IOTSB | |
| 2495 | + * | |
| 2496 | + * This service unbinds the PCI device specified by the argument pci_device | |
| 2497 | + * from the IOTSB identified * by the arguments devhandle and iotsb_handle. | |
| 2498 | + * | |
| 2499 | + * If the PCI device is not bound to the specified IOTSB then this service will | |
| 2500 | + * fail with status ENOMAP | |
| 2501 | + */ | |
| 2502 | +#define HV_FAST_PCI_IOTSB_UNBIND 0x194 | |
| 2503 | + | |
| 2504 | +/* pci_iotsb_get_binding() | |
| 2505 | + * TRAP: HV_FAST_TRAP | |
| 2506 | + * FUNCTION: HV_FAST_PCI_IOTSB_GET_BINDING | |
| 2507 | + * ARG0: devhandle | |
| 2508 | + * ARG1: iotsb_handle | |
| 2509 | + * ARG2: iova | |
| 2510 | + * RET0: status | |
| 2511 | + * RET1: iotsb_handle | |
| 2512 | + * ERRORS: EINVAL Invalid devhandle, pci_device, or iova | |
| 2513 | + * ENOMAP The PCI function is not bound to an IOTSB at iova | |
| 2514 | + * | |
| 2515 | + * This service returns the IOTSB binding, iotsb_handle, for a given pci_device | |
| 2516 | + * and DMA virtual address, iova. | |
| 2517 | + * | |
| 2518 | + * iova must be the base address of a DMA virtual address range as defined by | |
| 2519 | + * the iommu-address-ranges property in the root complex device node defined | |
| 2520 | + * by the argument devhandle. | |
| 2521 | + */ | |
| 2522 | +#define HV_FAST_PCI_IOTSB_GET_BINDING 0x195 | |
| 2523 | + | |
| 2524 | +/* pci_iotsb_map() | |
| 2525 | + * TRAP: HV_FAST_TRAP | |
| 2526 | + * FUNCTION: HV_FAST_PCI_IOTSB_MAP | |
| 2527 | + * ARG0: devhandle | |
| 2528 | + * ARG1: iotsb_handle | |
| 2529 | + * ARG2: index_count | |
| 2530 | + * ARG3: iotte_attributes | |
| 2531 | + * ARG4: io_page_list_p | |
| 2532 | + * RET0: status | |
| 2533 | + * RET1: #mapped | |
| 2534 | + * ERRORS: EINVAL Invalid devhandle, iotsb_handle, #iottes, | |
| 2535 | + * iotsb_index or iotte_attributes | |
| 2536 | + * EBADALIGN Improperly aligned io_page_list_p or I/O page | |
| 2537 | + * address in the I/O page list. | |
| 2538 | + * ENORADDR Invalid io_page_list_p or I/O page address in | |
| 2539 | + * the I/O page list. | |
| 2540 | + * | |
| 2541 | + * This service creates and flushes mappings in the IOTSB defined by the | |
| 2542 | + * arguments devhandle, iotsb. | |
| 2543 | + * | |
| 2544 | + * The index_count argument consists of two fields. Bits 63:48 contain #iotte | |
| 2545 | + * and bits 47:0 contain iotsb_index | |
| 2546 | + * | |
| 2547 | + * The first mapping is created in the IOTSB index specified by iotsb_index. | |
| 2548 | + * Subsequent mappings are created at iotsb_index+1 and so on. | |
| 2549 | + * | |
| 2550 | + * The attributes of each mapping are defined by the argument iotte_attributes. | |
| 2551 | + * | |
| 2552 | + * The io_page_list_p specifies the real address of the 64-bit-aligned list of | |
| 2553 | + * #iottes I/O page addresses. Each page address must be a properly aligned | |
| 2554 | + * real address of a page to be mapped in the IOTSB. The first entry in the I/O | |
| 2555 | + * page list contains the real address of the first page, the 2nd entry for the | |
| 2556 | + * 2nd page, and so on. | |
| 2557 | + * | |
| 2558 | + * #iottes must be greater than zero. | |
| 2559 | + * | |
| 2560 | + * The return value #mapped is the actual number of mappings created, which may | |
| 2561 | + * be less than or equal to the argument #iottes. If the function returns | |
| 2562 | + * successfully with a #mapped value less than the requested #iottes then the | |
| 2563 | + * caller should continue to invoke the service with updated iotsb_index, | |
| 2564 | + * #iottes, and io_page_list_p arguments until all pages are mapped. | |
| 2565 | + * | |
| 2566 | + * This service must not be used to demap a mapping. In other words, all | |
| 2567 | + * mappings must be valid and have one or both of the RW attribute bits set. | |
| 2568 | + * | |
| 2569 | + * Note: | |
| 2570 | + * It is implementation-defined whether I/O page real address validity checking | |
| 2571 | + * is done at time mappings are established or deferred until they are | |
| 2572 | + * accessed. | |
| 2573 | + */ | |
| 2574 | +#define HV_FAST_PCI_IOTSB_MAP 0x196 | |
| 2575 | + | |
| 2576 | +/* pci_iotsb_map_one() | |
| 2577 | + * TRAP: HV_FAST_TRAP | |
| 2578 | + * FUNCTION: HV_FAST_PCI_IOTSB_MAP_ONE | |
| 2579 | + * ARG0: devhandle | |
| 2580 | + * ARG1: iotsb_handle | |
| 2581 | + * ARG2: iotsb_index | |
| 2582 | + * ARG3: iotte_attributes | |
| 2583 | + * ARG4: r_addr | |
| 2584 | + * RET0: status | |
| 2585 | + * ERRORS: EINVAL Invalid devhandle,iotsb_handle, iotsb_index | |
| 2586 | + * or iotte_attributes | |
| 2587 | + * EBADALIGN Improperly aligned r_addr | |
| 2588 | + * ENORADDR Invalid r_addr | |
| 2589 | + * | |
| 2590 | + * This service creates and flushes a single mapping in the IOTSB defined by the | |
| 2591 | + * arguments devhandle, iotsb. | |
| 2592 | + * | |
| 2593 | + * The mapping for the page at r_addr is created at the IOTSB index specified by | |
| 2594 | + * iotsb_index with the attributes iotte_attributes. | |
| 2595 | + * | |
| 2596 | + * This service must not be used to demap a mapping. In other words, the mapping | |
| 2597 | + * must be valid and have one or both of the RW attribute bits set. | |
| 2598 | + * | |
| 2599 | + * Note: | |
| 2600 | + * It is implementation-defined whether I/O page real address validity checking | |
| 2601 | + * is done at time mappings are established or deferred until they are | |
| 2602 | + * accessed. | |
| 2603 | + */ | |
| 2604 | +#define HV_FAST_PCI_IOTSB_MAP_ONE 0x197 | |
| 2605 | + | |
| 2606 | +/* pci_iotsb_demap() | |
| 2607 | + * TRAP: HV_FAST_TRAP | |
| 2608 | + * FUNCTION: HV_FAST_PCI_IOTSB_DEMAP | |
| 2609 | + * ARG0: devhandle | |
| 2610 | + * ARG1: iotsb_handle | |
| 2611 | + * ARG2: iotsb_index | |
| 2612 | + * ARG3: #iottes | |
| 2613 | + * RET0: status | |
| 2614 | + * RET1: #unmapped | |
| 2615 | + * ERRORS: EINVAL Invalid devhandle, iotsb_handle, iotsb_index or #iottes | |
| 2616 | + * | |
| 2617 | + * This service unmaps and flushes up to #iottes mappings starting at index | |
| 2618 | + * iotsb_index from the IOTSB defined by the arguments devhandle, iotsb. | |
| 2619 | + * | |
| 2620 | + * #iottes must be greater than zero. | |
| 2621 | + * | |
| 2622 | + * The actual number of IOTTEs unmapped is returned in #unmapped and may be less | |
| 2623 | + * than or equal to the requested number of IOTTEs, #iottes. | |
| 2624 | + * | |
| 2625 | + * If #unmapped is less than #iottes, the caller should continue to invoke this | |
| 2626 | + * service with updated iotsb_index and #iottes arguments until all pages are | |
| 2627 | + * demapped. | |
| 2628 | + */ | |
| 2629 | +#define HV_FAST_PCI_IOTSB_DEMAP 0x198 | |
| 2630 | + | |
| 2631 | +/* pci_iotsb_getmap() | |
| 2632 | + * TRAP: HV_FAST_TRAP | |
| 2633 | + * FUNCTION: HV_FAST_PCI_IOTSB_GETMAP | |
| 2634 | + * ARG0: devhandle | |
| 2635 | + * ARG1: iotsb_handle | |
| 2636 | + * ARG2: iotsb_index | |
| 2637 | + * RET0: status | |
| 2638 | + * RET1: r_addr | |
| 2639 | + * RET2: iotte_attributes | |
| 2640 | + * ERRORS: EINVAL Invalid devhandle, iotsb_handle, or iotsb_index | |
| 2641 | + * ENOMAP No mapping was found | |
| 2642 | + * | |
| 2643 | + * This service returns the mapping specified by index iotsb_index from the | |
| 2644 | + * IOTSB defined by the arguments devhandle, iotsb. | |
| 2645 | + * | |
| 2646 | + * Upon success, the real address of the mapping shall be returned in | |
| 2647 | + * r_addr and thethe IOTTE mapping attributes shall be returned in | |
| 2648 | + * iotte_attributes. | |
| 2649 | + * | |
| 2650 | + * The return value iotte_attributes may not include optional features used in | |
| 2651 | + * the call to create the mapping. | |
| 2652 | + */ | |
| 2653 | +#define HV_FAST_PCI_IOTSB_GETMAP 0x199 | |
| 2654 | + | |
| 2655 | +/* pci_iotsb_sync_mappings() | |
| 2656 | + * TRAP: HV_FAST_TRAP | |
| 2657 | + * FUNCTION: HV_FAST_PCI_IOTSB_SYNC_MAPPINGS | |
| 2658 | + * ARG0: devhandle | |
| 2659 | + * ARG1: iotsb_handle | |
| 2660 | + * ARG2: iotsb_index | |
| 2661 | + * ARG3: #iottes | |
| 2662 | + * RET0: status | |
| 2663 | + * RET1: #synced | |
| 2664 | + * ERROS: EINVAL Invalid devhandle, iotsb_handle, iotsb_index, or #iottes | |
| 2665 | + * | |
| 2666 | + * This service synchronizes #iottes mappings starting at index iotsb_index in | |
| 2667 | + * the IOTSB defined by the arguments devhandle, iotsb. | |
| 2668 | + * | |
| 2669 | + * #iottes must be greater than zero. | |
| 2670 | + * | |
| 2671 | + * The actual number of IOTTEs synchronized is returned in #synced, which may | |
| 2672 | + * be less than or equal to the requested number, #iottes. | |
| 2673 | + * | |
| 2674 | + * Upon a successful return, #synced is less than #iottes, the caller should | |
| 2675 | + * continue to invoke this service with updated iotsb_index and #iottes | |
| 2676 | + * arguments until all pages are synchronized. | |
| 2677 | + */ | |
| 2678 | +#define HV_FAST_PCI_IOTSB_SYNC_MAPPINGS 0x19a | |
| 2679 | + | |
| 2338 | 2680 | /* Logical Domain Channel services. */ |
| 2339 | 2681 | |
| 2340 | 2682 | #define LDC_CHANNEL_DOWN 0 |
| @@ -2993,6 +3335,7 @@ unsigned long sun4v_m7_set_perfreg(unsigned long reg_num, · 652 unmodified lines | ||
| 2993 | 3335 | #define HV_GRP_SDIO 0x0108 |
| 2994 | 3336 | #define HV_GRP_SDIO_ERR 0x0109 |
| 2995 | 3337 | #define HV_GRP_REBOOT_DATA 0x0110 |
| 3338 | +#define HV_GRP_ATU 0x0111 | |
| 2996 | 3339 | #define HV_GRP_M7_PERF 0x0114 |
| 2997 | 3340 | #define HV_GRP_NIAG_PERF 0x0200 |
| 2998 | 3341 | #define HV_GRP_FIRE_PERF 0x0201 |
| @@ -24,8 +24,36 @@ struct iommu_arena { · 23 unmodified lines | ||
| 24 | 24 | unsigned int limit; |
| 25 | 25 | }; |
| 26 | 26 | |
| 27 | +#define ATU_64_SPACE_SIZE 0x800000000 /* 32G */ | |
| 28 | + | |
| 29 | +/* Data structures for SPARC ATU architecture */ | |
| 30 | +struct atu_iotsb { | |
| 31 | + void *table; /* IOTSB table base virtual addr*/ | |
| 32 | + u64 ra; /* IOTSB table real addr */ | |
| 33 | + u64 dvma_size; /* ranges[3].size or OS slected 32G size */ | |
| 34 | + u64 dvma_base; /* ranges[3].base */ | |
| 35 | + u64 table_size; /* IOTSB table size */ | |
| 36 | + u64 page_size; /* IO PAGE size for IOTSB */ | |
| 37 | + u32 iotsb_num; /* tsbnum is same as iotsb_handle */ | |
| 38 | +}; | |
| 39 | + | |
| 40 | +struct atu_ranges { | |
| 41 | + u64 base; | |
| 42 | + u64 size; | |
| 43 | +}; | |
| 44 | + | |
| 45 | +struct atu { | |
| 46 | + struct atu_ranges *ranges; | |
| 47 | + struct atu_iotsb *iotsb; | |
| 48 | + struct iommu_map_table tbl; | |
| 49 | + u64 base; | |
| 50 | + u64 size; | |
| 51 | + u64 dma_addr_mask; | |
| 52 | +}; | |
| 53 | + | |
| 27 | 54 | struct iommu { |
| 28 | 55 | struct iommu_map_table tbl; |
| 56 | + struct atu *atu; | |
| 29 | 57 | spinlock_t lock; |
| 30 | 58 | u32 dma_addr_mask; |
| 31 | 59 | iopte_t *page_table; |
| @@ -39,6 +39,7 @@ static struct api_info api_table[] = { · 38 unmodified lines | ||
| 39 | 39 | { .group = HV_GRP_SDIO, }, |
| 40 | 40 | { .group = HV_GRP_SDIO_ERR, }, |
| 41 | 41 | { .group = HV_GRP_REBOOT_DATA, }, |
| 42 | + { .group = HV_GRP_ATU, .flags = FLAG_PRE_API }, | |
| 42 | 43 | { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, |
| 43 | 44 | { .group = HV_GRP_FIRE_PERF, }, |
| 44 | 45 | { .group = HV_GRP_N2_CPU, }, |
| @@ -760,8 +760,12 @@ int dma_supported(struct device *dev, u64 device_mask) · 759 unmodified lines | ||
| 760 | 760 | struct iommu *iommu = dev->archdata.iommu; |
| 761 | 761 | u64 dma_addr_mask = iommu->dma_addr_mask; |
| 762 | 762 | |
| 763 | − if (device_mask >= (1UL << 32UL)) | |
| 764 | − return 0; | |
| 763 | + if (device_mask > DMA_BIT_MASK(32)) { | |
| 764 | + if (iommu->atu) | |
| 765 | + dma_addr_mask = iommu->atu->dma_addr_mask; | |
| 766 | + else | |
| 767 | + return 0; | |
| 768 | + } | |
| 765 | 769 | |
| 766 | 770 | if ((device_mask & dma_addr_mask) == dma_addr_mask) |
| 767 | 771 | return 1; |
| @@ -13,7 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <linux/scatterlist.h> |
| 14 | 14 | #include <linux/device.h> |
| 15 | 15 | #include <linux/iommu-helper.h> |
| 16 | −#include <linux/scatterlist.h> | |
| 17 | 16 | |
| 18 | 17 | #include <asm/iommu.h> |
| 19 | 18 | |
| @@ -44,6 +44,9 @@ static struct vpci_version vpci_versions[] = { · 43 unmodified lines | ||
| 44 | 44 | { .major = 1, .minor = 1 }, |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | +static unsigned long vatu_major = 1; | |
| 48 | +static unsigned long vatu_minor = 1; | |
| 49 | + | |
| 47 | 50 | #define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) |
| 48 | 51 | |
| 49 | 52 | struct iommu_batch { |
| @@ -69,34 +72,57 @@ static inline void iommu_batch_start(struct device *dev, unsigned long prot, uns · 19 unmodified lines | ||
| 69 | 72 | } |
| 70 | 73 | |
| 71 | 74 | /* Interrupts must be disabled. */ |
| 72 | −static long iommu_batch_flush(struct iommu_batch *p) | |
| 75 | +static long iommu_batch_flush(struct iommu_batch *p, u64 mask) | |
| 73 | 76 | { |
| 74 | 77 | struct pci_pbm_info *pbm = p->dev->archdata.host_controller; |
| 78 | + u64 *pglist = p->pglist; | |
| 79 | + u64 index_count; | |
| 75 | 80 | unsigned long devhandle = pbm->devhandle; |
| 76 | 81 | unsigned long prot = p->prot; |
| 77 | 82 | unsigned long entry = p->entry; |
| 78 | − u64 *pglist = p->pglist; | |
| 79 | 83 | unsigned long npages = p->npages; |
| 84 | + unsigned long iotsb_num; | |
| 85 | + unsigned long ret; | |
| 86 | + long num; | |
| 80 | 87 | |
| 81 | 88 | /* VPCI maj=1, min=[0,1] only supports read and write */ |
| 82 | 89 | if (vpci_major < 2) |
| 83 | 90 | prot &= (HV_PCI_MAP_ATTR_READ | HV_PCI_MAP_ATTR_WRITE); |
| 84 | 91 | |
| 85 | 92 | while (npages != 0) { |
| 86 | − long num; | |
| 87 | − | |
| 88 | − num = pci_sun4v_iommu_map(devhandle, HV_PCI_TSBID(0, entry), | |
| 89 | − npages, prot, __pa(pglist)); | |
| 90 | − if (unlikely(num < 0)) { | |
| 91 | − if (printk_ratelimit()) | |
| 92 | − printk("iommu_batch_flush: IOMMU map of " | |
| 93 | − "[%08lx:%08llx:%lx:%lx:%lx] failed with " | |
| 94 | − "status %ld\n", | |
| 95 | − devhandle, HV_PCI_TSBID(0, entry), | |
| 96 | − npages, prot, __pa(pglist), num); | |
| 97 | − return -1; | |
| 93 | + if (mask <= DMA_BIT_MASK(32)) { | |
| 94 | + num = pci_sun4v_iommu_map(devhandle, | |
| 95 | + HV_PCI_TSBID(0, entry), | |
| 96 | + npages, | |
| 97 | + prot, | |
| 98 | + __pa(pglist)); | |
| 99 | + if (unlikely(num < 0)) { | |
| 100 | + pr_err_ratelimited("%s: IOMMU map of [%08lx:%08llx:%lx:%lx:%lx] failed with status %ld\n", | |
| 101 | + __func__, | |
| 102 | + devhandle, | |
| 103 | + HV_PCI_TSBID(0, entry), | |
| 104 | + npages, prot, __pa(pglist), | |
| 105 | + num); | |
| 106 | + return -1; | |
| 107 | + } | |
| 108 | + } else { | |
| 109 | + index_count = HV_PCI_IOTSB_INDEX_COUNT(npages, entry), | |
| 110 | + iotsb_num = pbm->iommu->atu->iotsb->iotsb_num; | |
| 111 | + ret = pci_sun4v_iotsb_map(devhandle, | |
| 112 | + iotsb_num, | |
| 113 | + index_count, | |
| 114 | + prot, | |
| 115 | + __pa(pglist), | |
| 116 | + &num); | |
| 117 | + if (unlikely(ret != HV_EOK)) { | |
| 118 | + pr_err_ratelimited("%s: ATU map of [%08lx:%lx:%llx:%lx:%lx] failed with status %ld\n", | |
| 119 | + __func__, | |
| 120 | + devhandle, iotsb_num, | |
| 121 | + index_count, prot, | |
| 122 | + __pa(pglist), ret); | |
| 123 | + return -1; | |
| 124 | + } | |
| 98 | 125 | } |
| 99 | − | |
| 100 | 126 | entry += num; |
| 101 | 127 | npages -= num; |
| 102 | 128 | pglist += num; |
| @@ -108,19 +134,19 @@ static long iommu_batch_flush(struct iommu_batch *p) · 5 unmodified lines | ||
| 108 | 134 | return 0; |
| 109 | 135 | } |
| 110 | 136 | |
| 111 | −static inline void iommu_batch_new_entry(unsigned long entry) | |
| 137 | +static inline void iommu_batch_new_entry(unsigned long entry, u64 mask) | |
| 112 | 138 | { |
| 113 | 139 | struct iommu_batch *p = this_cpu_ptr(&iommu_batch); |
| 114 | 140 | |
| 115 | 141 | if (p->entry + p->npages == entry) |
| 116 | 142 | return; |
| 117 | 143 | if (p->entry != ~0UL) |
| 118 | − iommu_batch_flush(p); | |
| 144 | + iommu_batch_flush(p, mask); | |
| 119 | 145 | p->entry = entry; |
| 120 | 146 | } |
| 121 | 147 | |
| 122 | 148 | /* Interrupts must be disabled. */ |
| 123 | −static inline long iommu_batch_add(u64 phys_page) | |
| 149 | +static inline long iommu_batch_add(u64 phys_page, u64 mask) | |
| 124 | 150 | { |
| 125 | 151 | struct iommu_batch *p = this_cpu_ptr(&iommu_batch); |
| 126 | 152 | |
| @@ -128,28 +154,31 @@ static inline long iommu_batch_add(u64 phys_page) · 1 unmodified line | ||
| 128 | 154 | |
| 129 | 155 | p->pglist[p->npages++] = phys_page; |
| 130 | 156 | if (p->npages == PGLIST_NENTS) |
| 131 | − return iommu_batch_flush(p); | |
| 157 | + return iommu_batch_flush(p, mask); | |
| 132 | 158 | |
| 133 | 159 | return 0; |
| 134 | 160 | } |
| 135 | 161 | |
| 136 | 162 | /* Interrupts must be disabled. */ |
| 137 | −static inline long iommu_batch_end(void) | |
| 163 | +static inline long iommu_batch_end(u64 mask) | |
| 138 | 164 | { |
| 139 | 165 | struct iommu_batch *p = this_cpu_ptr(&iommu_batch); |
| 140 | 166 | |
| 141 | 167 | BUG_ON(p->npages >= PGLIST_NENTS); |
| 142 | 168 | |
| 143 | − return iommu_batch_flush(p); | |
| 169 | + return iommu_batch_flush(p, mask); | |
| 144 | 170 | } |
| 145 | 171 | |
| 146 | 172 | static void *dma_4v_alloc_coherent(struct device *dev, size_t size, |
| 147 | 173 | dma_addr_t *dma_addrp, gfp_t gfp, |
| 148 | 174 | unsigned long attrs) |
| 149 | 175 | { |
| 176 | + u64 mask; | |
| 150 | 177 | unsigned long flags, order, first_page, npages, n; |
| 151 | 178 | unsigned long prot = 0; |
| 152 | 179 | struct iommu *iommu; |
| 180 | + struct atu *atu; | |
| 181 | + struct iommu_map_table *tbl; | |
| 153 | 182 | struct page *page; |
| 154 | 183 | void *ret; |
| 155 | 184 | long entry; |
| @@ -174,14 +203,21 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, · 18 unmodified lines | ||
| 174 | 203 | memset((char *)first_page, 0, PAGE_SIZE << order); |
| 175 | 204 | |
| 176 | 205 | iommu = dev->archdata.iommu; |
| 206 | + atu = iommu->atu; | |
| 207 | + | |
| 208 | + mask = dev->coherent_dma_mask; | |
| 209 | + if (mask <= DMA_BIT_MASK(32)) | |
| 210 | + tbl = &iommu->tbl; | |
| 211 | + else | |
| 212 | + tbl = &atu->tbl; | |
| 177 | 213 | |
| 178 | − entry = iommu_tbl_range_alloc(dev, &iommu->tbl, npages, NULL, | |
| 214 | + entry = iommu_tbl_range_alloc(dev, tbl, npages, NULL, | |
| 179 | 215 | (unsigned long)(-1), 0); |
| 180 | 216 | |
| 181 | 217 | if (unlikely(entry == IOMMU_ERROR_CODE)) |
| 182 | 218 | goto range_alloc_fail; |
| 183 | 219 | |
| 184 | − *dma_addrp = (iommu->tbl.table_map_base + (entry << IO_PAGE_SHIFT)); | |
| 220 | + *dma_addrp = (tbl->table_map_base + (entry << IO_PAGE_SHIFT)); | |
| 185 | 221 | ret = (void *) first_page; |
| 186 | 222 | first_page = __pa(first_page); |
| 187 | 223 | |
| @@ -193,12 +229,12 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, · 5 unmodified lines | ||
| 193 | 229 | entry); |
| 194 | 230 | |
| 195 | 231 | for (n = 0; n < npages; n++) { |
| 196 | − long err = iommu_batch_add(first_page + (n * PAGE_SIZE)); | |
| 232 | + long err = iommu_batch_add(first_page + (n * PAGE_SIZE), mask); | |
| 197 | 233 | if (unlikely(err < 0L)) |
| 198 | 234 | goto iommu_map_fail; |
| 199 | 235 | } |
| 200 | 236 | |
| 201 | − if (unlikely(iommu_batch_end() < 0L)) | |
| 237 | + if (unlikely(iommu_batch_end(mask) < 0L)) | |
| 202 | 238 | goto iommu_map_fail; |
| 203 | 239 | |
| 204 | 240 | local_irq_restore(flags); |
| @@ -206,25 +242,71 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, · 1 unmodified line | ||
| 206 | 242 | return ret; |
| 207 | 243 | |
| 208 | 244 | iommu_map_fail: |
| 209 | − iommu_tbl_range_free(&iommu->tbl, *dma_addrp, npages, IOMMU_ERROR_CODE); | |
| 245 | + iommu_tbl_range_free(tbl, *dma_addrp, npages, IOMMU_ERROR_CODE); | |
| 210 | 246 | |
| 211 | 247 | range_alloc_fail: |
| 212 | 248 | free_pages(first_page, order); |
| 213 | 249 | return NULL; |
| 214 | 250 | } |
| 215 | 251 | |
| 216 | −static void dma_4v_iommu_demap(void *demap_arg, unsigned long entry, | |
| 217 | − unsigned long npages) | |
| 252 | +unsigned long dma_4v_iotsb_bind(unsigned long devhandle, | |
| 253 | + unsigned long iotsb_num, | |
| 254 | + struct pci_bus *bus_dev) | |
| 255 | +{ | |
| 256 | + struct pci_dev *pdev; | |
| 257 | + unsigned long err; | |
| 258 | + unsigned int bus; | |
| 259 | + unsigned int device; | |
| 260 | + unsigned int fun; | |
| 261 | + | |
| 262 | + list_for_each_entry(pdev, &bus_dev->devices, bus_list) { | |
| 263 | + if (pdev->subordinate) { | |
| 264 | + /* No need to bind pci bridge */ | |
| 265 | + dma_4v_iotsb_bind(devhandle, iotsb_num, | |
| 266 | + pdev->subordinate); | |
| 267 | + } else { | |
| 268 | + bus = bus_dev->number; | |
| 269 | + device = PCI_SLOT(pdev->devfn); | |
| 270 | + fun = PCI_FUNC(pdev->devfn); | |
| 271 | + err = pci_sun4v_iotsb_bind(devhandle, iotsb_num, | |
| 272 | + HV_PCI_DEVICE_BUILD(bus, | |
| 273 | + device, | |
| 274 | + fun)); | |
| 275 | + | |
| 276 | + /* If bind fails for one device it is going to fail | |
| 277 | + * for rest of the devices because we are sharing | |
| 278 | + * IOTSB. So in case of failure simply return with | |
| 279 | + * error. | |
| 280 | + */ | |
| 281 | + if (err) | |
| 282 | + return err; | |
| 283 | + } | |
| 284 | + } | |
| 285 | + | |
| 286 | + return 0; | |
| 287 | +} | |
| 288 | + | |
| 289 | +static void dma_4v_iommu_demap(struct device *dev, unsigned long devhandle, | |
| 290 | + dma_addr_t dvma, unsigned long iotsb_num, | |
| 291 | + unsigned long entry, unsigned long npages) | |
| 218 | 292 | { |
| 219 | − u32 devhandle = *(u32 *)demap_arg; | |
| 220 | 293 | unsigned long num, flags; |
| 294 | + unsigned long ret; | |
| 221 | 295 | |
| 222 | 296 | local_irq_save(flags); |
| 223 | 297 | do { |
| 224 | − num = pci_sun4v_iommu_demap(devhandle, | |
| 225 | − HV_PCI_TSBID(0, entry), | |
| 226 | − npages); | |
| 227 | − | |
| 298 | + if (dvma <= DMA_BIT_MASK(32)) { | |
| 299 | + num = pci_sun4v_iommu_demap(devhandle, | |
| 300 | + HV_PCI_TSBID(0, entry), | |
| 301 | + npages); | |
| 302 | + } else { | |
| 303 | + ret = pci_sun4v_iotsb_demap(devhandle, iotsb_num, | |
| 304 | + entry, npages, &num); | |
| 305 | + if (unlikely(ret != HV_EOK)) { | |
| 306 | + pr_err_ratelimited("pci_iotsb_demap() failed with error: %ld\n", | |
| 307 | + ret); | |
| 308 | + } | |
| 309 | + } | |
| 228 | 310 | entry += num; |
| 229 | 311 | npages -= num; |
| 230 | 312 | } while (npages != 0); |
| @@ -236,16 +318,28 @@ static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, · 5 unmodified lines | ||
| 236 | 318 | { |
| 237 | 319 | struct pci_pbm_info *pbm; |
| 238 | 320 | struct iommu *iommu; |
| 321 | + struct atu *atu; | |
| 322 | + struct iommu_map_table *tbl; | |
| 239 | 323 | unsigned long order, npages, entry; |
| 324 | + unsigned long iotsb_num; | |
| 240 | 325 | u32 devhandle; |
| 241 | 326 | |
| 242 | 327 | npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; |
| 243 | 328 | iommu = dev->archdata.iommu; |
| 244 | 329 | pbm = dev->archdata.host_controller; |
| 330 | + atu = iommu->atu; | |
| 245 | 331 | devhandle = pbm->devhandle; |
| 246 | − entry = ((dvma - iommu->tbl.table_map_base) >> IO_PAGE_SHIFT); | |
| 247 | − dma_4v_iommu_demap(&devhandle, entry, npages); | |
| 248 | − iommu_tbl_range_free(&iommu->tbl, dvma, npages, IOMMU_ERROR_CODE); | |
| 332 | + | |
| 333 | + if (dvma <= DMA_BIT_MASK(32)) { | |
| 334 | + tbl = &iommu->tbl; | |
| 335 | + iotsb_num = 0; /* we don't care for legacy iommu */ | |
| 336 | + } else { | |
| 337 | + tbl = &atu->tbl; | |
| 338 | + iotsb_num = atu->iotsb->iotsb_num; | |
| 339 | + } | |
| 340 | + entry = ((dvma - tbl->table_map_base) >> IO_PAGE_SHIFT); | |
| 341 | + dma_4v_iommu_demap(dev, devhandle, dvma, iotsb_num, entry, npages); | |
| 342 | + iommu_tbl_range_free(tbl, dvma, npages, IOMMU_ERROR_CODE); | |
| 249 | 343 | order = get_order(size); |
| 250 | 344 | if (order < 10) |
| 251 | 345 | free_pages((unsigned long)cpu, order); |
| @@ -257,13 +351,17 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, · 5 unmodified lines | ||
| 257 | 351 | unsigned long attrs) |
| 258 | 352 | { |
| 259 | 353 | struct iommu *iommu; |
| 354 | + struct atu *atu; | |
| 355 | + struct iommu_map_table *tbl; | |
| 356 | + u64 mask; | |
| 260 | 357 | unsigned long flags, npages, oaddr; |
| 261 | 358 | unsigned long i, base_paddr; |
| 262 | − u32 bus_addr, ret; | |
| 263 | 359 | unsigned long prot; |
| 360 | + dma_addr_t bus_addr, ret; | |
| 264 | 361 | long entry; |
| 265 | 362 | |
| 266 | 363 | iommu = dev->archdata.iommu; |
| 364 | + atu = iommu->atu; | |
| 267 | 365 | |
| 268 | 366 | if (unlikely(direction == DMA_NONE)) |
| 269 | 367 | goto bad; |
| @@ -272,13 +370,19 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, · 2 unmodified lines | ||
| 272 | 370 | npages = IO_PAGE_ALIGN(oaddr + sz) - (oaddr & IO_PAGE_MASK); |
| 273 | 371 | npages >>= IO_PAGE_SHIFT; |
| 274 | 372 | |
| 275 | − entry = iommu_tbl_range_alloc(dev, &iommu->tbl, npages, NULL, | |
| 373 | + mask = *dev->dma_mask; | |
| 374 | + if (mask <= DMA_BIT_MASK(32)) | |
| 375 | + tbl = &iommu->tbl; | |
| 376 | + else | |
| 377 | + tbl = &atu->tbl; | |
| 378 | + | |
| 379 | + entry = iommu_tbl_range_alloc(dev, tbl, npages, NULL, | |
| 276 | 380 | (unsigned long)(-1), 0); |
| 277 | 381 | |
| 278 | 382 | if (unlikely(entry == IOMMU_ERROR_CODE)) |
| 279 | 383 | goto bad; |
| 280 | 384 | |
| 281 | − bus_addr = (iommu->tbl.table_map_base + (entry << IO_PAGE_SHIFT)); | |
| 385 | + bus_addr = (tbl->table_map_base + (entry << IO_PAGE_SHIFT)); | |
| 282 | 386 | ret = bus_addr | (oaddr & ~IO_PAGE_MASK); |
| 283 | 387 | base_paddr = __pa(oaddr & IO_PAGE_MASK); |
| 284 | 388 | prot = HV_PCI_MAP_ATTR_READ; |
| @@ -293,11 +397,11 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, · 8 unmodified lines | ||
| 293 | 397 | iommu_batch_start(dev, prot, entry); |
| 294 | 398 | |
| 295 | 399 | for (i = 0; i < npages; i++, base_paddr += IO_PAGE_SIZE) { |
| 296 | − long err = iommu_batch_add(base_paddr); | |
| 400 | + long err = iommu_batch_add(base_paddr, mask); | |
| 297 | 401 | if (unlikely(err < 0L)) |
| 298 | 402 | goto iommu_map_fail; |
| 299 | 403 | } |
| 300 | − if (unlikely(iommu_batch_end() < 0L)) | |
| 404 | + if (unlikely(iommu_batch_end(mask) < 0L)) | |
| 301 | 405 | goto iommu_map_fail; |
| 302 | 406 | |
| 303 | 407 | local_irq_restore(flags); |
| @@ -310,7 +414,7 @@ bad: · 6 unmodified lines | ||
| 310 | 414 | return DMA_ERROR_CODE; |
| 311 | 415 | |
| 312 | 416 | iommu_map_fail: |
| 313 | − iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, IOMMU_ERROR_CODE); | |
| 417 | + iommu_tbl_range_free(tbl, bus_addr, npages, IOMMU_ERROR_CODE); | |
| 314 | 418 | return DMA_ERROR_CODE; |
| 315 | 419 | } |
| 316 | 420 | |
| @@ -320,7 +424,10 @@ static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr, · 3 unmodified lines | ||
| 320 | 424 | { |
| 321 | 425 | struct pci_pbm_info *pbm; |
| 322 | 426 | struct iommu *iommu; |
| 427 | + struct atu *atu; | |
| 428 | + struct iommu_map_table *tbl; | |
| 323 | 429 | unsigned long npages; |
| 430 | + unsigned long iotsb_num; | |
| 324 | 431 | long entry; |
| 325 | 432 | u32 devhandle; |
| 326 | 433 | |
| @@ -332,14 +439,23 @@ static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr, · 5 unmodified lines | ||
| 332 | 439 | |
| 333 | 440 | iommu = dev->archdata.iommu; |
| 334 | 441 | pbm = dev->archdata.host_controller; |
| 442 | + atu = iommu->atu; | |
| 335 | 443 | devhandle = pbm->devhandle; |
| 336 | 444 | |
| 337 | 445 | npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK); |
| 338 | 446 | npages >>= IO_PAGE_SHIFT; |
| 339 | 447 | bus_addr &= IO_PAGE_MASK; |
| 340 | − entry = (bus_addr - iommu->tbl.table_map_base) >> IO_PAGE_SHIFT; | |
| 341 | − dma_4v_iommu_demap(&devhandle, entry, npages); | |
| 342 | − iommu_tbl_range_free(&iommu->tbl, bus_addr, npages, IOMMU_ERROR_CODE); | |
| 448 | + | |
| 449 | + if (bus_addr <= DMA_BIT_MASK(32)) { | |
| 450 | + iotsb_num = 0; /* we don't care for legacy iommu */ | |
| 451 | + tbl = &iommu->tbl; | |
| 452 | + } else { | |
| 453 | + iotsb_num = atu->iotsb->iotsb_num; | |
| 454 | + tbl = &atu->tbl; | |
| 455 | + } | |
| 456 | + entry = (bus_addr - tbl->table_map_base) >> IO_PAGE_SHIFT; | |
| 457 | + dma_4v_iommu_demap(dev, devhandle, bus_addr, iotsb_num, entry, npages); | |
| 458 | + iommu_tbl_range_free(tbl, bus_addr, npages, IOMMU_ERROR_CODE); | |
| 343 | 459 | } |
| 344 | 460 | |
| 345 | 461 | static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, |
| @@ -353,12 +469,17 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, · 7 unmodified lines | ||
| 353 | 469 | unsigned long seg_boundary_size; |
| 354 | 470 | int outcount, incount, i; |
| 355 | 471 | struct iommu *iommu; |
| 472 | + struct atu *atu; | |
| 473 | + struct iommu_map_table *tbl; | |
| 474 | + u64 mask; | |
| 356 | 475 | unsigned long base_shift; |
| 357 | 476 | long err; |
| 358 | 477 | |
| 359 | 478 | BUG_ON(direction == DMA_NONE); |
| 360 | 479 | |
| 361 | 480 | iommu = dev->archdata.iommu; |
| 481 | + atu = iommu->atu; | |
| 482 | + | |
| 362 | 483 | if (nelems == 0 || !iommu) |
| 363 | 484 | return 0; |
| 364 | 485 | |
| @@ -384,7 +505,15 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, · 19 unmodified lines | ||
| 384 | 505 | max_seg_size = dma_get_max_seg_size(dev); |
| 385 | 506 | seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, |
| 386 | 507 | IO_PAGE_SIZE) >> IO_PAGE_SHIFT; |
| 387 | − base_shift = iommu->tbl.table_map_base >> IO_PAGE_SHIFT; | |
| 508 | + | |
| 509 | + mask = *dev->dma_mask; | |
| 510 | + if (mask <= DMA_BIT_MASK(32)) | |
| 511 | + tbl = &iommu->tbl; | |
| 512 | + else | |
| 513 | + tbl = &atu->tbl; | |
| 514 | + | |
| 515 | + base_shift = tbl->table_map_base >> IO_PAGE_SHIFT; | |
| 516 | + | |
| 388 | 517 | for_each_sg(sglist, s, nelems, i) { |
| 389 | 518 | unsigned long paddr, npages, entry, out_entry = 0, slen; |
| 390 | 519 | |
| @@ -397,27 +526,26 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, · 6 unmodified lines | ||
| 397 | 526 | /* Allocate iommu entries for that segment */ |
| 398 | 527 | paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s); |
| 399 | 528 | npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE); |
| 400 | − entry = iommu_tbl_range_alloc(dev, &iommu->tbl, npages, | |
| 529 | + entry = iommu_tbl_range_alloc(dev, tbl, npages, | |
| 401 | 530 | &handle, (unsigned long)(-1), 0); |
| 402 | 531 | |
| 403 | 532 | /* Handle failure */ |
| 404 | 533 | if (unlikely(entry == IOMMU_ERROR_CODE)) { |
| 405 | − if (printk_ratelimit()) | |
| 406 | − printk(KERN_INFO "iommu_alloc failed, iommu %p paddr %lx" | |
| 407 | − " npages %lx\n", iommu, paddr, npages); | |
| 534 | + pr_err_ratelimited("iommu_alloc failed, iommu %p paddr %lx npages %lx\n", | |
| 535 | + tbl, paddr, npages); | |
| 408 | 536 | goto iommu_map_failed; |
| 409 | 537 | } |
| 410 | 538 | |
| 411 | − iommu_batch_new_entry(entry); | |
| 539 | + iommu_batch_new_entry(entry, mask); | |
| 412 | 540 | |
| 413 | 541 | /* Convert entry to a dma_addr_t */ |
| 414 | − dma_addr = iommu->tbl.table_map_base + (entry << IO_PAGE_SHIFT); | |
| 542 | + dma_addr = tbl->table_map_base + (entry << IO_PAGE_SHIFT); | |
| 415 | 543 | dma_addr |= (s->offset & ~IO_PAGE_MASK); |
| 416 | 544 | |
| 417 | 545 | /* Insert into HW table */ |
| 418 | 546 | paddr &= IO_PAGE_MASK; |
| 419 | 547 | while (npages--) { |
| 420 | − err = iommu_batch_add(paddr); | |
| 548 | + err = iommu_batch_add(paddr, mask); | |
| 421 | 549 | if (unlikely(err < 0L)) |
| 422 | 550 | goto iommu_map_failed; |
| 423 | 551 | paddr += IO_PAGE_SIZE; |
| @@ -452,7 +580,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, · 28 unmodified lines | ||
| 452 | 580 | dma_next = dma_addr + slen; |
| 453 | 581 | } |
| 454 | 582 | |
| 455 | − err = iommu_batch_end(); | |
| 583 | + err = iommu_batch_end(mask); | |
| 456 | 584 | |
| 457 | 585 | if (unlikely(err < 0L)) |
| 458 | 586 | goto iommu_map_failed; |
| @@ -475,7 +603,7 @@ iommu_map_failed: · 16 unmodified lines | ||
| 475 | 603 | vaddr = s->dma_address & IO_PAGE_MASK; |
| 476 | 604 | npages = iommu_num_pages(s->dma_address, s->dma_length, |
| 477 | 605 | IO_PAGE_SIZE); |
| 478 | − iommu_tbl_range_free(&iommu->tbl, vaddr, npages, | |
| 606 | + iommu_tbl_range_free(tbl, vaddr, npages, | |
| 479 | 607 | IOMMU_ERROR_CODE); |
| 480 | 608 | /* XXX demap? XXX */ |
| 481 | 609 | s->dma_address = DMA_ERROR_CODE; |
| @@ -496,13 +624,16 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, · 14 unmodified lines | ||
| 496 | 624 | struct pci_pbm_info *pbm; |
| 497 | 625 | struct scatterlist *sg; |
| 498 | 626 | struct iommu *iommu; |
| 627 | + struct atu *atu; | |
| 499 | 628 | unsigned long flags, entry; |
| 629 | + unsigned long iotsb_num; | |
| 500 | 630 | u32 devhandle; |
| 501 | 631 | |
| 502 | 632 | BUG_ON(direction == DMA_NONE); |
| 503 | 633 | |
| 504 | 634 | iommu = dev->archdata.iommu; |
| 505 | 635 | pbm = dev->archdata.host_controller; |
| 636 | + atu = iommu->atu; | |
| 506 | 637 | devhandle = pbm->devhandle; |
| 507 | 638 | |
| 508 | 639 | local_irq_save(flags); |
| @@ -512,15 +643,24 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, · 3 unmodified lines | ||
| 512 | 643 | dma_addr_t dma_handle = sg->dma_address; |
| 513 | 644 | unsigned int len = sg->dma_length; |
| 514 | 645 | unsigned long npages; |
| 515 | − struct iommu_map_table *tbl = &iommu->tbl; | |
| 646 | + struct iommu_map_table *tbl; | |
| 516 | 647 | unsigned long shift = IO_PAGE_SHIFT; |
| 517 | 648 | |
| 518 | 649 | if (!len) |
| 519 | 650 | break; |
| 520 | 651 | npages = iommu_num_pages(dma_handle, len, IO_PAGE_SIZE); |
| 652 | + | |
| 653 | + if (dma_handle <= DMA_BIT_MASK(32)) { | |
| 654 | + iotsb_num = 0; /* we don't care for legacy iommu */ | |
| 655 | + tbl = &iommu->tbl; | |
| 656 | + } else { | |
| 657 | + iotsb_num = atu->iotsb->iotsb_num; | |
| 658 | + tbl = &atu->tbl; | |
| 659 | + } | |
| 521 | 660 | entry = ((dma_handle - tbl->table_map_base) >> shift); |
| 522 | − dma_4v_iommu_demap(&devhandle, entry, npages); | |
| 523 | − iommu_tbl_range_free(&iommu->tbl, dma_handle, npages, | |
| 661 | + dma_4v_iommu_demap(dev, devhandle, dma_handle, iotsb_num, | |
| 662 | + entry, npages); | |
| 663 | + iommu_tbl_range_free(tbl, dma_handle, npages, | |
| 524 | 664 | IOMMU_ERROR_CODE); |
| 525 | 665 | sg = sg_next(sg); |
| 526 | 666 | } |
| @@ -581,6 +721,132 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, · 54 unmodified lines | ||
| 581 | 721 | return cnt; |
| 582 | 722 | } |
| 583 | 723 | |
| 724 | +static int pci_sun4v_atu_alloc_iotsb(struct pci_pbm_info *pbm) | |
| 725 | +{ | |
| 726 | + struct atu *atu = pbm->iommu->atu; | |
| 727 | + struct atu_iotsb *iotsb; | |
| 728 | + void *table; | |
| 729 | + u64 table_size; | |
| 730 | + u64 iotsb_num; | |
| 731 | + unsigned long order; | |
| 732 | + unsigned long err; | |
| 733 | + | |
| 734 | + iotsb = kzalloc(sizeof(*iotsb), GFP_KERNEL); | |
| 735 | + if (!iotsb) { | |
| 736 | + err = -ENOMEM; | |
| 737 | + goto out_err; | |
| 738 | + } | |
| 739 | + atu->iotsb = iotsb; | |
| 740 | + | |
| 741 | + /* calculate size of IOTSB */ | |
| 742 | + table_size = (atu->size / IO_PAGE_SIZE) * 8; | |
| 743 | + order = get_order(table_size); | |
| 744 | + table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); | |
| 745 | + if (!table) { | |
| 746 | + err = -ENOMEM; | |
| 747 | + goto table_failed; | |
| 748 | + } | |
| 749 | + iotsb->table = table; | |
| 750 | + iotsb->ra = __pa(table); | |
| 751 | + iotsb->dvma_size = atu->size; | |
| 752 | + iotsb->dvma_base = atu->base; | |
| 753 | + iotsb->table_size = table_size; | |
| 754 | + iotsb->page_size = IO_PAGE_SIZE; | |
| 755 | + | |
| 756 | + /* configure and register IOTSB with HV */ | |
| 757 | + err = pci_sun4v_iotsb_conf(pbm->devhandle, | |
| 758 | + iotsb->ra, | |
| 759 | + iotsb->table_size, | |
| 760 | + iotsb->page_size, | |
| 761 | + iotsb->dvma_base, | |
| 762 | + &iotsb_num); | |
| 763 | + if (err) { | |
| 764 | + pr_err(PFX "pci_iotsb_conf failed error: %ld\n", err); | |
| 765 | + goto iotsb_conf_failed; | |
| 766 | + } | |
| 767 | + iotsb->iotsb_num = iotsb_num; | |
| 768 | + | |
| 769 | + err = dma_4v_iotsb_bind(pbm->devhandle, iotsb_num, pbm->pci_bus); | |
| 770 | + if (err) { | |
| 771 | + pr_err(PFX "pci_iotsb_bind failed error: %ld\n", err); | |
| 772 | + goto iotsb_conf_failed; | |
| 773 | + } | |
| 774 | + | |
| 775 | + return 0; | |
| 776 | + | |
| 777 | +iotsb_conf_failed: | |
| 778 | + free_pages((unsigned long)table, order); | |
| 779 | +table_failed: | |
| 780 | + kfree(iotsb); | |
| 781 | +out_err: | |
| 782 | + return err; | |
| 783 | +} | |
| 784 | + | |
| 785 | +static int pci_sun4v_atu_init(struct pci_pbm_info *pbm) | |
| 786 | +{ | |
| 787 | + struct atu *atu = pbm->iommu->atu; | |
| 788 | + unsigned long err; | |
| 789 | + const u64 *ranges; | |
| 790 | + u64 map_size, num_iotte; | |
| 791 | + u64 dma_mask; | |
| 792 | + const u32 *page_size; | |
| 793 | + int len; | |
| 794 | + | |
| 795 | + ranges = of_get_property(pbm->op->dev.of_node, "iommu-address-ranges", | |
| 796 | + &len); | |
| 797 | + if (!ranges) { | |
| 798 | + pr_err(PFX "No iommu-address-ranges\n"); | |
| 799 | + return -EINVAL; | |
| 800 | + } | |
| 801 | + | |
| 802 | + page_size = of_get_property(pbm->op->dev.of_node, "iommu-pagesizes", | |
| 803 | + NULL); | |
| 804 | + if (!page_size) { | |
| 805 | + pr_err(PFX "No iommu-pagesizes\n"); | |
| 806 | + return -EINVAL; | |
| 807 | + } | |
| 808 | + | |
| 809 | + /* There are 4 iommu-address-ranges supported. Each range is pair of | |
| 810 | + * {base, size}. The ranges[0] and ranges[1] are 32bit address space | |
| 811 | + * while ranges[2] and ranges[3] are 64bit space. We want to use 64bit | |
| 812 | + * address ranges to support 64bit addressing. Because 'size' for | |
| 813 | + * address ranges[2] and ranges[3] are same we can select either of | |
| 814 | + * ranges[2] or ranges[3] for mapping. However due to 'size' is too | |
| 815 | + * large for OS to allocate IOTSB we are using fix size 32G | |
| 816 | + * (ATU_64_SPACE_SIZE) which is more than enough for all PCIe devices | |
| 817 | + * to share. | |
| 818 | + */ | |
| 819 | + atu->ranges = (struct atu_ranges *)ranges; | |
| 820 | + atu->base = atu->ranges[3].base; | |
| 821 | + atu->size = ATU_64_SPACE_SIZE; | |
| 822 | + | |
| 823 | + /* Create IOTSB */ | |
| 824 | + err = pci_sun4v_atu_alloc_iotsb(pbm); | |
| 825 | + if (err) { | |
| 826 | + pr_err(PFX "Error creating ATU IOTSB\n"); | |
| 827 | + return err; | |
| 828 | + } | |
| 829 | + | |
| 830 | + /* Create ATU iommu map. | |
| 831 | + * One bit represents one iotte in IOTSB table. | |
| 832 | + */ | |
| 833 | + dma_mask = (roundup_pow_of_two(atu->size) - 1UL); | |
| 834 | + num_iotte = atu->size / IO_PAGE_SIZE; | |
| 835 | + map_size = num_iotte / 8; | |
| 836 | + atu->tbl.table_map_base = atu->base; | |
| 837 | + atu->dma_addr_mask = dma_mask; | |
| 838 | + atu->tbl.map = kzalloc(map_size, GFP_KERNEL); | |
| 839 | + if (!atu->tbl.map) | |
| 840 | + return -ENOMEM; | |
| 841 | + | |
| 842 | + iommu_tbl_pool_init(&atu->tbl, num_iotte, IO_PAGE_SHIFT, | |
| 843 | + NULL, false /* no large_pool */, | |
| 844 | + 0 /* default npools */, | |
| 845 | + false /* want span boundary checking */); | |
| 846 | + | |
| 847 | + return 0; | |
| 848 | +} | |
| 849 | + | |
| 584 | 850 | static int pci_sun4v_iommu_init(struct pci_pbm_info *pbm) |
| 585 | 851 | { |
| 586 | 852 | static const u32 vdma_default[] = { 0x80000000, 0x80000000 }; |
| @@ -918,6 +1184,18 @@ static int pci_sun4v_pbm_init(struct pci_pbm_info *pbm, · 331 unmodified lines | ||
| 918 | 1184 | |
| 919 | 1185 | pci_sun4v_scan_bus(pbm, &op->dev); |
| 920 | 1186 | |
| 1187 | + /* if atu_init fails its not complete failure. | |
| 1188 | + * we can still continue using legacy iommu. | |
| 1189 | + */ | |
| 1190 | + if (pbm->iommu->atu) { | |
| 1191 | + err = pci_sun4v_atu_init(pbm); | |
| 1192 | + if (err) { | |
| 1193 | + kfree(pbm->iommu->atu); | |
| 1194 | + pbm->iommu->atu = NULL; | |
| 1195 | + pr_err(PFX "ATU init failed, err=%d\n", err); | |
| 1196 | + } | |
| 1197 | + } | |
| 1198 | + | |
| 921 | 1199 | pbm->next = pci_pbm_root; |
| 922 | 1200 | pci_pbm_root = pbm; |
| 923 | 1201 | |
| @@ -931,8 +1209,10 @@ static int pci_sun4v_probe(struct platform_device *op) · 7 unmodified lines | ||
| 931 | 1209 | struct pci_pbm_info *pbm; |
| 932 | 1210 | struct device_node *dp; |
| 933 | 1211 | struct iommu *iommu; |
| 1212 | + struct atu *atu; | |
| 934 | 1213 | u32 devhandle; |
| 935 | 1214 | int i, err = -ENODEV; |
| 1215 | + static bool hv_atu = true; | |
| 936 | 1216 | |
| 937 | 1217 | dp = op->dev.of_node; |
| 938 | 1218 | |
| @@ -954,6 +1234,19 @@ static int pci_sun4v_probe(struct platform_device *op) · 15 unmodified lines | ||
| 954 | 1234 | pr_info(PFX "Registered hvapi major[%lu] minor[%lu]\n", |
| 955 | 1235 | vpci_major, vpci_minor); |
| 956 | 1236 | |
| 1237 | + err = sun4v_hvapi_register(HV_GRP_ATU, vatu_major, &vatu_minor); | |
| 1238 | + if (err) { | |
| 1239 | + /* don't return an error if we fail to register the | |
| 1240 | + * ATU group, but ATU hcalls won't be available. | |
| 1241 | + */ | |
| 1242 | + hv_atu = false; | |
| 1243 | + pr_err(PFX "Could not register hvapi ATU err=%d\n", | |
| 1244 | + err); | |
| 1245 | + } else { | |
| 1246 | + pr_info(PFX "Registered hvapi ATU major[%lu] minor[%lu]\n", | |
| 1247 | + vatu_major, vatu_minor); | |
| 1248 | + } | |
| 1249 | + | |
| 957 | 1250 | dma_ops = &sun4v_dma_ops; |
| 958 | 1251 | } |
| 959 | 1252 | |
| @@ -991,6 +1284,14 @@ static int pci_sun4v_probe(struct platform_device *op) · 31 unmodified lines | ||
| 991 | 1284 | } |
| 992 | 1285 | |
| 993 | 1286 | pbm->iommu = iommu; |
| 1287 | + iommu->atu = NULL; | |
| 1288 | + if (hv_atu) { | |
| 1289 | + atu = kzalloc(sizeof(*atu), GFP_KERNEL); | |
| 1290 | + if (!atu) | |
| 1291 | + pr_err(PFX "Could not allocate atu\n"); | |
| 1292 | + else | |
| 1293 | + iommu->atu = atu; | |
| 1294 | + } | |
| 994 | 1295 | |
| 995 | 1296 | err = pci_sun4v_pbm_init(pbm, op, devhandle); |
| 996 | 1297 | if (err) |
| @@ -1001,6 +1302,7 @@ static int pci_sun4v_probe(struct platform_device *op) · 4 unmodified lines | ||
| 1001 | 1302 | return 0; |
| 1002 | 1303 | |
| 1003 | 1304 | out_free_iommu: |
| 1305 | + kfree(iommu->atu); | |
| 1004 | 1306 | kfree(pbm->iommu); |
| 1005 | 1307 | |
| 1006 | 1308 | out_free_controller: |
| @@ -89,4 +89,25 @@ unsigned long pci_sun4v_msg_setvalid(unsigned long devhandle, · 88 unmodified lines | ||
| 89 | 89 | unsigned long msinum, |
| 90 | 90 | unsigned long valid); |
| 91 | 91 | |
| 92 | +/* Sun4v HV IOMMU v2 APIs */ | |
| 93 | +unsigned long pci_sun4v_iotsb_conf(unsigned long devhandle, | |
| 94 | + unsigned long ra, | |
| 95 | + unsigned long table_size, | |
| 96 | + unsigned long page_size, | |
| 97 | + unsigned long dvma_base, | |
| 98 | + u64 *iotsb_num); | |
| 99 | +unsigned long pci_sun4v_iotsb_bind(unsigned long devhandle, | |
| 100 | + unsigned long iotsb_num, | |
| 101 | + unsigned int pci_device); | |
| 102 | +unsigned long pci_sun4v_iotsb_map(unsigned long devhandle, | |
| 103 | + unsigned long iotsb_num, | |
| 104 | + unsigned long iotsb_index_iottes, | |
| 105 | + unsigned long io_attributes, | |
| 106 | + unsigned long io_page_list_pa, | |
| 107 | + long *mapped); | |
| 108 | +unsigned long pci_sun4v_iotsb_demap(unsigned long devhandle, | |
| 109 | + unsigned long iotsb_num, | |
| 110 | + unsigned long iotsb_index, | |
| 111 | + unsigned long iottes, | |
| 112 | + unsigned long *demapped); | |
| 92 | 113 | #endif /* !(_PCI_SUN4V_H) */ |
| @@ -360,3 +360,71 @@ ENTRY(pci_sun4v_msg_setvalid) · 359 unmodified lines | ||
| 360 | 360 | mov %o0, %o0 |
| 361 | 361 | ENDPROC(pci_sun4v_msg_setvalid) |
| 362 | 362 | |
| 363 | + /* | |
| 364 | + * %o0: devhandle | |
| 365 | + * %o1: r_addr | |
| 366 | + * %o2: size | |
| 367 | + * %o3: pagesize | |
| 368 | + * %o4: virt | |
| 369 | + * %o5: &iotsb_num/&iotsb_handle | |
| 370 | + * | |
| 371 | + * returns %o0: status | |
| 372 | + * %o1: iotsb_num/iotsb_handle | |
| 373 | + */ | |
| 374 | +ENTRY(pci_sun4v_iotsb_conf) | |
| 375 | + mov %o5, %g1 | |
| 376 | + mov HV_FAST_PCI_IOTSB_CONF, %o5 | |
| 377 | + ta HV_FAST_TRAP | |
| 378 | + retl | |
| 379 | + stx %o1, [%g1] | |
| 380 | +ENDPROC(pci_sun4v_iotsb_conf) | |
| 381 | + | |
| 382 | + /* | |
| 383 | + * %o0: devhandle | |
| 384 | + * %o1: iotsb_num/iotsb_handle | |
| 385 | + * %o2: pci_device | |
| 386 | + * | |
| 387 | + * returns %o0: status | |
| 388 | + */ | |
| 389 | +ENTRY(pci_sun4v_iotsb_bind) | |
| 390 | + mov HV_FAST_PCI_IOTSB_BIND, %o5 | |
| 391 | + ta HV_FAST_TRAP | |
| 392 | + retl | |
| 393 | + nop | |
| 394 | +ENDPROC(pci_sun4v_iotsb_bind) | |
| 395 | + | |
| 396 | + /* | |
| 397 | + * %o0: devhandle | |
| 398 | + * %o1: iotsb_num/iotsb_handle | |
| 399 | + * %o2: index_count | |
| 400 | + * %o3: iotte_attributes | |
| 401 | + * %o4: io_page_list_p | |
| 402 | + * %o5: &mapped | |
| 403 | + * | |
| 404 | + * returns %o0: status | |
| 405 | + * %o1: #mapped | |
| 406 | + */ | |
| 407 | +ENTRY(pci_sun4v_iotsb_map) | |
| 408 | + mov %o5, %g1 | |
| 409 | + mov HV_FAST_PCI_IOTSB_MAP, %o5 | |
| 410 | + ta HV_FAST_TRAP | |
| 411 | + retl | |
| 412 | + stx %o1, [%g1] | |
| 413 | +ENDPROC(pci_sun4v_iotsb_map) | |
| 414 | + | |
| 415 | + /* | |
| 416 | + * %o0: devhandle | |
| 417 | + * %o1: iotsb_num/iotsb_handle | |
| 418 | + * %o2: iotsb_index | |
| 419 | + * %o3: #iottes | |
| 420 | + * %o4: &demapped | |
| 421 | + * | |
| 422 | + * returns %o0: status | |
| 423 | + * %o1: #demapped | |
| 424 | + */ | |
| 425 | +ENTRY(pci_sun4v_iotsb_demap) | |
| 426 | + mov HV_FAST_PCI_IOTSB_DEMAP, %o5 | |
| 427 | + ta HV_FAST_TRAP | |
| 428 | + retl | |
| 429 | + stx %o1, [%o4] | |
| 430 | +ENDPROC(pci_sun4v_iotsb_demap) | |
| @@ -89,7 +89,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) · 88 unmodified lines | ||
| 89 | 89 | sf = (struct signal_frame __user *) regs->u_regs[UREG_FP]; |
| 90 | 90 | |
| 91 | 91 | /* 1. Make sure we are not getting garbage from the user */ |
| 92 | − if (!invalid_frame_pointer(sf, sizeof(*sf))) | |
| 92 | + if (invalid_frame_pointer(sf, sizeof(*sf))) | |
| 93 | 93 | goto segv_and_exit; |
| 94 | 94 | |
| 95 | 95 | if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP])) |
| @@ -150,7 +150,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) · 54 unmodified lines | ||
| 150 | 150 | |
| 151 | 151 | synchronize_user_stack(); |
| 152 | 152 | sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP]; |
| 153 | − if (!invalid_frame_pointer(sf, sizeof(*sf))) | |
| 153 | + if (invalid_frame_pointer(sf, sizeof(*sf))) | |
| 154 | 154 | goto segv; |
| 155 | 155 | |
| 156 | 156 | if (get_user(ufp, &sf->regs.u_regs[UREG_FP])) |
| @@ -802,8 +802,10 @@ struct mdesc_mblock { · 801 unmodified lines | ||
| 802 | 802 | }; |
| 803 | 803 | static struct mdesc_mblock *mblocks; |
| 804 | 804 | static int num_mblocks; |
| 805 | +static int find_numa_node_for_addr(unsigned long pa, | |
| 806 | + struct node_mem_mask *pnode_mask); | |
| 805 | 807 | |
| 806 | −static unsigned long ra_to_pa(unsigned long addr) | |
| 808 | +static unsigned long __init ra_to_pa(unsigned long addr) | |
| 807 | 809 | { |
| 808 | 810 | int i; |
| 809 | 811 | |
| @@ -819,8 +821,11 @@ static unsigned long ra_to_pa(unsigned long addr) · 9 unmodified lines | ||
| 819 | 821 | return addr; |
| 820 | 822 | } |
| 821 | 823 | |
| 822 | −static int find_node(unsigned long addr) | |
| 824 | +static int __init find_node(unsigned long addr) | |
| 823 | 825 | { |
| 826 | + static bool search_mdesc = true; | |
| 827 | + static struct node_mem_mask last_mem_mask = { ~0UL, ~0UL }; | |
| 828 | + static int last_index; | |
| 824 | 829 | int i; |
| 825 | 830 | |
| 826 | 831 | addr = ra_to_pa(addr); |
| @@ -830,13 +835,30 @@ static int find_node(unsigned long addr) · 3 unmodified lines | ||
| 830 | 835 | if ((addr & p->mask) == p->val) |
| 831 | 836 | return i; |
| 832 | 837 | } |
| 833 | − /* The following condition has been observed on LDOM guests.*/ | |
| 834 | − WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node" | |
| 835 | − " rule. Some physical memory will be owned by node 0."); | |
| 836 | − return 0; | |
| 838 | + /* The following condition has been observed on LDOM guests because | |
| 839 | + * node_masks only contains the best latency mask and value. | |
| 840 | + * LDOM guest's mdesc can contain a single latency group to | |
| 841 | + * cover multiple address range. Print warning message only if the | |
| 842 | + * address cannot be found in node_masks nor mdesc. | |
| 843 | + */ | |
| 844 | + if ((search_mdesc) && | |
| 845 | + ((addr & last_mem_mask.mask) != last_mem_mask.val)) { | |
| 846 | + /* find the available node in the mdesc */ | |
| 847 | + last_index = find_numa_node_for_addr(addr, &last_mem_mask); | |
| 848 | + numadbg("find_node: latency group for address 0x%lx is %d\n", | |
| 849 | + addr, last_index); | |
| 850 | + if ((last_index < 0) || (last_index >= num_node_masks)) { | |
| 851 | + /* WARN_ONCE() and use default group 0 */ | |
| 852 | + WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node rule. Some physical memory will be owned by node 0."); | |
| 853 | + search_mdesc = false; | |
| 854 | + last_index = 0; | |
| 855 | + } | |
| 856 | + } | |
| 857 | + | |
| 858 | + return last_index; | |
| 837 | 859 | } |
| 838 | 860 | |
| 839 | −static u64 memblock_nid_range(u64 start, u64 end, int *nid) | |
| 861 | +static u64 __init memblock_nid_range(u64 start, u64 end, int *nid) | |
| 840 | 862 | { |
| 841 | 863 | *nid = find_node(start); |
| 842 | 864 | start += PAGE_SIZE; |
| @@ -1160,6 +1182,41 @@ int __node_distance(int from, int to) · 317 unmodified lines | ||
| 1160 | 1182 | return numa_latency[from][to]; |
| 1161 | 1183 | } |
| 1162 | 1184 | |
| 1185 | +static int find_numa_node_for_addr(unsigned long pa, | |
| 1186 | + struct node_mem_mask *pnode_mask) | |
| 1187 | +{ | |
| 1188 | + struct mdesc_handle *md = mdesc_grab(); | |
| 1189 | + u64 node, arc; | |
| 1190 | + int i = 0; | |
| 1191 | + | |
| 1192 | + node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups"); | |
| 1193 | + if (node == MDESC_NODE_NULL) | |
| 1194 | + goto out; | |
| 1195 | + | |
| 1196 | + mdesc_for_each_node_by_name(md, node, "group") { | |
| 1197 | + mdesc_for_each_arc(arc, md, node, MDESC_ARC_TYPE_FWD) { | |
| 1198 | + u64 target = mdesc_arc_target(md, arc); | |
| 1199 | + struct mdesc_mlgroup *m = find_mlgroup(target); | |
| 1200 | + | |
| 1201 | + if (!m) | |
| 1202 | + continue; | |
| 1203 | + if ((pa & m->mask) == m->match) { | |
| 1204 | + if (pnode_mask) { | |
| 1205 | + pnode_mask->mask = m->mask; | |
| 1206 | + pnode_mask->val = m->match; | |
| 1207 | + } | |
| 1208 | + mdesc_release(md); | |
| 1209 | + return i; | |
| 1210 | + } | |
| 1211 | + } | |
| 1212 | + i++; | |
| 1213 | + } | |
| 1214 | + | |
| 1215 | +out: | |
| 1216 | + mdesc_release(md); | |
| 1217 | + return -1; | |
| 1218 | +} | |
| 1219 | + | |
| 1163 | 1220 | static int __init find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp) |
| 1164 | 1221 | { |
| 1165 | 1222 | int i; |
| @@ -61,4 +61,7 @@ · 60 unmodified lines | ||
| 61 | 61 | */ |
| 62 | 62 | #define __write_once __read_mostly |
| 63 | 63 | |
| 64 | +/* __ro_after_init is the generic name for the tile arch __write_once. */ | |
| 65 | +#define __ro_after_init __read_mostly | |
| 66 | + | |
| 64 | 67 | #endif /* _ASM_TILE_CACHE_H */ |
| @@ -888,7 +888,7 @@ static int helper_rfc4106_encrypt(struct aead_request *req) · 887 unmodified lines | ||
| 888 | 888 | unsigned long auth_tag_len = crypto_aead_authsize(tfm); |
| 889 | 889 | u8 iv[16] __attribute__ ((__aligned__(AESNI_ALIGN))); |
| 890 | 890 | struct scatter_walk src_sg_walk; |
| 891 | − struct scatter_walk dst_sg_walk; | |
| 891 | + struct scatter_walk dst_sg_walk = {}; | |
| 892 | 892 | unsigned int i; |
| 893 | 893 | |
| 894 | 894 | /* Assuming we are supporting rfc4106 64-bit extended */ |
| @@ -968,7 +968,7 @@ static int helper_rfc4106_decrypt(struct aead_request *req) · 73 unmodified lines | ||
| 968 | 968 | u8 iv[16] __attribute__ ((__aligned__(AESNI_ALIGN))); |
| 969 | 969 | u8 authTag[16]; |
| 970 | 970 | struct scatter_walk src_sg_walk; |
| 971 | − struct scatter_walk dst_sg_walk; | |
| 971 | + struct scatter_walk dst_sg_walk = {}; | |
| 972 | 972 | unsigned int i; |
| 973 | 973 | |
| 974 | 974 | if (unlikely(req->assoclen != 16 && req->assoclen != 20)) |
| @@ -8,8 +8,12 @@ · 7 unmodified lines | ||
| 8 | 8 | #define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00 |
| 9 | 9 | #define PCI_DEVICE_ID_INTEL_HSW_U_IMC 0x0a04 |
| 10 | 10 | #define PCI_DEVICE_ID_INTEL_BDW_IMC 0x1604 |
| 11 | −#define PCI_DEVICE_ID_INTEL_SKL_IMC 0x191f | |
| 12 | −#define PCI_DEVICE_ID_INTEL_SKL_U_IMC 0x190c | |
| 11 | +#define PCI_DEVICE_ID_INTEL_SKL_U_IMC 0x1904 | |
| 12 | +#define PCI_DEVICE_ID_INTEL_SKL_Y_IMC 0x190c | |
| 13 | +#define PCI_DEVICE_ID_INTEL_SKL_HD_IMC 0x1900 | |
| 14 | +#define PCI_DEVICE_ID_INTEL_SKL_HQ_IMC 0x1910 | |
| 15 | +#define PCI_DEVICE_ID_INTEL_SKL_SD_IMC 0x190f | |
| 16 | +#define PCI_DEVICE_ID_INTEL_SKL_SQ_IMC 0x191f | |
| 13 | 17 | |
| 14 | 18 | /* SNB event control */ |
| 15 | 19 | #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff |
| @@ -616,13 +620,29 @@ static const struct pci_device_id bdw_uncore_pci_ids[] = { · 600 unmodified lines | ||
| 616 | 620 | |
| 617 | 621 | static const struct pci_device_id skl_uncore_pci_ids[] = { |
| 618 | 622 | { /* IMC */ |
| 619 | − PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_IMC), | |
| 623 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_Y_IMC), | |
| 620 | 624 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), |
| 621 | 625 | }, |
| 622 | 626 | { /* IMC */ |
| 623 | 627 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_U_IMC), |
| 624 | 628 | .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), |
| 625 | 629 | }, |
| 630 | + { /* IMC */ | |
| 631 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_HD_IMC), | |
| 632 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 633 | + }, | |
| 634 | + { /* IMC */ | |
| 635 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_HQ_IMC), | |
| 636 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 637 | + }, | |
| 638 | + { /* IMC */ | |
| 639 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_SD_IMC), | |
| 640 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 641 | + }, | |
| 642 | + { /* IMC */ | |
| 643 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_SQ_IMC), | |
| 644 | + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), | |
| 645 | + }, | |
| 626 | 646 | |
| 627 | 647 | { /* end: all zeroes */ }, |
| 628 | 648 | }; |
| @@ -666,8 +686,12 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = { · 37 unmodified lines | ||
| 666 | 686 | IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */ |
| 667 | 687 | IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */ |
| 668 | 688 | IMC_DEV(BDW_IMC, &bdw_uncore_pci_driver), /* 5th Gen Core U */ |
| 669 | − IMC_DEV(SKL_IMC, &skl_uncore_pci_driver), /* 6th Gen Core */ | |
| 689 | + IMC_DEV(SKL_Y_IMC, &skl_uncore_pci_driver), /* 6th Gen Core Y */ | |
| 670 | 690 | IMC_DEV(SKL_U_IMC, &skl_uncore_pci_driver), /* 6th Gen Core U */ |
| 691 | + IMC_DEV(SKL_HD_IMC, &skl_uncore_pci_driver), /* 6th Gen Core H Dual Core */ | |
| 692 | + IMC_DEV(SKL_HQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core H Quad Core */ | |
| 693 | + IMC_DEV(SKL_SD_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Dual Core */ | |
| 694 | + IMC_DEV(SKL_SQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Quad Core */ | |
| 671 | 695 | { /* end marker */ } |
| 672 | 696 | }; |
| 673 | 697 | |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | extern int intel_mid_pci_init(void); |
| 19 | 19 | extern int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state); |
| 20 | +extern pci_power_t intel_mid_pci_get_power_state(struct pci_dev *pdev); | |
| 20 | 21 | |
| 21 | 22 | extern void intel_mid_pwr_power_off(void); |
| 22 | 23 | |
| @@ -1042,8 +1042,11 @@ static int apm_get_power_status(u_short *status, u_short *bat, u_short *life) · 1041 unmodified lines | ||
| 1042 | 1042 | |
| 1043 | 1043 | if (apm_info.get_power_status_broken) |
| 1044 | 1044 | return APM_32_UNSUPPORTED; |
| 1045 | − if (apm_bios_call(&call)) | |
| 1045 | + if (apm_bios_call(&call)) { | |
| 1046 | + if (!call.err) | |
| 1047 | + return APM_NO_ERROR; | |
| 1046 | 1048 | return call.err; |
| 1049 | + } | |
| 1047 | 1050 | *status = call.ebx; |
| 1048 | 1051 | *bat = call.ecx; |
| 1049 | 1052 | if (apm_info.get_power_status_swabinminutes) { |
| @@ -347,7 +347,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c) · 346 unmodified lines | ||
| 347 | 347 | #ifdef CONFIG_SMP |
| 348 | 348 | unsigned bits; |
| 349 | 349 | int cpu = smp_processor_id(); |
| 350 | − unsigned int socket_id, core_complex_id; | |
| 351 | 350 | |
| 352 | 351 | bits = c->x86_coreid_bits; |
| 353 | 352 | /* Low order bits define the core id (index of core in socket) */ |
| @@ -365,10 +364,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c) · 11 unmodified lines | ||
| 365 | 364 | if (c->x86 != 0x17 || !cpuid_edx(0x80000006)) |
| 366 | 365 | return; |
| 367 | 366 | |
| 368 | − socket_id = (c->apicid >> bits) - 1; | |
| 369 | − core_complex_id = (c->apicid & ((1 << bits) - 1)) >> 3; | |
| 370 | − | |
| 371 | − per_cpu(cpu_llc_id, cpu) = (socket_id << 3) | core_complex_id; | |
| 367 | + per_cpu(cpu_llc_id, cpu) = c->apicid >> 3; | |
| 372 | 368 | #endif |
| 373 | 369 | } |
| 374 | 370 | |
| @@ -978,6 +978,35 @@ static void x86_init_cache_qos(struct cpuinfo_x86 *c) · 977 unmodified lines | ||
| 978 | 978 | } |
| 979 | 979 | } |
| 980 | 980 | |
| 981 | +/* | |
| 982 | + * The physical to logical package id mapping is initialized from the | |
| 983 | + * acpi/mptables information. Make sure that CPUID actually agrees with | |
| 984 | + * that. | |
| 985 | + */ | |
| 986 | +static void sanitize_package_id(struct cpuinfo_x86 *c) | |
| 987 | +{ | |
| 988 | +#ifdef CONFIG_SMP | |
| 989 | + unsigned int pkg, apicid, cpu = smp_processor_id(); | |
| 990 | + | |
| 991 | + apicid = apic->cpu_present_to_apicid(cpu); | |
| 992 | + pkg = apicid >> boot_cpu_data.x86_coreid_bits; | |
| 993 | + | |
| 994 | + if (apicid != c->initial_apicid) { | |
| 995 | + pr_err(FW_BUG "CPU%u: APIC id mismatch. Firmware: %x CPUID: %x\n", | |
| 996 | + cpu, apicid, c->initial_apicid); | |
| 997 | + c->initial_apicid = apicid; | |
| 998 | + } | |
| 999 | + if (pkg != c->phys_proc_id) { | |
| 1000 | + pr_err(FW_BUG "CPU%u: Using firmware package id %u instead of %u\n", | |
| 1001 | + cpu, pkg, c->phys_proc_id); | |
| 1002 | + c->phys_proc_id = pkg; | |
| 1003 | + } | |
| 1004 | + c->logical_proc_id = topology_phys_to_logical_pkg(pkg); | |
| 1005 | +#else | |
| 1006 | + c->logical_proc_id = 0; | |
| 1007 | +#endif | |
| 1008 | +} | |
| 1009 | + | |
| 981 | 1010 | /* |
| 982 | 1011 | * This does the hard work of actually picking apart the CPU stuff... |
| 983 | 1012 | */ |
| @@ -1103,8 +1132,7 @@ static void identify_cpu(struct cpuinfo_x86 *c) · 119 unmodified lines | ||
| 1103 | 1132 | #ifdef CONFIG_NUMA |
| 1104 | 1133 | numa_add_cpu(smp_processor_id()); |
| 1105 | 1134 | #endif |
| 1106 | − /* The boot/hotplug time assigment got cleared, restore it */ | |
| 1107 | − c->logical_proc_id = topology_phys_to_logical_pkg(c->phys_proc_id); | |
| 1135 | + sanitize_package_id(c); | |
| 1108 | 1136 | } |
| 1109 | 1137 | |
| 1110 | 1138 | /* |
| @@ -156,6 +156,16 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, · 155 unmodified lines | ||
| 156 | 156 | } |
| 157 | 157 | |
| 158 | 158 | |
| 159 | +static int kvm_hv_set_sint(struct kvm_kernel_irq_routing_entry *e, | |
| 160 | + struct kvm *kvm, int irq_source_id, int level, | |
| 161 | + bool line_status) | |
| 162 | +{ | |
| 163 | + if (!level) | |
| 164 | + return -1; | |
| 165 | + | |
| 166 | + return kvm_hv_synic_set_irq(kvm, e->hv_sint.vcpu, e->hv_sint.sint); | |
| 167 | +} | |
| 168 | + | |
| 159 | 169 | int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, |
| 160 | 170 | struct kvm *kvm, int irq_source_id, int level, |
| 161 | 171 | bool line_status) |
| @@ -163,18 +173,26 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e, · 1 unmodified line | ||
| 163 | 173 | struct kvm_lapic_irq irq; |
| 164 | 174 | int r; |
| 165 | 175 | |
| 166 | − if (unlikely(e->type != KVM_IRQ_ROUTING_MSI)) | |
| 167 | − return -EWOULDBLOCK; | |
| 176 | + switch (e->type) { | |
| 177 | + case KVM_IRQ_ROUTING_HV_SINT: | |
| 178 | + return kvm_hv_set_sint(e, kvm, irq_source_id, level, | |
| 179 | + line_status); | |
| 168 | 180 | |
| 169 | − if (kvm_msi_route_invalid(kvm, e)) | |
| 170 | − return -EINVAL; | |
| 181 | + case KVM_IRQ_ROUTING_MSI: | |
| 182 | + if (kvm_msi_route_invalid(kvm, e)) | |
| 183 | + return -EINVAL; | |
| 171 | 184 | |
| 172 | − kvm_set_msi_irq(kvm, e, &irq); | |
| 185 | + kvm_set_msi_irq(kvm, e, &irq); | |
| 173 | 186 | |
| 174 | − if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL)) | |
| 175 | − return r; | |
| 176 | − else | |
| 177 | − return -EWOULDBLOCK; | |
| 187 | + if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL)) | |
| 188 | + return r; | |
| 189 | + break; | |
| 190 | + | |
| 191 | + default: | |
| 192 | + break; | |
| 193 | + } | |
| 194 | + | |
| 195 | + return -EWOULDBLOCK; | |
| 178 | 196 | } |
| 179 | 197 | |
| 180 | 198 | int kvm_request_irq_source_id(struct kvm *kvm) |
| @@ -254,16 +272,6 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, · 73 unmodified lines | ||
| 254 | 272 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 255 | 273 | } |
| 256 | 274 | |
| 257 | −static int kvm_hv_set_sint(struct kvm_kernel_irq_routing_entry *e, | |
| 258 | − struct kvm *kvm, int irq_source_id, int level, | |
| 259 | − bool line_status) | |
| 260 | −{ | |
| 261 | − if (!level) | |
| 262 | − return -1; | |
| 263 | − | |
| 264 | − return kvm_hv_synic_set_irq(kvm, e->hv_sint.vcpu, e->hv_sint.sint); | |
| 265 | −} | |
| 266 | − | |
| 267 | 275 | int kvm_set_routing_entry(struct kvm *kvm, |
| 268 | 276 | struct kvm_kernel_irq_routing_entry *e, |
| 269 | 277 | const struct kvm_irq_routing_entry *ue) |
| @@ -423,18 +431,6 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, · 153 unmodified lines | ||
| 423 | 431 | srcu_read_unlock(&kvm->irq_srcu, idx); |
| 424 | 432 | } |
| 425 | 433 | |
| 426 | −int kvm_arch_set_irq(struct kvm_kernel_irq_routing_entry *irq, struct kvm *kvm, | |
| 427 | − int irq_source_id, int level, bool line_status) | |
| 428 | −{ | |
| 429 | − switch (irq->type) { | |
| 430 | − case KVM_IRQ_ROUTING_HV_SINT: | |
| 431 | − return kvm_hv_set_sint(irq, kvm, irq_source_id, level, | |
| 432 | − line_status); | |
| 433 | − default: | |
| 434 | − return -EWOULDBLOCK; | |
| 435 | − } | |
| 436 | −} | |
| 437 | − | |
| 438 | 434 | void kvm_arch_irq_routing_update(struct kvm *kvm) |
| 439 | 435 | { |
| 440 | 436 | kvm_hv_irq_routing_update(kvm); |
| @@ -210,7 +210,18 @@ static void kvm_on_user_return(struct user_return_notifier *urn) · 209 unmodified lines | ||
| 210 | 210 | struct kvm_shared_msrs *locals |
| 211 | 211 | = container_of(urn, struct kvm_shared_msrs, urn); |
| 212 | 212 | struct kvm_shared_msr_values *values; |
| 213 | + unsigned long flags; | |
| 213 | 214 | |
| 215 | + /* | |
| 216 | + * Disabling irqs at this point since the following code could be | |
| 217 | + * interrupted and executed through kvm_arch_hardware_disable() | |
| 218 | + */ | |
| 219 | + local_irq_save(flags); | |
| 220 | + if (locals->registered) { | |
| 221 | + locals->registered = false; | |
| 222 | + user_return_notifier_unregister(urn); | |
| 223 | + } | |
| 224 | + local_irq_restore(flags); | |
| 214 | 225 | for (slot = 0; slot < shared_msrs_global.nr; ++slot) { |
| 215 | 226 | values = &locals->values[slot]; |
| 216 | 227 | if (values->host != values->curr) { |
| @@ -218,8 +229,6 @@ static void kvm_on_user_return(struct user_return_notifier *urn) · 1 unmodified line | ||
| 218 | 229 | values->curr = values->host; |
| 219 | 230 | } |
| 220 | 231 | } |
| 221 | − locals->registered = false; | |
| 222 | − user_return_notifier_unregister(urn); | |
| 223 | 232 | } |
| 224 | 233 | |
| 225 | 234 | static void shared_msr_update(unsigned slot, u32 msr) |
| @@ -1724,18 +1733,23 @@ static void kvm_gen_update_masterclock(struct kvm *kvm) · 1498 unmodified lines | ||
| 1724 | 1733 | |
| 1725 | 1734 | static u64 __get_kvmclock_ns(struct kvm *kvm) |
| 1726 | 1735 | { |
| 1727 | − struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, 0); | |
| 1728 | 1736 | struct kvm_arch *ka = &kvm->arch; |
| 1729 | − s64 ns; | |
| 1737 | + struct pvclock_vcpu_time_info hv_clock; | |
| 1730 | 1738 | |
| 1731 | − if (vcpu->arch.hv_clock.flags & PVCLOCK_TSC_STABLE_BIT) { | |
| 1732 | − u64 tsc = kvm_read_l1_tsc(vcpu, rdtsc()); | |
| 1733 | − ns = __pvclock_read_cycles(&vcpu->arch.hv_clock, tsc); | |
| 1734 | − } else { | |
| 1735 | − ns = ktime_get_boot_ns() + ka->kvmclock_offset; | |
| 1739 | + spin_lock(&ka->pvclock_gtod_sync_lock); | |
| 1740 | + if (!ka->use_master_clock) { | |
| 1741 | + spin_unlock(&ka->pvclock_gtod_sync_lock); | |
| 1742 | + return ktime_get_boot_ns() + ka->kvmclock_offset; | |
| 1736 | 1743 | } |
| 1737 | 1744 | |
| 1738 | − return ns; | |
| 1745 | + hv_clock.tsc_timestamp = ka->master_cycle_now; | |
| 1746 | + hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset; | |
| 1747 | + spin_unlock(&ka->pvclock_gtod_sync_lock); | |
| 1748 | + | |
| 1749 | + kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL, | |
| 1750 | + &hv_clock.tsc_shift, | |
| 1751 | + &hv_clock.tsc_to_system_mul); | |
| 1752 | + return __pvclock_read_cycles(&hv_clock, rdtsc()); | |
| 1739 | 1753 | } |
| 1740 | 1754 | |
| 1741 | 1755 | u64 get_kvmclock_ns(struct kvm *kvm) |
| @@ -2596,7 +2610,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 854 unmodified lines | ||
| 2596 | 2610 | case KVM_CAP_PIT_STATE2: |
| 2597 | 2611 | case KVM_CAP_SET_IDENTITY_MAP_ADDR: |
| 2598 | 2612 | case KVM_CAP_XEN_HVM: |
| 2599 | − case KVM_CAP_ADJUST_CLOCK: | |
| 2600 | 2613 | case KVM_CAP_VCPU_EVENTS: |
| 2601 | 2614 | case KVM_CAP_HYPERV: |
| 2602 | 2615 | case KVM_CAP_HYPERV_VAPIC: |
| @@ -2623,6 +2636,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 20 unmodified lines | ||
| 2623 | 2636 | #endif |
| 2624 | 2637 | r = 1; |
| 2625 | 2638 | break; |
| 2639 | + case KVM_CAP_ADJUST_CLOCK: | |
| 2640 | + r = KVM_CLOCK_TSC_STABLE; | |
| 2641 | + break; | |
| 2626 | 2642 | case KVM_CAP_X86_SMM: |
| 2627 | 2643 | /* SMBASE is usually relocated above 1M on modern chipsets, |
| 2628 | 2644 | * and SMM handlers might indeed rely on 4G segment limits, |
| @@ -3415,6 +3431,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 786 unmodified lines | ||
| 3415 | 3431 | }; |
| 3416 | 3432 | case KVM_SET_VAPIC_ADDR: { |
| 3417 | 3433 | struct kvm_vapic_addr va; |
| 3434 | + int idx; | |
| 3418 | 3435 | |
| 3419 | 3436 | r = -EINVAL; |
| 3420 | 3437 | if (!lapic_in_kernel(vcpu)) |
| @@ -3422,7 +3439,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 1 unmodified line | ||
| 3422 | 3439 | r = -EFAULT; |
| 3423 | 3440 | if (copy_from_user(&va, argp, sizeof va)) |
| 3424 | 3441 | goto out; |
| 3442 | + idx = srcu_read_lock(&vcpu->kvm->srcu); | |
| 3425 | 3443 | r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); |
| 3444 | + srcu_read_unlock(&vcpu->kvm->srcu, idx); | |
| 3426 | 3445 | break; |
| 3427 | 3446 | } |
| 3428 | 3447 | case KVM_X86_SETUP_MCE: { |
| @@ -4103,9 +4122,11 @@ long kvm_arch_vm_ioctl(struct file *filp, · 674 unmodified lines | ||
| 4103 | 4122 | struct kvm_clock_data user_ns; |
| 4104 | 4123 | u64 now_ns; |
| 4105 | 4124 | |
| 4106 | − now_ns = get_kvmclock_ns(kvm); | |
| 4125 | + local_irq_disable(); | |
| 4126 | + now_ns = __get_kvmclock_ns(kvm); | |
| 4107 | 4127 | user_ns.clock = now_ns; |
| 4108 | − user_ns.flags = 0; | |
| 4128 | + user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0; | |
| 4129 | + local_irq_enable(); | |
| 4109 | 4130 | memset(&user_ns.pad, 0, sizeof(user_ns.pad)); |
| 4110 | 4131 | |
| 4111 | 4132 | r = -EFAULT; |
| @@ -861,7 +861,7 @@ static void __init __efi_enter_virtual_mode(void) · 860 unmodified lines | ||
| 861 | 861 | int count = 0, pg_shift = 0; |
| 862 | 862 | void *new_memmap = NULL; |
| 863 | 863 | efi_status_t status; |
| 864 | − phys_addr_t pa; | |
| 864 | + unsigned long pa; | |
| 865 | 865 | |
| 866 | 866 | efi.systab = NULL; |
| 867 | 867 | |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <linux/io.h> |
| 32 | 32 | #include <linux/reboot.h> |
| 33 | 33 | #include <linux/slab.h> |
| 34 | +#include <linux/ucs2_string.h> | |
| 34 | 35 | |
| 35 | 36 | #include <asm/setup.h> |
| 36 | 37 | #include <asm/page.h> |
| @@ -211,6 +212,35 @@ void efi_sync_low_kernel_mappings(void) · 174 unmodified lines | ||
| 211 | 212 | memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); |
| 212 | 213 | } |
| 213 | 214 | |
| 215 | +/* | |
| 216 | + * Wrapper for slow_virt_to_phys() that handles NULL addresses. | |
| 217 | + */ | |
| 218 | +static inline phys_addr_t | |
| 219 | +virt_to_phys_or_null_size(void *va, unsigned long size) | |
| 220 | +{ | |
| 221 | + bool bad_size; | |
| 222 | + | |
| 223 | + if (!va) | |
| 224 | + return 0; | |
| 225 | + | |
| 226 | + if (virt_addr_valid(va)) | |
| 227 | + return virt_to_phys(va); | |
| 228 | + | |
| 229 | + /* | |
| 230 | + * A fully aligned variable on the stack is guaranteed not to | |
| 231 | + * cross a page bounary. Try to catch strings on the stack by | |
| 232 | + * checking that 'size' is a power of two. | |
| 233 | + */ | |
| 234 | + bad_size = size > PAGE_SIZE || !is_power_of_2(size); | |
| 235 | + | |
| 236 | + WARN_ON(!IS_ALIGNED((unsigned long)va, size) || bad_size); | |
| 237 | + | |
| 238 | + return slow_virt_to_phys(va); | |
| 239 | +} | |
| 240 | + | |
| 241 | +#define virt_to_phys_or_null(addr) \ | |
| 242 | + virt_to_phys_or_null_size((addr), sizeof(*(addr))) | |
| 243 | + | |
| 214 | 244 | int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) |
| 215 | 245 | { |
| 216 | 246 | unsigned long pfn, text; |
| @@ -494,8 +524,8 @@ static efi_status_t efi_thunk_get_time(efi_time_t *tm, efi_time_cap_t *tc) · 277 unmodified lines | ||
| 494 | 524 | |
| 495 | 525 | spin_lock(&rtc_lock); |
| 496 | 526 | |
| 497 | − phys_tm = virt_to_phys(tm); | |
| 498 | − phys_tc = virt_to_phys(tc); | |
| 527 | + phys_tm = virt_to_phys_or_null(tm); | |
| 528 | + phys_tc = virt_to_phys_or_null(tc); | |
| 499 | 529 | |
| 500 | 530 | status = efi_thunk(get_time, phys_tm, phys_tc); |
| 501 | 531 | |
| @@ -511,7 +541,7 @@ static efi_status_t efi_thunk_set_time(efi_time_t *tm) · 9 unmodified lines | ||
| 511 | 541 | |
| 512 | 542 | spin_lock(&rtc_lock); |
| 513 | 543 | |
| 514 | − phys_tm = virt_to_phys(tm); | |
| 544 | + phys_tm = virt_to_phys_or_null(tm); | |
| 515 | 545 | |
| 516 | 546 | status = efi_thunk(set_time, phys_tm); |
| 517 | 547 | |
| @@ -529,9 +559,9 @@ efi_thunk_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending, · 11 unmodified lines | ||
| 529 | 559 | |
| 530 | 560 | spin_lock(&rtc_lock); |
| 531 | 561 | |
| 532 | − phys_enabled = virt_to_phys(enabled); | |
| 533 | − phys_pending = virt_to_phys(pending); | |
| 534 | − phys_tm = virt_to_phys(tm); | |
| 562 | + phys_enabled = virt_to_phys_or_null(enabled); | |
| 563 | + phys_pending = virt_to_phys_or_null(pending); | |
| 564 | + phys_tm = virt_to_phys_or_null(tm); | |
| 535 | 565 | |
| 536 | 566 | status = efi_thunk(get_wakeup_time, phys_enabled, |
| 537 | 567 | phys_pending, phys_tm); |
| @@ -549,7 +579,7 @@ efi_thunk_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) · 11 unmodified lines | ||
| 549 | 579 | |
| 550 | 580 | spin_lock(&rtc_lock); |
| 551 | 581 | |
| 552 | − phys_tm = virt_to_phys(tm); | |
| 582 | + phys_tm = virt_to_phys_or_null(tm); | |
| 553 | 583 | |
| 554 | 584 | status = efi_thunk(set_wakeup_time, enabled, phys_tm); |
| 555 | 585 | |
| @@ -558,6 +588,10 @@ efi_thunk_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) · 2 unmodified lines | ||
| 558 | 588 | return status; |
| 559 | 589 | } |
| 560 | 590 | |
| 591 | +static unsigned long efi_name_size(efi_char16_t *name) | |
| 592 | +{ | |
| 593 | + return ucs2_strsize(name, EFI_VAR_NAME_LEN) + 1; | |
| 594 | +} | |
| 561 | 595 | |
| 562 | 596 | static efi_status_t |
| 563 | 597 | efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor, |
| @@ -567,11 +601,11 @@ efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor, · 3 unmodified lines | ||
| 567 | 601 | u32 phys_name, phys_vendor, phys_attr; |
| 568 | 602 | u32 phys_data_size, phys_data; |
| 569 | 603 | |
| 570 | − phys_data_size = virt_to_phys(data_size); | |
| 571 | − phys_vendor = virt_to_phys(vendor); | |
| 572 | − phys_name = virt_to_phys(name); | |
| 573 | − phys_attr = virt_to_phys(attr); | |
| 574 | − phys_data = virt_to_phys(data); | |
| 604 | + phys_data_size = virt_to_phys_or_null(data_size); | |
| 605 | + phys_vendor = virt_to_phys_or_null(vendor); | |
| 606 | + phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); | |
| 607 | + phys_attr = virt_to_phys_or_null(attr); | |
| 608 | + phys_data = virt_to_phys_or_null_size(data, *data_size); | |
| 575 | 609 | |
| 576 | 610 | status = efi_thunk(get_variable, phys_name, phys_vendor, |
| 577 | 611 | phys_attr, phys_data_size, phys_data); |
| @@ -586,9 +620,9 @@ efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor, · 8 unmodified lines | ||
| 586 | 620 | u32 phys_name, phys_vendor, phys_data; |
| 587 | 621 | efi_status_t status; |
| 588 | 622 | |
| 589 | − phys_name = virt_to_phys(name); | |
| 590 | − phys_vendor = virt_to_phys(vendor); | |
| 591 | − phys_data = virt_to_phys(data); | |
| 623 | + phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); | |
| 624 | + phys_vendor = virt_to_phys_or_null(vendor); | |
| 625 | + phys_data = virt_to_phys_or_null_size(data, data_size); | |
| 592 | 626 | |
| 593 | 627 | /* If data_size is > sizeof(u32) we've got problems */ |
| 594 | 628 | status = efi_thunk(set_variable, phys_name, phys_vendor, |
| @@ -605,9 +639,9 @@ efi_thunk_get_next_variable(unsigned long *name_size, · 10 unmodified lines | ||
| 605 | 639 | efi_status_t status; |
| 606 | 640 | u32 phys_name_size, phys_name, phys_vendor; |
| 607 | 641 | |
| 608 | − phys_name_size = virt_to_phys(name_size); | |
| 609 | − phys_vendor = virt_to_phys(vendor); | |
| 610 | − phys_name = virt_to_phys(name); | |
| 642 | + phys_name_size = virt_to_phys_or_null(name_size); | |
| 643 | + phys_vendor = virt_to_phys_or_null(vendor); | |
| 644 | + phys_name = virt_to_phys_or_null_size(name, *name_size); | |
| 611 | 645 | |
| 612 | 646 | status = efi_thunk(get_next_variable, phys_name_size, |
| 613 | 647 | phys_name, phys_vendor); |
| @@ -621,7 +655,7 @@ efi_thunk_get_next_high_mono_count(u32 *count) · 7 unmodified lines | ||
| 621 | 655 | efi_status_t status; |
| 622 | 656 | u32 phys_count; |
| 623 | 657 | |
| 624 | − phys_count = virt_to_phys(count); | |
| 658 | + phys_count = virt_to_phys_or_null(count); | |
| 625 | 659 | status = efi_thunk(get_next_high_mono_count, phys_count); |
| 626 | 660 | |
| 627 | 661 | return status; |
| @@ -633,7 +667,7 @@ efi_thunk_reset_system(int reset_type, efi_status_t status, · 5 unmodified lines | ||
| 633 | 667 | { |
| 634 | 668 | u32 phys_data; |
| 635 | 669 | |
| 636 | − phys_data = virt_to_phys(data); | |
| 670 | + phys_data = virt_to_phys_or_null_size(data, data_size); | |
| 637 | 671 | |
| 638 | 672 | efi_thunk(reset_system, reset_type, status, data_size, phys_data); |
| 639 | 673 | } |
| @@ -661,9 +695,9 @@ efi_thunk_query_variable_info(u32 attr, u64 *storage_space, · 21 unmodified lines | ||
| 661 | 695 | if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) |
| 662 | 696 | return EFI_UNSUPPORTED; |
| 663 | 697 | |
| 664 | − phys_storage = virt_to_phys(storage_space); | |
| 665 | − phys_remaining = virt_to_phys(remaining_space); | |
| 666 | − phys_max = virt_to_phys(max_variable_size); | |
| 698 | + phys_storage = virt_to_phys_or_null(storage_space); | |
| 699 | + phys_remaining = virt_to_phys_or_null(remaining_space); | |
| 700 | + phys_max = virt_to_phys_or_null(max_variable_size); | |
| 667 | 701 | |
| 668 | 702 | status = efi_thunk(query_variable_info, attr, phys_storage, |
| 669 | 703 | phys_remaining, phys_max); |
| @@ -272,6 +272,25 @@ int intel_mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state) · 271 unmodified lines | ||
| 272 | 272 | } |
| 273 | 273 | EXPORT_SYMBOL_GPL(intel_mid_pci_set_power_state); |
| 274 | 274 | |
| 275 | +pci_power_t intel_mid_pci_get_power_state(struct pci_dev *pdev) | |
| 276 | +{ | |
| 277 | + struct mid_pwr *pwr = midpwr; | |
| 278 | + int id, reg, bit; | |
| 279 | + u32 power; | |
| 280 | + | |
| 281 | + if (!pwr || !pwr->available) | |
| 282 | + return PCI_UNKNOWN; | |
| 283 | + | |
| 284 | + id = intel_mid_pwr_get_lss_id(pdev); | |
| 285 | + if (id < 0) | |
| 286 | + return PCI_UNKNOWN; | |
| 287 | + | |
| 288 | + reg = (id * LSS_PWS_BITS) / 32; | |
| 289 | + bit = (id * LSS_PWS_BITS) % 32; | |
| 290 | + power = mid_pwr_get_state(pwr, reg); | |
| 291 | + return (__force pci_power_t)((power >> bit) & 3); | |
| 292 | +} | |
| 293 | + | |
| 275 | 294 | void intel_mid_pwr_power_off(void) |
| 276 | 295 | { |
| 277 | 296 | struct mid_pwr *pwr = midpwr; |
| @@ -16,6 +16,7 @@ KCOV_INSTRUMENT := n · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -MD -Os -mcmodel=large |
| 18 | 18 | KBUILD_CFLAGS += -m$(BITS) |
| 19 | +KBUILD_CFLAGS += $(call cc-option,-fno-PIE) | |
| 19 | 20 | |
| 20 | 21 | $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE |
| 21 | 22 | $(call if_changed,ld) |
| @@ -767,7 +767,14 @@ __SYSCALL(346, sys_preadv2, 6) · 766 unmodified lines | ||
| 767 | 767 | #define __NR_pwritev2 347 |
| 768 | 768 | __SYSCALL(347, sys_pwritev2, 6) |
| 769 | 769 | |
| 770 | −#define __NR_syscall_count 348 | |
| 770 | +#define __NR_pkey_mprotect 348 | |
| 771 | +__SYSCALL(348, sys_pkey_mprotect, 4) | |
| 772 | +#define __NR_pkey_alloc 349 | |
| 773 | +__SYSCALL(349, sys_pkey_alloc, 2) | |
| 774 | +#define __NR_pkey_free 350 | |
| 775 | +__SYSCALL(350, sys_pkey_free, 1) | |
| 776 | + | |
| 777 | +#define __NR_syscall_count 351 | |
| 771 | 778 | |
| 772 | 779 | /* |
| 773 | 780 | * sysxtensa syscall handler |
| @@ -172,10 +172,11 @@ void __init time_init(void) · 171 unmodified lines | ||
| 172 | 172 | { |
| 173 | 173 | of_clk_init(NULL); |
| 174 | 174 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT |
| 175 | − printk("Calibrating CPU frequency "); | |
| 175 | + pr_info("Calibrating CPU frequency "); | |
| 176 | 176 | calibrate_ccount(); |
| 177 | − printk("%d.%02d MHz\n", (int)ccount_freq/1000000, | |
| 178 | − (int)(ccount_freq/10000)%100); | |
| 177 | + pr_cont("%d.%02d MHz\n", | |
| 178 | + (int)ccount_freq / 1000000, | |
| 179 | + (int)(ccount_freq / 10000) % 100); | |
| 179 | 180 | #else |
| 180 | 181 | ccount_freq = CONFIG_XTENSA_CPU_CLOCK*1000000UL; |
| 181 | 182 | #endif |
| @@ -210,9 +211,8 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) · 28 unmodified lines | ||
| 210 | 211 | void calibrate_delay(void) |
| 211 | 212 | { |
| 212 | 213 | loops_per_jiffy = ccount_freq / HZ; |
| 213 | − printk("Calibrating delay loop (skipped)... " | |
| 214 | − "%lu.%02lu BogoMIPS preset\n", | |
| 215 | − loops_per_jiffy/(1000000/HZ), | |
| 216 | − (loops_per_jiffy/(10000/HZ)) % 100); | |
| 214 | + pr_info("Calibrating delay loop (skipped)... %lu.%02lu BogoMIPS preset\n", | |
| 215 | + loops_per_jiffy / (1000000 / HZ), | |
| 216 | + (loops_per_jiffy / (10000 / HZ)) % 100); | |
| 217 | 217 | } |
| 218 | 218 | #endif |
| @@ -465,26 +465,25 @@ void show_regs(struct pt_regs * regs) · 464 unmodified lines | ||
| 465 | 465 | |
| 466 | 466 | for (i = 0; i < 16; i++) { |
| 467 | 467 | if ((i % 8) == 0) |
| 468 | − printk(KERN_INFO "a%02d:", i); | |
| 469 | − printk(KERN_CONT " %08lx", regs->areg[i]); | |
| 468 | + pr_info("a%02d:", i); | |
| 469 | + pr_cont(" %08lx", regs->areg[i]); | |
| 470 | 470 | } |
| 471 | − printk(KERN_CONT "\n"); | |
| 472 | − | |
| 473 | − printk("pc: %08lx, ps: %08lx, depc: %08lx, excvaddr: %08lx\n", | |
| 474 | − regs->pc, regs->ps, regs->depc, regs->excvaddr); | |
| 475 | − printk("lbeg: %08lx, lend: %08lx lcount: %08lx, sar: %08lx\n", | |
| 476 | − regs->lbeg, regs->lend, regs->lcount, regs->sar); | |
| 471 | + pr_cont("\n"); | |
| 472 | + pr_info("pc: %08lx, ps: %08lx, depc: %08lx, excvaddr: %08lx\n", | |
| 473 | + regs->pc, regs->ps, regs->depc, regs->excvaddr); | |
| 474 | + pr_info("lbeg: %08lx, lend: %08lx lcount: %08lx, sar: %08lx\n", | |
| 475 | + regs->lbeg, regs->lend, regs->lcount, regs->sar); | |
| 477 | 476 | if (user_mode(regs)) |
| 478 | − printk("wb: %08lx, ws: %08lx, wmask: %08lx, syscall: %ld\n", | |
| 479 | − regs->windowbase, regs->windowstart, regs->wmask, | |
| 480 | − regs->syscall); | |
| 477 | + pr_cont("wb: %08lx, ws: %08lx, wmask: %08lx, syscall: %ld\n", | |
| 478 | + regs->windowbase, regs->windowstart, regs->wmask, | |
| 479 | + regs->syscall); | |
| 481 | 480 | } |
| 482 | 481 | |
| 483 | 482 | static int show_trace_cb(struct stackframe *frame, void *data) |
| 484 | 483 | { |
| 485 | 484 | if (kernel_text_address(frame->pc)) { |
| 486 | − printk(" [<%08lx>] ", frame->pc); | |
| 487 | − print_symbol("%s\n", frame->pc); | |
| 485 | + pr_cont(" [<%08lx>]", frame->pc); | |
| 486 | + print_symbol(" %s\n", frame->pc); | |
| 488 | 487 | } |
| 489 | 488 | return 0; |
| 490 | 489 | } |
| @@ -494,19 +493,13 @@ void show_trace(struct task_struct *task, unsigned long *sp) · 3 unmodified lines | ||
| 494 | 493 | if (!sp) |
| 495 | 494 | sp = stack_pointer(task); |
| 496 | 495 | |
| 497 | − printk("Call Trace:"); | |
| 498 | −#ifdef CONFIG_KALLSYMS | |
| 499 | − printk("\n"); | |
| 500 | −#endif | |
| 496 | + pr_info("Call Trace:\n"); | |
| 501 | 497 | walk_stackframe(sp, show_trace_cb, NULL); |
| 502 | − printk("\n"); | |
| 498 | +#ifndef CONFIG_KALLSYMS | |
| 499 | + pr_cont("\n"); | |
| 500 | +#endif | |
| 503 | 501 | } |
| 504 | 502 | |
| 505 | −/* | |
| 506 | − * This routine abuses get_user()/put_user() to reference pointers | |
| 507 | − * with at least a bit of error checking ... | |
| 508 | − */ | |
| 509 | − | |
| 510 | 503 | static int kstack_depth_to_print = 24; |
| 511 | 504 | |
| 512 | 505 | void show_stack(struct task_struct *task, unsigned long *sp) |
| @@ -518,52 +511,29 @@ void show_stack(struct task_struct *task, unsigned long *sp) · 5 unmodified lines | ||
| 518 | 511 | sp = stack_pointer(task); |
| 519 | 512 | stack = sp; |
| 520 | 513 | |
| 521 | − printk("\nStack: "); | |
| 514 | + pr_info("Stack:\n"); | |
| 522 | 515 | |
| 523 | 516 | for (i = 0; i < kstack_depth_to_print; i++) { |
| 524 | 517 | if (kstack_end(sp)) |
| 525 | 518 | break; |
| 526 | − if (i && ((i % 8) == 0)) | |
| 527 | − printk("\n "); | |
| 528 | − printk("%08lx ", *sp++); | |
| 519 | + pr_cont(" %08lx", *sp++); | |
| 520 | + if (i % 8 == 7) | |
| 521 | + pr_cont("\n"); | |
| 529 | 522 | } |
| 530 | − printk("\n"); | |
| 531 | 523 | show_trace(task, stack); |
| 532 | 524 | } |
| 533 | 525 | |
| 534 | −void show_code(unsigned int *pc) | |
| 535 | −{ | |
| 536 | − long i; | |
| 537 | − | |
| 538 | − printk("\nCode:"); | |
| 539 | − | |
| 540 | − for(i = -3 ; i < 6 ; i++) { | |
| 541 | − unsigned long insn; | |
| 542 | − if (__get_user(insn, pc + i)) { | |
| 543 | − printk(" (Bad address in pc)\n"); | |
| 544 | − break; | |
| 545 | − } | |
| 546 | − printk("%c%08lx%c",(i?' ':'<'),insn,(i?' ':'>')); | |
| 547 | − } | |
| 548 | −} | |
| 549 | − | |
| 550 | 526 | DEFINE_SPINLOCK(die_lock); |
| 551 | 527 | |
| 552 | 528 | void die(const char * str, struct pt_regs * regs, long err) |
| 553 | 529 | { |
| 554 | 530 | static int die_counter; |
| 555 | − int nl = 0; | |
| 556 | 531 | |
| 557 | 532 | console_verbose(); |
| 558 | 533 | spin_lock_irq(&die_lock); |
| 559 | 534 | |
| 560 | − printk("%s: sig: %ld [#%d]\n", str, err, ++die_counter); | |
| 561 | −#ifdef CONFIG_PREEMPT | |
| 562 | − printk("PREEMPT "); | |
| 563 | − nl = 1; | |
| 564 | −#endif | |
| 565 | − if (nl) | |
| 566 | − printk("\n"); | |
| 535 | + pr_info("%s: sig: %ld [#%d]%s\n", str, err, ++die_counter, | |
| 536 | + IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : ""); | |
| 567 | 537 | show_regs(regs); |
| 568 | 538 | if (!user_mode(regs)) |
| 569 | 539 | show_stack(NULL, (unsigned long*)regs->areg[1]); |
| @@ -214,23 +214,26 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, · 213 unmodified lines | ||
| 214 | 214 | |
| 215 | 215 | ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0); |
| 216 | 216 | |
| 217 | − if (ctx->more) { | |
| 217 | + if (!result) { | |
| 218 | + err = af_alg_wait_for_completion( | |
| 219 | + crypto_ahash_init(&ctx->req), | |
| 220 | + &ctx->completion); | |
| 221 | + if (err) | |
| 222 | + goto unlock; | |
| 223 | + } | |
| 224 | + | |
| 225 | + if (!result || ctx->more) { | |
| 218 | 226 | ctx->more = 0; |
| 219 | 227 | err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req), |
| 220 | 228 | &ctx->completion); |
| 221 | 229 | if (err) |
| 222 | 230 | goto unlock; |
| 223 | − } else if (!result) { | |
| 224 | − err = af_alg_wait_for_completion( | |
| 225 | − crypto_ahash_digest(&ctx->req), | |
| 226 | − &ctx->completion); | |
| 227 | 231 | } |
| 228 | 232 | |
| 229 | 233 | err = memcpy_to_msg(msg, ctx->result, len); |
| 230 | 234 | |
| 231 | − hash_free_result(sk, ctx); | |
| 232 | − | |
| 233 | 235 | unlock: |
| 236 | + hash_free_result(sk, ctx); | |
| 234 | 237 | release_sock(sk); |
| 235 | 238 | |
| 236 | 239 | return err ?: len; |
| @@ -122,7 +122,7 @@ static int acpi_apd_create_device(struct acpi_device *adev, · 121 unmodified lines | ||
| 122 | 122 | int ret; |
| 123 | 123 | |
| 124 | 124 | if (!dev_desc) { |
| 125 | − pdev = acpi_create_platform_device(adev); | |
| 125 | + pdev = acpi_create_platform_device(adev, NULL); | |
| 126 | 126 | return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1; |
| 127 | 127 | } |
| 128 | 128 | |
| @@ -139,14 +139,8 @@ static int acpi_apd_create_device(struct acpi_device *adev, · 10 unmodified lines | ||
| 139 | 139 | goto err_out; |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | − if (dev_desc->properties) { | |
| 143 | − ret = device_add_properties(&adev->dev, dev_desc->properties); | |
| 144 | − if (ret) | |
| 145 | − goto err_out; | |
| 146 | − } | |
| 147 | − | |
| 148 | 142 | adev->driver_data = pdata; |
| 149 | − pdev = acpi_create_platform_device(adev); | |
| 143 | + pdev = acpi_create_platform_device(adev, dev_desc->properties); | |
| 150 | 144 | if (!IS_ERR_OR_NULL(pdev)) |
| 151 | 145 | return 1; |
| 152 | 146 | |
| @@ -395,7 +395,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev, · 394 unmodified lines | ||
| 395 | 395 | |
| 396 | 396 | dev_desc = (const struct lpss_device_desc *)id->driver_data; |
| 397 | 397 | if (!dev_desc) { |
| 398 | − pdev = acpi_create_platform_device(adev); | |
| 398 | + pdev = acpi_create_platform_device(adev, NULL); | |
| 399 | 399 | return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1; |
| 400 | 400 | } |
| 401 | 401 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
| @@ -451,14 +451,8 @@ static int acpi_lpss_create_device(struct acpi_device *adev, · 49 unmodified lines | ||
| 451 | 451 | goto err_out; |
| 452 | 452 | } |
| 453 | 453 | |
| 454 | − if (dev_desc->properties) { | |
| 455 | − ret = device_add_properties(&adev->dev, dev_desc->properties); | |
| 456 | − if (ret) | |
| 457 | − goto err_out; | |
| 458 | − } | |
| 459 | − | |
| 460 | 454 | adev->driver_data = pdata; |
| 461 | − pdev = acpi_create_platform_device(adev); | |
| 455 | + pdev = acpi_create_platform_device(adev, dev_desc->properties); | |
| 462 | 456 | if (!IS_ERR_OR_NULL(pdev)) { |
| 463 | 457 | return 1; |
| 464 | 458 | } |
| @@ -50,6 +50,7 @@ static void acpi_platform_fill_resource(struct acpi_device *adev, · 49 unmodified lines | ||
| 50 | 50 | /** |
| 51 | 51 | * acpi_create_platform_device - Create platform device for ACPI device node |
| 52 | 52 | * @adev: ACPI device node to create a platform device for. |
| 53 | + * @properties: Optional collection of build-in properties. | |
| 53 | 54 | * |
| 54 | 55 | * Check if the given @adev can be represented as a platform device and, if |
| 55 | 56 | * that's the case, create and register a platform device, populate its common |
| @@ -57,7 +58,8 @@ static void acpi_platform_fill_resource(struct acpi_device *adev, · 1 unmodified line | ||
| 57 | 58 | * |
| 58 | 59 | * Name of the platform device will be the same as @adev's. |
| 59 | 60 | */ |
| 60 | −struct platform_device *acpi_create_platform_device(struct acpi_device *adev) | |
| 61 | +struct platform_device *acpi_create_platform_device(struct acpi_device *adev, | |
| 62 | + struct property_entry *properties) | |
| 61 | 63 | { |
| 62 | 64 | struct platform_device *pdev = NULL; |
| 63 | 65 | struct platform_device_info pdevinfo; |
| @@ -106,6 +108,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) · 42 unmodified lines | ||
| 106 | 108 | pdevinfo.res = resources; |
| 107 | 109 | pdevinfo.num_res = count; |
| 108 | 110 | pdevinfo.fwnode = acpi_fwnode_handle(adev); |
| 111 | + pdevinfo.properties = properties; | |
| 109 | 112 | |
| 110 | 113 | if (acpi_dma_supported(adev)) |
| 111 | 114 | pdevinfo.dma_mask = DMA_BIT_MASK(32); |
| @@ -480,19 +480,17 @@ static void acpi_tb_convert_fadt(void) · 479 unmodified lines | ||
| 480 | 480 | u32 i; |
| 481 | 481 | |
| 482 | 482 | /* |
| 483 | − * For ACPI 1.0 FADTs (revision 1), ensure that reserved fields which | |
| 483 | + * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which | |
| 484 | 484 | * should be zero are indeed zero. This will workaround BIOSs that |
| 485 | 485 | * inadvertently place values in these fields. |
| 486 | 486 | * |
| 487 | 487 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located |
| 488 | 488 | * at offset 45, 55, 95, and the word located at offset 109, 110. |
| 489 | 489 | * |
| 490 | − * Note: The FADT revision value is unreliable because of BIOS errors. | |
| 491 | − * The table length is instead used as the final word on the version. | |
| 492 | − * | |
| 493 | − * Note: FADT revision 3 is the ACPI 2.0 version of the FADT. | |
| 490 | + * Note: The FADT revision value is unreliable. Only the length can be | |
| 491 | + * trusted. | |
| 494 | 492 | */ |
| 495 | − if (acpi_gbl_FADT.header.length <= ACPI_FADT_V3_SIZE) { | |
| 493 | + if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) { | |
| 496 | 494 | acpi_gbl_FADT.preferred_profile = 0; |
| 497 | 495 | acpi_gbl_FADT.pstate_control = 0; |
| 498 | 496 | acpi_gbl_FADT.cst_control = 0; |
| @@ -34,11 +34,11 @@ static int int340x_thermal_handler_attach(struct acpi_device *adev, · 33 unmodified lines | ||
| 34 | 34 | const struct acpi_device_id *id) |
| 35 | 35 | { |
| 36 | 36 | if (IS_ENABLED(CONFIG_INT340X_THERMAL)) |
| 37 | − acpi_create_platform_device(adev); | |
| 37 | + acpi_create_platform_device(adev, NULL); | |
| 38 | 38 | /* Intel SoC DTS thermal driver needs INT3401 to set IRQ descriptor */ |
| 39 | 39 | else if (IS_ENABLED(CONFIG_INTEL_SOC_DTS_THERMAL) && |
| 40 | 40 | id->driver_data == INT3401_DEVICE) |
| 41 | − acpi_create_platform_device(adev); | |
| 41 | + acpi_create_platform_device(adev, NULL); | |
| 42 | 42 | return 1; |
| 43 | 43 | } |
| 44 | 44 | |
| @@ -1734,7 +1734,7 @@ static void acpi_default_enumeration(struct acpi_device *device) · 1733 unmodified lines | ||
| 1734 | 1734 | &is_spi_i2c_slave); |
| 1735 | 1735 | acpi_dev_free_resource_list(&resource_list); |
| 1736 | 1736 | if (!is_spi_i2c_slave) { |
| 1737 | − acpi_create_platform_device(device); | |
| 1737 | + acpi_create_platform_device(device, NULL); | |
| 1738 | 1738 | acpi_device_set_enumerated(device); |
| 1739 | 1739 | } else { |
| 1740 | 1740 | blocking_notifier_call_chain(&acpi_reconfig_chain, |
| @@ -324,7 +324,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) · 323 unmodified lines | ||
| 324 | 324 | { |
| 325 | 325 | int ret = -EPROBE_DEFER; |
| 326 | 326 | int local_trigger_count = atomic_read(&deferred_trigger_count); |
| 327 | − bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE); | |
| 327 | + bool test_remove = IS_ENABLED(CONFIG_DEBUG_TEST_DRIVER_REMOVE) && | |
| 328 | + !drv->suppress_bind_attrs; | |
| 328 | 329 | |
| 329 | 330 | if (defer_all_probes) { |
| 330 | 331 | /* |
| @@ -383,7 +384,7 @@ re_probe: · 52 unmodified lines | ||
| 383 | 384 | if (test_remove) { |
| 384 | 385 | test_remove = false; |
| 385 | 386 | |
| 386 | − if (dev->bus && dev->bus->remove) | |
| 387 | + if (dev->bus->remove) | |
| 387 | 388 | dev->bus->remove(dev); |
| 388 | 389 | else if (drv->remove) |
| 389 | 390 | drv->remove(dev); |
| @@ -1027,6 +1027,8 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a · 1026 unmodified lines | ||
| 1027 | 1027 | TRACE_DEVICE(dev); |
| 1028 | 1028 | TRACE_SUSPEND(0); |
| 1029 | 1029 | |
| 1030 | + dpm_wait_for_children(dev, async); | |
| 1031 | + | |
| 1030 | 1032 | if (async_error) |
| 1031 | 1033 | goto Complete; |
| 1032 | 1034 | |
| @@ -1038,8 +1040,6 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a · 5 unmodified lines | ||
| 1038 | 1040 | if (dev->power.syscore || dev->power.direct_complete) |
| 1039 | 1041 | goto Complete; |
| 1040 | 1042 | |
| 1041 | − dpm_wait_for_children(dev, async); | |
| 1042 | − | |
| 1043 | 1043 | if (dev->pm_domain) { |
| 1044 | 1044 | info = "noirq power domain "; |
| 1045 | 1045 | callback = pm_noirq_op(&dev->pm_domain->ops, state); |
| @@ -1174,6 +1174,8 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as · 128 unmodified lines | ||
| 1174 | 1174 | |
| 1175 | 1175 | __pm_runtime_disable(dev, false); |
| 1176 | 1176 | |
| 1177 | + dpm_wait_for_children(dev, async); | |
| 1178 | + | |
| 1177 | 1179 | if (async_error) |
| 1178 | 1180 | goto Complete; |
| 1179 | 1181 | |
| @@ -1185,8 +1187,6 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as · 5 unmodified lines | ||
| 1185 | 1187 | if (dev->power.syscore || dev->power.direct_complete) |
| 1186 | 1188 | goto Complete; |
| 1187 | 1189 | |
| 1188 | − dpm_wait_for_children(dev, async); | |
| 1189 | − | |
| 1190 | 1190 | if (dev->pm_domain) { |
| 1191 | 1191 | info = "late power domain "; |
| 1192 | 1192 | callback = pm_late_early_op(&dev->pm_domain->ops, state); |
| @@ -853,45 +853,6 @@ rqbiocnt(struct request *r) · 852 unmodified lines | ||
| 853 | 853 | return n; |
| 854 | 854 | } |
| 855 | 855 | |
| 856 | −/* This can be removed if we are certain that no users of the block | |
| 857 | − * layer will ever use zero-count pages in bios. Otherwise we have to | |
| 858 | − * protect against the put_page sometimes done by the network layer. | |
| 859 | − * | |
| 860 | − * See http://oss.sgi.com/archives/xfs/2007-01/msg00594.html for | |
| 861 | − * discussion. | |
| 862 | − * | |
| 863 | − * We cannot use get_page in the workaround, because it insists on a | |
| 864 | − * positive page count as a precondition. So we use _refcount directly. | |
| 865 | − */ | |
| 866 | −static void | |
| 867 | −bio_pageinc(struct bio *bio) | |
| 868 | −{ | |
| 869 | − struct bio_vec bv; | |
| 870 | − struct page *page; | |
| 871 | − struct bvec_iter iter; | |
| 872 | − | |
| 873 | − bio_for_each_segment(bv, bio, iter) { | |
| 874 | − /* Non-zero page count for non-head members of | |
| 875 | − * compound pages is no longer allowed by the kernel. | |
| 876 | − */ | |
| 877 | − page = compound_head(bv.bv_page); | |
| 878 | − page_ref_inc(page); | |
| 879 | − } | |
| 880 | −} | |
| 881 | − | |
| 882 | −static void | |
| 883 | −bio_pagedec(struct bio *bio) | |
| 884 | −{ | |
| 885 | − struct page *page; | |
| 886 | − struct bio_vec bv; | |
| 887 | − struct bvec_iter iter; | |
| 888 | − | |
| 889 | − bio_for_each_segment(bv, bio, iter) { | |
| 890 | − page = compound_head(bv.bv_page); | |
| 891 | − page_ref_dec(page); | |
| 892 | − } | |
| 893 | −} | |
| 894 | − | |
| 895 | 856 | static void |
| 896 | 857 | bufinit(struct buf *buf, struct request *rq, struct bio *bio) |
| 897 | 858 | { |
| @@ -899,7 +860,6 @@ bufinit(struct buf *buf, struct request *rq, struct bio *bio) · 1 unmodified line | ||
| 899 | 860 | buf->rq = rq; |
| 900 | 861 | buf->bio = bio; |
| 901 | 862 | buf->iter = bio->bi_iter; |
| 902 | − bio_pageinc(bio); | |
| 903 | 863 | } |
| 904 | 864 | |
| 905 | 865 | static struct buf * |
| @@ -1127,7 +1087,6 @@ aoe_end_buf(struct aoedev *d, struct buf *buf) · 221 unmodified lines | ||
| 1127 | 1087 | if (buf == d->ip.buf) |
| 1128 | 1088 | d->ip.buf = NULL; |
| 1129 | 1089 | rq = buf->rq; |
| 1130 | − bio_pagedec(buf->bio); | |
| 1131 | 1090 | mempool_free(buf, d->bufpool); |
| 1132 | 1091 | n = (unsigned long) rq->special; |
| 1133 | 1092 | rq->special = (void *) --n; |
| @@ -1871,7 +1871,7 @@ int drbd_send(struct drbd_connection *connection, struct socket *sock, · 1870 unmodified lines | ||
| 1871 | 1871 | drbd_update_congested(connection); |
| 1872 | 1872 | } |
| 1873 | 1873 | do { |
| 1874 | − rv = kernel_sendmsg(sock, &msg, &iov, 1, size); | |
| 1874 | + rv = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len); | |
| 1875 | 1875 | if (rv == -EAGAIN) { |
| 1876 | 1876 | if (we_should_drop_the_connection(connection, sock)) |
| 1877 | 1877 | break; |
| @@ -599,7 +599,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, · 598 unmodified lines | ||
| 599 | 599 | return -EINVAL; |
| 600 | 600 | |
| 601 | 601 | sreq = blk_mq_alloc_request(bdev_get_queue(bdev), WRITE, 0); |
| 602 | − if (!sreq) | |
| 602 | + if (IS_ERR(sreq)) | |
| 603 | 603 | return -ENOMEM; |
| 604 | 604 | |
| 605 | 605 | mutex_unlock(&nbd->tx_lock); |
| @@ -484,7 +484,7 @@ static int bt_bmc_remove(struct platform_device *pdev) · 483 unmodified lines | ||
| 484 | 484 | } |
| 485 | 485 | |
| 486 | 486 | static const struct of_device_id bt_bmc_match[] = { |
| 487 | − { .compatible = "aspeed,ast2400-bt-bmc" }, | |
| 487 | + { .compatible = "aspeed,ast2400-ibt-bmc" }, | |
| 488 | 488 | { }, |
| 489 | 489 | }; |
| 490 | 490 | |
| @@ -502,4 +502,4 @@ module_platform_driver(bt_bmc_driver); · 11 unmodified lines | ||
| 502 | 502 | MODULE_DEVICE_TABLE(of, bt_bmc_match); |
| 503 | 503 | MODULE_LICENSE("GPL"); |
| 504 | 504 | MODULE_AUTHOR("Alistair Popple <alistair@popple.id.au>"); |
| 505 | −MODULE_DESCRIPTION("Linux device interface to the BT interface"); | |
| 505 | +MODULE_DESCRIPTION("Linux device interface to the IPMI BT interface"); | |
| @@ -748,10 +748,7 @@ static int pp_release(struct inode *inode, struct file *file) · 747 unmodified lines | ||
| 748 | 748 | } |
| 749 | 749 | |
| 750 | 750 | if (pp->pdev) { |
| 751 | − const char *name = pp->pdev->name; | |
| 752 | − | |
| 753 | 751 | parport_unregister_device(pp->pdev); |
| 754 | − kfree(name); | |
| 755 | 752 | pp->pdev = NULL; |
| 756 | 753 | pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); |
| 757 | 754 | } |
| @@ -700,6 +700,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg, · 699 unmodified lines | ||
| 700 | 700 | struct mux_hwclock *hwc, |
| 701 | 701 | const struct clk_ops *ops, |
| 702 | 702 | unsigned long min_rate, |
| 703 | + unsigned long max_rate, | |
| 703 | 704 | unsigned long pct80_rate, |
| 704 | 705 | const char *fmt, int idx) |
| 705 | 706 | { |
| @@ -728,6 +729,8 @@ static struct clk * __init create_mux_common(struct clockgen *cg, · 22 unmodified lines | ||
| 728 | 729 | continue; |
| 729 | 730 | if (rate < min_rate) |
| 730 | 731 | continue; |
| 732 | + if (rate > max_rate) | |
| 733 | + continue; | |
| 731 | 734 | |
| 732 | 735 | parent_names[j] = div->name; |
| 733 | 736 | hwc->parent_to_clksel[j] = i; |
| @@ -759,7 +762,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) · 25 unmodified lines | ||
| 759 | 762 | struct mux_hwclock *hwc; |
| 760 | 763 | const struct clockgen_pll_div *div; |
| 761 | 764 | unsigned long plat_rate, min_rate; |
| 762 | − u64 pct80_rate; | |
| 765 | + u64 max_rate, pct80_rate; | |
| 763 | 766 | u32 clksel; |
| 764 | 767 | |
| 765 | 768 | hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); |
| @@ -787,8 +790,8 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) · 21 unmodified lines | ||
| 787 | 790 | return NULL; |
| 788 | 791 | } |
| 789 | 792 | |
| 790 | − pct80_rate = clk_get_rate(div->clk); | |
| 791 | − pct80_rate *= 8; | |
| 793 | + max_rate = clk_get_rate(div->clk); | |
| 794 | + pct80_rate = max_rate * 8; | |
| 792 | 795 | do_div(pct80_rate, 10); |
| 793 | 796 | |
| 794 | 797 | plat_rate = clk_get_rate(cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk); |
| @@ -798,7 +801,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) · 3 unmodified lines | ||
| 798 | 801 | else |
| 799 | 802 | min_rate = plat_rate / 2; |
| 800 | 803 | |
| 801 | − return create_mux_common(cg, hwc, &cmux_ops, min_rate, | |
| 804 | + return create_mux_common(cg, hwc, &cmux_ops, min_rate, max_rate, | |
| 802 | 805 | pct80_rate, "cg-cmux%d", idx); |
| 803 | 806 | } |
| 804 | 807 | |
| @@ -813,7 +816,7 @@ static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx) · 8 unmodified lines | ||
| 813 | 816 | hwc->reg = cg->regs + 0x20 * idx + 0x10; |
| 814 | 817 | hwc->info = cg->info.hwaccel[idx]; |
| 815 | 818 | |
| 816 | − return create_mux_common(cg, hwc, &hwaccel_ops, 0, 0, | |
| 819 | + return create_mux_common(cg, hwc, &hwaccel_ops, 0, ULONG_MAX, 0, | |
| 817 | 820 | "cg-hwaccel%d", idx); |
| 818 | 821 | } |
| 819 | 822 | |
| @@ -463,22 +463,20 @@ static int xgene_clk_enable(struct clk_hw *hw) · 462 unmodified lines | ||
| 463 | 463 | struct xgene_clk *pclk = to_xgene_clk(hw); |
| 464 | 464 | unsigned long flags = 0; |
| 465 | 465 | u32 data; |
| 466 | − phys_addr_t reg; | |
| 467 | 466 | |
| 468 | 467 | if (pclk->lock) |
| 469 | 468 | spin_lock_irqsave(pclk->lock, flags); |
| 470 | 469 | |
| 471 | 470 | if (pclk->param.csr_reg != NULL) { |
| 472 | 471 | pr_debug("%s clock enabled\n", clk_hw_get_name(hw)); |
| 473 | − reg = __pa(pclk->param.csr_reg); | |
| 474 | 472 | /* First enable the clock */ |
| 475 | 473 | data = xgene_clk_read(pclk->param.csr_reg + |
| 476 | 474 | pclk->param.reg_clk_offset); |
| 477 | 475 | data |= pclk->param.reg_clk_mask; |
| 478 | 476 | xgene_clk_write(data, pclk->param.csr_reg + |
| 479 | 477 | pclk->param.reg_clk_offset); |
| 480 | − pr_debug("%s clock PADDR base %pa clk offset 0x%08X mask 0x%08X value 0x%08X\n", | |
| 481 | − clk_hw_get_name(hw), ®, | |
| 478 | + pr_debug("%s clk offset 0x%08X mask 0x%08X value 0x%08X\n", | |
| 479 | + clk_hw_get_name(hw), | |
| 482 | 480 | pclk->param.reg_clk_offset, pclk->param.reg_clk_mask, |
| 483 | 481 | data); |
| 484 | 482 | |
| @@ -488,8 +486,8 @@ static int xgene_clk_enable(struct clk_hw *hw) · 3 unmodified lines | ||
| 488 | 486 | data &= ~pclk->param.reg_csr_mask; |
| 489 | 487 | xgene_clk_write(data, pclk->param.csr_reg + |
| 490 | 488 | pclk->param.reg_csr_offset); |
| 491 | − pr_debug("%s CSR RESET PADDR base %pa csr offset 0x%08X mask 0x%08X value 0x%08X\n", | |
| 492 | − clk_hw_get_name(hw), ®, | |
| 489 | + pr_debug("%s csr offset 0x%08X mask 0x%08X value 0x%08X\n", | |
| 490 | + clk_hw_get_name(hw), | |
| 493 | 491 | pclk->param.reg_csr_offset, pclk->param.reg_csr_mask, |
| 494 | 492 | data); |
| 495 | 493 | } |
| @@ -223,7 +223,7 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw, · 222 unmodified lines | ||
| 223 | 223 | temp64 *= mfn; |
| 224 | 224 | do_div(temp64, mfd); |
| 225 | 225 | |
| 226 | − return (parent_rate * div) + (u32)temp64; | |
| 226 | + return parent_rate * div + (unsigned long)temp64; | |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | 229 | static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, |
| @@ -247,7 +247,11 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, · 17 unmodified lines | ||
| 247 | 247 | do_div(temp64, parent_rate); |
| 248 | 248 | mfn = temp64; |
| 249 | 249 | |
| 250 | − return parent_rate * div + parent_rate * mfn / mfd; | |
| 250 | + temp64 = (u64)parent_rate; | |
| 251 | + temp64 *= mfn; | |
| 252 | + do_div(temp64, mfd); | |
| 253 | + | |
| 254 | + return parent_rate * div + (unsigned long)temp64; | |
| 251 | 255 | } |
| 252 | 256 | |
| 253 | 257 | static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, |
| @@ -313,7 +313,7 @@ static void __init mmp2_clk_init(struct device_node *np) · 312 unmodified lines | ||
| 313 | 313 | } |
| 314 | 314 | |
| 315 | 315 | pxa_unit->apmu_base = of_iomap(np, 1); |
| 316 | − if (!pxa_unit->mpmu_base) { | |
| 316 | + if (!pxa_unit->apmu_base) { | |
| 317 | 317 | pr_err("failed to map apmu registers\n"); |
| 318 | 318 | return; |
| 319 | 319 | } |
| @@ -262,7 +262,7 @@ static void __init pxa168_clk_init(struct device_node *np) · 261 unmodified lines | ||
| 262 | 262 | } |
| 263 | 263 | |
| 264 | 264 | pxa_unit->apmu_base = of_iomap(np, 1); |
| 265 | − if (!pxa_unit->mpmu_base) { | |
| 265 | + if (!pxa_unit->apmu_base) { | |
| 266 | 266 | pr_err("failed to map apmu registers\n"); |
| 267 | 267 | return; |
| 268 | 268 | } |
| @@ -282,7 +282,7 @@ static void __init pxa910_clk_init(struct device_node *np) · 281 unmodified lines | ||
| 282 | 282 | } |
| 283 | 283 | |
| 284 | 284 | pxa_unit->apmu_base = of_iomap(np, 1); |
| 285 | − if (!pxa_unit->mpmu_base) { | |
| 285 | + if (!pxa_unit->apmu_base) { | |
| 286 | 286 | pr_err("failed to map apmu registers\n"); |
| 287 | 287 | return; |
| 288 | 288 | } |
| @@ -294,7 +294,7 @@ static void __init pxa910_clk_init(struct device_node *np) · 5 unmodified lines | ||
| 294 | 294 | } |
| 295 | 295 | |
| 296 | 296 | pxa_unit->apbcp_base = of_iomap(np, 3); |
| 297 | − if (!pxa_unit->mpmu_base) { | |
| 297 | + if (!pxa_unit->apbcp_base) { | |
| 298 | 298 | pr_err("failed to map apbcp registers\n"); |
| 299 | 299 | return; |
| 300 | 300 | } |
| @@ -144,11 +144,8 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, · 143 unmodified lines | ||
| 144 | 144 | ddrclk->ddr_flag = ddr_flag; |
| 145 | 145 | |
| 146 | 146 | clk = clk_register(NULL, &ddrclk->hw); |
| 147 | − if (IS_ERR(clk)) { | |
| 148 | − pr_err("%s: could not register ddrclk %s\n", __func__, name); | |
| 147 | + if (IS_ERR(clk)) | |
| 149 | 148 | kfree(ddrclk); |
| 150 | − return NULL; | |
| 151 | − } | |
| 152 | 149 | |
| 153 | 150 | return clk; |
| 154 | 151 | } |
| @@ -132,28 +132,34 @@ free_clkout: · 131 unmodified lines | ||
| 132 | 132 | pr_err("%s: failed to register clkout clock\n", __func__); |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | +/* | |
| 136 | + * We use CLK_OF_DECLARE_DRIVER initialization method to avoid setting | |
| 137 | + * the OF_POPULATED flag on the pmu device tree node, so later the | |
| 138 | + * Exynos PMU platform device can be properly probed with PMU driver. | |
| 139 | + */ | |
| 140 | + | |
| 135 | 141 | static void __init exynos4_clkout_init(struct device_node *node) |
| 136 | 142 | { |
| 137 | 143 | exynos_clkout_init(node, EXYNOS4_CLKOUT_MUX_MASK); |
| 138 | 144 | } |
| 139 | −CLK_OF_DECLARE(exynos4210_clkout, "samsung,exynos4210-pmu", | |
| 145 | +CLK_OF_DECLARE_DRIVER(exynos4210_clkout, "samsung,exynos4210-pmu", | |
| 140 | 146 | exynos4_clkout_init); |
| 141 | −CLK_OF_DECLARE(exynos4212_clkout, "samsung,exynos4212-pmu", | |
| 147 | +CLK_OF_DECLARE_DRIVER(exynos4212_clkout, "samsung,exynos4212-pmu", | |
| 142 | 148 | exynos4_clkout_init); |
| 143 | −CLK_OF_DECLARE(exynos4412_clkout, "samsung,exynos4412-pmu", | |
| 149 | +CLK_OF_DECLARE_DRIVER(exynos4412_clkout, "samsung,exynos4412-pmu", | |
| 144 | 150 | exynos4_clkout_init); |
| 145 | −CLK_OF_DECLARE(exynos3250_clkout, "samsung,exynos3250-pmu", | |
| 151 | +CLK_OF_DECLARE_DRIVER(exynos3250_clkout, "samsung,exynos3250-pmu", | |
| 146 | 152 | exynos4_clkout_init); |
| 147 | 153 | |
| 148 | 154 | static void __init exynos5_clkout_init(struct device_node *node) |
| 149 | 155 | { |
| 150 | 156 | exynos_clkout_init(node, EXYNOS5_CLKOUT_MUX_MASK); |
| 151 | 157 | } |
| 152 | −CLK_OF_DECLARE(exynos5250_clkout, "samsung,exynos5250-pmu", | |
| 158 | +CLK_OF_DECLARE_DRIVER(exynos5250_clkout, "samsung,exynos5250-pmu", | |
| 153 | 159 | exynos5_clkout_init); |
| 154 | −CLK_OF_DECLARE(exynos5410_clkout, "samsung,exynos5410-pmu", | |
| 160 | +CLK_OF_DECLARE_DRIVER(exynos5410_clkout, "samsung,exynos5410-pmu", | |
| 155 | 161 | exynos5_clkout_init); |
| 156 | −CLK_OF_DECLARE(exynos5420_clkout, "samsung,exynos5420-pmu", | |
| 162 | +CLK_OF_DECLARE_DRIVER(exynos5420_clkout, "samsung,exynos5420-pmu", | |
| 157 | 163 | exynos5_clkout_init); |
| 158 | −CLK_OF_DECLARE(exynos5433_clkout, "samsung,exynos5433-pmu", | |
| 164 | +CLK_OF_DECLARE_DRIVER(exynos5433_clkout, "samsung,exynos5433-pmu", | |
| 159 | 165 | exynos5_clkout_init); |
| @@ -137,7 +137,7 @@ static void dbg_dump_sg(const char *level, const char *prefix_str, · 136 unmodified lines | ||
| 137 | 137 | } |
| 138 | 138 | |
| 139 | 139 | buf = it_page + it->offset; |
| 140 | − len = min(tlen, it->length); | |
| 140 | + len = min_t(size_t, tlen, it->length); | |
| 141 | 141 | print_hex_dump(level, prefix_str, prefix_type, rowsize, |
| 142 | 142 | groupsize, buf, len, ascii); |
| 143 | 143 | tlen -= len; |
| @@ -4583,6 +4583,15 @@ static int __init caam_algapi_init(void) · 4439 unmodified lines | ||
| 4583 | 4583 | if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES)) |
| 4584 | 4584 | continue; |
| 4585 | 4585 | |
| 4586 | + /* | |
| 4587 | + * Check support for AES modes not available | |
| 4588 | + * on LP devices. | |
| 4589 | + */ | |
| 4590 | + if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP) | |
| 4591 | + if ((alg->class1_alg_type & OP_ALG_AAI_MASK) == | |
| 4592 | + OP_ALG_AAI_XTS) | |
| 4593 | + continue; | |
| 4594 | + | |
| 4586 | 4595 | t_alg = caam_alg_alloc(alg); |
| 4587 | 4596 | if (IS_ERR(t_alg)) { |
| 4588 | 4597 | err = PTR_ERR(t_alg); |
| @@ -306,6 +306,7 @@ config MMP_TDMA · 305 unmodified lines | ||
| 306 | 306 | depends on ARCH_MMP || COMPILE_TEST |
| 307 | 307 | select DMA_ENGINE |
| 308 | 308 | select MMP_SRAM if ARCH_MMP |
| 309 | + select GENERIC_ALLOCATOR | |
| 309 | 310 | help |
| 310 | 311 | Support the MMP Two-Channel DMA engine. |
| 311 | 312 | This engine used for MMP Audio DMA and pxa910 SQU. |
| @@ -317,6 +317,12 @@ static irqreturn_t cppi41_irq(int irq, void *data) · 316 unmodified lines | ||
| 317 | 317 | |
| 318 | 318 | while (val) { |
| 319 | 319 | u32 desc, len; |
| 320 | + int error; | |
| 321 | + | |
| 322 | + error = pm_runtime_get(cdd->ddev.dev); | |
| 323 | + if (error < 0) | |
| 324 | + dev_err(cdd->ddev.dev, "%s pm runtime get: %i\n", | |
| 325 | + __func__, error); | |
| 320 | 326 | |
| 321 | 327 | q_num = __fls(val); |
| 322 | 328 | val &= ~(1 << q_num); |
| @@ -338,7 +344,6 @@ static irqreturn_t cppi41_irq(int irq, void *data) · 15 unmodified lines | ||
| 338 | 344 | dma_cookie_complete(&c->txd); |
| 339 | 345 | dmaengine_desc_get_callback_invoke(&c->txd, NULL); |
| 340 | 346 | |
| 341 | − /* Paired with cppi41_dma_issue_pending */ | |
| 342 | 347 | pm_runtime_mark_last_busy(cdd->ddev.dev); |
| 343 | 348 | pm_runtime_put_autosuspend(cdd->ddev.dev); |
| 344 | 349 | } |
| @@ -362,8 +367,13 @@ static int cppi41_dma_alloc_chan_resources(struct dma_chan *chan) · 17 unmodified lines | ||
| 362 | 367 | int error; |
| 363 | 368 | |
| 364 | 369 | error = pm_runtime_get_sync(cdd->ddev.dev); |
| 365 | − if (error < 0) | |
| 370 | + if (error < 0) { | |
| 371 | + dev_err(cdd->ddev.dev, "%s pm runtime get: %i\n", | |
| 372 | + __func__, error); | |
| 373 | + pm_runtime_put_noidle(cdd->ddev.dev); | |
| 374 | + | |
| 366 | 375 | return error; |
| 376 | + } | |
| 367 | 377 | |
| 368 | 378 | dma_cookie_init(chan); |
| 369 | 379 | dma_async_tx_descriptor_init(&c->txd, chan); |
| @@ -385,8 +395,11 @@ static void cppi41_dma_free_chan_resources(struct dma_chan *chan) · 15 unmodified lines | ||
| 385 | 395 | int error; |
| 386 | 396 | |
| 387 | 397 | error = pm_runtime_get_sync(cdd->ddev.dev); |
| 388 | − if (error < 0) | |
| 398 | + if (error < 0) { | |
| 399 | + pm_runtime_put_noidle(cdd->ddev.dev); | |
| 400 | + | |
| 389 | 401 | return; |
| 402 | + } | |
| 390 | 403 | |
| 391 | 404 | WARN_ON(!list_empty(&cdd->pending)); |
| 392 | 405 | |
| @@ -460,9 +473,9 @@ static void cppi41_dma_issue_pending(struct dma_chan *chan) · 67 unmodified lines | ||
| 460 | 473 | struct cppi41_dd *cdd = c->cdd; |
| 461 | 474 | int error; |
| 462 | 475 | |
| 463 | − /* PM runtime paired with dmaengine_desc_get_callback_invoke */ | |
| 464 | 476 | error = pm_runtime_get(cdd->ddev.dev); |
| 465 | 477 | if ((error != -EINPROGRESS) && error < 0) { |
| 478 | + pm_runtime_put_noidle(cdd->ddev.dev); | |
| 466 | 479 | dev_err(cdd->ddev.dev, "Failed to pm_runtime_get: %i\n", |
| 467 | 480 | error); |
| 468 | 481 | |
| @@ -473,6 +486,9 @@ static void cppi41_dma_issue_pending(struct dma_chan *chan) · 4 unmodified lines | ||
| 473 | 486 | push_desc_queue(c); |
| 474 | 487 | else |
| 475 | 488 | pending_desc(c); |
| 489 | + | |
| 490 | + pm_runtime_mark_last_busy(cdd->ddev.dev); | |
| 491 | + pm_runtime_put_autosuspend(cdd->ddev.dev); | |
| 476 | 492 | } |
| 477 | 493 | |
| 478 | 494 | static u32 get_host_pd0(u32 length) |
| @@ -1059,8 +1075,8 @@ err_chans: · 580 unmodified lines | ||
| 1059 | 1075 | deinit_cppi41(dev, cdd); |
| 1060 | 1076 | err_init_cppi: |
| 1061 | 1077 | pm_runtime_dont_use_autosuspend(dev); |
| 1062 | − pm_runtime_put_sync(dev); | |
| 1063 | 1078 | err_get_sync: |
| 1079 | + pm_runtime_put_sync(dev); | |
| 1064 | 1080 | pm_runtime_disable(dev); |
| 1065 | 1081 | iounmap(cdd->usbss_mem); |
| 1066 | 1082 | iounmap(cdd->ctrl_mem); |
| @@ -1072,7 +1088,12 @@ err_get_sync: · 5 unmodified lines | ||
| 1072 | 1088 | static int cppi41_dma_remove(struct platform_device *pdev) |
| 1073 | 1089 | { |
| 1074 | 1090 | struct cppi41_dd *cdd = platform_get_drvdata(pdev); |
| 1091 | + int error; | |
| 1075 | 1092 | |
| 1093 | + error = pm_runtime_get_sync(&pdev->dev); | |
| 1094 | + if (error < 0) | |
| 1095 | + dev_err(&pdev->dev, "%s could not pm_runtime_get: %i\n", | |
| 1096 | + __func__, error); | |
| 1076 | 1097 | of_dma_controller_free(pdev->dev.of_node); |
| 1077 | 1098 | dma_async_device_unregister(&cdd->ddev); |
| 1078 | 1099 | |
| @@ -1628,6 +1628,7 @@ static int edma_alloc_chan_resources(struct dma_chan *chan) · 1627 unmodified lines | ||
| 1628 | 1628 | if (echan->slot[0] < 0) { |
| 1629 | 1629 | dev_err(dev, "Entry slot allocation failed for channel %u\n", |
| 1630 | 1630 | EDMA_CHAN_SLOT(echan->ch_num)); |
| 1631 | + ret = echan->slot[0]; | |
| 1631 | 1632 | goto err_slot; |
| 1632 | 1633 | } |
| 1633 | 1634 | |
| @@ -578,7 +578,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( · 577 unmodified lines | ||
| 578 | 578 | |
| 579 | 579 | burst = convert_burst(8); |
| 580 | 580 | width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); |
| 581 | − v_lli->cfg |= DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | | |
| 581 | + v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | | |
| 582 | 582 | DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | |
| 583 | 583 | DMA_CHAN_CFG_DST_LINEAR_MODE | |
| 584 | 584 | DMA_CHAN_CFG_SRC_LINEAR_MODE | |
| @@ -22,10 +22,6 @@ menuconfig GPIOLIB · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | if GPIOLIB |
| 24 | 24 | |
| 25 | −config GPIO_DEVRES | |
| 26 | − def_bool y | |
| 27 | − depends on HAS_IOMEM | |
| 28 | − | |
| 29 | 25 | config OF_GPIO |
| 30 | 26 | def_bool y |
| 31 | 27 | depends on OF |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG |
| 4 | 4 | |
| 5 | −obj-$(CONFIG_GPIO_DEVRES) += devres.o | |
| 5 | +obj-$(CONFIG_GPIOLIB) += devres.o | |
| 6 | 6 | obj-$(CONFIG_GPIOLIB) += gpiolib.o |
| 7 | 7 | obj-$(CONFIG_GPIOLIB) += gpiolib-legacy.o |
| 8 | 8 | obj-$(CONFIG_OF_GPIO) += gpiolib-of.o |
| @@ -372,14 +372,15 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc, · 371 unmodified lines | ||
| 372 | 372 | |
| 373 | 373 | bank_shift = fls((chip->gpio_chip.ngpio - 1) / BANK_SZ); |
| 374 | 374 | |
| 375 | − memcpy(reg_val, chip->reg_output, NBANK(chip)); | |
| 376 | 375 | mutex_lock(&chip->i2c_lock); |
| 376 | + memcpy(reg_val, chip->reg_output, NBANK(chip)); | |
| 377 | 377 | for (bank = 0; bank < NBANK(chip); bank++) { |
| 378 | 378 | bank_mask = mask[bank / sizeof(*mask)] >> |
| 379 | 379 | ((bank % sizeof(*mask)) * 8); |
| 380 | 380 | if (bank_mask) { |
| 381 | 381 | bank_val = bits[bank / sizeof(*bits)] >> |
| 382 | 382 | ((bank % sizeof(*bits)) * 8); |
| 383 | + bank_val &= bank_mask; | |
| 383 | 384 | reg_val[bank] = (reg_val[bank] & ~bank_mask) | bank_val; |
| 384 | 385 | } |
| 385 | 386 | } |
| @@ -607,7 +608,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, · 221 unmodified lines | ||
| 607 | 608 | |
| 608 | 609 | if (client->irq && irq_base != -1 |
| 609 | 610 | && (chip->driver_data & PCA_INT)) { |
| 610 | − | |
| 611 | 611 | ret = pca953x_read_regs(chip, |
| 612 | 612 | chip->regs->input, chip->irq_stat); |
| 613 | 613 | if (ret) |
| @@ -97,7 +97,7 @@ static int tc3589x_gpio_get_direction(struct gpio_chip *chip, · 96 unmodified lines | ||
| 97 | 97 | if (ret < 0) |
| 98 | 98 | return ret; |
| 99 | 99 | |
| 100 | − return !!(ret & BIT(pos)); | |
| 100 | + return !(ret & BIT(pos)); | |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | static int tc3589x_gpio_set_single_ended(struct gpio_chip *chip, |
| @@ -2737,8 +2737,11 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) · 2736 unmodified lines | ||
| 2737 | 2737 | if (IS_ERR(desc)) |
| 2738 | 2738 | return PTR_ERR(desc); |
| 2739 | 2739 | |
| 2740 | − /* Flush direction if something changed behind our back */ | |
| 2741 | − if (chip->get_direction) { | |
| 2740 | + /* | |
| 2741 | + * If it's fast: flush the direction setting if something changed | |
| 2742 | + * behind our back | |
| 2743 | + */ | |
| 2744 | + if (!chip->can_sleep && chip->get_direction) { | |
| 2742 | 2745 | int dir = chip->get_direction(chip, offset); |
| 2743 | 2746 | |
| 2744 | 2747 | if (dir) |
| @@ -459,6 +459,7 @@ struct amdgpu_bo { · 458 unmodified lines | ||
| 459 | 459 | u64 metadata_flags; |
| 460 | 460 | void *metadata; |
| 461 | 461 | u32 metadata_size; |
| 462 | + unsigned prime_shared_count; | |
| 462 | 463 | /* list of all virtual address to which this bo |
| 463 | 464 | * is associated to |
| 464 | 465 | */ |
| @@ -395,9 +395,12 @@ static int acp_hw_fini(void *handle) · 394 unmodified lines | ||
| 395 | 395 | { |
| 396 | 396 | int i, ret; |
| 397 | 397 | struct device *dev; |
| 398 | − | |
| 399 | 398 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 400 | 399 | |
| 400 | + /* return early if no ACP */ | |
| 401 | + if (!adev->acp.acp_genpd) | |
| 402 | + return 0; | |
| 403 | + | |
| 401 | 404 | for (i = 0; i < ACP_DEVS ; i++) { |
| 402 | 405 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); |
| 403 | 406 | ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev); |
| @@ -132,7 +132,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, · 131 unmodified lines | ||
| 132 | 132 | entry->priority = min(info[i].bo_priority, |
| 133 | 133 | AMDGPU_BO_LIST_MAX_PRIORITY); |
| 134 | 134 | entry->tv.bo = &entry->robj->tbo; |
| 135 | − entry->tv.shared = true; | |
| 135 | + entry->tv.shared = !entry->robj->prime_shared_count; | |
| 136 | 136 | |
| 137 | 137 | if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS) |
| 138 | 138 | gds_obj = entry->robj; |
| @@ -795,10 +795,19 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, · 794 unmodified lines | ||
| 795 | 795 | if (!adev->pm.fw) { |
| 796 | 796 | switch (adev->asic_type) { |
| 797 | 797 | case CHIP_TOPAZ: |
| 798 | − strcpy(fw_name, "amdgpu/topaz_smc.bin"); | |
| 798 | + if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) || | |
| 799 | + ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) || | |
| 800 | + ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87))) | |
| 801 | + strcpy(fw_name, "amdgpu/topaz_k_smc.bin"); | |
| 802 | + else | |
| 803 | + strcpy(fw_name, "amdgpu/topaz_smc.bin"); | |
| 799 | 804 | break; |
| 800 | 805 | case CHIP_TONGA: |
| 801 | − strcpy(fw_name, "amdgpu/tonga_smc.bin"); | |
| 806 | + if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) || | |
| 807 | + ((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) | |
| 808 | + strcpy(fw_name, "amdgpu/tonga_k_smc.bin"); | |
| 809 | + else | |
| 810 | + strcpy(fw_name, "amdgpu/tonga_smc.bin"); | |
| 802 | 811 | break; |
| 803 | 812 | case CHIP_FIJI: |
| 804 | 813 | strcpy(fw_name, "amdgpu/fiji_smc.bin"); |
| @@ -769,7 +769,7 @@ static void amdgpu_connector_unregister(struct drm_connector *connector) · 768 unmodified lines | ||
| 769 | 769 | { |
| 770 | 770 | struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector); |
| 771 | 771 | |
| 772 | − if (amdgpu_connector->ddc_bus->has_aux) { | |
| 772 | + if (amdgpu_connector->ddc_bus && amdgpu_connector->ddc_bus->has_aux) { | |
| 773 | 773 | drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux); |
| 774 | 774 | amdgpu_connector->ddc_bus->has_aux = false; |
| 775 | 775 | } |
| @@ -658,12 +658,10 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev) · 657 unmodified lines | ||
| 658 | 658 | return false; |
| 659 | 659 | |
| 660 | 660 | if (amdgpu_passthrough(adev)) { |
| 661 | − /* for FIJI: In whole GPU pass-through virtualization case | |
| 662 | − * old smc fw won't clear some registers (e.g. MEM_SIZE, BIOS_SCRATCH) | |
| 663 | − * so amdgpu_card_posted return false and driver will incorrectly skip vPost. | |
| 664 | − * but if we force vPost do in pass-through case, the driver reload will hang. | |
| 665 | − * whether doing vPost depends on amdgpu_card_posted if smc version is above | |
| 666 | − * 00160e00 for FIJI. | |
| 661 | + /* for FIJI: In whole GPU pass-through virtualization case, after VM reboot | |
| 662 | + * some old smc fw still need driver do vPost otherwise gpu hang, while | |
| 663 | + * those smc fw version above 22.15 doesn't have this flaw, so we force | |
| 664 | + * vpost executed for smc version below 22.15 | |
| 667 | 665 | */ |
| 668 | 666 | if (adev->asic_type == CHIP_FIJI) { |
| 669 | 667 | int err; |
| @@ -674,22 +672,11 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev) · 4 unmodified lines | ||
| 674 | 672 | return true; |
| 675 | 673 | |
| 676 | 674 | fw_ver = *((uint32_t *)adev->pm.fw->data + 69); |
| 677 | − if (fw_ver >= 0x00160e00) | |
| 678 | − return !amdgpu_card_posted(adev); | |
| 675 | + if (fw_ver < 0x00160e00) | |
| 676 | + return true; | |
| 679 | 677 | } |
| 680 | − } else { | |
| 681 | − /* in bare-metal case, amdgpu_card_posted return false | |
| 682 | − * after system reboot/boot, and return true if driver | |
| 683 | − * reloaded. | |
| 684 | − * we shouldn't do vPost after driver reload otherwise GPU | |
| 685 | − * could hang. | |
| 686 | − */ | |
| 687 | − if (amdgpu_card_posted(adev)) | |
| 688 | − return false; | |
| 689 | 678 | } |
| 690 | − | |
| 691 | − /* we assume vPost is neede for all other cases */ | |
| 692 | − return true; | |
| 679 | + return !amdgpu_card_posted(adev); | |
| 693 | 680 | } |
| 694 | 681 | |
| 695 | 682 | /** |
| @@ -735,8 +735,20 @@ static struct pci_driver amdgpu_kms_pci_driver = { · 734 unmodified lines | ||
| 735 | 735 | |
| 736 | 736 | static int __init amdgpu_init(void) |
| 737 | 737 | { |
| 738 | − amdgpu_sync_init(); | |
| 739 | − amdgpu_fence_slab_init(); | |
| 738 | + int r; | |
| 739 | + | |
| 740 | + r = amdgpu_sync_init(); | |
| 741 | + if (r) | |
| 742 | + goto error_sync; | |
| 743 | + | |
| 744 | + r = amdgpu_fence_slab_init(); | |
| 745 | + if (r) | |
| 746 | + goto error_fence; | |
| 747 | + | |
| 748 | + r = amd_sched_fence_slab_init(); | |
| 749 | + if (r) | |
| 750 | + goto error_sched; | |
| 751 | + | |
| 740 | 752 | if (vgacon_text_force()) { |
| 741 | 753 | DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); |
| 742 | 754 | return -EINVAL; |
| @@ -748,6 +760,15 @@ static int __init amdgpu_init(void) · 5 unmodified lines | ||
| 748 | 760 | amdgpu_register_atpx_handler(); |
| 749 | 761 | /* let modprobe override vga console setting */ |
| 750 | 762 | return drm_pci_init(driver, pdriver); |
| 763 | + | |
| 764 | +error_sched: | |
| 765 | + amdgpu_fence_slab_fini(); | |
| 766 | + | |
| 767 | +error_fence: | |
| 768 | + amdgpu_sync_fini(); | |
| 769 | + | |
| 770 | +error_sync: | |
| 771 | + return r; | |
| 751 | 772 | } |
| 752 | 773 | |
| 753 | 774 | static void __exit amdgpu_exit(void) |
| @@ -756,6 +777,7 @@ static void __exit amdgpu_exit(void) · 2 unmodified lines | ||
| 756 | 777 | drm_pci_exit(driver, pdriver); |
| 757 | 778 | amdgpu_unregister_atpx_handler(); |
| 758 | 779 | amdgpu_sync_fini(); |
| 780 | + amd_sched_fence_slab_fini(); | |
| 759 | 781 | amdgpu_fence_slab_fini(); |
| 760 | 782 | } |
| 761 | 783 | |
| @@ -99,6 +99,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags) · 98 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | if ((amdgpu_runtime_pm != 0) && |
| 101 | 101 | amdgpu_has_atpx() && |
| 102 | + (amdgpu_is_atpx_hybrid() || | |
| 103 | + amdgpu_has_atpx_dgpu_power_cntl()) && | |
| 102 | 104 | ((flags & AMD_IS_APU) == 0)) |
| 103 | 105 | flags |= AMD_IS_PX; |
| 104 | 106 | |
| @@ -74,20 +74,36 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev, · 73 unmodified lines | ||
| 74 | 74 | if (ret) |
| 75 | 75 | return ERR_PTR(ret); |
| 76 | 76 | |
| 77 | + bo->prime_shared_count = 1; | |
| 77 | 78 | return &bo->gem_base; |
| 78 | 79 | } |
| 79 | 80 | |
| 80 | 81 | int amdgpu_gem_prime_pin(struct drm_gem_object *obj) |
| 81 | 82 | { |
| 82 | 83 | struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); |
| 83 | − int ret = 0; | |
| 84 | + long ret = 0; | |
| 84 | 85 | |
| 85 | 86 | ret = amdgpu_bo_reserve(bo, false); |
| 86 | 87 | if (unlikely(ret != 0)) |
| 87 | 88 | return ret; |
| 88 | 89 | |
| 90 | + /* | |
| 91 | + * Wait for all shared fences to complete before we switch to future | |
| 92 | + * use of exclusive fence on this prime shared bo. | |
| 93 | + */ | |
| 94 | + ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, true, false, | |
| 95 | + MAX_SCHEDULE_TIMEOUT); | |
| 96 | + if (unlikely(ret < 0)) { | |
| 97 | + DRM_DEBUG_PRIME("Fence wait failed: %li\n", ret); | |
| 98 | + amdgpu_bo_unreserve(bo); | |
| 99 | + return ret; | |
| 100 | + } | |
| 101 | + | |
| 89 | 102 | /* pin buffer into GTT */ |
| 90 | 103 | ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL); |
| 104 | + if (likely(ret == 0)) | |
| 105 | + bo->prime_shared_count++; | |
| 106 | + | |
| 91 | 107 | amdgpu_bo_unreserve(bo); |
| 92 | 108 | return ret; |
| 93 | 109 | } |
| @@ -102,6 +118,8 @@ void amdgpu_gem_prime_unpin(struct drm_gem_object *obj) · 8 unmodified lines | ||
| 102 | 118 | return; |
| 103 | 119 | |
| 104 | 120 | amdgpu_bo_unpin(bo); |
| 121 | + if (bo->prime_shared_count) | |
| 122 | + bo->prime_shared_count--; | |
| 105 | 123 | amdgpu_bo_unreserve(bo); |
| 106 | 124 | } |
| 107 | 125 | |
| @@ -80,7 +80,9 @@ · 79 unmodified lines | ||
| 80 | 80 | #include "dce_virtual.h" |
| 81 | 81 | |
| 82 | 82 | MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); |
| 83 | +MODULE_FIRMWARE("amdgpu/topaz_k_smc.bin"); | |
| 83 | 84 | MODULE_FIRMWARE("amdgpu/tonga_smc.bin"); |
| 85 | +MODULE_FIRMWARE("amdgpu/tonga_k_smc.bin"); | |
| 84 | 86 | MODULE_FIRMWARE("amdgpu/fiji_smc.bin"); |
| 85 | 87 | MODULE_FIRMWARE("amdgpu/polaris10_smc.bin"); |
| 86 | 88 | MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin"); |
| @@ -272,7 +272,7 @@ bool phm_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hw · 271 unmodified lines | ||
| 272 | 272 | PHM_FUNC_CHECK(hwmgr); |
| 273 | 273 | |
| 274 | 274 | if (hwmgr->hwmgr_func->check_smc_update_required_for_display_configuration == NULL) |
| 275 | − return -EINVAL; | |
| 275 | + return false; | |
| 276 | 276 | |
| 277 | 277 | return hwmgr->hwmgr_func->check_smc_update_required_for_display_configuration(hwmgr); |
| 278 | 278 | } |
| @@ -710,8 +710,10 @@ int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, · 709 unmodified lines | ||
| 710 | 710 | uint32_t vol; |
| 711 | 711 | int ret = 0; |
| 712 | 712 | |
| 713 | − if (hwmgr->chip_id < CHIP_POLARIS10) { | |
| 714 | − atomctrl_get_voltage_evv_on_sclk(hwmgr, voltage_type, sclk, id, voltage); | |
| 713 | + if (hwmgr->chip_id < CHIP_TONGA) { | |
| 714 | + ret = atomctrl_get_voltage_evv(hwmgr, id, voltage); | |
| 715 | + } else if (hwmgr->chip_id < CHIP_POLARIS10) { | |
| 716 | + ret = atomctrl_get_voltage_evv_on_sclk(hwmgr, voltage_type, sclk, id, voltage); | |
| 715 | 717 | if (*voltage >= 2000 || *voltage == 0) |
| 716 | 718 | *voltage = 1150; |
| 717 | 719 | } else { |
| @@ -1460,19 +1460,17 @@ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr) · 1459 unmodified lines | ||
| 1460 | 1460 | struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = NULL; |
| 1461 | 1461 | |
| 1462 | 1462 | |
| 1463 | − if (table_info == NULL) | |
| 1464 | − return -EINVAL; | |
| 1465 | − | |
| 1466 | − sclk_table = table_info->vdd_dep_on_sclk; | |
| 1467 | − | |
| 1468 | 1463 | for (i = 0; i < SMU7_MAX_LEAKAGE_COUNT; i++) { |
| 1469 | 1464 | vv_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i; |
| 1470 | 1465 | |
| 1471 | 1466 | if (data->vdd_gfx_control == SMU7_VOLTAGE_CONTROL_BY_SVID2) { |
| 1472 | − if (0 == phm_get_sclk_for_voltage_evv(hwmgr, | |
| 1467 | + if ((hwmgr->pp_table_version == PP_TABLE_V1) | |
| 1468 | + && !phm_get_sclk_for_voltage_evv(hwmgr, | |
| 1473 | 1469 | table_info->vddgfx_lookup_table, vv_id, &sclk)) { |
| 1474 | 1470 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
| 1475 | 1471 | PHM_PlatformCaps_ClockStretcher)) { |
| 1472 | + sclk_table = table_info->vdd_dep_on_sclk; | |
| 1473 | + | |
| 1476 | 1474 | for (j = 1; j < sclk_table->count; j++) { |
| 1477 | 1475 | if (sclk_table->entries[j].clk == sclk && |
| 1478 | 1476 | sclk_table->entries[j].cks_enable == 0) { |
| @@ -1498,12 +1496,15 @@ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr) · 19 unmodified lines | ||
| 1498 | 1496 | } |
| 1499 | 1497 | } |
| 1500 | 1498 | } else { |
| 1501 | − | |
| 1502 | 1499 | if ((hwmgr->pp_table_version == PP_TABLE_V0) |
| 1503 | 1500 | || !phm_get_sclk_for_voltage_evv(hwmgr, |
| 1504 | 1501 | table_info->vddc_lookup_table, vv_id, &sclk)) { |
| 1505 | 1502 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, |
| 1506 | 1503 | PHM_PlatformCaps_ClockStretcher)) { |
| 1504 | + if (table_info == NULL) | |
| 1505 | + return -EINVAL; | |
| 1506 | + sclk_table = table_info->vdd_dep_on_sclk; | |
| 1507 | + | |
| 1507 | 1508 | for (j = 1; j < sclk_table->count; j++) { |
| 1508 | 1509 | if (sclk_table->entries[j].clk == sclk && |
| 1509 | 1510 | sclk_table->entries[j].cks_enable == 0) { |
| @@ -2133,9 +2134,11 @@ static int smu7_patch_limits_vddc(struct pp_hwmgr *hwmgr, · 623 unmodified lines | ||
| 2133 | 2134 | struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend); |
| 2134 | 2135 | |
| 2135 | 2136 | if (tab) { |
| 2137 | + vddc = tab->vddc; | |
| 2136 | 2138 | smu7_patch_ppt_v0_with_vdd_leakage(hwmgr, &vddc, |
| 2137 | 2139 | &data->vddc_leakage); |
| 2138 | 2140 | tab->vddc = vddc; |
| 2141 | + vddci = tab->vddci; | |
| 2139 | 2142 | smu7_patch_ppt_v0_with_vdd_leakage(hwmgr, &vddci, |
| 2140 | 2143 | &data->vddci_leakage); |
| 2141 | 2144 | tab->vddci = vddci; |
| @@ -4228,18 +4231,26 @@ static int smu7_get_sclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks) · 2086 unmodified lines | ||
| 4228 | 4231 | { |
| 4229 | 4232 | struct phm_ppt_v1_information *table_info = |
| 4230 | 4233 | (struct phm_ppt_v1_information *)hwmgr->pptable; |
| 4231 | − struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table; | |
| 4234 | + struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table = NULL; | |
| 4235 | + struct phm_clock_voltage_dependency_table *sclk_table; | |
| 4232 | 4236 | int i; |
| 4233 | 4237 | |
| 4234 | − if (table_info == NULL) | |
| 4235 | − return -EINVAL; | |
| 4236 | − | |
| 4237 | − dep_sclk_table = table_info->vdd_dep_on_sclk; | |
| 4238 | − | |
| 4239 | − for (i = 0; i < dep_sclk_table->count; i++) { | |
| 4240 | − clocks->clock[i] = dep_sclk_table->entries[i].clk; | |
| 4241 | − clocks->count++; | |
| 4238 | + if (hwmgr->pp_table_version == PP_TABLE_V1) { | |
| 4239 | + if (table_info == NULL || table_info->vdd_dep_on_sclk == NULL) | |
| 4240 | + return -EINVAL; | |
| 4241 | + dep_sclk_table = table_info->vdd_dep_on_sclk; | |
| 4242 | + for (i = 0; i < dep_sclk_table->count; i++) { | |
| 4243 | + clocks->clock[i] = dep_sclk_table->entries[i].clk; | |
| 4244 | + clocks->count++; | |
| 4245 | + } | |
| 4246 | + } else if (hwmgr->pp_table_version == PP_TABLE_V0) { | |
| 4247 | + sclk_table = hwmgr->dyn_state.vddc_dependency_on_sclk; | |
| 4248 | + for (i = 0; i < sclk_table->count; i++) { | |
| 4249 | + clocks->clock[i] = sclk_table->entries[i].clk; | |
| 4250 | + clocks->count++; | |
| 4251 | + } | |
| 4242 | 4252 | } |
| 4253 | + | |
| 4243 | 4254 | return 0; |
| 4244 | 4255 | } |
| 4245 | 4256 | |
| @@ -4261,17 +4272,24 @@ static int smu7_get_mclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks) · 15 unmodified lines | ||
| 4261 | 4272 | (struct phm_ppt_v1_information *)hwmgr->pptable; |
| 4262 | 4273 | struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table; |
| 4263 | 4274 | int i; |
| 4275 | + struct phm_clock_voltage_dependency_table *mclk_table; | |
| 4264 | 4276 | |
| 4265 | − if (table_info == NULL) | |
| 4266 | − return -EINVAL; | |
| 4267 | − | |
| 4268 | − dep_mclk_table = table_info->vdd_dep_on_mclk; | |
| 4269 | − | |
| 4270 | − for (i = 0; i < dep_mclk_table->count; i++) { | |
| 4271 | − clocks->clock[i] = dep_mclk_table->entries[i].clk; | |
| 4272 | − clocks->latency[i] = smu7_get_mem_latency(hwmgr, | |
| 4277 | + if (hwmgr->pp_table_version == PP_TABLE_V1) { | |
| 4278 | + if (table_info == NULL) | |
| 4279 | + return -EINVAL; | |
| 4280 | + dep_mclk_table = table_info->vdd_dep_on_mclk; | |
| 4281 | + for (i = 0; i < dep_mclk_table->count; i++) { | |
| 4282 | + clocks->clock[i] = dep_mclk_table->entries[i].clk; | |
| 4283 | + clocks->latency[i] = smu7_get_mem_latency(hwmgr, | |
| 4273 | 4284 | dep_mclk_table->entries[i].clk); |
| 4274 | − clocks->count++; | |
| 4285 | + clocks->count++; | |
| 4286 | + } | |
| 4287 | + } else if (hwmgr->pp_table_version == PP_TABLE_V0) { | |
| 4288 | + mclk_table = hwmgr->dyn_state.vddc_dependency_on_mclk; | |
| 4289 | + for (i = 0; i < mclk_table->count; i++) { | |
| 4290 | + clocks->clock[i] = mclk_table->entries[i].clk; | |
| 4291 | + clocks->count++; | |
| 4292 | + } | |
| 4275 | 4293 | } |
| 4276 | 4294 | return 0; |
| 4277 | 4295 | } |
| @@ -30,7 +30,7 @@ int smu7_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, · 29 unmodified lines | ||
| 30 | 30 | struct phm_fan_speed_info *fan_speed_info) |
| 31 | 31 | { |
| 32 | 32 | if (hwmgr->thermal_controller.fanInfo.bNoFan) |
| 33 | − return 0; | |
| 33 | + return -ENODEV; | |
| 34 | 34 | |
| 35 | 35 | fan_speed_info->supports_percent_read = true; |
| 36 | 36 | fan_speed_info->supports_percent_write = true; |
| @@ -60,7 +60,7 @@ int smu7_fan_ctrl_get_fan_speed_percent(struct pp_hwmgr *hwmgr, · 23 unmodified lines | ||
| 60 | 60 | uint64_t tmp64; |
| 61 | 61 | |
| 62 | 62 | if (hwmgr->thermal_controller.fanInfo.bNoFan) |
| 63 | − return 0; | |
| 63 | + return -ENODEV; | |
| 64 | 64 | |
| 65 | 65 | duty100 = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, |
| 66 | 66 | CG_FDO_CTRL1, FMAX_DUTY100); |
| @@ -89,7 +89,7 @@ int smu7_fan_ctrl_get_fan_speed_rpm(struct pp_hwmgr *hwmgr, uint32_t *speed) · 22 unmodified lines | ||
| 89 | 89 | if (hwmgr->thermal_controller.fanInfo.bNoFan || |
| 90 | 90 | (hwmgr->thermal_controller.fanInfo. |
| 91 | 91 | ucTachometerPulsesPerRevolution == 0)) |
| 92 | − return 0; | |
| 92 | + return -ENODEV; | |
| 93 | 93 | |
| 94 | 94 | tach_period = PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, |
| 95 | 95 | CG_TACH_STATUS, TACH_PERIOD); |
| @@ -34,9 +34,6 @@ static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity); · 33 unmodified lines | ||
| 34 | 34 | static void amd_sched_wakeup(struct amd_gpu_scheduler *sched); |
| 35 | 35 | static void amd_sched_process_job(struct fence *f, struct fence_cb *cb); |
| 36 | 36 | |
| 37 | −struct kmem_cache *sched_fence_slab; | |
| 38 | −atomic_t sched_fence_slab_ref = ATOMIC_INIT(0); | |
| 39 | − | |
| 40 | 37 | /* Initialize a given run queue struct */ |
| 41 | 38 | static void amd_sched_rq_init(struct amd_sched_rq *rq) |
| 42 | 39 | { |
| @@ -618,13 +615,6 @@ int amd_sched_init(struct amd_gpu_scheduler *sched, · 575 unmodified lines | ||
| 618 | 615 | INIT_LIST_HEAD(&sched->ring_mirror_list); |
| 619 | 616 | spin_lock_init(&sched->job_list_lock); |
| 620 | 617 | atomic_set(&sched->hw_rq_count, 0); |
| 621 | − if (atomic_inc_return(&sched_fence_slab_ref) == 1) { | |
| 622 | − sched_fence_slab = kmem_cache_create( | |
| 623 | − "amd_sched_fence", sizeof(struct amd_sched_fence), 0, | |
| 624 | − SLAB_HWCACHE_ALIGN, NULL); | |
| 625 | − if (!sched_fence_slab) | |
| 626 | − return -ENOMEM; | |
| 627 | − } | |
| 628 | 618 | |
| 629 | 619 | /* Each scheduler will run on a seperate kernel thread */ |
| 630 | 620 | sched->thread = kthread_run(amd_sched_main, sched, sched->name); |
| @@ -645,7 +635,4 @@ void amd_sched_fini(struct amd_gpu_scheduler *sched) · 14 unmodified lines | ||
| 645 | 635 | { |
| 646 | 636 | if (sched->thread) |
| 647 | 637 | kthread_stop(sched->thread); |
| 648 | − rcu_barrier(); | |
| 649 | − if (atomic_dec_and_test(&sched_fence_slab_ref)) | |
| 650 | − kmem_cache_destroy(sched_fence_slab); | |
| 651 | 638 | } |
| @@ -30,9 +30,6 @@ · 29 unmodified lines | ||
| 30 | 30 | struct amd_gpu_scheduler; |
| 31 | 31 | struct amd_sched_rq; |
| 32 | 32 | |
| 33 | −extern struct kmem_cache *sched_fence_slab; | |
| 34 | −extern atomic_t sched_fence_slab_ref; | |
| 35 | − | |
| 36 | 33 | /** |
| 37 | 34 | * A scheduler entity is a wrapper around a job queue or a group |
| 38 | 35 | * of other entities. Entities take turns emitting jobs from their |
| @@ -145,6 +142,9 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched, · 106 unmodified lines | ||
| 145 | 142 | struct amd_sched_entity *entity); |
| 146 | 143 | void amd_sched_entity_push_job(struct amd_sched_job *sched_job); |
| 147 | 144 | |
| 145 | +int amd_sched_fence_slab_init(void); | |
| 146 | +void amd_sched_fence_slab_fini(void); | |
| 147 | + | |
| 148 | 148 | struct amd_sched_fence *amd_sched_fence_create( |
| 149 | 149 | struct amd_sched_entity *s_entity, void *owner); |
| 150 | 150 | void amd_sched_fence_scheduled(struct amd_sched_fence *fence); |
| @@ -27,6 +27,25 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <drm/drmP.h> |
| 28 | 28 | #include "gpu_scheduler.h" |
| 29 | 29 | |
| 30 | +static struct kmem_cache *sched_fence_slab; | |
| 31 | + | |
| 32 | +int amd_sched_fence_slab_init(void) | |
| 33 | +{ | |
| 34 | + sched_fence_slab = kmem_cache_create( | |
| 35 | + "amd_sched_fence", sizeof(struct amd_sched_fence), 0, | |
| 36 | + SLAB_HWCACHE_ALIGN, NULL); | |
| 37 | + if (!sched_fence_slab) | |
| 38 | + return -ENOMEM; | |
| 39 | + | |
| 40 | + return 0; | |
| 41 | +} | |
| 42 | + | |
| 43 | +void amd_sched_fence_slab_fini(void) | |
| 44 | +{ | |
| 45 | + rcu_barrier(); | |
| 46 | + kmem_cache_destroy(sched_fence_slab); | |
| 47 | +} | |
| 48 | + | |
| 30 | 49 | struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *entity, |
| 31 | 50 | void *owner) |
| 32 | 51 | { |
| @@ -14,170 +14,45 @@ · 13 unmodified lines | ||
| 14 | 14 | * |
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | −#include <drm/drm_crtc_helper.h> | |
| 17 | +#include <drm/drm_crtc.h> | |
| 18 | 18 | #include <drm/drm_encoder_slave.h> |
| 19 | −#include <drm/drm_atomic_helper.h> | |
| 20 | 19 | |
| 21 | 20 | #include "arcpgu.h" |
| 22 | 21 | |
| 23 | −struct arcpgu_drm_connector { | |
| 24 | − struct drm_connector connector; | |
| 25 | − struct drm_encoder_slave *encoder_slave; | |
| 26 | −}; | |
| 27 | − | |
| 28 | −static int arcpgu_drm_connector_get_modes(struct drm_connector *connector) | |
| 29 | −{ | |
| 30 | − const struct drm_encoder_slave_funcs *sfuncs; | |
| 31 | − struct drm_encoder_slave *slave; | |
| 32 | − struct arcpgu_drm_connector *con = | |
| 33 | − container_of(connector, struct arcpgu_drm_connector, connector); | |
| 34 | − | |
| 35 | − slave = con->encoder_slave; | |
| 36 | − if (slave == NULL) { | |
| 37 | − dev_err(connector->dev->dev, | |
| 38 | − "connector_get_modes: cannot find slave encoder for connector\n"); | |
| 39 | − return 0; | |
| 40 | − } | |
| 41 | − | |
| 42 | − sfuncs = slave->slave_funcs; | |
| 43 | − if (sfuncs->get_modes == NULL) | |
| 44 | − return 0; | |
| 45 | − | |
| 46 | − return sfuncs->get_modes(&slave->base, connector); | |
| 47 | −} | |
| 48 | − | |
| 49 | −static enum drm_connector_status | |
| 50 | −arcpgu_drm_connector_detect(struct drm_connector *connector, bool force) | |
| 51 | −{ | |
| 52 | − enum drm_connector_status status = connector_status_unknown; | |
| 53 | − const struct drm_encoder_slave_funcs *sfuncs; | |
| 54 | − struct drm_encoder_slave *slave; | |
| 55 | − | |
| 56 | − struct arcpgu_drm_connector *con = | |
| 57 | − container_of(connector, struct arcpgu_drm_connector, connector); | |
| 58 | − | |
| 59 | − slave = con->encoder_slave; | |
| 60 | − if (slave == NULL) { | |
| 61 | − dev_err(connector->dev->dev, | |
| 62 | − "connector_detect: cannot find slave encoder for connector\n"); | |
| 63 | − return status; | |
| 64 | − } | |
| 65 | − | |
| 66 | − sfuncs = slave->slave_funcs; | |
| 67 | − if (sfuncs && sfuncs->detect) | |
| 68 | − return sfuncs->detect(&slave->base, connector); | |
| 69 | − | |
| 70 | − dev_err(connector->dev->dev, "connector_detect: could not detect slave funcs\n"); | |
| 71 | − return status; | |
| 72 | −} | |
| 73 | − | |
| 74 | −static void arcpgu_drm_connector_destroy(struct drm_connector *connector) | |
| 75 | −{ | |
| 76 | − drm_connector_unregister(connector); | |
| 77 | − drm_connector_cleanup(connector); | |
| 78 | −} | |
| 79 | − | |
| 80 | −static const struct drm_connector_helper_funcs | |
| 81 | −arcpgu_drm_connector_helper_funcs = { | |
| 82 | − .get_modes = arcpgu_drm_connector_get_modes, | |
| 83 | −}; | |
| 84 | − | |
| 85 | −static const struct drm_connector_funcs arcpgu_drm_connector_funcs = { | |
| 86 | − .dpms = drm_helper_connector_dpms, | |
| 87 | − .reset = drm_atomic_helper_connector_reset, | |
| 88 | − .detect = arcpgu_drm_connector_detect, | |
| 89 | − .fill_modes = drm_helper_probe_single_connector_modes, | |
| 90 | − .destroy = arcpgu_drm_connector_destroy, | |
| 91 | − .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | |
| 92 | − .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | |
| 93 | −}; | |
| 94 | − | |
| 95 | −static struct drm_encoder_helper_funcs arcpgu_drm_encoder_helper_funcs = { | |
| 96 | − .dpms = drm_i2c_encoder_dpms, | |
| 97 | − .mode_fixup = drm_i2c_encoder_mode_fixup, | |
| 98 | − .mode_set = drm_i2c_encoder_mode_set, | |
| 99 | − .prepare = drm_i2c_encoder_prepare, | |
| 100 | − .commit = drm_i2c_encoder_commit, | |
| 101 | − .detect = drm_i2c_encoder_detect, | |
| 102 | −}; | |
| 103 | − | |
| 104 | 22 | static struct drm_encoder_funcs arcpgu_drm_encoder_funcs = { |
| 105 | 23 | .destroy = drm_encoder_cleanup, |
| 106 | 24 | }; |
| 107 | 25 | |
| 108 | 26 | int arcpgu_drm_hdmi_init(struct drm_device *drm, struct device_node *np) |
| 109 | 27 | { |
| 110 | − struct arcpgu_drm_connector *arcpgu_connector; | |
| 111 | − struct drm_i2c_encoder_driver *driver; | |
| 112 | − struct drm_encoder_slave *encoder; | |
| 113 | − struct drm_connector *connector; | |
| 114 | − struct i2c_client *i2c_slave; | |
| 115 | − int ret; | |
| 28 | + struct drm_encoder *encoder; | |
| 29 | + struct drm_bridge *bridge; | |
| 30 | + | |
| 31 | + int ret = 0; | |
| 116 | 32 | |
| 117 | 33 | encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL); |
| 118 | 34 | if (encoder == NULL) |
| 119 | 35 | return -ENOMEM; |
| 120 | 36 | |
| 121 | − i2c_slave = of_find_i2c_device_by_node(np); | |
| 122 | − if (!i2c_slave || !i2c_get_clientdata(i2c_slave)) { | |
| 123 | − dev_err(drm->dev, "failed to find i2c slave encoder\n"); | |
| 124 | − return -EPROBE_DEFER; | |
| 125 | − } | |
| 126 | − | |
| 127 | − if (i2c_slave->dev.driver == NULL) { | |
| 128 | − dev_err(drm->dev, "failed to find i2c slave driver\n"); | |
| 37 | + /* Locate drm bridge from the hdmi encoder DT node */ | |
| 38 | + bridge = of_drm_find_bridge(np); | |
| 39 | + if (!bridge) | |
| 129 | 40 | return -EPROBE_DEFER; |
| 130 | − } | |
| 131 | 41 | |
| 132 | − driver = | |
| 133 | − to_drm_i2c_encoder_driver(to_i2c_driver(i2c_slave->dev.driver)); | |
| 134 | − ret = driver->encoder_init(i2c_slave, drm, encoder); | |
| 135 | − if (ret) { | |
| 136 | − dev_err(drm->dev, "failed to initialize i2c encoder slave\n"); | |
| 137 | − return ret; | |
| 138 | − } | |
| 139 | − | |
| 140 | − encoder->base.possible_crtcs = 1; | |
| 141 | − encoder->base.possible_clones = 0; | |
| 142 | − ret = drm_encoder_init(drm, &encoder->base, &arcpgu_drm_encoder_funcs, | |
| 42 | + encoder->possible_crtcs = 1; | |
| 43 | + encoder->possible_clones = 0; | |
| 44 | + ret = drm_encoder_init(drm, encoder, &arcpgu_drm_encoder_funcs, | |
| 143 | 45 | DRM_MODE_ENCODER_TMDS, NULL); |
| 144 | 46 | if (ret) |
| 145 | 47 | return ret; |
| 146 | 48 | |
| 147 | − drm_encoder_helper_add(&encoder->base, | |
| 148 | − &arcpgu_drm_encoder_helper_funcs); | |
| 149 | − | |
| 150 | − arcpgu_connector = devm_kzalloc(drm->dev, sizeof(*arcpgu_connector), | |
| 151 | − GFP_KERNEL); | |
| 152 | − if (!arcpgu_connector) { | |
| 153 | − ret = -ENOMEM; | |
| 154 | − goto error_encoder_cleanup; | |
| 155 | − } | |
| 156 | − | |
| 157 | − connector = &arcpgu_connector->connector; | |
| 158 | − drm_connector_helper_add(connector, &arcpgu_drm_connector_helper_funcs); | |
| 159 | − ret = drm_connector_init(drm, connector, &arcpgu_drm_connector_funcs, | |
| 160 | − DRM_MODE_CONNECTOR_HDMIA); | |
| 161 | − if (ret < 0) { | |
| 162 | − dev_err(drm->dev, "failed to initialize drm connector\n"); | |
| 163 | − goto error_encoder_cleanup; | |
| 164 | − } | |
| 49 | + /* Link drm_bridge to encoder */ | |
| 50 | + bridge->encoder = encoder; | |
| 51 | + encoder->bridge = bridge; | |
| 165 | 52 | |
| 166 | − ret = drm_mode_connector_attach_encoder(connector, &encoder->base); | |
| 167 | − if (ret < 0) { | |
| 168 | − dev_err(drm->dev, "could not attach connector to encoder\n"); | |
| 169 | − drm_connector_unregister(connector); | |
| 170 | − goto error_connector_cleanup; | |
| 171 | − } | |
| 172 | − | |
| 173 | − arcpgu_connector->encoder_slave = encoder; | |
| 174 | − | |
| 175 | − return 0; | |
| 176 | − | |
| 177 | −error_connector_cleanup: | |
| 178 | − drm_connector_cleanup(connector); | |
| 53 | + ret = drm_bridge_attach(drm, bridge); | |
| 54 | + if (ret) | |
| 55 | + drm_encoder_cleanup(encoder); | |
| 179 | 56 | |
| 180 | −error_encoder_cleanup: | |
| 181 | − drm_encoder_cleanup(&encoder->base); | |
| 182 | 57 | return ret; |
| 183 | 58 | } |
| @@ -25,8 +25,13 @@ · 24 unmodified lines | ||
| 25 | 25 | static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc, |
| 26 | 26 | struct drm_crtc_state *old_crtc_state) |
| 27 | 27 | { |
| 28 | + struct drm_device *dev = crtc->dev; | |
| 29 | + struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; | |
| 28 | 30 | struct drm_pending_vblank_event *event = crtc->state->event; |
| 29 | 31 | |
| 32 | + regmap_write(fsl_dev->regmap, | |
| 33 | + DCU_UPDATE_MODE, DCU_UPDATE_MODE_READREG); | |
| 34 | + | |
| 30 | 35 | if (event) { |
| 31 | 36 | crtc->state->event = NULL; |
| 32 | 37 | |
| @@ -39,11 +44,15 @@ static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc, · 6 unmodified lines | ||
| 39 | 44 | } |
| 40 | 45 | } |
| 41 | 46 | |
| 42 | −static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc) | |
| 47 | +static void fsl_dcu_drm_crtc_atomic_disable(struct drm_crtc *crtc, | |
| 48 | + struct drm_crtc_state *old_crtc_state) | |
| 43 | 49 | { |
| 44 | 50 | struct drm_device *dev = crtc->dev; |
| 45 | 51 | struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; |
| 46 | 52 | |
| 53 | + /* always disable planes on the CRTC */ | |
| 54 | + drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, true); | |
| 55 | + | |
| 47 | 56 | drm_crtc_vblank_off(crtc); |
| 48 | 57 | |
| 49 | 58 | regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, |
| @@ -122,8 +131,8 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc) · 72 unmodified lines | ||
| 122 | 131 | } |
| 123 | 132 | |
| 124 | 133 | static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = { |
| 134 | + .atomic_disable = fsl_dcu_drm_crtc_atomic_disable, | |
| 125 | 135 | .atomic_flush = fsl_dcu_drm_crtc_atomic_flush, |
| 126 | − .disable = fsl_dcu_drm_disable_crtc, | |
| 127 | 136 | .enable = fsl_dcu_drm_crtc_enable, |
| 128 | 137 | .mode_set_nofb = fsl_dcu_drm_crtc_mode_set_nofb, |
| 129 | 138 | }; |
| @@ -59,8 +59,6 @@ static int fsl_dcu_drm_irq_init(struct drm_device *dev) · 58 unmodified lines | ||
| 59 | 59 | |
| 60 | 60 | regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0); |
| 61 | 61 | regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0); |
| 62 | − regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, | |
| 63 | − DCU_UPDATE_MODE_READREG); | |
| 64 | 62 | |
| 65 | 63 | return ret; |
| 66 | 64 | } |
| @@ -139,8 +137,6 @@ static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg) · 72 unmodified lines | ||
| 139 | 137 | drm_handle_vblank(dev, 0); |
| 140 | 138 | |
| 141 | 139 | regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status); |
| 142 | − regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, | |
| 143 | − DCU_UPDATE_MODE_READREG); | |
| 144 | 140 | |
| 145 | 141 | return IRQ_HANDLED; |
| 146 | 142 | } |
| @@ -160,11 +160,6 @@ static void fsl_dcu_drm_plane_atomic_update(struct drm_plane *plane, · 159 unmodified lines | ||
| 160 | 160 | DCU_LAYER_POST_SKIP(0) | |
| 161 | 161 | DCU_LAYER_PRE_SKIP(0)); |
| 162 | 162 | } |
| 163 | − regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, | |
| 164 | − DCU_MODE_DCU_MODE_MASK, | |
| 165 | − DCU_MODE_DCU_MODE(DCU_MODE_NORMAL)); | |
| 166 | − regmap_write(fsl_dev->regmap, | |
| 167 | − DCU_UPDATE_MODE, DCU_UPDATE_MODE_READREG); | |
| 168 | 163 | |
| 169 | 164 | return; |
| 170 | 165 | } |
| @@ -1806,7 +1806,7 @@ int i915_gem_fault(struct vm_area_struct *area, struct vm_fault *vmf) · 1805 unmodified lines | ||
| 1806 | 1806 | /* Use a partial view if it is bigger than available space */ |
| 1807 | 1807 | chunk_size = MIN_CHUNK_PAGES; |
| 1808 | 1808 | if (i915_gem_object_is_tiled(obj)) |
| 1809 | − chunk_size = max(chunk_size, tile_row_pages(obj)); | |
| 1809 | + chunk_size = roundup(chunk_size, tile_row_pages(obj)); | |
| 1810 | 1810 | |
| 1811 | 1811 | memset(&view, 0, sizeof(view)); |
| 1812 | 1812 | view.type = I915_GGTT_VIEW_PARTIAL; |
| @@ -3543,8 +3543,22 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, · 1730 unmodified lines | ||
| 3543 | 3543 | if (view->type == I915_GGTT_VIEW_NORMAL) |
| 3544 | 3544 | vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, |
| 3545 | 3545 | PIN_MAPPABLE | PIN_NONBLOCK); |
| 3546 | − if (IS_ERR(vma)) | |
| 3547 | − vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, 0); | |
| 3546 | + if (IS_ERR(vma)) { | |
| 3547 | + struct drm_i915_private *i915 = to_i915(obj->base.dev); | |
| 3548 | + unsigned int flags; | |
| 3549 | + | |
| 3550 | + /* Valleyview is definitely limited to scanning out the first | |
| 3551 | + * 512MiB. Lets presume this behaviour was inherited from the | |
| 3552 | + * g4x display engine and that all earlier gen are similarly | |
| 3553 | + * limited. Testing suggests that it is a little more | |
| 3554 | + * complicated than this. For example, Cherryview appears quite | |
| 3555 | + * happy to scanout from anywhere within its global aperture. | |
| 3556 | + */ | |
| 3557 | + flags = 0; | |
| 3558 | + if (HAS_GMCH_DISPLAY(i915)) | |
| 3559 | + flags = PIN_MAPPABLE; | |
| 3560 | + vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, flags); | |
| 3561 | + } | |
| 3548 | 3562 | if (IS_ERR(vma)) |
| 3549 | 3563 | goto err_unpin_display; |
| 3550 | 3564 | |
| @@ -1281,6 +1281,12 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, · 1280 unmodified lines | ||
| 1281 | 1281 | return ctx; |
| 1282 | 1282 | } |
| 1283 | 1283 | |
| 1284 | +static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj) | |
| 1285 | +{ | |
| 1286 | + return !(obj->cache_level == I915_CACHE_NONE || | |
| 1287 | + obj->cache_level == I915_CACHE_WT); | |
| 1288 | +} | |
| 1289 | + | |
| 1284 | 1290 | void i915_vma_move_to_active(struct i915_vma *vma, |
| 1285 | 1291 | struct drm_i915_gem_request *req, |
| 1286 | 1292 | unsigned int flags) |
| @@ -1311,6 +1317,8 @@ void i915_vma_move_to_active(struct i915_vma *vma, · 24 unmodified lines | ||
| 1311 | 1317 | |
| 1312 | 1318 | /* update for the implicit flush after a batch */ |
| 1313 | 1319 | obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; |
| 1320 | + if (!obj->cache_dirty && gpu_write_needs_clflush(obj)) | |
| 1321 | + obj->cache_dirty = true; | |
| 1314 | 1322 | } |
| 1315 | 1323 | |
| 1316 | 1324 | if (flags & EXEC_OBJECT_NEEDS_FENCE) |
| @@ -1143,7 +1143,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, · 1142 unmodified lines | ||
| 1143 | 1143 | if (!child) |
| 1144 | 1144 | return; |
| 1145 | 1145 | |
| 1146 | − aux_channel = child->raw[25]; | |
| 1146 | + aux_channel = child->common.aux_channel; | |
| 1147 | 1147 | ddc_pin = child->common.ddc_pin; |
| 1148 | 1148 | |
| 1149 | 1149 | is_dvi = child->common.device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING; |
| @@ -1673,7 +1673,8 @@ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port) · 523 unmodified lines | ||
| 1673 | 1673 | return false; |
| 1674 | 1674 | } |
| 1675 | 1675 | |
| 1676 | −bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port) | |
| 1676 | +static bool child_dev_is_dp_dual_mode(const union child_device_config *p_child, | |
| 1677 | + enum port port) | |
| 1677 | 1678 | { |
| 1678 | 1679 | static const struct { |
| 1679 | 1680 | u16 dp, hdmi; |
| @@ -1687,22 +1688,35 @@ bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum por · 7 unmodified lines | ||
| 1687 | 1688 | [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, |
| 1688 | 1689 | [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, |
| 1689 | 1690 | }; |
| 1690 | − int i; | |
| 1691 | 1691 | |
| 1692 | 1692 | if (port == PORT_A || port >= ARRAY_SIZE(port_mapping)) |
| 1693 | 1693 | return false; |
| 1694 | 1694 | |
| 1695 | − if (!dev_priv->vbt.child_dev_num) | |
| 1695 | + if ((p_child->common.device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) != | |
| 1696 | + (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS)) | |
| 1696 | 1697 | return false; |
| 1697 | 1698 | |
| 1699 | + if (p_child->common.dvo_port == port_mapping[port].dp) | |
| 1700 | + return true; | |
| 1701 | + | |
| 1702 | + /* Only accept a HDMI dvo_port as DP++ if it has an AUX channel */ | |
| 1703 | + if (p_child->common.dvo_port == port_mapping[port].hdmi && | |
| 1704 | + p_child->common.aux_channel != 0) | |
| 1705 | + return true; | |
| 1706 | + | |
| 1707 | + return false; | |
| 1708 | +} | |
| 1709 | + | |
| 1710 | +bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, | |
| 1711 | + enum port port) | |
| 1712 | +{ | |
| 1713 | + int i; | |
| 1714 | + | |
| 1698 | 1715 | for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { |
| 1699 | 1716 | const union child_device_config *p_child = |
| 1700 | 1717 | &dev_priv->vbt.child_dev[i]; |
| 1701 | 1718 | |
| 1702 | − if ((p_child->common.dvo_port == port_mapping[port].dp || | |
| 1703 | − p_child->common.dvo_port == port_mapping[port].hdmi) && | |
| 1704 | − (p_child->common.device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) == | |
| 1705 | − (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS)) | |
| 1719 | + if (child_dev_is_dp_dual_mode(p_child, port)) | |
| 1706 | 1720 | return true; |
| 1707 | 1721 | } |
| 1708 | 1722 | |
| @@ -10243,6 +10243,29 @@ static void bxt_modeset_commit_cdclk(struct drm_atomic_state *old_state) · 10242 unmodified lines | ||
| 10243 | 10243 | bxt_set_cdclk(to_i915(dev), req_cdclk); |
| 10244 | 10244 | } |
| 10245 | 10245 | |
| 10246 | +static int bdw_adjust_min_pipe_pixel_rate(struct intel_crtc_state *crtc_state, | |
| 10247 | + int pixel_rate) | |
| 10248 | +{ | |
| 10249 | + struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); | |
| 10250 | + | |
| 10251 | + /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ | |
| 10252 | + if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled) | |
| 10253 | + pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95); | |
| 10254 | + | |
| 10255 | + /* BSpec says "Do not use DisplayPort with CDCLK less than | |
| 10256 | + * 432 MHz, audio enabled, port width x4, and link rate | |
| 10257 | + * HBR2 (5.4 GHz), or else there may be audio corruption or | |
| 10258 | + * screen corruption." | |
| 10259 | + */ | |
| 10260 | + if (intel_crtc_has_dp_encoder(crtc_state) && | |
| 10261 | + crtc_state->has_audio && | |
| 10262 | + crtc_state->port_clock >= 540000 && | |
| 10263 | + crtc_state->lane_count == 4) | |
| 10264 | + pixel_rate = max(432000, pixel_rate); | |
| 10265 | + | |
| 10266 | + return pixel_rate; | |
| 10267 | +} | |
| 10268 | + | |
| 10246 | 10269 | /* compute the max rate for new configuration */ |
| 10247 | 10270 | static int ilk_max_pixel_rate(struct drm_atomic_state *state) |
| 10248 | 10271 | { |
| @@ -10268,9 +10291,9 @@ static int ilk_max_pixel_rate(struct drm_atomic_state *state) · 19 unmodified lines | ||
| 10268 | 10291 | |
| 10269 | 10292 | pixel_rate = ilk_pipe_pixel_rate(crtc_state); |
| 10270 | 10293 | |
| 10271 | − /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ | |
| 10272 | − if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled) | |
| 10273 | − pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95); | |
| 10294 | + if (IS_BROADWELL(dev_priv) || IS_GEN9(dev_priv)) | |
| 10295 | + pixel_rate = bdw_adjust_min_pipe_pixel_rate(crtc_state, | |
| 10296 | + pixel_rate); | |
| 10274 | 10297 | |
| 10275 | 10298 | intel_state->min_pixclk[i] = pixel_rate; |
| 10276 | 10299 | } |
| @@ -4463,21 +4463,11 @@ static enum drm_connector_status · 4462 unmodified lines | ||
| 4463 | 4463 | intel_dp_detect(struct drm_connector *connector, bool force) |
| 4464 | 4464 | { |
| 4465 | 4465 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
| 4466 | − struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | |
| 4467 | − struct intel_encoder *intel_encoder = &intel_dig_port->base; | |
| 4468 | 4466 | enum drm_connector_status status = connector->status; |
| 4469 | 4467 | |
| 4470 | 4468 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", |
| 4471 | 4469 | connector->base.id, connector->name); |
| 4472 | 4470 | |
| 4473 | − if (intel_dp->is_mst) { | |
| 4474 | − /* MST devices are disconnected from a monitor POV */ | |
| 4475 | − intel_dp_unset_edid(intel_dp); | |
| 4476 | − if (intel_encoder->type != INTEL_OUTPUT_EDP) | |
| 4477 | − intel_encoder->type = INTEL_OUTPUT_DP; | |
| 4478 | − return connector_status_disconnected; | |
| 4479 | − } | |
| 4480 | − | |
| 4481 | 4471 | /* If full detect is not performed yet, do a full detect */ |
| 4482 | 4472 | if (!intel_dp->detect_done) |
| 4483 | 4473 | status = intel_dp_long_pulse(intel_dp->attached_connector); |
| @@ -1799,6 +1799,50 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c · 1798 unmodified lines | ||
| 1799 | 1799 | intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE; |
| 1800 | 1800 | } |
| 1801 | 1801 | |
| 1802 | +static u8 intel_hdmi_ddc_pin(struct drm_i915_private *dev_priv, | |
| 1803 | + enum port port) | |
| 1804 | +{ | |
| 1805 | + const struct ddi_vbt_port_info *info = | |
| 1806 | + &dev_priv->vbt.ddi_port_info[port]; | |
| 1807 | + u8 ddc_pin; | |
| 1808 | + | |
| 1809 | + if (info->alternate_ddc_pin) { | |
| 1810 | + DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (VBT)\n", | |
| 1811 | + info->alternate_ddc_pin, port_name(port)); | |
| 1812 | + return info->alternate_ddc_pin; | |
| 1813 | + } | |
| 1814 | + | |
| 1815 | + switch (port) { | |
| 1816 | + case PORT_B: | |
| 1817 | + if (IS_BROXTON(dev_priv)) | |
| 1818 | + ddc_pin = GMBUS_PIN_1_BXT; | |
| 1819 | + else | |
| 1820 | + ddc_pin = GMBUS_PIN_DPB; | |
| 1821 | + break; | |
| 1822 | + case PORT_C: | |
| 1823 | + if (IS_BROXTON(dev_priv)) | |
| 1824 | + ddc_pin = GMBUS_PIN_2_BXT; | |
| 1825 | + else | |
| 1826 | + ddc_pin = GMBUS_PIN_DPC; | |
| 1827 | + break; | |
| 1828 | + case PORT_D: | |
| 1829 | + if (IS_CHERRYVIEW(dev_priv)) | |
| 1830 | + ddc_pin = GMBUS_PIN_DPD_CHV; | |
| 1831 | + else | |
| 1832 | + ddc_pin = GMBUS_PIN_DPD; | |
| 1833 | + break; | |
| 1834 | + default: | |
| 1835 | + MISSING_CASE(port); | |
| 1836 | + ddc_pin = GMBUS_PIN_DPB; | |
| 1837 | + break; | |
| 1838 | + } | |
| 1839 | + | |
| 1840 | + DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (platform default)\n", | |
| 1841 | + ddc_pin, port_name(port)); | |
| 1842 | + | |
| 1843 | + return ddc_pin; | |
| 1844 | +} | |
| 1845 | + | |
| 1802 | 1846 | void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, |
| 1803 | 1847 | struct intel_connector *intel_connector) |
| 1804 | 1848 | { |
| @@ -1808,7 +1852,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, · 3 unmodified lines | ||
| 1808 | 1852 | struct drm_device *dev = intel_encoder->base.dev; |
| 1809 | 1853 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 1810 | 1854 | enum port port = intel_dig_port->port; |
| 1811 | − uint8_t alternate_ddc_pin; | |
| 1812 | 1855 | |
| 1813 | 1856 | DRM_DEBUG_KMS("Adding HDMI connector on port %c\n", |
| 1814 | 1857 | port_name(port)); |
| @@ -1826,12 +1869,10 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, · 11 unmodified lines | ||
| 1826 | 1869 | connector->doublescan_allowed = 0; |
| 1827 | 1870 | connector->stereo_allowed = 1; |
| 1828 | 1871 | |
| 1872 | + intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(dev_priv, port); | |
| 1873 | + | |
| 1829 | 1874 | switch (port) { |
| 1830 | 1875 | case PORT_B: |
| 1831 | − if (IS_BROXTON(dev_priv)) | |
| 1832 | − intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT; | |
| 1833 | − else | |
| 1834 | − intel_hdmi->ddc_bus = GMBUS_PIN_DPB; | |
| 1835 | 1876 | /* |
| 1836 | 1877 | * On BXT A0/A1, sw needs to activate DDIA HPD logic and |
| 1837 | 1878 | * interrupts to check the external panel connection. |
| @@ -1842,46 +1883,17 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, · 4 unmodified lines | ||
| 1842 | 1883 | intel_encoder->hpd_pin = HPD_PORT_B; |
| 1843 | 1884 | break; |
| 1844 | 1885 | case PORT_C: |
| 1845 | − if (IS_BROXTON(dev_priv)) | |
| 1846 | − intel_hdmi->ddc_bus = GMBUS_PIN_2_BXT; | |
| 1847 | − else | |
| 1848 | − intel_hdmi->ddc_bus = GMBUS_PIN_DPC; | |
| 1849 | 1886 | intel_encoder->hpd_pin = HPD_PORT_C; |
| 1850 | 1887 | break; |
| 1851 | 1888 | case PORT_D: |
| 1852 | − if (WARN_ON(IS_BROXTON(dev_priv))) | |
| 1853 | − intel_hdmi->ddc_bus = GMBUS_PIN_DISABLED; | |
| 1854 | − else if (IS_CHERRYVIEW(dev_priv)) | |
| 1855 | − intel_hdmi->ddc_bus = GMBUS_PIN_DPD_CHV; | |
| 1856 | − else | |
| 1857 | − intel_hdmi->ddc_bus = GMBUS_PIN_DPD; | |
| 1858 | 1889 | intel_encoder->hpd_pin = HPD_PORT_D; |
| 1859 | 1890 | break; |
| 1860 | 1891 | case PORT_E: |
| 1861 | − /* On SKL PORT E doesn't have seperate GMBUS pin | |
| 1862 | − * We rely on VBT to set a proper alternate GMBUS pin. */ | |
| 1863 | − alternate_ddc_pin = | |
| 1864 | − dev_priv->vbt.ddi_port_info[PORT_E].alternate_ddc_pin; | |
| 1865 | − switch (alternate_ddc_pin) { | |
| 1866 | − case DDC_PIN_B: | |
| 1867 | − intel_hdmi->ddc_bus = GMBUS_PIN_DPB; | |
| 1868 | − break; | |
| 1869 | − case DDC_PIN_C: | |
| 1870 | − intel_hdmi->ddc_bus = GMBUS_PIN_DPC; | |
| 1871 | − break; | |
| 1872 | − case DDC_PIN_D: | |
| 1873 | − intel_hdmi->ddc_bus = GMBUS_PIN_DPD; | |
| 1874 | − break; | |
| 1875 | − default: | |
| 1876 | − MISSING_CASE(alternate_ddc_pin); | |
| 1877 | − } | |
| 1878 | 1892 | intel_encoder->hpd_pin = HPD_PORT_E; |
| 1879 | 1893 | break; |
| 1880 | − case PORT_A: | |
| 1881 | − intel_encoder->hpd_pin = HPD_PORT_A; | |
| 1882 | − /* Internal port only for eDP. */ | |
| 1883 | 1894 | default: |
| 1884 | − BUG(); | |
| 1895 | + MISSING_CASE(port); | |
| 1896 | + return; | |
| 1885 | 1897 | } |
| 1886 | 1898 | |
| 1887 | 1899 | if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { |
| @@ -1139,7 +1139,9 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv) · 1138 unmodified lines | ||
| 1139 | 1139 | |
| 1140 | 1140 | intel_power_sequencer_reset(dev_priv); |
| 1141 | 1141 | |
| 1142 | − intel_hpd_poll_init(dev_priv); | |
| 1142 | + /* Prevent us from re-enabling polling on accident in late suspend */ | |
| 1143 | + if (!dev_priv->drm.dev->power.is_suspended) | |
| 1144 | + intel_hpd_poll_init(dev_priv); | |
| 1143 | 1145 | } |
| 1144 | 1146 | |
| 1145 | 1147 | static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, |
| @@ -358,7 +358,7 @@ vlv_update_plane(struct drm_plane *dplane, · 357 unmodified lines | ||
| 358 | 358 | int plane = intel_plane->plane; |
| 359 | 359 | u32 sprctl; |
| 360 | 360 | u32 sprsurf_offset, linear_offset; |
| 361 | − unsigned int rotation = dplane->state->rotation; | |
| 361 | + unsigned int rotation = plane_state->base.rotation; | |
| 362 | 362 | const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; |
| 363 | 363 | int crtc_x = plane_state->base.dst.x1; |
| 364 | 364 | int crtc_y = plane_state->base.dst.y1; |
| @@ -280,7 +280,8 @@ struct common_child_dev_config { · 279 unmodified lines | ||
| 280 | 280 | u8 dp_support:1; |
| 281 | 281 | u8 tmds_support:1; |
| 282 | 282 | u8 support_reserved:5; |
| 283 | − u8 not_common3[12]; | |
| 283 | + u8 aux_channel; | |
| 284 | + u8 not_common3[11]; | |
| 284 | 285 | u8 iboost_level; |
| 285 | 286 | } __packed; |
| 286 | 287 | |
| @@ -68,6 +68,12 @@ static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, · 67 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | ipu_dc_disable_channel(ipu_crtc->dc); |
| 70 | 70 | ipu_di_disable(ipu_crtc->di); |
| 71 | + /* | |
| 72 | + * Planes must be disabled before DC clock is removed, as otherwise the | |
| 73 | + * attached IDMACs will be left in undefined state, possibly hanging | |
| 74 | + * the IPU or even system. | |
| 75 | + */ | |
| 76 | + drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); | |
| 71 | 77 | ipu_dc_disable(ipu); |
| 72 | 78 | |
| 73 | 79 | spin_lock_irq(&crtc->dev->event_lock); |
| @@ -77,9 +83,6 @@ static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, · 3 unmodified lines | ||
| 77 | 83 | } |
| 78 | 84 | spin_unlock_irq(&crtc->dev->event_lock); |
| 79 | 85 | |
| 80 | − /* always disable planes on the CRTC */ | |
| 81 | − drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, true); | |
| 82 | − | |
| 83 | 86 | drm_crtc_vblank_off(crtc); |
| 84 | 87 | } |
| 85 | 88 | |
| @@ -80,6 +80,7 @@ static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp, · 79 unmodified lines | ||
| 80 | 80 | ddp_comp); |
| 81 | 81 | |
| 82 | 82 | priv->crtc = crtc; |
| 83 | + writel(0x0, comp->regs + DISP_REG_OVL_INTSTA); | |
| 83 | 84 | writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN); |
| 84 | 85 | } |
| 85 | 86 | |
| @@ -432,11 +432,16 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, · 431 unmodified lines | ||
| 432 | 432 | unsigned long pll_rate; |
| 433 | 433 | unsigned int factor; |
| 434 | 434 | |
| 435 | + /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */ | |
| 435 | 436 | pix_rate = 1000UL * mode->clock; |
| 436 | − if (mode->clock <= 74000) | |
| 437 | + if (mode->clock <= 27000) | |
| 438 | + factor = 16 * 3; | |
| 439 | + else if (mode->clock <= 84000) | |
| 437 | 440 | factor = 8 * 3; |
| 438 | − else | |
| 441 | + else if (mode->clock <= 167000) | |
| 439 | 442 | factor = 4 * 3; |
| 443 | + else | |
| 444 | + factor = 2 * 3; | |
| 440 | 445 | pll_rate = pix_rate * factor; |
| 441 | 446 | |
| 442 | 447 | dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n", |
| @@ -1133,12 +1133,6 @@ static int mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi, · 1132 unmodified lines | ||
| 1133 | 1133 | phy_power_on(hdmi->phy); |
| 1134 | 1134 | mtk_hdmi_aud_output_config(hdmi, mode); |
| 1135 | 1135 | |
| 1136 | − mtk_hdmi_setup_audio_infoframe(hdmi); | |
| 1137 | − mtk_hdmi_setup_avi_infoframe(hdmi, mode); | |
| 1138 | − mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI"); | |
| 1139 | − if (mode->flags & DRM_MODE_FLAG_3D_MASK) | |
| 1140 | − mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode); | |
| 1141 | − | |
| 1142 | 1136 | mtk_hdmi_hw_vid_black(hdmi, false); |
| 1143 | 1137 | mtk_hdmi_hw_aud_unmute(hdmi); |
| 1144 | 1138 | mtk_hdmi_hw_send_av_unmute(hdmi); |
| @@ -1401,6 +1395,16 @@ static void mtk_hdmi_bridge_pre_enable(struct drm_bridge *bridge) · 256 unmodified lines | ||
| 1401 | 1395 | hdmi->powered = true; |
| 1402 | 1396 | } |
| 1403 | 1397 | |
| 1398 | +static void mtk_hdmi_send_infoframe(struct mtk_hdmi *hdmi, | |
| 1399 | + struct drm_display_mode *mode) | |
| 1400 | +{ | |
| 1401 | + mtk_hdmi_setup_audio_infoframe(hdmi); | |
| 1402 | + mtk_hdmi_setup_avi_infoframe(hdmi, mode); | |
| 1403 | + mtk_hdmi_setup_spd_infoframe(hdmi, "mediatek", "On-chip HDMI"); | |
| 1404 | + if (mode->flags & DRM_MODE_FLAG_3D_MASK) | |
| 1405 | + mtk_hdmi_setup_vendor_specific_infoframe(hdmi, mode); | |
| 1406 | +} | |
| 1407 | + | |
| 1404 | 1408 | static void mtk_hdmi_bridge_enable(struct drm_bridge *bridge) |
| 1405 | 1409 | { |
| 1406 | 1410 | struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge); |
| @@ -1409,6 +1413,7 @@ static void mtk_hdmi_bridge_enable(struct drm_bridge *bridge) · 2 unmodified lines | ||
| 1409 | 1413 | clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PLL]); |
| 1410 | 1414 | clk_prepare_enable(hdmi->clk[MTK_HDMI_CLK_HDMI_PIXEL]); |
| 1411 | 1415 | phy_power_on(hdmi->phy); |
| 1416 | + mtk_hdmi_send_infoframe(hdmi, &hdmi->mode); | |
| 1412 | 1417 | |
| 1413 | 1418 | hdmi->enabled = true; |
| 1414 | 1419 | } |
| @@ -265,6 +265,9 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, · 264 unmodified lines | ||
| 265 | 265 | struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); |
| 266 | 266 | unsigned int pre_div; |
| 267 | 267 | unsigned int div; |
| 268 | + unsigned int pre_ibias; | |
| 269 | + unsigned int hdmi_ibias; | |
| 270 | + unsigned int imp_en; | |
| 268 | 271 | |
| 269 | 272 | dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__, |
| 270 | 273 | rate, parent_rate); |
| @@ -298,18 +301,31 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, · 27 unmodified lines | ||
| 298 | 301 | (0x1 << PLL_BR_SHIFT), |
| 299 | 302 | RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC | |
| 300 | 303 | RG_HDMITX_PLL_BR); |
| 301 | − mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_PRD_IMP_EN); | |
| 304 | + if (rate < 165000000) { | |
| 305 | + mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, | |
| 306 | + RG_HDMITX_PRD_IMP_EN); | |
| 307 | + pre_ibias = 0x3; | |
| 308 | + imp_en = 0x0; | |
| 309 | + hdmi_ibias = hdmi_phy->ibias; | |
| 310 | + } else { | |
| 311 | + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3, | |
| 312 | + RG_HDMITX_PRD_IMP_EN); | |
| 313 | + pre_ibias = 0x6; | |
| 314 | + imp_en = 0xf; | |
| 315 | + hdmi_ibias = hdmi_phy->ibias_up; | |
| 316 | + } | |
| 302 | 317 | mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, |
| 303 | − (0x3 << PRD_IBIAS_CLK_SHIFT) | | |
| 304 | − (0x3 << PRD_IBIAS_D2_SHIFT) | | |
| 305 | − (0x3 << PRD_IBIAS_D1_SHIFT) | | |
| 306 | − (0x3 << PRD_IBIAS_D0_SHIFT), | |
| 318 | + (pre_ibias << PRD_IBIAS_CLK_SHIFT) | | |
| 319 | + (pre_ibias << PRD_IBIAS_D2_SHIFT) | | |
| 320 | + (pre_ibias << PRD_IBIAS_D1_SHIFT) | | |
| 321 | + (pre_ibias << PRD_IBIAS_D0_SHIFT), | |
| 307 | 322 | RG_HDMITX_PRD_IBIAS_CLK | |
| 308 | 323 | RG_HDMITX_PRD_IBIAS_D2 | |
| 309 | 324 | RG_HDMITX_PRD_IBIAS_D1 | |
| 310 | 325 | RG_HDMITX_PRD_IBIAS_D0); |
| 311 | 326 | mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3, |
| 312 | − (0x0 << DRV_IMP_EN_SHIFT), RG_HDMITX_DRV_IMP_EN); | |
| 327 | + (imp_en << DRV_IMP_EN_SHIFT), | |
| 328 | + RG_HDMITX_DRV_IMP_EN); | |
| 313 | 329 | mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, |
| 314 | 330 | (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) | |
| 315 | 331 | (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) | |
| @@ -318,12 +334,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, · 2 unmodified lines | ||
| 318 | 334 | RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 | |
| 319 | 335 | RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0); |
| 320 | 336 | mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5, |
| 321 | − (hdmi_phy->ibias << DRV_IBIAS_CLK_SHIFT) | | |
| 322 | − (hdmi_phy->ibias << DRV_IBIAS_D2_SHIFT) | | |
| 323 | − (hdmi_phy->ibias << DRV_IBIAS_D1_SHIFT) | | |
| 324 | − (hdmi_phy->ibias << DRV_IBIAS_D0_SHIFT), | |
| 325 | − RG_HDMITX_DRV_IBIAS_CLK | RG_HDMITX_DRV_IBIAS_D2 | | |
| 326 | − RG_HDMITX_DRV_IBIAS_D1 | RG_HDMITX_DRV_IBIAS_D0); | |
| 337 | + (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) | | |
| 338 | + (hdmi_ibias << DRV_IBIAS_D2_SHIFT) | | |
| 339 | + (hdmi_ibias << DRV_IBIAS_D1_SHIFT) | | |
| 340 | + (hdmi_ibias << DRV_IBIAS_D0_SHIFT), | |
| 341 | + RG_HDMITX_DRV_IBIAS_CLK | | |
| 342 | + RG_HDMITX_DRV_IBIAS_D2 | | |
| 343 | + RG_HDMITX_DRV_IBIAS_D1 | | |
| 344 | + RG_HDMITX_DRV_IBIAS_D0); | |
| 327 | 345 | return 0; |
| 328 | 346 | } |
| 329 | 347 | |
| @@ -139,6 +139,7 @@ struct msm_dsi_host { · 138 unmodified lines | ||
| 139 | 139 | |
| 140 | 140 | u32 err_work_state; |
| 141 | 141 | struct work_struct err_work; |
| 142 | + struct work_struct hpd_work; | |
| 142 | 143 | struct workqueue_struct *workqueue; |
| 143 | 144 | |
| 144 | 145 | /* DSI 6G TX buffer*/ |
| @@ -1294,6 +1295,14 @@ static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host) · 1149 unmodified lines | ||
| 1294 | 1295 | wmb(); /* make sure dsi controller enabled again */ |
| 1295 | 1296 | } |
| 1296 | 1297 | |
| 1298 | +static void dsi_hpd_worker(struct work_struct *work) | |
| 1299 | +{ | |
| 1300 | + struct msm_dsi_host *msm_host = | |
| 1301 | + container_of(work, struct msm_dsi_host, hpd_work); | |
| 1302 | + | |
| 1303 | + drm_helper_hpd_irq_event(msm_host->dev); | |
| 1304 | +} | |
| 1305 | + | |
| 1297 | 1306 | static void dsi_err_worker(struct work_struct *work) |
| 1298 | 1307 | { |
| 1299 | 1308 | struct msm_dsi_host *msm_host = |
| @@ -1480,7 +1489,7 @@ static int dsi_host_attach(struct mipi_dsi_host *host, · 180 unmodified lines | ||
| 1480 | 1489 | |
| 1481 | 1490 | DBG("id=%d", msm_host->id); |
| 1482 | 1491 | if (msm_host->dev) |
| 1483 | − drm_helper_hpd_irq_event(msm_host->dev); | |
| 1492 | + queue_work(msm_host->workqueue, &msm_host->hpd_work); | |
| 1484 | 1493 | |
| 1485 | 1494 | return 0; |
| 1486 | 1495 | } |
| @@ -1494,7 +1503,7 @@ static int dsi_host_detach(struct mipi_dsi_host *host, · 7 unmodified lines | ||
| 1494 | 1503 | |
| 1495 | 1504 | DBG("id=%d", msm_host->id); |
| 1496 | 1505 | if (msm_host->dev) |
| 1497 | − drm_helper_hpd_irq_event(msm_host->dev); | |
| 1506 | + queue_work(msm_host->workqueue, &msm_host->hpd_work); | |
| 1498 | 1507 | |
| 1499 | 1508 | return 0; |
| 1500 | 1509 | } |
| @@ -1748,6 +1757,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) · 247 unmodified lines | ||
| 1748 | 1757 | /* setup workqueue */ |
| 1749 | 1758 | msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0); |
| 1750 | 1759 | INIT_WORK(&msm_host->err_work, dsi_err_worker); |
| 1760 | + INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker); | |
| 1751 | 1761 | |
| 1752 | 1762 | msm_dsi->host = &msm_host->base; |
| 1753 | 1763 | msm_dsi->id = msm_host->id; |
| @@ -521,6 +521,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) · 520 unmodified lines | ||
| 521 | 521 | .parent_names = (const char *[]){ "xo" }, |
| 522 | 522 | .num_parents = 1, |
| 523 | 523 | .name = vco_name, |
| 524 | + .flags = CLK_IGNORE_UNUSED, | |
| 524 | 525 | .ops = &clk_ops_dsi_pll_28nm_vco, |
| 525 | 526 | }; |
| 526 | 527 | struct device *dev = &pll_28nm->pdev->dev; |
| @@ -412,6 +412,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) · 411 unmodified lines | ||
| 412 | 412 | struct clk_init_data vco_init = { |
| 413 | 413 | .parent_names = (const char *[]){ "pxo" }, |
| 414 | 414 | .num_parents = 1, |
| 415 | + .flags = CLK_IGNORE_UNUSED, | |
| 415 | 416 | .ops = &clk_ops_dsi_pll_28nm_vco, |
| 416 | 417 | }; |
| 417 | 418 | struct device *dev = &pll_28nm->pdev->dev; |
| @@ -702,6 +702,7 @@ static struct clk_init_data pll_init = { · 701 unmodified lines | ||
| 702 | 702 | .ops = &hdmi_8996_pll_ops, |
| 703 | 703 | .parent_names = hdmi_pll_parents, |
| 704 | 704 | .num_parents = ARRAY_SIZE(hdmi_pll_parents), |
| 705 | + .flags = CLK_IGNORE_UNUSED, | |
| 705 | 706 | }; |
| 706 | 707 | |
| 707 | 708 | int msm_hdmi_pll_8996_init(struct platform_device *pdev) |
| @@ -424,6 +424,7 @@ static struct clk_init_data pll_init = { · 423 unmodified lines | ||
| 424 | 424 | .ops = &hdmi_pll_ops, |
| 425 | 425 | .parent_names = hdmi_pll_parents, |
| 426 | 426 | .num_parents = ARRAY_SIZE(hdmi_pll_parents), |
| 427 | + .flags = CLK_IGNORE_UNUSED, | |
| 427 | 428 | }; |
| 428 | 429 | |
| 429 | 430 | int msm_hdmi_pll_8960_init(struct platform_device *pdev) |
| @@ -272,7 +272,7 @@ const struct mdp5_cfg_hw msm8x16_config = { · 271 unmodified lines | ||
| 272 | 272 | .count = 2, |
| 273 | 273 | .base = { 0x14000, 0x16000 }, |
| 274 | 274 | .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | |
| 275 | − MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION, | |
| 275 | + MDP_PIPE_CAP_DECIMATION, | |
| 276 | 276 | }, |
| 277 | 277 | .pipe_dma = { |
| 278 | 278 | .count = 1, |
| @@ -282,7 +282,7 @@ const struct mdp5_cfg_hw msm8x16_config = { · 3 unmodified lines | ||
| 282 | 282 | .lm = { |
| 283 | 283 | .count = 2, /* LM0 and LM3 */ |
| 284 | 284 | .base = { 0x44000, 0x47000 }, |
| 285 | − .nb_stages = 5, | |
| 285 | + .nb_stages = 8, | |
| 286 | 286 | .max_width = 2048, |
| 287 | 287 | .max_height = 0xFFFF, |
| 288 | 288 | }, |
| @@ -223,12 +223,7 @@ static void blend_setup(struct drm_crtc *crtc) · 222 unmodified lines | ||
| 223 | 223 | plane_cnt++; |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | − /* | |
| 227 | − * If there is no base layer, enable border color. | |
| 228 | − * Although it's not possbile in current blend logic, | |
| 229 | − * put it here as a reminder. | |
| 230 | − */ | |
| 231 | − if (!pstates[STAGE_BASE] && plane_cnt) { | |
| 226 | + if (!pstates[STAGE_BASE]) { | |
| 232 | 227 | ctl_blend_flags |= MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT; |
| 233 | 228 | DBG("Border Color is enabled"); |
| 234 | 229 | } |
| @@ -365,6 +360,15 @@ static int pstate_cmp(const void *a, const void *b) · 130 unmodified lines | ||
| 365 | 360 | return pa->state->zpos - pb->state->zpos; |
| 366 | 361 | } |
| 367 | 362 | |
| 363 | +/* is there a helper for this? */ | |
| 364 | +static bool is_fullscreen(struct drm_crtc_state *cstate, | |
| 365 | + struct drm_plane_state *pstate) | |
| 366 | +{ | |
| 367 | + return (pstate->crtc_x <= 0) && (pstate->crtc_y <= 0) && | |
| 368 | + ((pstate->crtc_x + pstate->crtc_w) >= cstate->mode.hdisplay) && | |
| 369 | + ((pstate->crtc_y + pstate->crtc_h) >= cstate->mode.vdisplay); | |
| 370 | +} | |
| 371 | + | |
| 368 | 372 | static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, |
| 369 | 373 | struct drm_crtc_state *state) |
| 370 | 374 | { |
| @@ -375,21 +379,11 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, · 4 unmodified lines | ||
| 375 | 379 | struct plane_state pstates[STAGE_MAX + 1]; |
| 376 | 380 | const struct mdp5_cfg_hw *hw_cfg; |
| 377 | 381 | const struct drm_plane_state *pstate; |
| 378 | − int cnt = 0, i; | |
| 382 | + int cnt = 0, base = 0, i; | |
| 379 | 383 | |
| 380 | 384 | DBG("%s: check", mdp5_crtc->name); |
| 381 | 385 | |
| 382 | − /* verify that there are not too many planes attached to crtc | |
| 383 | − * and that we don't have conflicting mixer stages: | |
| 384 | − */ | |
| 385 | − hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); | |
| 386 | 386 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { |
| 387 | − if (cnt >= (hw_cfg->lm.nb_stages)) { | |
| 388 | − dev_err(dev->dev, "too many planes!\n"); | |
| 389 | − return -EINVAL; | |
| 390 | − } | |
| 391 | − | |
| 392 | − | |
| 393 | 387 | pstates[cnt].plane = plane; |
| 394 | 388 | pstates[cnt].state = to_mdp5_plane_state(pstate); |
| 395 | 389 | |
| @@ -399,8 +393,24 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, · 3 unmodified lines | ||
| 399 | 393 | /* assign a stage based on sorted zpos property */ |
| 400 | 394 | sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); |
| 401 | 395 | |
| 396 | + /* if the bottom-most layer is not fullscreen, we need to use | |
| 397 | + * it for solid-color: | |
| 398 | + */ | |
| 399 | + if ((cnt > 0) && !is_fullscreen(state, &pstates[0].state->base)) | |
| 400 | + base++; | |
| 401 | + | |
| 402 | + /* verify that there are not too many planes attached to crtc | |
| 403 | + * and that we don't have conflicting mixer stages: | |
| 404 | + */ | |
| 405 | + hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); | |
| 406 | + | |
| 407 | + if ((cnt + base) >= hw_cfg->lm.nb_stages) { | |
| 408 | + dev_err(dev->dev, "too many planes!\n"); | |
| 409 | + return -EINVAL; | |
| 410 | + } | |
| 411 | + | |
| 402 | 412 | for (i = 0; i < cnt; i++) { |
| 403 | − pstates[i].state->stage = STAGE_BASE + i; | |
| 413 | + pstates[i].state->stage = STAGE_BASE + i + base; | |
| 404 | 414 | DBG("%s: assign pipe %s on stage=%d", mdp5_crtc->name, |
| 405 | 415 | pipe2name(mdp5_plane_pipe(pstates[i].plane)), |
| 406 | 416 | pstates[i].state->stage); |
| @@ -292,8 +292,7 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, · 291 unmodified lines | ||
| 292 | 292 | format = to_mdp_format(msm_framebuffer_format(state->fb)); |
| 293 | 293 | if (MDP_FORMAT_IS_YUV(format) && |
| 294 | 294 | !pipe_supports_yuv(mdp5_plane->caps)) { |
| 295 | − dev_err(plane->dev->dev, | |
| 296 | − "Pipe doesn't support YUV\n"); | |
| 295 | + DBG("Pipe doesn't support YUV\n"); | |
| 297 | 296 | |
| 298 | 297 | return -EINVAL; |
| 299 | 298 | } |
| @@ -301,8 +300,7 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, · 1 unmodified line | ||
| 301 | 300 | if (!(mdp5_plane->caps & MDP_PIPE_CAP_SCALE) && |
| 302 | 301 | (((state->src_w >> 16) != state->crtc_w) || |
| 303 | 302 | ((state->src_h >> 16) != state->crtc_h))) { |
| 304 | − dev_err(plane->dev->dev, | |
| 305 | − "Pipe doesn't support scaling (%dx%d -> %dx%d)\n", | |
| 303 | + DBG("Pipe doesn't support scaling (%dx%d -> %dx%d)\n", | |
| 306 | 304 | state->src_w >> 16, state->src_h >> 16, |
| 307 | 305 | state->crtc_w, state->crtc_h); |
| 308 | 306 | |
| @@ -313,8 +311,7 @@ static int mdp5_plane_atomic_check(struct drm_plane *plane, · 4 unmodified lines | ||
| 313 | 311 | vflip = !!(state->rotation & DRM_REFLECT_Y); |
| 314 | 312 | if ((vflip && !(mdp5_plane->caps & MDP_PIPE_CAP_VFLIP)) || |
| 315 | 313 | (hflip && !(mdp5_plane->caps & MDP_PIPE_CAP_HFLIP))) { |
| 316 | − dev_err(plane->dev->dev, | |
| 317 | − "Pipe doesn't support flip\n"); | |
| 314 | + DBG("Pipe doesn't support flip\n"); | |
| 318 | 315 | |
| 319 | 316 | return -EINVAL; |
| 320 | 317 | } |
| @@ -228,7 +228,7 @@ static int msm_drm_uninit(struct device *dev) · 227 unmodified lines | ||
| 228 | 228 | flush_workqueue(priv->atomic_wq); |
| 229 | 229 | destroy_workqueue(priv->atomic_wq); |
| 230 | 230 | |
| 231 | − if (kms) | |
| 231 | + if (kms && kms->funcs) | |
| 232 | 232 | kms->funcs->destroy(kms); |
| 233 | 233 | |
| 234 | 234 | if (gpu) { |
| @@ -154,6 +154,9 @@ void msm_gem_shrinker_init(struct drm_device *dev) · 153 unmodified lines | ||
| 154 | 154 | void msm_gem_shrinker_cleanup(struct drm_device *dev) |
| 155 | 155 | { |
| 156 | 156 | struct msm_drm_private *priv = dev->dev_private; |
| 157 | − WARN_ON(unregister_vmap_purge_notifier(&priv->vmap_notifier)); | |
| 158 | − unregister_shrinker(&priv->shrinker); | |
| 157 | + | |
| 158 | + if (priv->shrinker.nr_deferred) { | |
| 159 | + WARN_ON(unregister_vmap_purge_notifier(&priv->vmap_notifier)); | |
| 160 | + unregister_shrinker(&priv->shrinker); | |
| 161 | + } | |
| 159 | 162 | } |
| @@ -931,7 +931,7 @@ static void radeon_connector_unregister(struct drm_connector *connector) · 930 unmodified lines | ||
| 931 | 931 | { |
| 932 | 932 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 933 | 933 | |
| 934 | − if (radeon_connector->ddc_bus->has_aux) { | |
| 934 | + if (radeon_connector->ddc_bus && radeon_connector->ddc_bus->has_aux) { | |
| 935 | 935 | drm_dp_aux_unregister(&radeon_connector->ddc_bus->aux); |
| 936 | 936 | radeon_connector->ddc_bus->has_aux = false; |
| 937 | 937 | } |
| @@ -104,6 +104,14 @@ static const char radeon_family_name[][16] = { · 103 unmodified lines | ||
| 104 | 104 | "LAST", |
| 105 | 105 | }; |
| 106 | 106 | |
| 107 | +#if defined(CONFIG_VGA_SWITCHEROO) | |
| 108 | +bool radeon_has_atpx_dgpu_power_cntl(void); | |
| 109 | +bool radeon_is_atpx_hybrid(void); | |
| 110 | +#else | |
| 111 | +static inline bool radeon_has_atpx_dgpu_power_cntl(void) { return false; } | |
| 112 | +static inline bool radeon_is_atpx_hybrid(void) { return false; } | |
| 113 | +#endif | |
| 114 | + | |
| 107 | 115 | #define RADEON_PX_QUIRK_DISABLE_PX (1 << 0) |
| 108 | 116 | #define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1) |
| 109 | 117 | |
| @@ -160,6 +168,11 @@ static void radeon_device_handle_px_quirks(struct radeon_device *rdev) · 50 unmodified lines | ||
| 160 | 168 | |
| 161 | 169 | if (rdev->px_quirk_flags & RADEON_PX_QUIRK_DISABLE_PX) |
| 162 | 170 | rdev->flags &= ~RADEON_IS_PX; |
| 171 | + | |
| 172 | + /* disable PX is the system doesn't support dGPU power control or hybrid gfx */ | |
| 173 | + if (!radeon_is_atpx_hybrid() && | |
| 174 | + !radeon_has_atpx_dgpu_power_cntl()) | |
| 175 | + rdev->flags &= ~RADEON_IS_PX; | |
| 163 | 176 | } |
| 164 | 177 | |
| 165 | 178 | /** |
| @@ -142,9 +142,9 @@ static int sun4i_drv_bind(struct device *dev) · 141 unmodified lines | ||
| 142 | 142 | |
| 143 | 143 | /* Create our layers */ |
| 144 | 144 | drv->layers = sun4i_layers_init(drm); |
| 145 | − if (!drv->layers) { | |
| 145 | + if (IS_ERR(drv->layers)) { | |
| 146 | 146 | dev_err(drm->dev, "Couldn't create the planes\n"); |
| 147 | − ret = -EINVAL; | |
| 147 | + ret = PTR_ERR(drv->layers); | |
| 148 | 148 | goto free_drm; |
| 149 | 149 | } |
| 150 | 150 | |
| @@ -152,15 +152,13 @@ static void sun4i_rgb_encoder_enable(struct drm_encoder *encoder) · 151 unmodified lines | ||
| 152 | 152 | |
| 153 | 153 | DRM_DEBUG_DRIVER("Enabling RGB output\n"); |
| 154 | 154 | |
| 155 | − if (!IS_ERR(tcon->panel)) { | |
| 155 | + if (!IS_ERR(tcon->panel)) | |
| 156 | 156 | drm_panel_prepare(tcon->panel); |
| 157 | − drm_panel_enable(tcon->panel); | |
| 158 | − } | |
| 159 | − | |
| 160 | − /* encoder->bridge can be NULL; drm_bridge_enable checks for it */ | |
| 161 | − drm_bridge_enable(encoder->bridge); | |
| 162 | 157 | |
| 163 | 158 | sun4i_tcon_channel_enable(tcon, 0); |
| 159 | + | |
| 160 | + if (!IS_ERR(tcon->panel)) | |
| 161 | + drm_panel_enable(tcon->panel); | |
| 164 | 162 | } |
| 165 | 163 | |
| 166 | 164 | static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder) |
| @@ -171,15 +169,13 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder) · 4 unmodified lines | ||
| 171 | 169 | |
| 172 | 170 | DRM_DEBUG_DRIVER("Disabling RGB output\n"); |
| 173 | 171 | |
| 174 | − sun4i_tcon_channel_disable(tcon, 0); | |
| 172 | + if (!IS_ERR(tcon->panel)) | |
| 173 | + drm_panel_disable(tcon->panel); | |
| 175 | 174 | |
| 176 | − /* encoder->bridge can be NULL; drm_bridge_disable checks for it */ | |
| 177 | − drm_bridge_disable(encoder->bridge); | |
| 175 | + sun4i_tcon_channel_disable(tcon, 0); | |
| 178 | 176 | |
| 179 | − if (!IS_ERR(tcon->panel)) { | |
| 180 | − drm_panel_disable(tcon->panel); | |
| 177 | + if (!IS_ERR(tcon->panel)) | |
| 181 | 178 | drm_panel_unprepare(tcon->panel); |
| 182 | − } | |
| 183 | 179 | } |
| 184 | 180 | |
| 185 | 181 | static void sun4i_rgb_encoder_mode_set(struct drm_encoder *encoder, |
| @@ -98,17 +98,23 @@ success: · 97 unmodified lines | ||
| 98 | 98 | static int udl_select_std_channel(struct udl_device *udl) |
| 99 | 99 | { |
| 100 | 100 | int ret; |
| 101 | − u8 set_def_chn[] = {0x57, 0xCD, 0xDC, 0xA7, | |
| 102 | − 0x1C, 0x88, 0x5E, 0x15, | |
| 103 | − 0x60, 0xFE, 0xC6, 0x97, | |
| 104 | − 0x16, 0x3D, 0x47, 0xF2}; | |
| 101 | + static const u8 set_def_chn[] = {0x57, 0xCD, 0xDC, 0xA7, | |
| 102 | + 0x1C, 0x88, 0x5E, 0x15, | |
| 103 | + 0x60, 0xFE, 0xC6, 0x97, | |
| 104 | + 0x16, 0x3D, 0x47, 0xF2}; | |
| 105 | + void *sendbuf; | |
| 106 | + | |
| 107 | + sendbuf = kmemdup(set_def_chn, sizeof(set_def_chn), GFP_KERNEL); | |
| 108 | + if (!sendbuf) | |
| 109 | + return -ENOMEM; | |
| 105 | 110 | |
| 106 | 111 | ret = usb_control_msg(udl->udev, |
| 107 | 112 | usb_sndctrlpipe(udl->udev, 0), |
| 108 | 113 | NR_USB_REQUEST_CHANNEL, |
| 109 | 114 | (USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0, |
| 110 | − set_def_chn, sizeof(set_def_chn), | |
| 115 | + sendbuf, sizeof(set_def_chn), | |
| 111 | 116 | USB_CTRL_SET_TIMEOUT); |
| 117 | + kfree(sendbuf); | |
| 112 | 118 | return ret < 0 ? ret : 0; |
| 113 | 119 | } |
| 114 | 120 | |
| @@ -961,7 +961,7 @@ int vmbus_device_register(struct hv_device *child_device_obj) · 960 unmodified lines | ||
| 961 | 961 | { |
| 962 | 962 | int ret = 0; |
| 963 | 963 | |
| 964 | − dev_set_name(&child_device_obj->device, "vmbus-%pUl", | |
| 964 | + dev_set_name(&child_device_obj->device, "%pUl", | |
| 965 | 965 | child_device_obj->channel->offermsg.offer.if_instance.b); |
| 966 | 966 | |
| 967 | 967 | child_device_obj->device.bus = &hv_bus; |
| @@ -59,7 +59,6 @@ config I2C_CHARDEV · 58 unmodified lines | ||
| 59 | 59 | |
| 60 | 60 | config I2C_MUX |
| 61 | 61 | tristate "I2C bus multiplexing support" |
| 62 | − depends on HAS_IOMEM | |
| 63 | 62 | help |
| 64 | 63 | Say Y here if you want the I2C core to support the ability to |
| 65 | 64 | handle multiplexed I2C bus topologies, by presenting each |
| @@ -347,7 +347,7 @@ static int dc_i2c_probe(struct platform_device *pdev) · 346 unmodified lines | ||
| 347 | 347 | |
| 348 | 348 | ret = i2c_add_adapter(&i2c->adap); |
| 349 | 349 | if (ret < 0) { |
| 350 | − clk_unprepare(i2c->clk); | |
| 350 | + clk_disable_unprepare(i2c->clk); | |
| 351 | 351 | return ret; |
| 352 | 352 | } |
| 353 | 353 | |
| @@ -63,6 +63,7 @@ config I2C_MUX_PINCTRL · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | config I2C_MUX_REG |
| 65 | 65 | tristate "Register-based I2C multiplexer" |
| 66 | + depends on HAS_IOMEM | |
| 66 | 67 | help |
| 67 | 68 | If you say yes to this option, support will be included for a |
| 68 | 69 | register based I2C multiplexer. This driver provides access to |
| @@ -69,10 +69,28 @@ static int i2c_demux_activate_master(struct i2c_demux_pinctrl_priv *priv, u32 ne · 68 unmodified lines | ||
| 69 | 69 | goto err_with_revert; |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | − p = devm_pinctrl_get_select(adap->dev.parent, priv->bus_name); | |
| 72 | + /* | |
| 73 | + * Check if there are pinctrl states at all. Note: we cant' use | |
| 74 | + * devm_pinctrl_get_select() because we need to distinguish between | |
| 75 | + * the -ENODEV from devm_pinctrl_get() and pinctrl_lookup_state(). | |
| 76 | + */ | |
| 77 | + p = devm_pinctrl_get(adap->dev.parent); | |
| 73 | 78 | if (IS_ERR(p)) { |
| 74 | 79 | ret = PTR_ERR(p); |
| 75 | − goto err_with_put; | |
| 80 | + /* continue if just no pinctrl states (e.g. i2c-gpio), otherwise exit */ | |
| 81 | + if (ret != -ENODEV) | |
| 82 | + goto err_with_put; | |
| 83 | + } else { | |
| 84 | + /* there are states. check and use them */ | |
| 85 | + struct pinctrl_state *s = pinctrl_lookup_state(p, priv->bus_name); | |
| 86 | + | |
| 87 | + if (IS_ERR(s)) { | |
| 88 | + ret = PTR_ERR(s); | |
| 89 | + goto err_with_put; | |
| 90 | + } | |
| 91 | + ret = pinctrl_select_state(p, s); | |
| 92 | + if (ret < 0) | |
| 93 | + goto err_with_put; | |
| 76 | 94 | } |
| 77 | 95 | |
| 78 | 96 | priv->chan[new_chan].parent_adap = adap; |
| @@ -268,9 +268,9 @@ static int pca954x_probe(struct i2c_client *client, · 267 unmodified lines | ||
| 268 | 268 | /* discard unconfigured channels */ |
| 269 | 269 | break; |
| 270 | 270 | idle_disconnect_pd = pdata->modes[num].deselect_on_exit; |
| 271 | − data->deselect |= (idle_disconnect_pd | |
| 272 | − || idle_disconnect_dt) << num; | |
| 273 | 271 | } |
| 272 | + data->deselect |= (idle_disconnect_pd || | |
| 273 | + idle_disconnect_dt) << num; | |
| 274 | 274 | |
| 275 | 275 | ret = i2c_mux_add_adapter(muxc, force, num, class); |
| 276 | 276 | |
| @@ -743,8 +743,8 @@ static int st_accel_read_raw(struct iio_dev *indio_dev, · 742 unmodified lines | ||
| 743 | 743 | |
| 744 | 744 | return IIO_VAL_INT; |
| 745 | 745 | case IIO_CHAN_INFO_SCALE: |
| 746 | − *val = 0; | |
| 747 | − *val2 = adata->current_fullscale->gain; | |
| 746 | + *val = adata->current_fullscale->gain / 1000000; | |
| 747 | + *val2 = adata->current_fullscale->gain % 1000000; | |
| 748 | 748 | return IIO_VAL_INT_PLUS_MICRO; |
| 749 | 749 | case IIO_CHAN_INFO_SAMP_FREQ: |
| 750 | 750 | *val = adata->odr; |
| @@ -763,9 +763,13 @@ static int st_accel_write_raw(struct iio_dev *indio_dev, · 12 unmodified lines | ||
| 763 | 763 | int err; |
| 764 | 764 | |
| 765 | 765 | switch (mask) { |
| 766 | − case IIO_CHAN_INFO_SCALE: | |
| 767 | − err = st_sensors_set_fullscale_by_gain(indio_dev, val2); | |
| 766 | + case IIO_CHAN_INFO_SCALE: { | |
| 767 | + int gain; | |
| 768 | + | |
| 769 | + gain = val * 1000000 + val2; | |
| 770 | + err = st_sensors_set_fullscale_by_gain(indio_dev, gain); | |
| 768 | 771 | break; |
| 772 | + } | |
| 769 | 773 | case IIO_CHAN_INFO_SAMP_FREQ: |
| 770 | 774 | if (val2) |
| 771 | 775 | return -EINVAL; |
| @@ -30,26 +30,26 @@ static struct { · 29 unmodified lines | ||
| 30 | 30 | u32 usage_id; |
| 31 | 31 | int unit; /* 0 for default others from HID sensor spec */ |
| 32 | 32 | int scale_val0; /* scale, whole number */ |
| 33 | − int scale_val1; /* scale, fraction in micros */ | |
| 33 | + int scale_val1; /* scale, fraction in nanos */ | |
| 34 | 34 | } unit_conversion[] = { |
| 35 | − {HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650}, | |
| 35 | + {HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650000}, | |
| 36 | 36 | {HID_USAGE_SENSOR_ACCEL_3D, |
| 37 | 37 | HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, 1, 0}, |
| 38 | 38 | {HID_USAGE_SENSOR_ACCEL_3D, |
| 39 | − HID_USAGE_SENSOR_UNITS_G, 9, 806650}, | |
| 39 | + HID_USAGE_SENSOR_UNITS_G, 9, 806650000}, | |
| 40 | 40 | |
| 41 | − {HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453}, | |
| 41 | + {HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453293}, | |
| 42 | 42 | {HID_USAGE_SENSOR_GYRO_3D, |
| 43 | 43 | HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND, 1, 0}, |
| 44 | 44 | {HID_USAGE_SENSOR_GYRO_3D, |
| 45 | − HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453}, | |
| 45 | + HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453293}, | |
| 46 | 46 | |
| 47 | − {HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000}, | |
| 47 | + {HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000000}, | |
| 48 | 48 | {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0}, |
| 49 | 49 | |
| 50 | − {HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453}, | |
| 50 | + {HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453293}, | |
| 51 | 51 | {HID_USAGE_SENSOR_INCLINOMETER_3D, |
| 52 | − HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453}, | |
| 52 | + HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453293}, | |
| 53 | 53 | {HID_USAGE_SENSOR_INCLINOMETER_3D, |
| 54 | 54 | HID_USAGE_SENSOR_UNITS_RADIANS, 1, 0}, |
| 55 | 55 | |
| @@ -57,7 +57,7 @@ static struct { · 1 unmodified line | ||
| 57 | 57 | {HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0}, |
| 58 | 58 | |
| 59 | 59 | {HID_USAGE_SENSOR_PRESSURE, 0, 100, 0}, |
| 60 | − {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000}, | |
| 60 | + {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000000}, | |
| 61 | 61 | }; |
| 62 | 62 | |
| 63 | 63 | static int pow_10(unsigned power) |
| @@ -266,15 +266,15 @@ EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value); · 202 unmodified lines | ||
| 266 | 266 | /* |
| 267 | 267 | * This fuction applies the unit exponent to the scale. |
| 268 | 268 | * For example: |
| 269 | − * 9.806650 ->exp:2-> val0[980]val1[665000] | |
| 270 | − * 9.000806 ->exp:2-> val0[900]val1[80600] | |
| 271 | − * 0.174535 ->exp:2-> val0[17]val1[453500] | |
| 272 | − * 1.001745 ->exp:0-> val0[1]val1[1745] | |
| 273 | − * 1.001745 ->exp:2-> val0[100]val1[174500] | |
| 274 | − * 1.001745 ->exp:4-> val0[10017]val1[450000] | |
| 275 | − * 9.806650 ->exp:-2-> val0[0]val1[98066] | |
| 269 | + * 9.806650000 ->exp:2-> val0[980]val1[665000000] | |
| 270 | + * 9.000806000 ->exp:2-> val0[900]val1[80600000] | |
| 271 | + * 0.174535293 ->exp:2-> val0[17]val1[453529300] | |
| 272 | + * 1.001745329 ->exp:0-> val0[1]val1[1745329] | |
| 273 | + * 1.001745329 ->exp:2-> val0[100]val1[174532900] | |
| 274 | + * 1.001745329 ->exp:4-> val0[10017]val1[453290000] | |
| 275 | + * 9.806650000 ->exp:-2-> val0[0]val1[98066500] | |
| 276 | 276 | */ |
| 277 | −static void adjust_exponent_micro(int *val0, int *val1, int scale0, | |
| 277 | +static void adjust_exponent_nano(int *val0, int *val1, int scale0, | |
| 278 | 278 | int scale1, int exp) |
| 279 | 279 | { |
| 280 | 280 | int i; |
| @@ -285,32 +285,32 @@ static void adjust_exponent_micro(int *val0, int *val1, int scale0, · 4 unmodified lines | ||
| 285 | 285 | if (exp > 0) { |
| 286 | 286 | *val0 = scale0 * pow_10(exp); |
| 287 | 287 | res = 0; |
| 288 | − if (exp > 6) { | |
| 288 | + if (exp > 9) { | |
| 289 | 289 | *val1 = 0; |
| 290 | 290 | return; |
| 291 | 291 | } |
| 292 | 292 | for (i = 0; i < exp; ++i) { |
| 293 | − x = scale1 / pow_10(5 - i); | |
| 293 | + x = scale1 / pow_10(8 - i); | |
| 294 | 294 | res += (pow_10(exp - 1 - i) * x); |
| 295 | − scale1 = scale1 % pow_10(5 - i); | |
| 295 | + scale1 = scale1 % pow_10(8 - i); | |
| 296 | 296 | } |
| 297 | 297 | *val0 += res; |
| 298 | 298 | *val1 = scale1 * pow_10(exp); |
| 299 | 299 | } else if (exp < 0) { |
| 300 | 300 | exp = abs(exp); |
| 301 | − if (exp > 6) { | |
| 301 | + if (exp > 9) { | |
| 302 | 302 | *val0 = *val1 = 0; |
| 303 | 303 | return; |
| 304 | 304 | } |
| 305 | 305 | *val0 = scale0 / pow_10(exp); |
| 306 | 306 | rem = scale0 % pow_10(exp); |
| 307 | 307 | res = 0; |
| 308 | − for (i = 0; i < (6 - exp); ++i) { | |
| 309 | − x = scale1 / pow_10(5 - i); | |
| 310 | − res += (pow_10(5 - exp - i) * x); | |
| 311 | − scale1 = scale1 % pow_10(5 - i); | |
| 308 | + for (i = 0; i < (9 - exp); ++i) { | |
| 309 | + x = scale1 / pow_10(8 - i); | |
| 310 | + res += (pow_10(8 - exp - i) * x); | |
| 311 | + scale1 = scale1 % pow_10(8 - i); | |
| 312 | 312 | } |
| 313 | − *val1 = rem * pow_10(6 - exp) + res; | |
| 313 | + *val1 = rem * pow_10(9 - exp) + res; | |
| 314 | 314 | } else { |
| 315 | 315 | *val0 = scale0; |
| 316 | 316 | *val1 = scale1; |
| @@ -332,14 +332,14 @@ int hid_sensor_format_scale(u32 usage_id, · 15 unmodified lines | ||
| 332 | 332 | unit_conversion[i].unit == attr_info->units) { |
| 333 | 333 | exp = hid_sensor_convert_exponent( |
| 334 | 334 | attr_info->unit_expo); |
| 335 | − adjust_exponent_micro(val0, val1, | |
| 335 | + adjust_exponent_nano(val0, val1, | |
| 336 | 336 | unit_conversion[i].scale_val0, |
| 337 | 337 | unit_conversion[i].scale_val1, exp); |
| 338 | 338 | break; |
| 339 | 339 | } |
| 340 | 340 | } |
| 341 | 341 | |
| 342 | − return IIO_VAL_INT_PLUS_MICRO; | |
| 342 | + return IIO_VAL_INT_PLUS_NANO; | |
| 343 | 343 | } |
| 344 | 344 | EXPORT_SYMBOL(hid_sensor_format_scale); |
| 345 | 345 | |
| @@ -612,7 +612,7 @@ EXPORT_SYMBOL(st_sensors_sysfs_sampling_frequency_avail); · 611 unmodified lines | ||
| 612 | 612 | ssize_t st_sensors_sysfs_scale_avail(struct device *dev, |
| 613 | 613 | struct device_attribute *attr, char *buf) |
| 614 | 614 | { |
| 615 | − int i, len = 0; | |
| 615 | + int i, len = 0, q, r; | |
| 616 | 616 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
| 617 | 617 | struct st_sensor_data *sdata = iio_priv(indio_dev); |
| 618 | 618 | |
| @@ -621,8 +621,10 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev, · 2 unmodified lines | ||
| 621 | 621 | if (sdata->sensor_settings->fs.fs_avl[i].num == 0) |
| 622 | 622 | break; |
| 623 | 623 | |
| 624 | − len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", | |
| 625 | − sdata->sensor_settings->fs.fs_avl[i].gain); | |
| 624 | + q = sdata->sensor_settings->fs.fs_avl[i].gain / 1000000; | |
| 625 | + r = sdata->sensor_settings->fs.fs_avl[i].gain % 1000000; | |
| 626 | + | |
| 627 | + len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", q, r); | |
| 626 | 628 | } |
| 627 | 629 | mutex_unlock(&indio_dev->mlock); |
| 628 | 630 | buf[len - 1] = '\n'; |
| @@ -335,6 +335,7 @@ static struct platform_driver hid_dev_rot_platform_driver = { · 334 unmodified lines | ||
| 335 | 335 | .id_table = hid_dev_rot_ids, |
| 336 | 336 | .driver = { |
| 337 | 337 | .name = KBUILD_MODNAME, |
| 338 | + .pm = &hid_sensor_pm_ops, | |
| 338 | 339 | }, |
| 339 | 340 | .probe = hid_dev_rot_probe, |
| 340 | 341 | .remove = hid_dev_rot_remove, |
| @@ -136,6 +136,8 @@ static int maxim_thermocouple_read(struct maxim_thermocouple_data *data, · 135 unmodified lines | ||
| 136 | 136 | ret = spi_read(data->spi, (void *)&buf32, storage_bytes); |
| 137 | 137 | *val = be32_to_cpu(buf32); |
| 138 | 138 | break; |
| 139 | + default: | |
| 140 | + ret = -EINVAL; | |
| 139 | 141 | } |
| 140 | 142 | |
| 141 | 143 | if (ret) |
| @@ -699,13 +699,16 @@ EXPORT_SYMBOL(rdma_addr_cancel); · 698 unmodified lines | ||
| 699 | 699 | struct resolve_cb_context { |
| 700 | 700 | struct rdma_dev_addr *addr; |
| 701 | 701 | struct completion comp; |
| 702 | + int status; | |
| 702 | 703 | }; |
| 703 | 704 | |
| 704 | 705 | static void resolve_cb(int status, struct sockaddr *src_addr, |
| 705 | 706 | struct rdma_dev_addr *addr, void *context) |
| 706 | 707 | { |
| 707 | − memcpy(((struct resolve_cb_context *)context)->addr, addr, sizeof(struct | |
| 708 | − rdma_dev_addr)); | |
| 708 | + if (!status) | |
| 709 | + memcpy(((struct resolve_cb_context *)context)->addr, | |
| 710 | + addr, sizeof(struct rdma_dev_addr)); | |
| 711 | + ((struct resolve_cb_context *)context)->status = status; | |
| 709 | 712 | complete(&((struct resolve_cb_context *)context)->comp); |
| 710 | 713 | } |
| 711 | 714 | |
| @@ -743,6 +746,10 @@ int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid, · 31 unmodified lines | ||
| 743 | 746 | |
| 744 | 747 | wait_for_completion(&ctx.comp); |
| 745 | 748 | |
| 749 | + ret = ctx.status; | |
| 750 | + if (ret) | |
| 751 | + return ret; | |
| 752 | + | |
| 746 | 753 | memcpy(dmac, dev_addr.dst_dev_addr, ETH_ALEN); |
| 747 | 754 | dev = dev_get_by_index(&init_net, dev_addr.bound_dev_if); |
| 748 | 755 | if (!dev) |
| @@ -80,6 +80,8 @@ static struct ib_cm { · 79 unmodified lines | ||
| 80 | 80 | __be32 random_id_operand; |
| 81 | 81 | struct list_head timewait_list; |
| 82 | 82 | struct workqueue_struct *wq; |
| 83 | + /* Sync on cm change port state */ | |
| 84 | + spinlock_t state_lock; | |
| 83 | 85 | } cm; |
| 84 | 86 | |
| 85 | 87 | /* Counter indexes ordered by attribute ID */ |
| @@ -161,6 +163,8 @@ struct cm_port { · 75 unmodified lines | ||
| 161 | 163 | struct ib_mad_agent *mad_agent; |
| 162 | 164 | struct kobject port_obj; |
| 163 | 165 | u8 port_num; |
| 166 | + struct list_head cm_priv_prim_list; | |
| 167 | + struct list_head cm_priv_altr_list; | |
| 164 | 168 | struct cm_counter_group counter_group[CM_COUNTER_GROUPS]; |
| 165 | 169 | }; |
| 166 | 170 | |
| @@ -241,6 +245,12 @@ struct cm_id_private { · 74 unmodified lines | ||
| 241 | 245 | u8 service_timeout; |
| 242 | 246 | u8 target_ack_delay; |
| 243 | 247 | |
| 248 | + struct list_head prim_list; | |
| 249 | + struct list_head altr_list; | |
| 250 | + /* Indicates that the send port mad is registered and av is set */ | |
| 251 | + int prim_send_port_not_ready; | |
| 252 | + int altr_send_port_not_ready; | |
| 253 | + | |
| 244 | 254 | struct list_head work_list; |
| 245 | 255 | atomic_t work_count; |
| 246 | 256 | }; |
| @@ -259,20 +269,47 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv, · 12 unmodified lines | ||
| 259 | 269 | struct ib_mad_agent *mad_agent; |
| 260 | 270 | struct ib_mad_send_buf *m; |
| 261 | 271 | struct ib_ah *ah; |
| 272 | + struct cm_av *av; | |
| 273 | + unsigned long flags, flags2; | |
| 274 | + int ret = 0; | |
| 262 | 275 | |
| 276 | + /* don't let the port to be released till the agent is down */ | |
| 277 | + spin_lock_irqsave(&cm.state_lock, flags2); | |
| 278 | + spin_lock_irqsave(&cm.lock, flags); | |
| 279 | + if (!cm_id_priv->prim_send_port_not_ready) | |
| 280 | + av = &cm_id_priv->av; | |
| 281 | + else if (!cm_id_priv->altr_send_port_not_ready && | |
| 282 | + (cm_id_priv->alt_av.port)) | |
| 283 | + av = &cm_id_priv->alt_av; | |
| 284 | + else { | |
| 285 | + pr_info("%s: not valid CM id\n", __func__); | |
| 286 | + ret = -ENODEV; | |
| 287 | + spin_unlock_irqrestore(&cm.lock, flags); | |
| 288 | + goto out; | |
| 289 | + } | |
| 290 | + spin_unlock_irqrestore(&cm.lock, flags); | |
| 291 | + /* Make sure the port haven't released the mad yet */ | |
| 263 | 292 | mad_agent = cm_id_priv->av.port->mad_agent; |
| 264 | − ah = ib_create_ah(mad_agent->qp->pd, &cm_id_priv->av.ah_attr); | |
| 265 | − if (IS_ERR(ah)) | |
| 266 | − return PTR_ERR(ah); | |
| 293 | + if (!mad_agent) { | |
| 294 | + pr_info("%s: not a valid MAD agent\n", __func__); | |
| 295 | + ret = -ENODEV; | |
| 296 | + goto out; | |
| 297 | + } | |
| 298 | + ah = ib_create_ah(mad_agent->qp->pd, &av->ah_attr); | |
| 299 | + if (IS_ERR(ah)) { | |
| 300 | + ret = PTR_ERR(ah); | |
| 301 | + goto out; | |
| 302 | + } | |
| 267 | 303 | |
| 268 | 304 | m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn, |
| 269 | − cm_id_priv->av.pkey_index, | |
| 305 | + av->pkey_index, | |
| 270 | 306 | 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, |
| 271 | 307 | GFP_ATOMIC, |
| 272 | 308 | IB_MGMT_BASE_VERSION); |
| 273 | 309 | if (IS_ERR(m)) { |
| 274 | 310 | ib_destroy_ah(ah); |
| 275 | − return PTR_ERR(m); | |
| 311 | + ret = PTR_ERR(m); | |
| 312 | + goto out; | |
| 276 | 313 | } |
| 277 | 314 | |
| 278 | 315 | /* Timeout set by caller if response is expected. */ |
| @@ -282,7 +319,10 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv, · 3 unmodified lines | ||
| 282 | 319 | atomic_inc(&cm_id_priv->refcount); |
| 283 | 320 | m->context[0] = cm_id_priv; |
| 284 | 321 | *msg = m; |
| 285 | − return 0; | |
| 322 | + | |
| 323 | +out: | |
| 324 | + spin_unlock_irqrestore(&cm.state_lock, flags2); | |
| 325 | + return ret; | |
| 286 | 326 | } |
| 287 | 327 | |
| 288 | 328 | static int cm_alloc_response_msg(struct cm_port *port, |
| @@ -352,7 +392,8 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc, · 63 unmodified lines | ||
| 352 | 392 | grh, &av->ah_attr); |
| 353 | 393 | } |
| 354 | 394 | |
| 355 | −static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) | |
| 395 | +static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av, | |
| 396 | + struct cm_id_private *cm_id_priv) | |
| 356 | 397 | { |
| 357 | 398 | struct cm_device *cm_dev; |
| 358 | 399 | struct cm_port *port = NULL; |
| @@ -387,7 +428,17 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) · 28 unmodified lines | ||
| 387 | 428 | &av->ah_attr); |
| 388 | 429 | av->timeout = path->packet_life_time + 1; |
| 389 | 430 | |
| 390 | − return 0; | |
| 431 | + spin_lock_irqsave(&cm.lock, flags); | |
| 432 | + if (&cm_id_priv->av == av) | |
| 433 | + list_add_tail(&cm_id_priv->prim_list, &port->cm_priv_prim_list); | |
| 434 | + else if (&cm_id_priv->alt_av == av) | |
| 435 | + list_add_tail(&cm_id_priv->altr_list, &port->cm_priv_altr_list); | |
| 436 | + else | |
| 437 | + ret = -EINVAL; | |
| 438 | + | |
| 439 | + spin_unlock_irqrestore(&cm.lock, flags); | |
| 440 | + | |
| 441 | + return ret; | |
| 391 | 442 | } |
| 392 | 443 | |
| 393 | 444 | static int cm_alloc_id(struct cm_id_private *cm_id_priv) |
| @@ -677,6 +728,8 @@ struct ib_cm_id *ib_create_cm_id(struct ib_device *device, · 283 unmodified lines | ||
| 677 | 728 | spin_lock_init(&cm_id_priv->lock); |
| 678 | 729 | init_completion(&cm_id_priv->comp); |
| 679 | 730 | INIT_LIST_HEAD(&cm_id_priv->work_list); |
| 731 | + INIT_LIST_HEAD(&cm_id_priv->prim_list); | |
| 732 | + INIT_LIST_HEAD(&cm_id_priv->altr_list); | |
| 680 | 733 | atomic_set(&cm_id_priv->work_count, -1); |
| 681 | 734 | atomic_set(&cm_id_priv->refcount, 1); |
| 682 | 735 | return &cm_id_priv->id; |
| @@ -892,6 +945,15 @@ retest: · 209 unmodified lines | ||
| 892 | 945 | break; |
| 893 | 946 | } |
| 894 | 947 | |
| 948 | + spin_lock_irq(&cm.lock); | |
| 949 | + if (!list_empty(&cm_id_priv->altr_list) && | |
| 950 | + (!cm_id_priv->altr_send_port_not_ready)) | |
| 951 | + list_del(&cm_id_priv->altr_list); | |
| 952 | + if (!list_empty(&cm_id_priv->prim_list) && | |
| 953 | + (!cm_id_priv->prim_send_port_not_ready)) | |
| 954 | + list_del(&cm_id_priv->prim_list); | |
| 955 | + spin_unlock_irq(&cm.lock); | |
| 956 | + | |
| 895 | 957 | cm_free_id(cm_id->local_id); |
| 896 | 958 | cm_deref_id(cm_id_priv); |
| 897 | 959 | wait_for_completion(&cm_id_priv->comp); |
| @@ -1192,12 +1254,13 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, · 294 unmodified lines | ||
| 1192 | 1254 | goto out; |
| 1193 | 1255 | } |
| 1194 | 1256 | |
| 1195 | − ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av); | |
| 1257 | + ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av, | |
| 1258 | + cm_id_priv); | |
| 1196 | 1259 | if (ret) |
| 1197 | 1260 | goto error1; |
| 1198 | 1261 | if (param->alternate_path) { |
| 1199 | 1262 | ret = cm_init_av_by_path(param->alternate_path, |
| 1200 | − &cm_id_priv->alt_av); | |
| 1263 | + &cm_id_priv->alt_av, cm_id_priv); | |
| 1201 | 1264 | if (ret) |
| 1202 | 1265 | goto error1; |
| 1203 | 1266 | } |
| @@ -1653,7 +1716,8 @@ static int cm_req_handler(struct cm_work *work) · 449 unmodified lines | ||
| 1653 | 1716 | dev_put(gid_attr.ndev); |
| 1654 | 1717 | } |
| 1655 | 1718 | work->path[0].gid_type = gid_attr.gid_type; |
| 1656 | − ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); | |
| 1719 | + ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av, | |
| 1720 | + cm_id_priv); | |
| 1657 | 1721 | } |
| 1658 | 1722 | if (ret) { |
| 1659 | 1723 | int err = ib_get_cached_gid(work->port->cm_dev->ib_device, |
| @@ -1672,7 +1736,8 @@ static int cm_req_handler(struct cm_work *work) · 12 unmodified lines | ||
| 1672 | 1736 | goto rejected; |
| 1673 | 1737 | } |
| 1674 | 1738 | if (req_msg->alt_local_lid) { |
| 1675 | − ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av); | |
| 1739 | + ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av, | |
| 1740 | + cm_id_priv); | |
| 1676 | 1741 | if (ret) { |
| 1677 | 1742 | ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_ALT_GID, |
| 1678 | 1743 | &work->path[0].sgid, |
| @@ -2727,7 +2792,8 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id, · 1048 unmodified lines | ||
| 2727 | 2792 | goto out; |
| 2728 | 2793 | } |
| 2729 | 2794 | |
| 2730 | − ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av); | |
| 2795 | + ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av, | |
| 2796 | + cm_id_priv); | |
| 2731 | 2797 | if (ret) |
| 2732 | 2798 | goto out; |
| 2733 | 2799 | cm_id_priv->alt_av.timeout = |
| @@ -2839,7 +2905,8 @@ static int cm_lap_handler(struct cm_work *work) · 105 unmodified lines | ||
| 2839 | 2905 | cm_init_av_for_response(work->port, work->mad_recv_wc->wc, |
| 2840 | 2906 | work->mad_recv_wc->recv_buf.grh, |
| 2841 | 2907 | &cm_id_priv->av); |
| 2842 | − cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av); | |
| 2908 | + cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av, | |
| 2909 | + cm_id_priv); | |
| 2843 | 2910 | ret = atomic_inc_and_test(&cm_id_priv->work_count); |
| 2844 | 2911 | if (!ret) |
| 2845 | 2912 | list_add_tail(&work->list, &cm_id_priv->work_list); |
| @@ -3031,7 +3098,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id, · 185 unmodified lines | ||
| 3031 | 3098 | return -EINVAL; |
| 3032 | 3099 | |
| 3033 | 3100 | cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
| 3034 | − ret = cm_init_av_by_path(param->path, &cm_id_priv->av); | |
| 3101 | + ret = cm_init_av_by_path(param->path, &cm_id_priv->av, cm_id_priv); | |
| 3035 | 3102 | if (ret) |
| 3036 | 3103 | goto out; |
| 3037 | 3104 | |
| @@ -3468,7 +3535,9 @@ out: · 430 unmodified lines | ||
| 3468 | 3535 | static int cm_migrate(struct ib_cm_id *cm_id) |
| 3469 | 3536 | { |
| 3470 | 3537 | struct cm_id_private *cm_id_priv; |
| 3538 | + struct cm_av tmp_av; | |
| 3471 | 3539 | unsigned long flags; |
| 3540 | + int tmp_send_port_not_ready; | |
| 3472 | 3541 | int ret = 0; |
| 3473 | 3542 | |
| 3474 | 3543 | cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
| @@ -3477,7 +3546,14 @@ static int cm_migrate(struct ib_cm_id *cm_id) · 2 unmodified lines | ||
| 3477 | 3546 | (cm_id->lap_state == IB_CM_LAP_UNINIT || |
| 3478 | 3547 | cm_id->lap_state == IB_CM_LAP_IDLE)) { |
| 3479 | 3548 | cm_id->lap_state = IB_CM_LAP_IDLE; |
| 3549 | + /* Swap address vector */ | |
| 3550 | + tmp_av = cm_id_priv->av; | |
| 3480 | 3551 | cm_id_priv->av = cm_id_priv->alt_av; |
| 3552 | + cm_id_priv->alt_av = tmp_av; | |
| 3553 | + /* Swap port send ready state */ | |
| 3554 | + tmp_send_port_not_ready = cm_id_priv->prim_send_port_not_ready; | |
| 3555 | + cm_id_priv->prim_send_port_not_ready = cm_id_priv->altr_send_port_not_ready; | |
| 3556 | + cm_id_priv->altr_send_port_not_ready = tmp_send_port_not_ready; | |
| 3481 | 3557 | } else |
| 3482 | 3558 | ret = -EINVAL; |
| 3483 | 3559 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
| @@ -3888,6 +3964,9 @@ static void cm_add_one(struct ib_device *ib_device) · 404 unmodified lines | ||
| 3888 | 3964 | port->cm_dev = cm_dev; |
| 3889 | 3965 | port->port_num = i; |
| 3890 | 3966 | |
| 3967 | + INIT_LIST_HEAD(&port->cm_priv_prim_list); | |
| 3968 | + INIT_LIST_HEAD(&port->cm_priv_altr_list); | |
| 3969 | + | |
| 3891 | 3970 | ret = cm_create_port_fs(port); |
| 3892 | 3971 | if (ret) |
| 3893 | 3972 | goto error1; |
| @@ -3945,6 +4024,8 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data) · 51 unmodified lines | ||
| 3945 | 4024 | { |
| 3946 | 4025 | struct cm_device *cm_dev = client_data; |
| 3947 | 4026 | struct cm_port *port; |
| 4027 | + struct cm_id_private *cm_id_priv; | |
| 4028 | + struct ib_mad_agent *cur_mad_agent; | |
| 3948 | 4029 | struct ib_port_modify port_modify = { |
| 3949 | 4030 | .clr_port_cap_mask = IB_PORT_CM_SUP |
| 3950 | 4031 | }; |
| @@ -3968,15 +4049,27 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data) · 17 unmodified lines | ||
| 3968 | 4049 | |
| 3969 | 4050 | port = cm_dev->port[i-1]; |
| 3970 | 4051 | ib_modify_port(ib_device, port->port_num, 0, &port_modify); |
| 4052 | + /* Mark all the cm_id's as not valid */ | |
| 4053 | + spin_lock_irq(&cm.lock); | |
| 4054 | + list_for_each_entry(cm_id_priv, &port->cm_priv_altr_list, altr_list) | |
| 4055 | + cm_id_priv->altr_send_port_not_ready = 1; | |
| 4056 | + list_for_each_entry(cm_id_priv, &port->cm_priv_prim_list, prim_list) | |
| 4057 | + cm_id_priv->prim_send_port_not_ready = 1; | |
| 4058 | + spin_unlock_irq(&cm.lock); | |
| 3971 | 4059 | /* |
| 3972 | 4060 | * We flush the queue here after the going_down set, this |
| 3973 | 4061 | * verify that no new works will be queued in the recv handler, |
| 3974 | 4062 | * after that we can call the unregister_mad_agent |
| 3975 | 4063 | */ |
| 3976 | 4064 | flush_workqueue(cm.wq); |
| 3977 | − ib_unregister_mad_agent(port->mad_agent); | |
| 4065 | + spin_lock_irq(&cm.state_lock); | |
| 4066 | + cur_mad_agent = port->mad_agent; | |
| 4067 | + port->mad_agent = NULL; | |
| 4068 | + spin_unlock_irq(&cm.state_lock); | |
| 4069 | + ib_unregister_mad_agent(cur_mad_agent); | |
| 3978 | 4070 | cm_remove_port_fs(port); |
| 3979 | 4071 | } |
| 4072 | + | |
| 3980 | 4073 | device_unregister(cm_dev->device); |
| 3981 | 4074 | kfree(cm_dev); |
| 3982 | 4075 | } |
| @@ -3989,6 +4082,7 @@ static int __init ib_cm_init(void) · 6 unmodified lines | ||
| 3989 | 4082 | INIT_LIST_HEAD(&cm.device_list); |
| 3990 | 4083 | rwlock_init(&cm.device_lock); |
| 3991 | 4084 | spin_lock_init(&cm.lock); |
| 4085 | + spin_lock_init(&cm.state_lock); | |
| 3992 | 4086 | cm.listen_service_table = RB_ROOT; |
| 3993 | 4087 | cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID); |
| 3994 | 4088 | cm.remote_id_table = RB_ROOT; |
| @@ -1094,47 +1094,47 @@ static void cma_save_ib_info(struct sockaddr *src_addr, · 1093 unmodified lines | ||
| 1094 | 1094 | } |
| 1095 | 1095 | } |
| 1096 | 1096 | |
| 1097 | −static void cma_save_ip4_info(struct sockaddr *src_addr, | |
| 1098 | − struct sockaddr *dst_addr, | |
| 1097 | +static void cma_save_ip4_info(struct sockaddr_in *src_addr, | |
| 1098 | + struct sockaddr_in *dst_addr, | |
| 1099 | 1099 | struct cma_hdr *hdr, |
| 1100 | 1100 | __be16 local_port) |
| 1101 | 1101 | { |
| 1102 | − struct sockaddr_in *ip4; | |
| 1103 | − | |
| 1104 | 1102 | if (src_addr) { |
| 1105 | − ip4 = (struct sockaddr_in *)src_addr; | |
| 1106 | − ip4->sin_family = AF_INET; | |
| 1107 | − ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr; | |
| 1108 | − ip4->sin_port = local_port; | |
| 1103 | + *src_addr = (struct sockaddr_in) { | |
| 1104 | + .sin_family = AF_INET, | |
| 1105 | + .sin_addr.s_addr = hdr->dst_addr.ip4.addr, | |
| 1106 | + .sin_port = local_port, | |
| 1107 | + }; | |
| 1109 | 1108 | } |
| 1110 | 1109 | |
| 1111 | 1110 | if (dst_addr) { |
| 1112 | − ip4 = (struct sockaddr_in *)dst_addr; | |
| 1113 | − ip4->sin_family = AF_INET; | |
| 1114 | − ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr; | |
| 1115 | − ip4->sin_port = hdr->port; | |
| 1111 | + *dst_addr = (struct sockaddr_in) { | |
| 1112 | + .sin_family = AF_INET, | |
| 1113 | + .sin_addr.s_addr = hdr->src_addr.ip4.addr, | |
| 1114 | + .sin_port = hdr->port, | |
| 1115 | + }; | |
| 1116 | 1116 | } |
| 1117 | 1117 | } |
| 1118 | 1118 | |
| 1119 | −static void cma_save_ip6_info(struct sockaddr *src_addr, | |
| 1120 | − struct sockaddr *dst_addr, | |
| 1119 | +static void cma_save_ip6_info(struct sockaddr_in6 *src_addr, | |
| 1120 | + struct sockaddr_in6 *dst_addr, | |
| 1121 | 1121 | struct cma_hdr *hdr, |
| 1122 | 1122 | __be16 local_port) |
| 1123 | 1123 | { |
| 1124 | − struct sockaddr_in6 *ip6; | |
| 1125 | − | |
| 1126 | 1124 | if (src_addr) { |
| 1127 | − ip6 = (struct sockaddr_in6 *)src_addr; | |
| 1128 | − ip6->sin6_family = AF_INET6; | |
| 1129 | − ip6->sin6_addr = hdr->dst_addr.ip6; | |
| 1130 | − ip6->sin6_port = local_port; | |
| 1125 | + *src_addr = (struct sockaddr_in6) { | |
| 1126 | + .sin6_family = AF_INET6, | |
| 1127 | + .sin6_addr = hdr->dst_addr.ip6, | |
| 1128 | + .sin6_port = local_port, | |
| 1129 | + }; | |
| 1131 | 1130 | } |
| 1132 | 1131 | |
| 1133 | 1132 | if (dst_addr) { |
| 1134 | − ip6 = (struct sockaddr_in6 *)dst_addr; | |
| 1135 | − ip6->sin6_family = AF_INET6; | |
| 1136 | − ip6->sin6_addr = hdr->src_addr.ip6; | |
| 1137 | − ip6->sin6_port = hdr->port; | |
| 1133 | + *dst_addr = (struct sockaddr_in6) { | |
| 1134 | + .sin6_family = AF_INET6, | |
| 1135 | + .sin6_addr = hdr->src_addr.ip6, | |
| 1136 | + .sin6_port = hdr->port, | |
| 1137 | + }; | |
| 1138 | 1138 | } |
| 1139 | 1139 | } |
| 1140 | 1140 | |
| @@ -1159,10 +1159,12 @@ static int cma_save_ip_info(struct sockaddr *src_addr, · 18 unmodified lines | ||
| 1159 | 1159 | |
| 1160 | 1160 | switch (cma_get_ip_ver(hdr)) { |
| 1161 | 1161 | case 4: |
| 1162 | − cma_save_ip4_info(src_addr, dst_addr, hdr, port); | |
| 1162 | + cma_save_ip4_info((struct sockaddr_in *)src_addr, | |
| 1163 | + (struct sockaddr_in *)dst_addr, hdr, port); | |
| 1163 | 1164 | break; |
| 1164 | 1165 | case 6: |
| 1165 | − cma_save_ip6_info(src_addr, dst_addr, hdr, port); | |
| 1166 | + cma_save_ip6_info((struct sockaddr_in6 *)src_addr, | |
| 1167 | + (struct sockaddr_in6 *)dst_addr, hdr, port); | |
| 1166 | 1168 | break; |
| 1167 | 1169 | default: |
| 1168 | 1170 | return -EAFNOSUPPORT; |
| @@ -2436,6 +2438,18 @@ static int iboe_tos_to_sl(struct net_device *ndev, int tos) · 1267 unmodified lines | ||
| 2436 | 2438 | return 0; |
| 2437 | 2439 | } |
| 2438 | 2440 | |
| 2441 | +static enum ib_gid_type cma_route_gid_type(enum rdma_network_type network_type, | |
| 2442 | + unsigned long supported_gids, | |
| 2443 | + enum ib_gid_type default_gid) | |
| 2444 | +{ | |
| 2445 | + if ((network_type == RDMA_NETWORK_IPV4 || | |
| 2446 | + network_type == RDMA_NETWORK_IPV6) && | |
| 2447 | + test_bit(IB_GID_TYPE_ROCE_UDP_ENCAP, &supported_gids)) | |
| 2448 | + return IB_GID_TYPE_ROCE_UDP_ENCAP; | |
| 2449 | + | |
| 2450 | + return default_gid; | |
| 2451 | +} | |
| 2452 | + | |
| 2439 | 2453 | static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) |
| 2440 | 2454 | { |
| 2441 | 2455 | struct rdma_route *route = &id_priv->id.route; |
| @@ -2461,6 +2475,8 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) · 19 unmodified lines | ||
| 2461 | 2475 | route->num_paths = 1; |
| 2462 | 2476 | |
| 2463 | 2477 | if (addr->dev_addr.bound_dev_if) { |
| 2478 | + unsigned long supported_gids; | |
| 2479 | + | |
| 2464 | 2480 | ndev = dev_get_by_index(&init_net, addr->dev_addr.bound_dev_if); |
| 2465 | 2481 | if (!ndev) { |
| 2466 | 2482 | ret = -ENODEV; |
| @@ -2484,7 +2500,12 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) · 17 unmodified lines | ||
| 2484 | 2500 | |
| 2485 | 2501 | route->path_rec->net = &init_net; |
| 2486 | 2502 | route->path_rec->ifindex = ndev->ifindex; |
| 2487 | − route->path_rec->gid_type = id_priv->gid_type; | |
| 2503 | + supported_gids = roce_gid_type_mask_support(id_priv->id.device, | |
| 2504 | + id_priv->id.port_num); | |
| 2505 | + route->path_rec->gid_type = | |
| 2506 | + cma_route_gid_type(addr->dev_addr.network, | |
| 2507 | + supported_gids, | |
| 2508 | + id_priv->gid_type); | |
| 2488 | 2509 | } |
| 2489 | 2510 | if (!ndev) { |
| 2490 | 2511 | ret = -ENODEV; |
| @@ -175,7 +175,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, · 174 unmodified lines | ||
| 175 | 175 | |
| 176 | 176 | cur_base = addr & PAGE_MASK; |
| 177 | 177 | |
| 178 | − if (npages == 0) { | |
| 178 | + if (npages == 0 || npages > UINT_MAX) { | |
| 179 | 179 | ret = -EINVAL; |
| 180 | 180 | goto out; |
| 181 | 181 | } |
| @@ -262,12 +262,9 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, · 261 unmodified lines | ||
| 262 | 262 | container_of(uobj, struct ib_uqp_object, uevent.uobject); |
| 263 | 263 | |
| 264 | 264 | idr_remove_uobj(&ib_uverbs_qp_idr, uobj); |
| 265 | − if (qp != qp->real_qp) { | |
| 266 | − ib_close_qp(qp); | |
| 267 | − } else { | |
| 265 | + if (qp == qp->real_qp) | |
| 268 | 266 | ib_uverbs_detach_umcast(qp, uqp); |
| 269 | − ib_destroy_qp(qp); | |
| 270 | − } | |
| 267 | + ib_destroy_qp(qp); | |
| 271 | 268 | ib_uverbs_release_uevent(file, &uqp->uevent); |
| 272 | 269 | kfree(uqp); |
| 273 | 270 | } |
| @@ -666,18 +666,6 @@ skip_cqe: · 665 unmodified lines | ||
| 666 | 666 | return ret; |
| 667 | 667 | } |
| 668 | 668 | |
| 669 | −static void invalidate_mr(struct c4iw_dev *rhp, u32 rkey) | |
| 670 | −{ | |
| 671 | − struct c4iw_mr *mhp; | |
| 672 | − unsigned long flags; | |
| 673 | − | |
| 674 | − spin_lock_irqsave(&rhp->lock, flags); | |
| 675 | − mhp = get_mhp(rhp, rkey >> 8); | |
| 676 | − if (mhp) | |
| 677 | − mhp->attr.state = 0; | |
| 678 | − spin_unlock_irqrestore(&rhp->lock, flags); | |
| 679 | −} | |
| 680 | − | |
| 681 | 669 | /* |
| 682 | 670 | * Get one cq entry from c4iw and map it to openib. |
| 683 | 671 | * |
| @@ -733,7 +721,7 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc) · 49 unmodified lines | ||
| 733 | 721 | CQE_OPCODE(&cqe) == FW_RI_SEND_WITH_SE_INV) { |
| 734 | 722 | wc->ex.invalidate_rkey = CQE_WRID_STAG(&cqe); |
| 735 | 723 | wc->wc_flags |= IB_WC_WITH_INVALIDATE; |
| 736 | − invalidate_mr(qhp->rhp, wc->ex.invalidate_rkey); | |
| 724 | + c4iw_invalidate_mr(qhp->rhp, wc->ex.invalidate_rkey); | |
| 737 | 725 | } |
| 738 | 726 | } else { |
| 739 | 727 | switch (CQE_OPCODE(&cqe)) { |
| @@ -762,7 +750,8 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc) · 22 unmodified lines | ||
| 762 | 750 | |
| 763 | 751 | /* Invalidate the MR if the fastreg failed */ |
| 764 | 752 | if (CQE_STATUS(&cqe) != T4_ERR_SUCCESS) |
| 765 | − invalidate_mr(qhp->rhp, CQE_WRID_FR_STAG(&cqe)); | |
| 753 | + c4iw_invalidate_mr(qhp->rhp, | |
| 754 | + CQE_WRID_FR_STAG(&cqe)); | |
| 766 | 755 | break; |
| 767 | 756 | default: |
| 768 | 757 | printk(KERN_ERR MOD "Unexpected opcode %d " |
| @@ -999,6 +999,6 @@ extern int db_coalescing_threshold; · 998 unmodified lines | ||
| 999 | 999 | extern int use_dsgl; |
| 1000 | 1000 | void c4iw_drain_rq(struct ib_qp *qp); |
| 1001 | 1001 | void c4iw_drain_sq(struct ib_qp *qp); |
| 1002 | − | |
| 1002 | +void c4iw_invalidate_mr(struct c4iw_dev *rhp, u32 rkey); | |
| 1003 | 1003 | |
| 1004 | 1004 | #endif |
| @@ -770,3 +770,15 @@ int c4iw_dereg_mr(struct ib_mr *ib_mr) · 769 unmodified lines | ||
| 770 | 770 | kfree(mhp); |
| 771 | 771 | return 0; |
| 772 | 772 | } |
| 773 | + | |
| 774 | +void c4iw_invalidate_mr(struct c4iw_dev *rhp, u32 rkey) | |
| 775 | +{ | |
| 776 | + struct c4iw_mr *mhp; | |
| 777 | + unsigned long flags; | |
| 778 | + | |
| 779 | + spin_lock_irqsave(&rhp->lock, flags); | |
| 780 | + mhp = get_mhp(rhp, rkey >> 8); | |
| 781 | + if (mhp) | |
| 782 | + mhp->attr.state = 0; | |
| 783 | + spin_unlock_irqrestore(&rhp->lock, flags); | |
| 784 | +} | |
| @@ -706,12 +706,8 @@ static int build_memreg(struct t4_sq *sq, union t4_wr *wqe, · 705 unmodified lines | ||
| 706 | 706 | return 0; |
| 707 | 707 | } |
| 708 | 708 | |
| 709 | −static int build_inv_stag(struct c4iw_dev *dev, union t4_wr *wqe, | |
| 710 | − struct ib_send_wr *wr, u8 *len16) | |
| 709 | +static int build_inv_stag(union t4_wr *wqe, struct ib_send_wr *wr, u8 *len16) | |
| 711 | 710 | { |
| 712 | − struct c4iw_mr *mhp = get_mhp(dev, wr->ex.invalidate_rkey >> 8); | |
| 713 | − | |
| 714 | − mhp->attr.state = 0; | |
| 715 | 711 | wqe->inv.stag_inv = cpu_to_be32(wr->ex.invalidate_rkey); |
| 716 | 712 | wqe->inv.r2 = 0; |
| 717 | 713 | *len16 = DIV_ROUND_UP(sizeof wqe->inv, 16); |
| @@ -797,11 +793,13 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 79 unmodified lines | ||
| 797 | 793 | spin_lock_irqsave(&qhp->lock, flag); |
| 798 | 794 | if (t4_wq_in_error(&qhp->wq)) { |
| 799 | 795 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 796 | + *bad_wr = wr; | |
| 800 | 797 | return -EINVAL; |
| 801 | 798 | } |
| 802 | 799 | num_wrs = t4_sq_avail(&qhp->wq); |
| 803 | 800 | if (num_wrs == 0) { |
| 804 | 801 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 802 | + *bad_wr = wr; | |
| 805 | 803 | return -ENOMEM; |
| 806 | 804 | } |
| 807 | 805 | while (wr) { |
| @@ -840,10 +838,13 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 32 unmodified lines | ||
| 840 | 838 | case IB_WR_RDMA_READ_WITH_INV: |
| 841 | 839 | fw_opcode = FW_RI_RDMA_READ_WR; |
| 842 | 840 | swsqe->opcode = FW_RI_READ_REQ; |
| 843 | − if (wr->opcode == IB_WR_RDMA_READ_WITH_INV) | |
| 841 | + if (wr->opcode == IB_WR_RDMA_READ_WITH_INV) { | |
| 842 | + c4iw_invalidate_mr(qhp->rhp, | |
| 843 | + wr->sg_list[0].lkey); | |
| 844 | 844 | fw_flags = FW_RI_RDMA_READ_INVALIDATE; |
| 845 | − else | |
| 845 | + } else { | |
| 846 | 846 | fw_flags = 0; |
| 847 | + } | |
| 847 | 848 | err = build_rdma_read(wqe, wr, &len16); |
| 848 | 849 | if (err) |
| 849 | 850 | break; |
| @@ -876,7 +877,8 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, · 26 unmodified lines | ||
| 876 | 877 | fw_flags |= FW_RI_LOCAL_FENCE_FLAG; |
| 877 | 878 | fw_opcode = FW_RI_INV_LSTAG_WR; |
| 878 | 879 | swsqe->opcode = FW_RI_LOCAL_INV; |
| 879 | − err = build_inv_stag(qhp->rhp, wqe, wr, &len16); | |
| 880 | + err = build_inv_stag(wqe, wr, &len16); | |
| 881 | + c4iw_invalidate_mr(qhp->rhp, wr->ex.invalidate_rkey); | |
| 880 | 882 | break; |
| 881 | 883 | default: |
| 882 | 884 | PDBG("%s post of type=%d TBD!\n", __func__, |
| @@ -934,11 +936,13 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, · 51 unmodified lines | ||
| 934 | 936 | spin_lock_irqsave(&qhp->lock, flag); |
| 935 | 937 | if (t4_wq_in_error(&qhp->wq)) { |
| 936 | 938 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 939 | + *bad_wr = wr; | |
| 937 | 940 | return -EINVAL; |
| 938 | 941 | } |
| 939 | 942 | num_wrs = t4_rq_avail(&qhp->wq); |
| 940 | 943 | if (num_wrs == 0) { |
| 941 | 944 | spin_unlock_irqrestore(&qhp->lock, flag); |
| 945 | + *bad_wr = wr; | |
| 942 | 946 | return -ENOMEM; |
| 943 | 947 | } |
| 944 | 948 | while (wr) { |
| @@ -775,75 +775,3 @@ void hfi1_put_proc_affinity(int cpu) · 774 unmodified lines | ||
| 775 | 775 | } |
| 776 | 776 | mutex_unlock(&affinity->lock); |
| 777 | 777 | } |
| 778 | − | |
| 779 | −int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf, | |
| 780 | − size_t count) | |
| 781 | −{ | |
| 782 | − struct hfi1_affinity_node *entry; | |
| 783 | − cpumask_var_t mask; | |
| 784 | − int ret, i; | |
| 785 | − | |
| 786 | − mutex_lock(&node_affinity.lock); | |
| 787 | − entry = node_affinity_lookup(dd->node); | |
| 788 | − | |
| 789 | − if (!entry) { | |
| 790 | − ret = -EINVAL; | |
| 791 | − goto unlock; | |
| 792 | − } | |
| 793 | − | |
| 794 | − ret = zalloc_cpumask_var(&mask, GFP_KERNEL); | |
| 795 | − if (!ret) { | |
| 796 | − ret = -ENOMEM; | |
| 797 | − goto unlock; | |
| 798 | − } | |
| 799 | − | |
| 800 | − ret = cpulist_parse(buf, mask); | |
| 801 | − if (ret) | |
| 802 | − goto out; | |
| 803 | − | |
| 804 | − if (!cpumask_subset(mask, cpu_online_mask) || cpumask_empty(mask)) { | |
| 805 | − dd_dev_warn(dd, "Invalid CPU mask\n"); | |
| 806 | − ret = -EINVAL; | |
| 807 | − goto out; | |
| 808 | − } | |
| 809 | − | |
| 810 | − /* reset the SDMA interrupt affinity details */ | |
| 811 | − init_cpu_mask_set(&entry->def_intr); | |
| 812 | − cpumask_copy(&entry->def_intr.mask, mask); | |
| 813 | − | |
| 814 | − /* Reassign the affinity for each SDMA interrupt. */ | |
| 815 | − for (i = 0; i < dd->num_msix_entries; i++) { | |
| 816 | − struct hfi1_msix_entry *msix; | |
| 817 | − | |
| 818 | − msix = &dd->msix_entries[i]; | |
| 819 | − if (msix->type != IRQ_SDMA) | |
| 820 | − continue; | |
| 821 | − | |
| 822 | − ret = get_irq_affinity(dd, msix); | |
| 823 | − | |
| 824 | − if (ret) | |
| 825 | − break; | |
| 826 | − } | |
| 827 | −out: | |
| 828 | − free_cpumask_var(mask); | |
| 829 | −unlock: | |
| 830 | − mutex_unlock(&node_affinity.lock); | |
| 831 | − return ret ? ret : strnlen(buf, PAGE_SIZE); | |
| 832 | −} | |
| 833 | − | |
| 834 | −int hfi1_get_sdma_affinity(struct hfi1_devdata *dd, char *buf) | |
| 835 | −{ | |
| 836 | − struct hfi1_affinity_node *entry; | |
| 837 | − | |
| 838 | − mutex_lock(&node_affinity.lock); | |
| 839 | − entry = node_affinity_lookup(dd->node); | |
| 840 | − | |
| 841 | − if (!entry) { | |
| 842 | − mutex_unlock(&node_affinity.lock); | |
| 843 | − return -EINVAL; | |
| 844 | − } | |
| 845 | − | |
| 846 | − cpumap_print_to_pagebuf(true, buf, &entry->def_intr.mask); | |
| 847 | − mutex_unlock(&node_affinity.lock); | |
| 848 | − return strnlen(buf, PAGE_SIZE); | |
| 849 | −} | |
| @@ -102,10 +102,6 @@ int hfi1_get_proc_affinity(int); · 101 unmodified lines | ||
| 102 | 102 | /* Release a CPU used by a user process. */ |
| 103 | 103 | void hfi1_put_proc_affinity(int); |
| 104 | 104 | |
| 105 | −int hfi1_get_sdma_affinity(struct hfi1_devdata *dd, char *buf); | |
| 106 | −int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf, | |
| 107 | − size_t count); | |
| 108 | − | |
| 109 | 105 | struct hfi1_affinity_node { |
| 110 | 106 | int node; |
| 111 | 107 | struct cpu_mask_set def_intr; |
| @@ -6301,19 +6301,8 @@ void set_up_vl15(struct hfi1_devdata *dd, u8 vau, u16 vl15buf) · 6300 unmodified lines | ||
| 6301 | 6301 | /* leave shared count at zero for both global and VL15 */ |
| 6302 | 6302 | write_global_credit(dd, vau, vl15buf, 0); |
| 6303 | 6303 | |
| 6304 | − /* We may need some credits for another VL when sending packets | |
| 6305 | − * with the snoop interface. Dividing it down the middle for VL15 | |
| 6306 | − * and VL0 should suffice. | |
| 6307 | − */ | |
| 6308 | − if (unlikely(dd->hfi1_snoop.mode_flag == HFI1_PORT_SNOOP_MODE)) { | |
| 6309 | − write_csr(dd, SEND_CM_CREDIT_VL15, (u64)(vl15buf >> 1) | |
| 6310 | − << SEND_CM_CREDIT_VL15_DEDICATED_LIMIT_VL_SHIFT); | |
| 6311 | − write_csr(dd, SEND_CM_CREDIT_VL, (u64)(vl15buf >> 1) | |
| 6312 | − << SEND_CM_CREDIT_VL_DEDICATED_LIMIT_VL_SHIFT); | |
| 6313 | − } else { | |
| 6314 | − write_csr(dd, SEND_CM_CREDIT_VL15, (u64)vl15buf | |
| 6315 | − << SEND_CM_CREDIT_VL15_DEDICATED_LIMIT_VL_SHIFT); | |
| 6316 | − } | |
| 6304 | + write_csr(dd, SEND_CM_CREDIT_VL15, (u64)vl15buf | |
| 6305 | + << SEND_CM_CREDIT_VL15_DEDICATED_LIMIT_VL_SHIFT); | |
| 6317 | 6306 | } |
| 6318 | 6307 | |
| 6319 | 6308 | /* |
| @@ -9915,9 +9904,6 @@ static void set_lidlmc(struct hfi1_pportdata *ppd) · 3595 unmodified lines | ||
| 9915 | 9904 | u32 mask = ~((1U << ppd->lmc) - 1); |
| 9916 | 9905 | u64 c1 = read_csr(ppd->dd, DCC_CFG_PORT_CONFIG1); |
| 9917 | 9906 | |
| 9918 | − if (dd->hfi1_snoop.mode_flag) | |
| 9919 | − dd_dev_info(dd, "Set lid/lmc while snooping"); | |
| 9920 | − | |
| 9921 | 9907 | c1 &= ~(DCC_CFG_PORT_CONFIG1_TARGET_DLID_SMASK |
| 9922 | 9908 | | DCC_CFG_PORT_CONFIG1_DLID_MASK_SMASK); |
| 9923 | 9909 | c1 |= ((ppd->lid & DCC_CFG_PORT_CONFIG1_TARGET_DLID_MASK) |
| @@ -12112,7 +12098,7 @@ static void update_synth_timer(unsigned long opaque) · 2188 unmodified lines | ||
| 12112 | 12098 | mod_timer(&dd->synth_stats_timer, jiffies + HZ * SYNTH_CNT_TIME); |
| 12113 | 12099 | } |
| 12114 | 12100 | |
| 12115 | −#define C_MAX_NAME 13 /* 12 chars + one for /0 */ | |
| 12101 | +#define C_MAX_NAME 16 /* 15 chars + one for /0 */ | |
| 12116 | 12102 | static int init_cntrs(struct hfi1_devdata *dd) |
| 12117 | 12103 | { |
| 12118 | 12104 | int i, rcv_ctxts, j; |
| @@ -14463,7 +14449,7 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev, · 2344 unmodified lines | ||
| 14463 | 14449 | * Any error printing is already done by the init code. |
| 14464 | 14450 | * On return, we have the chip mapped. |
| 14465 | 14451 | */ |
| 14466 | − ret = hfi1_pcie_ddinit(dd, pdev, ent); | |
| 14452 | + ret = hfi1_pcie_ddinit(dd, pdev); | |
| 14467 | 14453 | if (ret < 0) |
| 14468 | 14454 | goto bail_free; |
| 14469 | 14455 | |
| @@ -14691,6 +14677,11 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev, · 221 unmodified lines | ||
| 14691 | 14677 | if (ret) |
| 14692 | 14678 | goto bail_free_cntrs; |
| 14693 | 14679 | |
| 14680 | + init_completion(&dd->user_comp); | |
| 14681 | + | |
| 14682 | + /* The user refcount starts with one to inidicate an active device */ | |
| 14683 | + atomic_set(&dd->user_refcount, 1); | |
| 14684 | + | |
| 14694 | 14685 | goto bail; |
| 14695 | 14686 | |
| 14696 | 14687 | bail_free_rcverr: |
| @@ -320,6 +320,9 @@ · 319 unmodified lines | ||
| 320 | 320 | /* DC_DC8051_CFG_MODE.GENERAL bits */ |
| 321 | 321 | #define DISABLE_SELF_GUID_CHECK 0x2 |
| 322 | 322 | |
| 323 | +/* Bad L2 frame error code */ | |
| 324 | +#define BAD_L2_ERR 0x6 | |
| 325 | + | |
| 323 | 326 | /* |
| 324 | 327 | * Eager buffer minimum and maximum sizes supported by the hardware. |
| 325 | 328 | * All power-of-two sizes in between are supported as well. |
| @@ -599,7 +599,6 @@ static void __prescan_rxq(struct hfi1_packet *packet) · 598 unmodified lines | ||
| 599 | 599 | dd->rhf_offset; |
| 600 | 600 | struct rvt_qp *qp; |
| 601 | 601 | struct ib_header *hdr; |
| 602 | − struct ib_other_headers *ohdr; | |
| 603 | 602 | struct rvt_dev_info *rdi = &dd->verbs_dev.rdi; |
| 604 | 603 | u64 rhf = rhf_to_cpu(rhf_addr); |
| 605 | 604 | u32 etype = rhf_rcv_type(rhf), qpn, bth1; |
| @@ -615,18 +614,21 @@ static void __prescan_rxq(struct hfi1_packet *packet) · 9 unmodified lines | ||
| 615 | 614 | if (etype != RHF_RCV_TYPE_IB) |
| 616 | 615 | goto next; |
| 617 | 616 | |
| 618 | − hdr = hfi1_get_msgheader(dd, rhf_addr); | |
| 617 | + packet->hdr = hfi1_get_msgheader(dd, rhf_addr); | |
| 618 | + hdr = packet->hdr; | |
| 619 | 619 | |
| 620 | 620 | lnh = be16_to_cpu(hdr->lrh[0]) & 3; |
| 621 | 621 | |
| 622 | − if (lnh == HFI1_LRH_BTH) | |
| 623 | − ohdr = &hdr->u.oth; | |
| 624 | − else if (lnh == HFI1_LRH_GRH) | |
| 625 | − ohdr = &hdr->u.l.oth; | |
| 626 | − else | |
| 622 | + if (lnh == HFI1_LRH_BTH) { | |
| 623 | + packet->ohdr = &hdr->u.oth; | |
| 624 | + } else if (lnh == HFI1_LRH_GRH) { | |
| 625 | + packet->ohdr = &hdr->u.l.oth; | |
| 626 | + packet->rcv_flags |= HFI1_HAS_GRH; | |
| 627 | + } else { | |
| 627 | 628 | goto next; /* just in case */ |
| 629 | + } | |
| 628 | 630 | |
| 629 | − bth1 = be32_to_cpu(ohdr->bth[1]); | |
| 631 | + bth1 = be32_to_cpu(packet->ohdr->bth[1]); | |
| 630 | 632 | is_ecn = !!(bth1 & (HFI1_FECN_SMASK | HFI1_BECN_SMASK)); |
| 631 | 633 | |
| 632 | 634 | if (!is_ecn) |
| @@ -646,7 +648,7 @@ static void __prescan_rxq(struct hfi1_packet *packet) · 13 unmodified lines | ||
| 646 | 648 | |
| 647 | 649 | /* turn off BECN, FECN */ |
| 648 | 650 | bth1 &= ~(HFI1_FECN_SMASK | HFI1_BECN_SMASK); |
| 649 | − ohdr->bth[1] = cpu_to_be32(bth1); | |
| 651 | + packet->ohdr->bth[1] = cpu_to_be32(bth1); | |
| 650 | 652 | next: |
| 651 | 653 | update_ps_mdata(&mdata, rcd); |
| 652 | 654 | } |
| @@ -1360,12 +1362,25 @@ int process_receive_ib(struct hfi1_packet *packet) · 707 unmodified lines | ||
| 1360 | 1362 | |
| 1361 | 1363 | int process_receive_bypass(struct hfi1_packet *packet) |
| 1362 | 1364 | { |
| 1365 | + struct hfi1_devdata *dd = packet->rcd->dd; | |
| 1366 | + | |
| 1363 | 1367 | if (unlikely(rhf_err_flags(packet->rhf))) |
| 1364 | 1368 | handle_eflags(packet); |
| 1365 | 1369 | |
| 1366 | − dd_dev_err(packet->rcd->dd, | |
| 1370 | + dd_dev_err(dd, | |
| 1367 | 1371 | "Bypass packets are not supported in normal operation. Dropping\n"); |
| 1368 | − incr_cntr64(&packet->rcd->dd->sw_rcv_bypass_packet_errors); | |
| 1372 | + incr_cntr64(&dd->sw_rcv_bypass_packet_errors); | |
| 1373 | + if (!(dd->err_info_rcvport.status_and_code & OPA_EI_STATUS_SMASK)) { | |
| 1374 | + u64 *flits = packet->ebuf; | |
| 1375 | + | |
| 1376 | + if (flits && !(packet->rhf & RHF_LEN_ERR)) { | |
| 1377 | + dd->err_info_rcvport.packet_flit1 = flits[0]; | |
| 1378 | + dd->err_info_rcvport.packet_flit2 = | |
| 1379 | + packet->tlen > sizeof(flits[0]) ? flits[1] : 0; | |
| 1380 | + } | |
| 1381 | + dd->err_info_rcvport.status_and_code |= | |
| 1382 | + (OPA_EI_STATUS_SMASK | BAD_L2_ERR); | |
| 1383 | + } | |
| 1369 | 1384 | return RHF_RCV_CONTINUE; |
| 1370 | 1385 | } |
| 1371 | 1386 | |
| @@ -172,6 +172,9 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) · 171 unmodified lines | ||
| 172 | 172 | struct hfi1_devdata, |
| 173 | 173 | user_cdev); |
| 174 | 174 | |
| 175 | + if (!atomic_inc_not_zero(&dd->user_refcount)) | |
| 176 | + return -ENXIO; | |
| 177 | + | |
| 175 | 178 | /* Just take a ref now. Not all opens result in a context assign */ |
| 176 | 179 | kobject_get(&dd->kobj); |
| 177 | 180 | |
| @@ -183,11 +186,17 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) · 5 unmodified lines | ||
| 183 | 186 | fd->rec_cpu_num = -1; /* no cpu affinity by default */ |
| 184 | 187 | fd->mm = current->mm; |
| 185 | 188 | atomic_inc(&fd->mm->mm_count); |
| 186 | − } | |
| 189 | + fp->private_data = fd; | |
| 190 | + } else { | |
| 191 | + fp->private_data = NULL; | |
| 192 | + | |
| 193 | + if (atomic_dec_and_test(&dd->user_refcount)) | |
| 194 | + complete(&dd->user_comp); | |
| 187 | 195 | |
| 188 | − fp->private_data = fd; | |
| 196 | + return -ENOMEM; | |
| 197 | + } | |
| 189 | 198 | |
| 190 | − return fd ? 0 : -ENOMEM; | |
| 199 | + return 0; | |
| 191 | 200 | } |
| 192 | 201 | |
| 193 | 202 | static long hfi1_file_ioctl(struct file *fp, unsigned int cmd, |
| @@ -798,6 +807,10 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) · 604 unmodified lines | ||
| 798 | 807 | done: |
| 799 | 808 | mmdrop(fdata->mm); |
| 800 | 809 | kobject_put(&dd->kobj); |
| 810 | + | |
| 811 | + if (atomic_dec_and_test(&dd->user_refcount)) | |
| 812 | + complete(&dd->user_comp); | |
| 813 | + | |
| 801 | 814 | kfree(fdata); |
| 802 | 815 | return 0; |
| 803 | 816 | } |
| @@ -367,26 +367,6 @@ struct hfi1_packet { · 366 unmodified lines | ||
| 367 | 367 | u8 etype; |
| 368 | 368 | }; |
| 369 | 369 | |
| 370 | −/* | |
| 371 | − * Private data for snoop/capture support. | |
| 372 | − */ | |
| 373 | −struct hfi1_snoop_data { | |
| 374 | − int mode_flag; | |
| 375 | − struct cdev cdev; | |
| 376 | − struct device *class_dev; | |
| 377 | − /* protect snoop data */ | |
| 378 | − spinlock_t snoop_lock; | |
| 379 | − struct list_head queue; | |
| 380 | − wait_queue_head_t waitq; | |
| 381 | − void *filter_value; | |
| 382 | − int (*filter_callback)(void *hdr, void *data, void *value); | |
| 383 | − u64 dcc_cfg; /* saved value of DCC Cfg register */ | |
| 384 | −}; | |
| 385 | − | |
| 386 | −/* snoop mode_flag values */ | |
| 387 | −#define HFI1_PORT_SNOOP_MODE 1U | |
| 388 | −#define HFI1_PORT_CAPTURE_MODE 2U | |
| 389 | − | |
| 390 | 370 | struct rvt_sge_state; |
| 391 | 371 | |
| 392 | 372 | /* |
| @@ -613,8 +593,6 @@ struct hfi1_pportdata { · 220 unmodified lines | ||
| 613 | 593 | struct mutex hls_lock; |
| 614 | 594 | u32 host_link_state; |
| 615 | 595 | |
| 616 | − spinlock_t sdma_alllock ____cacheline_aligned_in_smp; | |
| 617 | − | |
| 618 | 596 | u32 lstate; /* logical link state */ |
| 619 | 597 | |
| 620 | 598 | /* these are the "32 bit" regs */ |
| @@ -1104,8 +1082,6 @@ struct hfi1_devdata { · 483 unmodified lines | ||
| 1104 | 1082 | char *portcntrnames; |
| 1105 | 1083 | size_t portcntrnameslen; |
| 1106 | 1084 | |
| 1107 | − struct hfi1_snoop_data hfi1_snoop; | |
| 1108 | − | |
| 1109 | 1085 | struct err_info_rcvport err_info_rcvport; |
| 1110 | 1086 | struct err_info_constraint err_info_rcv_constraint; |
| 1111 | 1087 | struct err_info_constraint err_info_xmit_constraint; |
| @@ -1141,8 +1117,8 @@ struct hfi1_devdata { · 29 unmodified lines | ||
| 1141 | 1117 | rhf_rcv_function_ptr normal_rhf_rcv_functions[8]; |
| 1142 | 1118 | |
| 1143 | 1119 | /* |
| 1144 | − * Handlers for outgoing data so that snoop/capture does not | |
| 1145 | − * have to have its hooks in the send path | |
| 1120 | + * Capability to have different send engines simply by changing a | |
| 1121 | + * pointer value. | |
| 1146 | 1122 | */ |
| 1147 | 1123 | send_routine process_pio_send; |
| 1148 | 1124 | send_routine process_dma_send; |
| @@ -1174,6 +1150,10 @@ struct hfi1_devdata { · 25 unmodified lines | ||
| 1174 | 1150 | spinlock_t aspm_lock; |
| 1175 | 1151 | /* Number of verbs contexts which have disabled ASPM */ |
| 1176 | 1152 | atomic_t aspm_disabled_cnt; |
| 1153 | + /* Keeps track of user space clients */ | |
| 1154 | + atomic_t user_refcount; | |
| 1155 | + /* Used to wait for outstanding user space clients before dev removal */ | |
| 1156 | + struct completion user_comp; | |
| 1177 | 1157 | |
| 1178 | 1158 | struct hfi1_affinity *affinity; |
| 1179 | 1159 | struct rhashtable sdma_rht; |
| @@ -1221,8 +1201,6 @@ struct hfi1_devdata *hfi1_lookup(int unit); · 41 unmodified lines | ||
| 1221 | 1201 | extern u32 hfi1_cpulist_count; |
| 1222 | 1202 | extern unsigned long *hfi1_cpulist; |
| 1223 | 1203 | |
| 1224 | −extern unsigned int snoop_drop_send; | |
| 1225 | −extern unsigned int snoop_force_capture; | |
| 1226 | 1204 | int hfi1_init(struct hfi1_devdata *, int); |
| 1227 | 1205 | int hfi1_count_units(int *npresentp, int *nupp); |
| 1228 | 1206 | int hfi1_count_active_units(void); |
| @@ -1557,13 +1535,6 @@ void set_up_vl15(struct hfi1_devdata *dd, u8 vau, u16 vl15buf); · 328 unmodified lines | ||
| 1557 | 1535 | void reset_link_credits(struct hfi1_devdata *dd); |
| 1558 | 1536 | void assign_remote_cm_au_table(struct hfi1_devdata *dd, u8 vcu); |
| 1559 | 1537 | |
| 1560 | −int snoop_recv_handler(struct hfi1_packet *packet); | |
| 1561 | −int snoop_send_dma_handler(struct rvt_qp *qp, struct hfi1_pkt_state *ps, | |
| 1562 | − u64 pbc); | |
| 1563 | −int snoop_send_pio_handler(struct rvt_qp *qp, struct hfi1_pkt_state *ps, | |
| 1564 | − u64 pbc); | |
| 1565 | −void snoop_inline_pio_send(struct hfi1_devdata *dd, struct pio_buf *pbuf, | |
| 1566 | − u64 pbc, const void *from, size_t count); | |
| 1567 | 1538 | int set_buffer_control(struct hfi1_pportdata *ppd, struct buffer_control *bc); |
| 1568 | 1539 | |
| 1569 | 1540 | static inline struct hfi1_devdata *dd_from_ppd(struct hfi1_pportdata *ppd) |
| @@ -1763,8 +1734,7 @@ int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len); · 193 unmodified lines | ||
| 1763 | 1734 | |
| 1764 | 1735 | int hfi1_pcie_init(struct pci_dev *, const struct pci_device_id *); |
| 1765 | 1736 | void hfi1_pcie_cleanup(struct pci_dev *); |
| 1766 | −int hfi1_pcie_ddinit(struct hfi1_devdata *, struct pci_dev *, | |
| 1767 | − const struct pci_device_id *); | |
| 1737 | +int hfi1_pcie_ddinit(struct hfi1_devdata *, struct pci_dev *); | |
| 1768 | 1738 | void hfi1_pcie_ddcleanup(struct hfi1_devdata *); |
| 1769 | 1739 | void hfi1_pcie_flr(struct hfi1_devdata *); |
| 1770 | 1740 | int pcie_speeds(struct hfi1_devdata *); |
| @@ -1799,8 +1769,6 @@ int kdeth_process_expected(struct hfi1_packet *packet); · 28 unmodified lines | ||
| 1799 | 1769 | int kdeth_process_eager(struct hfi1_packet *packet); |
| 1800 | 1770 | int process_receive_invalid(struct hfi1_packet *packet); |
| 1801 | 1771 | |
| 1802 | −extern rhf_rcv_function_ptr snoop_rhf_rcv_functions[8]; | |
| 1803 | − | |
| 1804 | 1772 | void update_sge(struct rvt_sge_state *ss, u32 length); |
| 1805 | 1773 | |
| 1806 | 1774 | /* global module parameter variables */ |
| @@ -1827,9 +1795,6 @@ extern struct mutex hfi1_mutex; · 20 unmodified lines | ||
| 1827 | 1795 | #define DRIVER_NAME "hfi1" |
| 1828 | 1796 | #define HFI1_USER_MINOR_BASE 0 |
| 1829 | 1797 | #define HFI1_TRACE_MINOR 127 |
| 1830 | −#define HFI1_DIAGPKT_MINOR 128 | |
| 1831 | −#define HFI1_DIAG_MINOR_BASE 129 | |
| 1832 | −#define HFI1_SNOOP_CAPTURE_BASE 200 | |
| 1833 | 1798 | #define HFI1_NMINORS 255 |
| 1834 | 1799 | |
| 1835 | 1800 | #define PCI_VENDOR_ID_INTEL 0x8086 |
| @@ -1848,7 +1813,13 @@ extern struct mutex hfi1_mutex; · 12 unmodified lines | ||
| 1848 | 1813 | static inline u64 hfi1_pkt_default_send_ctxt_mask(struct hfi1_devdata *dd, |
| 1849 | 1814 | u16 ctxt_type) |
| 1850 | 1815 | { |
| 1851 | − u64 base_sc_integrity = | |
| 1816 | + u64 base_sc_integrity; | |
| 1817 | + | |
| 1818 | + /* No integrity checks if HFI1_CAP_NO_INTEGRITY is set */ | |
| 1819 | + if (HFI1_CAP_IS_KSET(NO_INTEGRITY)) | |
| 1820 | + return 0; | |
| 1821 | + | |
| 1822 | + base_sc_integrity = | |
| 1852 | 1823 | SEND_CTXT_CHECK_ENABLE_DISALLOW_BYPASS_BAD_PKT_LEN_SMASK |
| 1853 | 1824 | | SEND_CTXT_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK |
| 1854 | 1825 | | SEND_CTXT_CHECK_ENABLE_DISALLOW_TOO_LONG_BYPASS_PACKETS_SMASK |
| @@ -1863,7 +1834,6 @@ static inline u64 hfi1_pkt_default_send_ctxt_mask(struct hfi1_devdata *dd, · 8 unmodified lines | ||
| 1863 | 1834 | | SEND_CTXT_CHECK_ENABLE_CHECK_VL_MAPPING_SMASK |
| 1864 | 1835 | | SEND_CTXT_CHECK_ENABLE_CHECK_OPCODE_SMASK |
| 1865 | 1836 | | SEND_CTXT_CHECK_ENABLE_CHECK_SLID_SMASK |
| 1866 | − | SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK | |
| 1867 | 1837 | | SEND_CTXT_CHECK_ENABLE_CHECK_VL_SMASK |
| 1868 | 1838 | | SEND_CTXT_CHECK_ENABLE_CHECK_ENABLE_SMASK; |
| 1869 | 1839 | |
| @@ -1872,18 +1842,23 @@ static inline u64 hfi1_pkt_default_send_ctxt_mask(struct hfi1_devdata *dd, · 2 unmodified lines | ||
| 1872 | 1842 | else |
| 1873 | 1843 | base_sc_integrity |= HFI1_PKT_KERNEL_SC_INTEGRITY; |
| 1874 | 1844 | |
| 1875 | − if (is_ax(dd)) | |
| 1876 | − /* turn off send-side job key checks - A0 */ | |
| 1877 | − return base_sc_integrity & | |
| 1878 | − ~SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; | |
| 1845 | + /* turn on send-side job key checks if !A0 */ | |
| 1846 | + if (!is_ax(dd)) | |
| 1847 | + base_sc_integrity |= SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; | |
| 1848 | + | |
| 1879 | 1849 | return base_sc_integrity; |
| 1880 | 1850 | } |
| 1881 | 1851 | |
| 1882 | 1852 | static inline u64 hfi1_pkt_base_sdma_integrity(struct hfi1_devdata *dd) |
| 1883 | 1853 | { |
| 1884 | − u64 base_sdma_integrity = | |
| 1854 | + u64 base_sdma_integrity; | |
| 1855 | + | |
| 1856 | + /* No integrity checks if HFI1_CAP_NO_INTEGRITY is set */ | |
| 1857 | + if (HFI1_CAP_IS_KSET(NO_INTEGRITY)) | |
| 1858 | + return 0; | |
| 1859 | + | |
| 1860 | + base_sdma_integrity = | |
| 1885 | 1861 | SEND_DMA_CHECK_ENABLE_DISALLOW_BYPASS_BAD_PKT_LEN_SMASK |
| 1886 | − | SEND_DMA_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK | |
| 1887 | 1862 | | SEND_DMA_CHECK_ENABLE_DISALLOW_TOO_LONG_BYPASS_PACKETS_SMASK |
| 1888 | 1863 | | SEND_DMA_CHECK_ENABLE_DISALLOW_TOO_LONG_IB_PACKETS_SMASK |
| 1889 | 1864 | | SEND_DMA_CHECK_ENABLE_DISALLOW_BAD_PKT_LEN_SMASK |
| @@ -1895,14 +1870,18 @@ static inline u64 hfi1_pkt_base_sdma_integrity(struct hfi1_devdata *dd) · 5 unmodified lines | ||
| 1895 | 1870 | | SEND_DMA_CHECK_ENABLE_CHECK_VL_MAPPING_SMASK |
| 1896 | 1871 | | SEND_DMA_CHECK_ENABLE_CHECK_OPCODE_SMASK |
| 1897 | 1872 | | SEND_DMA_CHECK_ENABLE_CHECK_SLID_SMASK |
| 1898 | − | SEND_DMA_CHECK_ENABLE_CHECK_JOB_KEY_SMASK | |
| 1899 | 1873 | | SEND_DMA_CHECK_ENABLE_CHECK_VL_SMASK |
| 1900 | 1874 | | SEND_DMA_CHECK_ENABLE_CHECK_ENABLE_SMASK; |
| 1901 | 1875 | |
| 1902 | − if (is_ax(dd)) | |
| 1903 | − /* turn off send-side job key checks - A0 */ | |
| 1904 | − return base_sdma_integrity & | |
| 1905 | − ~SEND_DMA_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; | |
| 1876 | + if (!HFI1_CAP_IS_KSET(STATIC_RATE_CTRL)) | |
| 1877 | + base_sdma_integrity |= | |
| 1878 | + SEND_DMA_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK; | |
| 1879 | + | |
| 1880 | + /* turn on send-side job key checks if !A0 */ | |
| 1881 | + if (!is_ax(dd)) | |
| 1882 | + base_sdma_integrity |= | |
| 1883 | + SEND_DMA_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; | |
| 1884 | + | |
| 1906 | 1885 | return base_sdma_integrity; |
| 1907 | 1886 | } |
| 1908 | 1887 | |
| @@ -144,6 +144,8 @@ int hfi1_create_ctxts(struct hfi1_devdata *dd) · 143 unmodified lines | ||
| 144 | 144 | struct hfi1_ctxtdata *rcd; |
| 145 | 145 | |
| 146 | 146 | ppd = dd->pport + (i % dd->num_pports); |
| 147 | + | |
| 148 | + /* dd->rcd[i] gets assigned inside the callee */ | |
| 147 | 149 | rcd = hfi1_create_ctxtdata(ppd, i, dd->node); |
| 148 | 150 | if (!rcd) { |
| 149 | 151 | dd_dev_err(dd, |
| @@ -169,8 +171,6 @@ int hfi1_create_ctxts(struct hfi1_devdata *dd) · 19 unmodified lines | ||
| 169 | 171 | if (!rcd->sc) { |
| 170 | 172 | dd_dev_err(dd, |
| 171 | 173 | "Unable to allocate kernel send context, failing\n"); |
| 172 | − dd->rcd[rcd->ctxt] = NULL; | |
| 173 | − hfi1_free_ctxtdata(dd, rcd); | |
| 174 | 174 | goto nomem; |
| 175 | 175 | } |
| 176 | 176 | |
| @@ -178,9 +178,6 @@ int hfi1_create_ctxts(struct hfi1_devdata *dd) · 1 unmodified line | ||
| 178 | 178 | if (ret < 0) { |
| 179 | 179 | dd_dev_err(dd, |
| 180 | 180 | "Failed to setup kernel receive context, failing\n"); |
| 181 | − sc_free(rcd->sc); | |
| 182 | − dd->rcd[rcd->ctxt] = NULL; | |
| 183 | − hfi1_free_ctxtdata(dd, rcd); | |
| 184 | 181 | ret = -EFAULT; |
| 185 | 182 | goto bail; |
| 186 | 183 | } |
| @@ -196,6 +193,10 @@ int hfi1_create_ctxts(struct hfi1_devdata *dd) · 9 unmodified lines | ||
| 196 | 193 | nomem: |
| 197 | 194 | ret = -ENOMEM; |
| 198 | 195 | bail: |
| 196 | + if (dd->rcd) { | |
| 197 | + for (i = 0; i < dd->num_rcv_contexts; ++i) | |
| 198 | + hfi1_free_ctxtdata(dd, dd->rcd[i]); | |
| 199 | + } | |
| 199 | 200 | kfree(dd->rcd); |
| 200 | 201 | dd->rcd = NULL; |
| 201 | 202 | return ret; |
| @@ -216,7 +217,7 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt, · 14 unmodified lines | ||
| 216 | 217 | dd->num_rcv_contexts - dd->first_user_ctxt) |
| 217 | 218 | kctxt_ngroups = (dd->rcv_entries.nctxt_extra - |
| 218 | 219 | (dd->num_rcv_contexts - dd->first_user_ctxt)); |
| 219 | − rcd = kzalloc(sizeof(*rcd), GFP_KERNEL); | |
| 220 | + rcd = kzalloc_node(sizeof(*rcd), GFP_KERNEL, numa); | |
| 220 | 221 | if (rcd) { |
| 221 | 222 | u32 rcvtids, max_entries; |
| 222 | 223 | |
| @@ -261,13 +262,6 @@ struct hfi1_ctxtdata *hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, u32 ctxt, · 38 unmodified lines | ||
| 261 | 262 | } |
| 262 | 263 | rcd->eager_base = base * dd->rcv_entries.group_size; |
| 263 | 264 | |
| 264 | − /* Validate and initialize Rcv Hdr Q variables */ | |
| 265 | − if (rcvhdrcnt % HDRQ_INCREMENT) { | |
| 266 | − dd_dev_err(dd, | |
| 267 | − "ctxt%u: header queue count %d must be divisible by %lu\n", | |
| 268 | − rcd->ctxt, rcvhdrcnt, HDRQ_INCREMENT); | |
| 269 | − goto bail; | |
| 270 | − } | |
| 271 | 265 | rcd->rcvhdrq_cnt = rcvhdrcnt; |
| 272 | 266 | rcd->rcvhdrqentsize = hfi1_hdrq_entsize; |
| 273 | 267 | /* |
| @@ -506,7 +500,6 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd, · 232 unmodified lines | ||
| 506 | 500 | INIT_WORK(&ppd->qsfp_info.qsfp_work, qsfp_event); |
| 507 | 501 | |
| 508 | 502 | mutex_init(&ppd->hls_lock); |
| 509 | − spin_lock_init(&ppd->sdma_alllock); | |
| 510 | 503 | spin_lock_init(&ppd->qsfp_info.qsfp_lock); |
| 511 | 504 | |
| 512 | 505 | ppd->qsfp_info.ppd = ppd; |
| @@ -1399,28 +1392,43 @@ static void postinit_cleanup(struct hfi1_devdata *dd) · 886 unmodified lines | ||
| 1399 | 1392 | hfi1_free_devdata(dd); |
| 1400 | 1393 | } |
| 1401 | 1394 | |
| 1395 | +static int init_validate_rcvhdrcnt(struct device *dev, uint thecnt) | |
| 1396 | +{ | |
| 1397 | + if (thecnt <= HFI1_MIN_HDRQ_EGRBUF_CNT) { | |
| 1398 | + hfi1_early_err(dev, "Receive header queue count too small\n"); | |
| 1399 | + return -EINVAL; | |
| 1400 | + } | |
| 1401 | + | |
| 1402 | + if (thecnt > HFI1_MAX_HDRQ_EGRBUF_CNT) { | |
| 1403 | + hfi1_early_err(dev, | |
| 1404 | + "Receive header queue count cannot be greater than %u\n", | |
| 1405 | + HFI1_MAX_HDRQ_EGRBUF_CNT); | |
| 1406 | + return -EINVAL; | |
| 1407 | + } | |
| 1408 | + | |
| 1409 | + if (thecnt % HDRQ_INCREMENT) { | |
| 1410 | + hfi1_early_err(dev, "Receive header queue count %d must be divisible by %lu\n", | |
| 1411 | + thecnt, HDRQ_INCREMENT); | |
| 1412 | + return -EINVAL; | |
| 1413 | + } | |
| 1414 | + | |
| 1415 | + return 0; | |
| 1416 | +} | |
| 1417 | + | |
| 1402 | 1418 | static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 1403 | 1419 | { |
| 1404 | 1420 | int ret = 0, j, pidx, initfail; |
| 1405 | − struct hfi1_devdata *dd = ERR_PTR(-EINVAL); | |
| 1421 | + struct hfi1_devdata *dd; | |
| 1406 | 1422 | struct hfi1_pportdata *ppd; |
| 1407 | 1423 | |
| 1408 | 1424 | /* First, lock the non-writable module parameters */ |
| 1409 | 1425 | HFI1_CAP_LOCK(); |
| 1410 | 1426 | |
| 1411 | 1427 | /* Validate some global module parameters */ |
| 1412 | − if (rcvhdrcnt <= HFI1_MIN_HDRQ_EGRBUF_CNT) { | |
| 1413 | − hfi1_early_err(&pdev->dev, "Header queue count too small\n"); | |
| 1414 | − ret = -EINVAL; | |
| 1415 | − goto bail; | |
| 1416 | − } | |
| 1417 | − if (rcvhdrcnt > HFI1_MAX_HDRQ_EGRBUF_CNT) { | |
| 1418 | − hfi1_early_err(&pdev->dev, | |
| 1419 | − "Receive header queue count cannot be greater than %u\n", | |
| 1420 | − HFI1_MAX_HDRQ_EGRBUF_CNT); | |
| 1421 | − ret = -EINVAL; | |
| 1428 | + ret = init_validate_rcvhdrcnt(&pdev->dev, rcvhdrcnt); | |
| 1429 | + if (ret) | |
| 1422 | 1430 | goto bail; |
| 1423 | − } | |
| 1431 | + | |
| 1424 | 1432 | /* use the encoding function as a sanitization check */ |
| 1425 | 1433 | if (!encode_rcv_header_entry_size(hfi1_hdrq_entsize)) { |
| 1426 | 1434 | hfi1_early_err(&pdev->dev, "Invalid HdrQ Entry size %u\n", |
| @@ -1461,26 +1469,25 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 34 unmodified lines | ||
| 1461 | 1469 | if (ret) |
| 1462 | 1470 | goto bail; |
| 1463 | 1471 | |
| 1464 | − /* | |
| 1465 | − * Do device-specific initialization, function table setup, dd | |
| 1466 | − * allocation, etc. | |
| 1467 | − */ | |
| 1468 | − switch (ent->device) { | |
| 1469 | − case PCI_DEVICE_ID_INTEL0: | |
| 1470 | − case PCI_DEVICE_ID_INTEL1: | |
| 1471 | − dd = hfi1_init_dd(pdev, ent); | |
| 1472 | − break; | |
| 1473 | − default: | |
| 1472 | + if (!(ent->device == PCI_DEVICE_ID_INTEL0 || | |
| 1473 | + ent->device == PCI_DEVICE_ID_INTEL1)) { | |
| 1474 | 1474 | hfi1_early_err(&pdev->dev, |
| 1475 | 1475 | "Failing on unknown Intel deviceid 0x%x\n", |
| 1476 | 1476 | ent->device); |
| 1477 | 1477 | ret = -ENODEV; |
| 1478 | + goto clean_bail; | |
| 1478 | 1479 | } |
| 1479 | 1480 | |
| 1480 | − if (IS_ERR(dd)) | |
| 1481 | + /* | |
| 1482 | + * Do device-specific initialization, function table setup, dd | |
| 1483 | + * allocation, etc. | |
| 1484 | + */ | |
| 1485 | + dd = hfi1_init_dd(pdev, ent); | |
| 1486 | + | |
| 1487 | + if (IS_ERR(dd)) { | |
| 1481 | 1488 | ret = PTR_ERR(dd); |
| 1482 | − if (ret) | |
| 1483 | 1489 | goto clean_bail; /* error already printed */ |
| 1490 | + } | |
| 1484 | 1491 | |
| 1485 | 1492 | ret = create_workqueues(dd); |
| 1486 | 1493 | if (ret) |
| @@ -1538,12 +1545,31 @@ bail: · 51 unmodified lines | ||
| 1538 | 1545 | return ret; |
| 1539 | 1546 | } |
| 1540 | 1547 | |
| 1548 | +static void wait_for_clients(struct hfi1_devdata *dd) | |
| 1549 | +{ | |
| 1550 | + /* | |
| 1551 | + * Remove the device init value and complete the device if there is | |
| 1552 | + * no clients or wait for active clients to finish. | |
| 1553 | + */ | |
| 1554 | + if (atomic_dec_and_test(&dd->user_refcount)) | |
| 1555 | + complete(&dd->user_comp); | |
| 1556 | + | |
| 1557 | + wait_for_completion(&dd->user_comp); | |
| 1558 | +} | |
| 1559 | + | |
| 1541 | 1560 | static void remove_one(struct pci_dev *pdev) |
| 1542 | 1561 | { |
| 1543 | 1562 | struct hfi1_devdata *dd = pci_get_drvdata(pdev); |
| 1544 | 1563 | |
| 1545 | 1564 | /* close debugfs files before ib unregister */ |
| 1546 | 1565 | hfi1_dbg_ibdev_exit(&dd->verbs_dev); |
| 1566 | + | |
| 1567 | + /* remove the /dev hfi1 interface */ | |
| 1568 | + hfi1_device_remove(dd); | |
| 1569 | + | |
| 1570 | + /* wait for existing user space clients to finish */ | |
| 1571 | + wait_for_clients(dd); | |
| 1572 | + | |
| 1547 | 1573 | /* unregister from IB core */ |
| 1548 | 1574 | hfi1_unregister_ib_device(dd); |
| 1549 | 1575 | |
| @@ -1558,8 +1584,6 @@ static void remove_one(struct pci_dev *pdev) · 8 unmodified lines | ||
| 1558 | 1584 | /* wait until all of our (qsfp) queue_work() calls complete */ |
| 1559 | 1585 | flush_workqueue(ib_wq); |
| 1560 | 1586 | |
| 1561 | − hfi1_device_remove(dd); | |
| 1562 | − | |
| 1563 | 1587 | postinit_cleanup(dd); |
| 1564 | 1588 | } |
| 1565 | 1589 | |
| @@ -157,8 +157,7 @@ void hfi1_pcie_cleanup(struct pci_dev *pdev) · 156 unmodified lines | ||
| 157 | 157 | * fields required to re-initialize after a chip reset, or for |
| 158 | 158 | * various other purposes |
| 159 | 159 | */ |
| 160 | −int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev, | |
| 161 | − const struct pci_device_id *ent) | |
| 160 | +int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev) | |
| 162 | 161 | { |
| 163 | 162 | unsigned long len; |
| 164 | 163 | resource_size_t addr; |
| @@ -668,19 +668,12 @@ void sc_set_cr_threshold(struct send_context *sc, u32 new_threshold) · 667 unmodified lines | ||
| 668 | 668 | void set_pio_integrity(struct send_context *sc) |
| 669 | 669 | { |
| 670 | 670 | struct hfi1_devdata *dd = sc->dd; |
| 671 | − u64 reg = 0; | |
| 672 | 671 | u32 hw_context = sc->hw_context; |
| 673 | 672 | int type = sc->type; |
| 674 | 673 | |
| 675 | − /* | |
| 676 | − * No integrity checks if HFI1_CAP_NO_INTEGRITY is set, or if | |
| 677 | − * we're snooping. | |
| 678 | − */ | |
| 679 | − if (likely(!HFI1_CAP_IS_KSET(NO_INTEGRITY)) && | |
| 680 | − dd->hfi1_snoop.mode_flag != HFI1_PORT_SNOOP_MODE) | |
| 681 | − reg = hfi1_pkt_default_send_ctxt_mask(dd, type); | |
| 682 | − | |
| 683 | − write_kctxt_csr(dd, hw_context, SC(CHECK_ENABLE), reg); | |
| 674 | + write_kctxt_csr(dd, hw_context, | |
| 675 | + SC(CHECK_ENABLE), | |
| 676 | + hfi1_pkt_default_send_ctxt_mask(dd, type)); | |
| 684 | 677 | } |
| 685 | 678 | |
| 686 | 679 | static u32 get_buffers_allocated(struct send_context *sc) |
| @@ -89,7 +89,7 @@ void hfi1_add_rnr_timer(struct rvt_qp *qp, u32 to) · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | lockdep_assert_held(&qp->s_lock); |
| 91 | 91 | qp->s_flags |= RVT_S_WAIT_RNR; |
| 92 | − qp->s_timer.expires = jiffies + usecs_to_jiffies(to); | |
| 92 | + priv->s_rnr_timer.expires = jiffies + usecs_to_jiffies(to); | |
| 93 | 93 | add_timer(&priv->s_rnr_timer); |
| 94 | 94 | } |
| 95 | 95 | |
| @@ -2009,11 +2009,6 @@ static void sdma_hw_start_up(struct sdma_engine *sde) · 2008 unmodified lines | ||
| 2009 | 2009 | write_sde_csr(sde, SD(ENG_ERR_CLEAR), reg); |
| 2010 | 2010 | } |
| 2011 | 2011 | |
| 2012 | −#define CLEAR_STATIC_RATE_CONTROL_SMASK(r) \ | |
| 2013 | −(r &= ~SEND_DMA_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK) | |
| 2014 | − | |
| 2015 | −#define SET_STATIC_RATE_CONTROL_SMASK(r) \ | |
| 2016 | −(r |= SEND_DMA_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK) | |
| 2017 | 2012 | /* |
| 2018 | 2013 | * set_sdma_integrity |
| 2019 | 2014 | * |
| @@ -2022,19 +2017,9 @@ static void sdma_hw_start_up(struct sdma_engine *sde) · 2 unmodified lines | ||
| 2022 | 2017 | static void set_sdma_integrity(struct sdma_engine *sde) |
| 2023 | 2018 | { |
| 2024 | 2019 | struct hfi1_devdata *dd = sde->dd; |
| 2025 | − u64 reg; | |
| 2026 | − | |
| 2027 | − if (unlikely(HFI1_CAP_IS_KSET(NO_INTEGRITY))) | |
| 2028 | − return; | |
| 2029 | − | |
| 2030 | − reg = hfi1_pkt_base_sdma_integrity(dd); | |
| 2031 | − | |
| 2032 | − if (HFI1_CAP_IS_KSET(STATIC_RATE_CTRL)) | |
| 2033 | − CLEAR_STATIC_RATE_CONTROL_SMASK(reg); | |
| 2034 | − else | |
| 2035 | − SET_STATIC_RATE_CONTROL_SMASK(reg); | |
| 2036 | 2020 | |
| 2037 | − write_sde_csr(sde, SD(CHECK_ENABLE), reg); | |
| 2021 | + write_sde_csr(sde, SD(CHECK_ENABLE), | |
| 2022 | + hfi1_pkt_base_sdma_integrity(dd)); | |
| 2038 | 2023 | } |
| 2039 | 2024 | |
| 2040 | 2025 | static void init_sdma_regs( |
| @@ -49,7 +49,6 @@ · 48 unmodified lines | ||
| 49 | 49 | #include "hfi.h" |
| 50 | 50 | #include "mad.h" |
| 51 | 51 | #include "trace.h" |
| 52 | −#include "affinity.h" | |
| 53 | 52 | |
| 54 | 53 | /* |
| 55 | 54 | * Start of per-port congestion control structures and support code |
| @@ -623,27 +622,6 @@ static ssize_t show_tempsense(struct device *device, · 567 unmodified lines | ||
| 623 | 622 | return ret; |
| 624 | 623 | } |
| 625 | 624 | |
| 626 | −static ssize_t show_sdma_affinity(struct device *device, | |
| 627 | − struct device_attribute *attr, char *buf) | |
| 628 | −{ | |
| 629 | − struct hfi1_ibdev *dev = | |
| 630 | − container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); | |
| 631 | − struct hfi1_devdata *dd = dd_from_dev(dev); | |
| 632 | − | |
| 633 | − return hfi1_get_sdma_affinity(dd, buf); | |
| 634 | −} | |
| 635 | − | |
| 636 | −static ssize_t store_sdma_affinity(struct device *device, | |
| 637 | − struct device_attribute *attr, | |
| 638 | − const char *buf, size_t count) | |
| 639 | −{ | |
| 640 | − struct hfi1_ibdev *dev = | |
| 641 | − container_of(device, struct hfi1_ibdev, rdi.ibdev.dev); | |
| 642 | − struct hfi1_devdata *dd = dd_from_dev(dev); | |
| 643 | − | |
| 644 | − return hfi1_set_sdma_affinity(dd, buf, count); | |
| 645 | −} | |
| 646 | − | |
| 647 | 625 | /* |
| 648 | 626 | * end of per-unit (or driver, in some cases, but replicated |
| 649 | 627 | * per unit) functions |
| @@ -658,8 +636,6 @@ static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL); · 8 unmodified lines | ||
| 658 | 636 | static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL); |
| 659 | 637 | static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL); |
| 660 | 638 | static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset); |
| 661 | −static DEVICE_ATTR(sdma_affinity, S_IWUSR | S_IRUGO, show_sdma_affinity, | |
| 662 | − store_sdma_affinity); | |
| 663 | 639 | |
| 664 | 640 | static struct device_attribute *hfi1_attributes[] = { |
| 665 | 641 | &dev_attr_hw_rev, |
| @@ -670,7 +646,6 @@ static struct device_attribute *hfi1_attributes[] = { · 4 unmodified lines | ||
| 670 | 646 | &dev_attr_boardversion, |
| 671 | 647 | &dev_attr_tempsense, |
| 672 | 648 | &dev_attr_chip_reset, |
| 673 | − &dev_attr_sdma_affinity, | |
| 674 | 649 | }; |
| 675 | 650 | |
| 676 | 651 | int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, |
| @@ -253,66 +253,6 @@ TRACE_EVENT(hfi1_mmu_invalidate, · 252 unmodified lines | ||
| 253 | 253 | ) |
| 254 | 254 | ); |
| 255 | 255 | |
| 256 | −#define SNOOP_PRN \ | |
| 257 | − "slid %.4x dlid %.4x qpn 0x%.6x opcode 0x%.2x,%s " \ | |
| 258 | − "svc lvl %d pkey 0x%.4x [header = %d bytes] [data = %d bytes]" | |
| 259 | − | |
| 260 | −TRACE_EVENT(snoop_capture, | |
| 261 | − TP_PROTO(struct hfi1_devdata *dd, | |
| 262 | − int hdr_len, | |
| 263 | − struct ib_header *hdr, | |
| 264 | − int data_len, | |
| 265 | − void *data), | |
| 266 | − TP_ARGS(dd, hdr_len, hdr, data_len, data), | |
| 267 | − TP_STRUCT__entry( | |
| 268 | − DD_DEV_ENTRY(dd) | |
| 269 | − __field(u16, slid) | |
| 270 | − __field(u16, dlid) | |
| 271 | − __field(u32, qpn) | |
| 272 | − __field(u8, opcode) | |
| 273 | − __field(u8, sl) | |
| 274 | − __field(u16, pkey) | |
| 275 | − __field(u32, hdr_len) | |
| 276 | − __field(u32, data_len) | |
| 277 | − __field(u8, lnh) | |
| 278 | − __dynamic_array(u8, raw_hdr, hdr_len) | |
| 279 | − __dynamic_array(u8, raw_pkt, data_len) | |
| 280 | − ), | |
| 281 | − TP_fast_assign( | |
| 282 | − struct ib_other_headers *ohdr; | |
| 283 | − | |
| 284 | − __entry->lnh = (u8)(be16_to_cpu(hdr->lrh[0]) & 3); | |
| 285 | − if (__entry->lnh == HFI1_LRH_BTH) | |
| 286 | − ohdr = &hdr->u.oth; | |
| 287 | − else | |
| 288 | − ohdr = &hdr->u.l.oth; | |
| 289 | − DD_DEV_ASSIGN(dd); | |
| 290 | − __entry->slid = be16_to_cpu(hdr->lrh[3]); | |
| 291 | − __entry->dlid = be16_to_cpu(hdr->lrh[1]); | |
| 292 | − __entry->qpn = be32_to_cpu(ohdr->bth[1]) & RVT_QPN_MASK; | |
| 293 | − __entry->opcode = (be32_to_cpu(ohdr->bth[0]) >> 24) & 0xff; | |
| 294 | − __entry->sl = (u8)(be16_to_cpu(hdr->lrh[0]) >> 4) & 0xf; | |
| 295 | − __entry->pkey = be32_to_cpu(ohdr->bth[0]) & 0xffff; | |
| 296 | − __entry->hdr_len = hdr_len; | |
| 297 | − __entry->data_len = data_len; | |
| 298 | − memcpy(__get_dynamic_array(raw_hdr), hdr, hdr_len); | |
| 299 | − memcpy(__get_dynamic_array(raw_pkt), data, data_len); | |
| 300 | − ), | |
| 301 | − TP_printk( | |
| 302 | − "[%s] " SNOOP_PRN, | |
| 303 | − __get_str(dev), | |
| 304 | − __entry->slid, | |
| 305 | − __entry->dlid, | |
| 306 | − __entry->qpn, | |
| 307 | − __entry->opcode, | |
| 308 | − show_ib_opcode(__entry->opcode), | |
| 309 | − __entry->sl, | |
| 310 | − __entry->pkey, | |
| 311 | − __entry->hdr_len, | |
| 312 | − __entry->data_len | |
| 313 | − ) | |
| 314 | −); | |
| 315 | − | |
| 316 | 256 | #endif /* __HFI1_TRACE_RX_H */ |
| 317 | 257 | |
| 318 | 258 | #undef TRACE_INCLUDE_PATH |
| @@ -1144,7 +1144,7 @@ static int pin_vector_pages(struct user_sdma_request *req, · 1143 unmodified lines | ||
| 1144 | 1144 | rb_node = hfi1_mmu_rb_extract(pq->handler, |
| 1145 | 1145 | (unsigned long)iovec->iov.iov_base, |
| 1146 | 1146 | iovec->iov.iov_len); |
| 1147 | − if (rb_node && !IS_ERR(rb_node)) | |
| 1147 | + if (rb_node) | |
| 1148 | 1148 | node = container_of(rb_node, struct sdma_mmu_node, rb); |
| 1149 | 1149 | else |
| 1150 | 1150 | rb_node = NULL; |
| @@ -102,7 +102,10 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr · 101 unmodified lines | ||
| 102 | 102 | if (vlan_tag < 0x1000) |
| 103 | 103 | vlan_tag |= (ah_attr->sl & 7) << 13; |
| 104 | 104 | ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24)); |
| 105 | − ah->av.eth.gid_index = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index); | |
| 105 | + ret = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index); | |
| 106 | + if (ret < 0) | |
| 107 | + return ERR_PTR(ret); | |
| 108 | + ah->av.eth.gid_index = ret; | |
| 106 | 109 | ah->av.eth.vlan = cpu_to_be16(vlan_tag); |
| 107 | 110 | ah->av.eth.hop_limit = ah_attr->grh.hop_limit; |
| 108 | 111 | if (ah_attr->static_rate) { |
| @@ -253,11 +253,14 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, · 252 unmodified lines | ||
| 253 | 253 | if (context) |
| 254 | 254 | if (ib_copy_to_udata(udata, &cq->mcq.cqn, sizeof (__u32))) { |
| 255 | 255 | err = -EFAULT; |
| 256 | − goto err_dbmap; | |
| 256 | + goto err_cq_free; | |
| 257 | 257 | } |
| 258 | 258 | |
| 259 | 259 | return &cq->ibcq; |
| 260 | 260 | |
| 261 | +err_cq_free: | |
| 262 | + mlx4_cq_free(dev->dev, &cq->mcq); | |
| 263 | + | |
| 261 | 264 | err_dbmap: |
| 262 | 265 | if (context) |
| 263 | 266 | mlx4_ib_db_unmap_user(to_mucontext(context), &cq->db); |
| @@ -932,8 +932,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, · 931 unmodified lines | ||
| 932 | 932 | if (err) |
| 933 | 933 | goto err_create; |
| 934 | 934 | } else { |
| 935 | − /* for now choose 64 bytes till we have a proper interface */ | |
| 936 | − cqe_size = 64; | |
| 935 | + cqe_size = cache_line_size() == 128 ? 128 : 64; | |
| 937 | 936 | err = create_cq_kernel(dev, cq, entries, cqe_size, &cqb, |
| 938 | 937 | &index, &inlen); |
| 939 | 938 | if (err) |
| @@ -2311,14 +2311,14 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context, · 2310 unmodified lines | ||
| 2311 | 2311 | { |
| 2312 | 2312 | struct mlx5_ib_dev *ibdev = (struct mlx5_ib_dev *)context; |
| 2313 | 2313 | struct ib_event ibev; |
| 2314 | − | |
| 2314 | + bool fatal = false; | |
| 2315 | 2315 | u8 port = 0; |
| 2316 | 2316 | |
| 2317 | 2317 | switch (event) { |
| 2318 | 2318 | case MLX5_DEV_EVENT_SYS_ERROR: |
| 2319 | − ibdev->ib_active = false; | |
| 2320 | 2319 | ibev.event = IB_EVENT_DEVICE_FATAL; |
| 2321 | 2320 | mlx5_ib_handle_internal_error(ibdev); |
| 2321 | + fatal = true; | |
| 2322 | 2322 | break; |
| 2323 | 2323 | |
| 2324 | 2324 | case MLX5_DEV_EVENT_PORT_UP: |
| @@ -2370,6 +2370,9 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context, · 45 unmodified lines | ||
| 2370 | 2370 | |
| 2371 | 2371 | if (ibdev->ib_active) |
| 2372 | 2372 | ib_dispatch_event(&ibev); |
| 2373 | + | |
| 2374 | + if (fatal) | |
| 2375 | + ibdev->ib_active = false; | |
| 2373 | 2376 | } |
| 2374 | 2377 | |
| 2375 | 2378 | static void get_ext_port_caps(struct mlx5_ib_dev *dev) |
| @@ -3115,7 +3118,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) · 739 unmodified lines | ||
| 3115 | 3118 | } |
| 3116 | 3119 | err = init_node_data(dev); |
| 3117 | 3120 | if (err) |
| 3118 | − goto err_dealloc; | |
| 3121 | + goto err_free_port; | |
| 3119 | 3122 | |
| 3120 | 3123 | mutex_init(&dev->flow_db.lock); |
| 3121 | 3124 | mutex_init(&dev->cap_mask_mutex); |
| @@ -3125,7 +3128,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) · 3 unmodified lines | ||
| 3125 | 3128 | if (ll == IB_LINK_LAYER_ETHERNET) { |
| 3126 | 3129 | err = mlx5_enable_roce(dev); |
| 3127 | 3130 | if (err) |
| 3128 | − goto err_dealloc; | |
| 3131 | + goto err_free_port; | |
| 3129 | 3132 | } |
| 3130 | 3133 | |
| 3131 | 3134 | err = create_dev_resources(&dev->devr); |
| @@ -626,6 +626,8 @@ struct mlx5_ib_dev { · 625 unmodified lines | ||
| 626 | 626 | struct mlx5_ib_resources devr; |
| 627 | 627 | struct mlx5_mr_cache cache; |
| 628 | 628 | struct timer_list delay_timer; |
| 629 | + /* Prevents soft lock on massive reg MRs */ | |
| 630 | + struct mutex slow_path_mutex; | |
| 629 | 631 | int fill_delay; |
| 630 | 632 | #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING |
| 631 | 633 | struct ib_odp_caps odp_caps; |
| @@ -610,6 +610,7 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev) · 609 unmodified lines | ||
| 610 | 610 | int err; |
| 611 | 611 | int i; |
| 612 | 612 | |
| 613 | + mutex_init(&dev->slow_path_mutex); | |
| 613 | 614 | cache->wq = alloc_ordered_workqueue("mkey_cache", WQ_MEM_RECLAIM); |
| 614 | 615 | if (!cache->wq) { |
| 615 | 616 | mlx5_ib_warn(dev, "failed to create work queue\n"); |
| @@ -1182,9 +1183,12 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, · 566 unmodified lines | ||
| 1182 | 1183 | goto error; |
| 1183 | 1184 | } |
| 1184 | 1185 | |
| 1185 | − if (!mr) | |
| 1186 | + if (!mr) { | |
| 1187 | + mutex_lock(&dev->slow_path_mutex); | |
| 1186 | 1188 | mr = reg_create(NULL, pd, virt_addr, length, umem, ncont, |
| 1187 | 1189 | page_shift, access_flags); |
| 1190 | + mutex_unlock(&dev->slow_path_mutex); | |
| 1191 | + } | |
| 1188 | 1192 | |
| 1189 | 1193 | if (IS_ERR(mr)) { |
| 1190 | 1194 | err = PTR_ERR(mr); |
| @@ -2051,8 +2051,8 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, · 2050 unmodified lines | ||
| 2051 | 2051 | |
| 2052 | 2052 | mlx5_ib_dbg(dev, "ib qpnum 0x%x, mlx qpn 0x%x, rcqn 0x%x, scqn 0x%x\n", |
| 2053 | 2053 | qp->ibqp.qp_num, qp->trans_qp.base.mqp.qpn, |
| 2054 | − to_mcq(init_attr->recv_cq)->mcq.cqn, | |
| 2055 | − to_mcq(init_attr->send_cq)->mcq.cqn); | |
| 2054 | + init_attr->recv_cq ? to_mcq(init_attr->recv_cq)->mcq.cqn : -1, | |
| 2055 | + init_attr->send_cq ? to_mcq(init_attr->send_cq)->mcq.cqn : -1); | |
| 2056 | 2056 | |
| 2057 | 2057 | qp->trans_qp.xrcdn = xrcdn; |
| 2058 | 2058 | |
| @@ -4814,6 +4814,14 @@ struct ib_rwq_ind_table *mlx5_ib_create_rwq_ind_table(struct ib_device *device, · 2755 unmodified lines | ||
| 4814 | 4814 | udata->inlen)) |
| 4815 | 4815 | return ERR_PTR(-EOPNOTSUPP); |
| 4816 | 4816 | |
| 4817 | + if (init_attr->log_ind_tbl_size > | |
| 4818 | + MLX5_CAP_GEN(dev->mdev, log_max_rqt_size)) { | |
| 4819 | + mlx5_ib_dbg(dev, "log_ind_tbl_size = %d is bigger than supported = %d\n", | |
| 4820 | + init_attr->log_ind_tbl_size, | |
| 4821 | + MLX5_CAP_GEN(dev->mdev, log_max_rqt_size)); | |
| 4822 | + return ERR_PTR(-EINVAL); | |
| 4823 | + } | |
| 4824 | + | |
| 4817 | 4825 | min_resp_len = offsetof(typeof(resp), reserved) + sizeof(resp.reserved); |
| 4818 | 4826 | if (udata->outlen && udata->outlen < min_resp_len) |
| 4819 | 4827 | return ERR_PTR(-EINVAL); |
| @@ -90,9 +90,6 @@ static u64 rvt_dma_map_page(struct ib_device *dev, struct page *page, · 89 unmodified lines | ||
| 90 | 90 | if (WARN_ON(!valid_dma_direction(direction))) |
| 91 | 91 | return BAD_DMA_ADDRESS; |
| 92 | 92 | |
| 93 | − if (offset + size > PAGE_SIZE) | |
| 94 | − return BAD_DMA_ADDRESS; | |
| 95 | − | |
| 96 | 93 | addr = (u64)page_address(page); |
| 97 | 94 | if (addr) |
| 98 | 95 | addr += offset; |
| @@ -243,10 +243,8 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port, · 242 unmodified lines | ||
| 243 | 243 | { |
| 244 | 244 | int err; |
| 245 | 245 | struct socket *sock; |
| 246 | − struct udp_port_cfg udp_cfg; | |
| 247 | − struct udp_tunnel_sock_cfg tnl_cfg; | |
| 248 | − | |
| 249 | − memset(&udp_cfg, 0, sizeof(udp_cfg)); | |
| 246 | + struct udp_port_cfg udp_cfg = {0}; | |
| 247 | + struct udp_tunnel_sock_cfg tnl_cfg = {0}; | |
| 250 | 248 | |
| 251 | 249 | if (ipv6) { |
| 252 | 250 | udp_cfg.family = AF_INET6; |
| @@ -264,10 +262,8 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port, · 11 unmodified lines | ||
| 264 | 262 | return ERR_PTR(err); |
| 265 | 263 | } |
| 266 | 264 | |
| 267 | − tnl_cfg.sk_user_data = NULL; | |
| 268 | 265 | tnl_cfg.encap_type = 1; |
| 269 | 266 | tnl_cfg.encap_rcv = rxe_udp_encap_recv; |
| 270 | − tnl_cfg.encap_destroy = NULL; | |
| 271 | 267 | |
| 272 | 268 | /* Setup UDP tunnel */ |
| 273 | 269 | setup_udp_tunnel_sock(net, sock, &tnl_cfg); |
| @@ -522,6 +522,7 @@ static void rxe_qp_reset(struct rxe_qp *qp) · 521 unmodified lines | ||
| 522 | 522 | if (qp->sq.queue) { |
| 523 | 523 | __rxe_do_task(&qp->comp.task); |
| 524 | 524 | __rxe_do_task(&qp->req.task); |
| 525 | + rxe_queue_reset(qp->sq.queue); | |
| 525 | 526 | } |
| 526 | 527 | |
| 527 | 528 | /* cleanup attributes */ |
| @@ -573,6 +574,7 @@ void rxe_qp_error(struct rxe_qp *qp) · 45 unmodified lines | ||
| 573 | 574 | { |
| 574 | 575 | qp->req.state = QP_STATE_ERROR; |
| 575 | 576 | qp->resp.state = QP_STATE_ERROR; |
| 577 | + qp->attr.qp_state = IB_QPS_ERR; | |
| 576 | 578 | |
| 577 | 579 | /* drain work and packet queues */ |
| 578 | 580 | rxe_run_task(&qp->resp.task, 1); |
| @@ -84,6 +84,15 @@ err1: · 83 unmodified lines | ||
| 84 | 84 | return -EINVAL; |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | +inline void rxe_queue_reset(struct rxe_queue *q) | |
| 88 | +{ | |
| 89 | + /* queue is comprised from header and the memory | |
| 90 | + * of the actual queue. See "struct rxe_queue_buf" in rxe_queue.h | |
| 91 | + * reset only the queue itself and not the management header | |
| 92 | + */ | |
| 93 | + memset(q->buf->data, 0, q->buf_size - sizeof(struct rxe_queue_buf)); | |
| 94 | +} | |
| 95 | + | |
| 87 | 96 | struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, |
| 88 | 97 | int *num_elem, |
| 89 | 98 | unsigned int elem_size) |
| @@ -84,6 +84,8 @@ int do_mmap_info(struct rxe_dev *rxe, · 83 unmodified lines | ||
| 84 | 84 | size_t buf_size, |
| 85 | 85 | struct rxe_mmap_info **ip_p); |
| 86 | 86 | |
| 87 | +void rxe_queue_reset(struct rxe_queue *q); | |
| 88 | + | |
| 87 | 89 | struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, |
| 88 | 90 | int *num_elem, |
| 89 | 91 | unsigned int elem_size); |
| @@ -696,7 +696,8 @@ next_wqe: · 695 unmodified lines | ||
| 696 | 696 | qp->req.wqe_index); |
| 697 | 697 | wqe->state = wqe_state_done; |
| 698 | 698 | wqe->status = IB_WC_SUCCESS; |
| 699 | − goto complete; | |
| 699 | + __rxe_do_task(&qp->comp.task); | |
| 700 | + return 0; | |
| 700 | 701 | } |
| 701 | 702 | payload = mtu; |
| 702 | 703 | } |
| @@ -745,13 +746,17 @@ err: · 42 unmodified lines | ||
| 745 | 746 | wqe->status = IB_WC_LOC_PROT_ERR; |
| 746 | 747 | wqe->state = wqe_state_error; |
| 747 | 748 | |
| 748 | −complete: | |
| 749 | − if (qp_type(qp) != IB_QPT_RC) { | |
| 750 | − while (rxe_completer(qp) == 0) | |
| 751 | − ; | |
| 752 | − } | |
| 753 | − | |
| 754 | − return 0; | |
| 749 | + /* | |
| 750 | + * IBA Spec. Section 10.7.3.1 SIGNALED COMPLETIONS | |
| 751 | + * ---------8<---------8<------------- | |
| 752 | + * ...Note that if a completion error occurs, a Work Completion | |
| 753 | + * will always be generated, even if the signaling | |
| 754 | + * indicator requests an Unsignaled Completion. | |
| 755 | + * ---------8<---------8<------------- | |
| 756 | + */ | |
| 757 | + wqe->wr.send_flags |= IB_SEND_SIGNALED; | |
| 758 | + __rxe_do_task(&qp->comp.task); | |
| 759 | + return -EAGAIN; | |
| 755 | 760 | |
| 756 | 761 | exit: |
| 757 | 762 | return -EAGAIN; |
| @@ -65,6 +65,7 @@ · 64 unmodified lines | ||
| 65 | 65 | #include <linux/mailbox_controller.h> |
| 66 | 66 | #include <linux/mailbox_client.h> |
| 67 | 67 | #include <linux/io-64-nonatomic-lo-hi.h> |
| 68 | +#include <acpi/pcc.h> | |
| 68 | 69 | |
| 69 | 70 | #include "mailbox.h" |
| 70 | 71 | |
| @@ -267,6 +268,8 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl, · 196 unmodified lines | ||
| 267 | 268 | if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone) |
| 268 | 269 | chan->txdone_method |= TXDONE_BY_ACK; |
| 269 | 270 | |
| 271 | + spin_unlock_irqrestore(&chan->lock, flags); | |
| 272 | + | |
| 270 | 273 | if (pcc_doorbell_irq[subspace_id] > 0) { |
| 271 | 274 | int rc; |
| 272 | 275 | |
| @@ -275,12 +278,11 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl, · 2 unmodified lines | ||
| 275 | 278 | if (unlikely(rc)) { |
| 276 | 279 | dev_err(dev, "failed to register PCC interrupt %d\n", |
| 277 | 280 | pcc_doorbell_irq[subspace_id]); |
| 281 | + pcc_mbox_free_channel(chan); | |
| 278 | 282 | chan = ERR_PTR(rc); |
| 279 | 283 | } |
| 280 | 284 | } |
| 281 | 285 | |
| 282 | − spin_unlock_irqrestore(&chan->lock, flags); | |
| 283 | − | |
| 284 | 286 | return chan; |
| 285 | 287 | } |
| 286 | 288 | EXPORT_SYMBOL_GPL(pcc_mbox_request_channel); |
| @@ -304,20 +306,19 @@ void pcc_mbox_free_channel(struct mbox_chan *chan) · 17 unmodified lines | ||
| 304 | 306 | return; |
| 305 | 307 | } |
| 306 | 308 | |
| 309 | + if (pcc_doorbell_irq[id] > 0) | |
| 310 | + devm_free_irq(chan->mbox->dev, pcc_doorbell_irq[id], chan); | |
| 311 | + | |
| 307 | 312 | spin_lock_irqsave(&chan->lock, flags); |
| 308 | 313 | chan->cl = NULL; |
| 309 | 314 | chan->active_req = NULL; |
| 310 | 315 | if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK)) |
| 311 | 316 | chan->txdone_method = TXDONE_BY_POLL; |
| 312 | 317 | |
| 313 | − if (pcc_doorbell_irq[id] > 0) | |
| 314 | − devm_free_irq(chan->mbox->dev, pcc_doorbell_irq[id], chan); | |
| 315 | − | |
| 316 | 318 | spin_unlock_irqrestore(&chan->lock, flags); |
| 317 | 319 | } |
| 318 | 320 | EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); |
| 319 | 321 | |
| 320 | − | |
| 321 | 322 | /** |
| 322 | 323 | * pcc_send_data - Called from Mailbox Controller code. Used |
| 323 | 324 | * here only to ring the channel doorbell. The PCC client |
| @@ -513,6 +513,11 @@ config DVB_AS102_FE · 512 unmodified lines | ||
| 513 | 513 | depends on DVB_CORE |
| 514 | 514 | default DVB_AS102 |
| 515 | 515 | |
| 516 | +config DVB_GP8PSK_FE | |
| 517 | + tristate | |
| 518 | + depends on DVB_CORE | |
| 519 | + default DVB_USB_GP8PSK | |
| 520 | + | |
| 516 | 521 | comment "DVB-C (cable) frontends" |
| 517 | 522 | depends on DVB_CORE |
| 518 | 523 | |
| @@ -121,6 +121,7 @@ obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o · 120 unmodified lines | ||
| 121 | 121 | obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o |
| 122 | 122 | obj-$(CONFIG_DVB_AF9033) += af9033.o |
| 123 | 123 | obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o |
| 124 | +obj-$(CONFIG_DVB_GP8PSK_FE) += gp8psk-fe.o | |
| 124 | 125 | obj-$(CONFIG_DVB_TC90522) += tc90522.o |
| 125 | 126 | obj-$(CONFIG_DVB_HORUS3A) += horus3a.o |
| 126 | 127 | obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o |
| @@ -1,5 +1,5 @@ | ||
| 1 | −/* DVB USB compliant Linux driver for the | |
| 2 | − * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module | |
| 1 | +/* | |
| 2 | + * Frontend driver for the GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module | |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com) |
| 5 | 5 | * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com) |
| @@ -8,17 +8,31 @@ · 2 unmodified lines | ||
| 8 | 8 | * |
| 9 | 9 | * This module is based off the vp7045 and vp702x modules |
| 10 | 10 | * |
| 11 | − * This program is free software; you can redistribute it and/or modify it | |
| 12 | − * under the terms of the GNU General Public License as published by the Free | |
| 13 | − * Software Foundation, version 2. | |
| 14 | − * | |
| 15 | − * see Documentation/dvb/README.dvb-usb for more information | |
| 11 | + * This program is free software; you can redistribute it and/or modify it | |
| 12 | + * under the terms of the GNU General Public License as published by the Free | |
| 13 | + * Software Foundation, version 2. | |
| 16 | 14 | */ |
| 17 | −#include "gp8psk.h" | |
| 15 | + | |
| 16 | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 17 | + | |
| 18 | +#include "gp8psk-fe.h" | |
| 19 | +#include "dvb_frontend.h" | |
| 20 | + | |
| 21 | +static int debug; | |
| 22 | +module_param(debug, int, 0644); | |
| 23 | +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | |
| 24 | + | |
| 25 | +#define dprintk(fmt, arg...) do { \ | |
| 26 | + if (debug) \ | |
| 27 | + printk(KERN_DEBUG pr_fmt("%s: " fmt), \ | |
| 28 | + __func__, ##arg); \ | |
| 29 | +} while (0) | |
| 18 | 30 | |
| 19 | 31 | struct gp8psk_fe_state { |
| 20 | 32 | struct dvb_frontend fe; |
| 21 | − struct dvb_usb_device *d; | |
| 33 | + void *priv; | |
| 34 | + const struct gp8psk_fe_ops *ops; | |
| 35 | + bool is_rev1; | |
| 22 | 36 | u8 lock; |
| 23 | 37 | u16 snr; |
| 24 | 38 | unsigned long next_status_check; |
| @@ -29,22 +43,24 @@ static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe) · 4 unmodified lines | ||
| 29 | 43 | { |
| 30 | 44 | struct gp8psk_fe_state *st = fe->demodulator_priv; |
| 31 | 45 | u8 status; |
| 32 | − gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1); | |
| 46 | + | |
| 47 | + st->ops->in(st->priv, GET_8PSK_CONFIG, 0, 0, &status, 1); | |
| 33 | 48 | return status & bmDCtuned; |
| 34 | 49 | } |
| 35 | 50 | |
| 36 | 51 | static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode) |
| 37 | 52 | { |
| 38 | − struct gp8psk_fe_state *state = fe->demodulator_priv; | |
| 39 | − return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0); | |
| 53 | + struct gp8psk_fe_state *st = fe->demodulator_priv; | |
| 54 | + | |
| 55 | + return st->ops->out(st->priv, SET_8PSK_CONFIG, mode, 0, NULL, 0); | |
| 40 | 56 | } |
| 41 | 57 | |
| 42 | 58 | static int gp8psk_fe_update_status(struct gp8psk_fe_state *st) |
| 43 | 59 | { |
| 44 | 60 | u8 buf[6]; |
| 45 | 61 | if (time_after(jiffies,st->next_status_check)) { |
| 46 | − gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1); | |
| 47 | − gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6); | |
| 62 | + st->ops->in(st->priv, GET_SIGNAL_LOCK, 0, 0, &st->lock, 1); | |
| 63 | + st->ops->in(st->priv, GET_SIGNAL_STRENGTH, 0, 0, buf, 6); | |
| 48 | 64 | st->snr = (buf[1]) << 8 | buf[0]; |
| 49 | 65 | st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; |
| 50 | 66 | } |
| @@ -116,13 +132,12 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front · 65 unmodified lines | ||
| 116 | 132 | |
| 117 | 133 | static int gp8psk_fe_set_frontend(struct dvb_frontend *fe) |
| 118 | 134 | { |
| 119 | − struct gp8psk_fe_state *state = fe->demodulator_priv; | |
| 135 | + struct gp8psk_fe_state *st = fe->demodulator_priv; | |
| 120 | 136 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
| 121 | 137 | u8 cmd[10]; |
| 122 | 138 | u32 freq = c->frequency * 1000; |
| 123 | − int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct); | |
| 124 | 139 | |
| 125 | − deb_fe("%s()\n", __func__); | |
| 140 | + dprintk("%s()\n", __func__); | |
| 126 | 141 | |
| 127 | 142 | cmd[4] = freq & 0xff; |
| 128 | 143 | cmd[5] = (freq >> 8) & 0xff; |
| @@ -136,21 +151,21 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe) · 7 unmodified lines | ||
| 136 | 151 | switch (c->delivery_system) { |
| 137 | 152 | case SYS_DVBS: |
| 138 | 153 | if (c->modulation != QPSK) { |
| 139 | − deb_fe("%s: unsupported modulation selected (%d)\n", | |
| 154 | + dprintk("%s: unsupported modulation selected (%d)\n", | |
| 140 | 155 | __func__, c->modulation); |
| 141 | 156 | return -EOPNOTSUPP; |
| 142 | 157 | } |
| 143 | 158 | c->fec_inner = FEC_AUTO; |
| 144 | 159 | break; |
| 145 | 160 | case SYS_DVBS2: /* kept for backwards compatibility */ |
| 146 | − deb_fe("%s: DVB-S2 delivery system selected\n", __func__); | |
| 161 | + dprintk("%s: DVB-S2 delivery system selected\n", __func__); | |
| 147 | 162 | break; |
| 148 | 163 | case SYS_TURBO: |
| 149 | − deb_fe("%s: Turbo-FEC delivery system selected\n", __func__); | |
| 164 | + dprintk("%s: Turbo-FEC delivery system selected\n", __func__); | |
| 150 | 165 | break; |
| 151 | 166 | |
| 152 | 167 | default: |
| 153 | − deb_fe("%s: unsupported delivery system selected (%d)\n", | |
| 168 | + dprintk("%s: unsupported delivery system selected (%d)\n", | |
| 154 | 169 | __func__, c->delivery_system); |
| 155 | 170 | return -EOPNOTSUPP; |
| 156 | 171 | } |
| @@ -161,9 +176,9 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe) · 4 unmodified lines | ||
| 161 | 176 | cmd[3] = (c->symbol_rate >> 24) & 0xff; |
| 162 | 177 | switch (c->modulation) { |
| 163 | 178 | case QPSK: |
| 164 | − if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) | |
| 179 | + if (st->is_rev1) | |
| 165 | 180 | if (gp8psk_tuned_to_DCII(fe)) |
| 166 | − gp8psk_bcm4500_reload(state->d); | |
| 181 | + st->ops->reload(st->priv); | |
| 167 | 182 | switch (c->fec_inner) { |
| 168 | 183 | case FEC_1_2: |
| 169 | 184 | cmd[9] = 0; break; |
| @@ -207,18 +222,18 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend *fe) · 37 unmodified lines | ||
| 207 | 222 | cmd[9] = 0; |
| 208 | 223 | break; |
| 209 | 224 | default: /* Unknown modulation */ |
| 210 | − deb_fe("%s: unsupported modulation selected (%d)\n", | |
| 225 | + dprintk("%s: unsupported modulation selected (%d)\n", | |
| 211 | 226 | __func__, c->modulation); |
| 212 | 227 | return -EOPNOTSUPP; |
| 213 | 228 | } |
| 214 | 229 | |
| 215 | − if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) | |
| 230 | + if (st->is_rev1) | |
| 216 | 231 | gp8psk_set_tuner_mode(fe, 0); |
| 217 | − gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10); | |
| 232 | + st->ops->out(st->priv, TUNE_8PSK, 0, 0, cmd, 10); | |
| 218 | 233 | |
| 219 | − state->lock = 0; | |
| 220 | − state->next_status_check = jiffies; | |
| 221 | − state->status_check_interval = 200; | |
| 234 | + st->lock = 0; | |
| 235 | + st->next_status_check = jiffies; | |
| 236 | + st->status_check_interval = 200; | |
| 222 | 237 | |
| 223 | 238 | return 0; |
| 224 | 239 | } |
| @@ -228,9 +243,9 @@ static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe, · 3 unmodified lines | ||
| 228 | 243 | { |
| 229 | 244 | struct gp8psk_fe_state *st = fe->demodulator_priv; |
| 230 | 245 | |
| 231 | − deb_fe("%s\n",__func__); | |
| 246 | + dprintk("%s\n", __func__); | |
| 232 | 247 | |
| 233 | − if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0, | |
| 248 | + if (st->ops->out(st->priv, SEND_DISEQC_COMMAND, m->msg[0], 0, | |
| 234 | 249 | m->msg, m->msg_len)) { |
| 235 | 250 | return -EINVAL; |
| 236 | 251 | } |
| @@ -243,12 +258,12 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe, · 6 unmodified lines | ||
| 243 | 258 | struct gp8psk_fe_state *st = fe->demodulator_priv; |
| 244 | 259 | u8 cmd; |
| 245 | 260 | |
| 246 | − deb_fe("%s\n",__func__); | |
| 261 | + dprintk("%s\n", __func__); | |
| 247 | 262 | |
| 248 | 263 | /* These commands are certainly wrong */ |
| 249 | 264 | cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01; |
| 250 | 265 | |
| 251 | − if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0, | |
| 266 | + if (st->ops->out(st->priv, SEND_DISEQC_COMMAND, cmd, 0, | |
| 252 | 267 | &cmd, 0)) { |
| 253 | 268 | return -EINVAL; |
| 254 | 269 | } |
| @@ -258,10 +273,10 @@ static int gp8psk_fe_send_diseqc_burst(struct dvb_frontend *fe, · 3 unmodified lines | ||
| 258 | 273 | static int gp8psk_fe_set_tone(struct dvb_frontend *fe, |
| 259 | 274 | enum fe_sec_tone_mode tone) |
| 260 | 275 | { |
| 261 | − struct gp8psk_fe_state* state = fe->demodulator_priv; | |
| 276 | + struct gp8psk_fe_state *st = fe->demodulator_priv; | |
| 262 | 277 | |
| 263 | − if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE, | |
| 264 | − (tone == SEC_TONE_ON), 0, NULL, 0)) { | |
| 278 | + if (st->ops->out(st->priv, SET_22KHZ_TONE, | |
| 279 | + (tone == SEC_TONE_ON), 0, NULL, 0)) { | |
| 265 | 280 | return -EINVAL; |
| 266 | 281 | } |
| 267 | 282 | return 0; |
| @@ -270,9 +285,9 @@ static int gp8psk_fe_set_tone(struct dvb_frontend *fe, · 2 unmodified lines | ||
| 270 | 285 | static int gp8psk_fe_set_voltage(struct dvb_frontend *fe, |
| 271 | 286 | enum fe_sec_voltage voltage) |
| 272 | 287 | { |
| 273 | − struct gp8psk_fe_state* state = fe->demodulator_priv; | |
| 288 | + struct gp8psk_fe_state *st = fe->demodulator_priv; | |
| 274 | 289 | |
| 275 | − if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, | |
| 290 | + if (st->ops->out(st->priv, SET_LNB_VOLTAGE, | |
| 276 | 291 | voltage == SEC_VOLTAGE_18, 0, NULL, 0)) { |
| 277 | 292 | return -EINVAL; |
| 278 | 293 | } |
| @@ -281,52 +296,60 @@ static int gp8psk_fe_set_voltage(struct dvb_frontend *fe, · 2 unmodified lines | ||
| 281 | 296 | |
| 282 | 297 | static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff) |
| 283 | 298 | { |
| 284 | − struct gp8psk_fe_state* state = fe->demodulator_priv; | |
| 285 | − return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0); | |
| 299 | + struct gp8psk_fe_state *st = fe->demodulator_priv; | |
| 300 | + | |
| 301 | + return st->ops->out(st->priv, USE_EXTRA_VOLT, onoff, 0, NULL, 0); | |
| 286 | 302 | } |
| 287 | 303 | |
| 288 | 304 | static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd) |
| 289 | 305 | { |
| 290 | − struct gp8psk_fe_state* state = fe->demodulator_priv; | |
| 306 | + struct gp8psk_fe_state *st = fe->demodulator_priv; | |
| 291 | 307 | u8 cmd = sw_cmd & 0x7f; |
| 292 | 308 | |
| 293 | − if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0, | |
| 294 | − NULL, 0)) { | |
| 309 | + if (st->ops->out(st->priv, SET_DN_SWITCH, cmd, 0, NULL, 0)) | |
| 295 | 310 | return -EINVAL; |
| 296 | − } | |
| 297 | − if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80), | |
| 298 | − 0, NULL, 0)) { | |
| 311 | + | |
| 312 | + if (st->ops->out(st->priv, SET_LNB_VOLTAGE, !!(sw_cmd & 0x80), | |
| 313 | + 0, NULL, 0)) | |
| 299 | 314 | return -EINVAL; |
| 300 | − } | |
| 301 | 315 | |
| 302 | 316 | return 0; |
| 303 | 317 | } |
| 304 | 318 | |
| 305 | 319 | static void gp8psk_fe_release(struct dvb_frontend* fe) |
| 306 | 320 | { |
| 307 | − struct gp8psk_fe_state *state = fe->demodulator_priv; | |
| 308 | − kfree(state); | |
| 321 | + struct gp8psk_fe_state *st = fe->demodulator_priv; | |
| 322 | + | |
| 323 | + kfree(st); | |
| 309 | 324 | } |
| 310 | 325 | |
| 311 | 326 | static struct dvb_frontend_ops gp8psk_fe_ops; |
| 312 | 327 | |
| 313 | −struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d) | |
| 328 | +struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops, | |
| 329 | + void *priv, bool is_rev1) | |
| 314 | 330 | { |
| 315 | − struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL); | |
| 316 | − if (s == NULL) | |
| 317 | − goto error; | |
| 318 | − | |
| 319 | − s->d = d; | |
| 320 | − memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops)); | |
| 321 | − s->fe.demodulator_priv = s; | |
| 322 | − | |
| 323 | − goto success; | |
| 324 | −error: | |
| 325 | − return NULL; | |
| 326 | −success: | |
| 327 | − return &s->fe; | |
| 328 | −} | |
| 331 | + struct gp8psk_fe_state *st; | |
| 329 | 332 | |
| 333 | + if (!ops || !ops->in || !ops->out || !ops->reload) { | |
| 334 | + pr_err("Error! gp8psk-fe ops not defined.\n"); | |
| 335 | + return NULL; | |
| 336 | + } | |
| 337 | + | |
| 338 | + st = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL); | |
| 339 | + if (!st) | |
| 340 | + return NULL; | |
| 341 | + | |
| 342 | + memcpy(&st->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops)); | |
| 343 | + st->fe.demodulator_priv = st; | |
| 344 | + st->ops = ops; | |
| 345 | + st->priv = priv; | |
| 346 | + st->is_rev1 = is_rev1; | |
| 347 | + | |
| 348 | + pr_info("Frontend %sattached\n", is_rev1 ? "revision 1 " : ""); | |
| 349 | + | |
| 350 | + return &st->fe; | |
| 351 | +} | |
| 352 | +EXPORT_SYMBOL_GPL(gp8psk_fe_attach); | |
| 330 | 353 | |
| 331 | 354 | static struct dvb_frontend_ops gp8psk_fe_ops = { |
| 332 | 355 | .delsys = { SYS_DVBS }, |
| @@ -370,3 +393,8 @@ static struct dvb_frontend_ops gp8psk_fe_ops = { · 37 unmodified lines | ||
| 370 | 393 | .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd, |
| 371 | 394 | .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage |
| 372 | 395 | }; |
| 396 | + | |
| 397 | +MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>"); | |
| 398 | +MODULE_DESCRIPTION("Frontend Driver for Genpix DVB-S"); | |
| 399 | +MODULE_VERSION("1.1"); | |
| 400 | +MODULE_LICENSE("GPL"); | |
| @@ -0,0 +1,82 @@ | ||
| 1 | +/* | |
| 2 | + * gp8psk_fe driver | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify | |
| 5 | + * it under the terms of the GNU General Public License as published by | |
| 6 | + * the Free Software Foundation; either version 2, or (at your option) | |
| 7 | + * any later version. | |
| 8 | + * | |
| 9 | + * This program is distributed in the hope that it will be useful, | |
| 10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | + * GNU General Public License for more details. | |
| 13 | + */ | |
| 14 | + | |
| 15 | +#ifndef GP8PSK_FE_H | |
| 16 | +#define GP8PSK_FE_H | |
| 17 | + | |
| 18 | +#include <linux/types.h> | |
| 19 | + | |
| 20 | +/* gp8psk commands */ | |
| 21 | + | |
| 22 | +#define GET_8PSK_CONFIG 0x80 /* in */ | |
| 23 | +#define SET_8PSK_CONFIG 0x81 | |
| 24 | +#define I2C_WRITE 0x83 | |
| 25 | +#define I2C_READ 0x84 | |
| 26 | +#define ARM_TRANSFER 0x85 | |
| 27 | +#define TUNE_8PSK 0x86 | |
| 28 | +#define GET_SIGNAL_STRENGTH 0x87 /* in */ | |
| 29 | +#define LOAD_BCM4500 0x88 | |
| 30 | +#define BOOT_8PSK 0x89 /* in */ | |
| 31 | +#define START_INTERSIL 0x8A /* in */ | |
| 32 | +#define SET_LNB_VOLTAGE 0x8B | |
| 33 | +#define SET_22KHZ_TONE 0x8C | |
| 34 | +#define SEND_DISEQC_COMMAND 0x8D | |
| 35 | +#define SET_DVB_MODE 0x8E | |
| 36 | +#define SET_DN_SWITCH 0x8F | |
| 37 | +#define GET_SIGNAL_LOCK 0x90 /* in */ | |
| 38 | +#define GET_FW_VERS 0x92 | |
| 39 | +#define GET_SERIAL_NUMBER 0x93 /* in */ | |
| 40 | +#define USE_EXTRA_VOLT 0x94 | |
| 41 | +#define GET_FPGA_VERS 0x95 | |
| 42 | +#define CW3K_INIT 0x9d | |
| 43 | + | |
| 44 | +/* PSK_configuration bits */ | |
| 45 | +#define bm8pskStarted 0x01 | |
| 46 | +#define bm8pskFW_Loaded 0x02 | |
| 47 | +#define bmIntersilOn 0x04 | |
| 48 | +#define bmDVBmode 0x08 | |
| 49 | +#define bm22kHz 0x10 | |
| 50 | +#define bmSEL18V 0x20 | |
| 51 | +#define bmDCtuned 0x40 | |
| 52 | +#define bmArmed 0x80 | |
| 53 | + | |
| 54 | +/* Satellite modulation modes */ | |
| 55 | +#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */ | |
| 56 | +#define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */ | |
| 57 | +#define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */ | |
| 58 | +#define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */ | |
| 59 | + | |
| 60 | +#define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */ | |
| 61 | +#define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */ | |
| 62 | +#define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */ | |
| 63 | +#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */ | |
| 64 | +#define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */ | |
| 65 | +#define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */ | |
| 66 | + | |
| 67 | +/* firmware revision id's */ | |
| 68 | +#define GP8PSK_FW_REV1 0x020604 | |
| 69 | +#define GP8PSK_FW_REV2 0x020704 | |
| 70 | +#define GP8PSK_FW_VERS(_fw_vers) \ | |
| 71 | + ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0]) | |
| 72 | + | |
| 73 | +struct gp8psk_fe_ops { | |
| 74 | + int (*in)(void *priv, u8 req, u16 value, u16 index, u8 *b, int blen); | |
| 75 | + int (*out)(void *priv, u8 req, u16 value, u16 index, u8 *b, int blen); | |
| 76 | + int (*reload)(void *priv); | |
| 77 | +}; | |
| 78 | + | |
| 79 | +struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops, | |
| 80 | + void *priv, bool is_rev1); | |
| 81 | + | |
| 82 | +#endif | |
| @@ -118,7 +118,7 @@ static int get_key_haup_common(struct IR_i2c *ir, enum rc_type *protocol, · 117 unmodified lines | ||
| 118 | 118 | *protocol = RC_TYPE_RC6_MCE; |
| 119 | 119 | dev &= 0x7f; |
| 120 | 120 | dprintk(1, "ir hauppauge (rc6-mce): t%d vendor=%d dev=%d code=%d\n", |
| 121 | − toggle, vendor, dev, code); | |
| 121 | + *ptoggle, vendor, dev, code); | |
| 122 | 122 | } else { |
| 123 | 123 | *ptoggle = 0; |
| 124 | 124 | *protocol = RC_TYPE_RC6_6A_32; |
| @@ -8,7 +8,7 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o · 7 unmodified lines | ||
| 8 | 8 | dvb-usb-vp702x-objs := vp702x.o vp702x-fe.o |
| 9 | 9 | obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o |
| 10 | 10 | |
| 11 | −dvb-usb-gp8psk-objs := gp8psk.o gp8psk-fe.o | |
| 11 | +dvb-usb-gp8psk-objs := gp8psk.o | |
| 12 | 12 | obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o |
| 13 | 13 | |
| 14 | 14 | dvb-usb-dtt200u-objs := dtt200u.o dtt200u-fe.o |
| @@ -53,7 +53,6 @@ struct af9005_device_state { · 52 unmodified lines | ||
| 53 | 53 | u8 sequence; |
| 54 | 54 | int led_state; |
| 55 | 55 | unsigned char data[256]; |
| 56 | − struct mutex data_mutex; | |
| 57 | 56 | }; |
| 58 | 57 | |
| 59 | 58 | static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, |
| @@ -72,7 +71,7 @@ static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, · 12 unmodified lines | ||
| 72 | 71 | return -EINVAL; |
| 73 | 72 | } |
| 74 | 73 | |
| 75 | − mutex_lock(&st->data_mutex); | |
| 74 | + mutex_lock(&d->data_mutex); | |
| 76 | 75 | st->data[0] = 14; /* rest of buffer length low */ |
| 77 | 76 | st->data[1] = 0; /* rest of buffer length high */ |
| 78 | 77 | |
| @@ -140,7 +139,7 @@ static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, · 61 unmodified lines | ||
| 140 | 139 | values[i] = st->data[8 + i]; |
| 141 | 140 | |
| 142 | 141 | ret: |
| 143 | − mutex_unlock(&st->data_mutex); | |
| 142 | + mutex_unlock(&d->data_mutex); | |
| 144 | 143 | return ret; |
| 145 | 144 | |
| 146 | 145 | } |
| @@ -481,7 +480,7 @@ int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf, · 334 unmodified lines | ||
| 481 | 480 | } |
| 482 | 481 | packet_len = wlen + 5; |
| 483 | 482 | |
| 484 | − mutex_lock(&st->data_mutex); | |
| 483 | + mutex_lock(&d->data_mutex); | |
| 485 | 484 | |
| 486 | 485 | st->data[0] = (u8) (packet_len & 0xff); |
| 487 | 486 | st->data[1] = (u8) ((packet_len & 0xff00) >> 8); |
| @@ -512,7 +511,7 @@ int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf, · 24 unmodified lines | ||
| 512 | 511 | rbuf[i] = st->data[i + 7]; |
| 513 | 512 | } |
| 514 | 513 | |
| 515 | − mutex_unlock(&st->data_mutex); | |
| 514 | + mutex_unlock(&d->data_mutex); | |
| 516 | 515 | return ret; |
| 517 | 516 | } |
| 518 | 517 | |
| @@ -523,7 +522,7 @@ int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values, · 4 unmodified lines | ||
| 523 | 522 | u8 seq; |
| 524 | 523 | int ret, i; |
| 525 | 524 | |
| 526 | − mutex_lock(&st->data_mutex); | |
| 525 | + mutex_lock(&d->data_mutex); | |
| 527 | 526 | |
| 528 | 527 | memset(st->data, 0, sizeof(st->data)); |
| 529 | 528 | |
| @@ -559,7 +558,7 @@ int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values, · 29 unmodified lines | ||
| 559 | 558 | for (i = 0; i < len; i++) |
| 560 | 559 | values[i] = st->data[6 + i]; |
| 561 | 560 | } |
| 562 | − mutex_unlock(&st->data_mutex); | |
| 561 | + mutex_unlock(&d->data_mutex); | |
| 563 | 562 | |
| 564 | 563 | return ret; |
| 565 | 564 | } |
| @@ -847,7 +846,7 @@ static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state) · 281 unmodified lines | ||
| 847 | 846 | return 0; |
| 848 | 847 | } |
| 849 | 848 | |
| 850 | − mutex_lock(&st->data_mutex); | |
| 849 | + mutex_lock(&d->data_mutex); | |
| 851 | 850 | |
| 852 | 851 | /* deb_info("rc_query\n"); */ |
| 853 | 852 | st->data[0] = 3; /* rest of packet length low */ |
| @@ -890,7 +889,7 @@ static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state) · 36 unmodified lines | ||
| 890 | 889 | } |
| 891 | 890 | |
| 892 | 891 | ret: |
| 893 | − mutex_unlock(&st->data_mutex); | |
| 892 | + mutex_unlock(&d->data_mutex); | |
| 894 | 893 | return ret; |
| 895 | 894 | } |
| 896 | 895 | |
| @@ -1004,20 +1003,8 @@ static struct dvb_usb_device_properties af9005_properties; · 107 unmodified lines | ||
| 1004 | 1003 | static int af9005_usb_probe(struct usb_interface *intf, |
| 1005 | 1004 | const struct usb_device_id *id) |
| 1006 | 1005 | { |
| 1007 | − struct dvb_usb_device *d; | |
| 1008 | − struct af9005_device_state *st; | |
| 1009 | − int ret; | |
| 1010 | − | |
| 1011 | − ret = dvb_usb_device_init(intf, &af9005_properties, | |
| 1012 | − THIS_MODULE, &d, adapter_nr); | |
| 1013 | − | |
| 1014 | − if (ret < 0) | |
| 1015 | − return ret; | |
| 1016 | − | |
| 1017 | − st = d->priv; | |
| 1018 | − mutex_init(&st->data_mutex); | |
| 1019 | − | |
| 1020 | − return 0; | |
| 1006 | + return dvb_usb_device_init(intf, &af9005_properties, | |
| 1007 | + THIS_MODULE, NULL, adapter_nr); | |
| 1021 | 1008 | } |
| 1022 | 1009 | |
| 1023 | 1010 | enum af9005_usb_table_entry { |
| @@ -42,7 +42,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); · 41 unmodified lines | ||
| 42 | 42 | struct cinergyt2_state { |
| 43 | 43 | u8 rc_counter; |
| 44 | 44 | unsigned char data[64]; |
| 45 | − struct mutex data_mutex; | |
| 46 | 45 | }; |
| 47 | 46 | |
| 48 | 47 | /* We are missing a release hook with usb_device data */ |
| @@ -56,12 +55,12 @@ static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable) · 7 unmodified lines | ||
| 56 | 55 | struct cinergyt2_state *st = d->priv; |
| 57 | 56 | int ret; |
| 58 | 57 | |
| 59 | − mutex_lock(&st->data_mutex); | |
| 58 | + mutex_lock(&d->data_mutex); | |
| 60 | 59 | st->data[0] = CINERGYT2_EP1_CONTROL_STREAM_TRANSFER; |
| 61 | 60 | st->data[1] = enable ? 1 : 0; |
| 62 | 61 | |
| 63 | 62 | ret = dvb_usb_generic_rw(d, st->data, 2, st->data, 64, 0); |
| 64 | − mutex_unlock(&st->data_mutex); | |
| 63 | + mutex_unlock(&d->data_mutex); | |
| 65 | 64 | |
| 66 | 65 | return ret; |
| 67 | 66 | } |
| @@ -71,12 +70,12 @@ static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable) · 3 unmodified lines | ||
| 71 | 70 | struct cinergyt2_state *st = d->priv; |
| 72 | 71 | int ret; |
| 73 | 72 | |
| 74 | − mutex_lock(&st->data_mutex); | |
| 73 | + mutex_lock(&d->data_mutex); | |
| 75 | 74 | st->data[0] = CINERGYT2_EP1_SLEEP_MODE; |
| 76 | 75 | st->data[1] = enable ? 0 : 1; |
| 77 | 76 | |
| 78 | 77 | ret = dvb_usb_generic_rw(d, st->data, 2, st->data, 3, 0); |
| 79 | − mutex_unlock(&st->data_mutex); | |
| 78 | + mutex_unlock(&d->data_mutex); | |
| 80 | 79 | |
| 81 | 80 | return ret; |
| 82 | 81 | } |
| @@ -89,7 +88,7 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) · 6 unmodified lines | ||
| 89 | 88 | |
| 90 | 89 | adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev); |
| 91 | 90 | |
| 92 | − mutex_lock(&st->data_mutex); | |
| 91 | + mutex_lock(&d->data_mutex); | |
| 93 | 92 | st->data[0] = CINERGYT2_EP1_GET_FIRMWARE_VERSION; |
| 94 | 93 | |
| 95 | 94 | ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0); |
| @@ -97,7 +96,7 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) · 1 unmodified line | ||
| 97 | 96 | deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep " |
| 98 | 97 | "state info\n"); |
| 99 | 98 | } |
| 100 | − mutex_unlock(&st->data_mutex); | |
| 99 | + mutex_unlock(&d->data_mutex); | |
| 101 | 100 | |
| 102 | 101 | /* Copy this pointer as we are gonna need it in the release phase */ |
| 103 | 102 | cinergyt2_usb_device = adap->dev; |
| @@ -166,7 +165,7 @@ static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) · 62 unmodified lines | ||
| 166 | 165 | |
| 167 | 166 | *state = REMOTE_NO_KEY_PRESSED; |
| 168 | 167 | |
| 169 | − mutex_lock(&st->data_mutex); | |
| 168 | + mutex_lock(&d->data_mutex); | |
| 170 | 169 | st->data[0] = CINERGYT2_EP1_GET_RC_EVENTS; |
| 171 | 170 | |
| 172 | 171 | ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0); |
| @@ -202,29 +201,17 @@ static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) · 29 unmodified lines | ||
| 202 | 201 | } |
| 203 | 202 | |
| 204 | 203 | ret: |
| 205 | − mutex_unlock(&st->data_mutex); | |
| 204 | + mutex_unlock(&d->data_mutex); | |
| 206 | 205 | return ret; |
| 207 | 206 | } |
| 208 | 207 | |
| 209 | 208 | static int cinergyt2_usb_probe(struct usb_interface *intf, |
| 210 | 209 | const struct usb_device_id *id) |
| 211 | 210 | { |
| 212 | − struct dvb_usb_device *d; | |
| 213 | − struct cinergyt2_state *st; | |
| 214 | − int ret; | |
| 215 | − | |
| 216 | − ret = dvb_usb_device_init(intf, &cinergyt2_properties, | |
| 217 | − THIS_MODULE, &d, adapter_nr); | |
| 218 | − if (ret < 0) | |
| 219 | − return ret; | |
| 220 | − | |
| 221 | − st = d->priv; | |
| 222 | − mutex_init(&st->data_mutex); | |
| 223 | − | |
| 224 | − return 0; | |
| 211 | + return dvb_usb_device_init(intf, &cinergyt2_properties, | |
| 212 | + THIS_MODULE, NULL, adapter_nr); | |
| 225 | 213 | } |
| 226 | 214 | |
| 227 | − | |
| 228 | 215 | static struct usb_device_id cinergyt2_usb_table[] = { |
| 229 | 216 | { USB_DEVICE(USB_VID_TERRATEC, 0x0038) }, |
| 230 | 217 | { 0 } |
| @@ -68,7 +68,7 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d, · 67 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | wo = (rbuf == NULL || rlen == 0); /* write-only */ |
| 70 | 70 | |
| 71 | − mutex_lock(&st->data_mutex); | |
| 71 | + mutex_lock(&d->data_mutex); | |
| 72 | 72 | st->data[0] = cmd; |
| 73 | 73 | memcpy(&st->data[1], wbuf, wlen); |
| 74 | 74 | if (wo) |
| @@ -77,7 +77,7 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d, · 2 unmodified lines | ||
| 77 | 77 | ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, |
| 78 | 78 | rbuf, rlen, 0); |
| 79 | 79 | |
| 80 | − mutex_unlock(&st->data_mutex); | |
| 80 | + mutex_unlock(&d->data_mutex); | |
| 81 | 81 | return ret; |
| 82 | 82 | } |
| 83 | 83 | |
| @@ -1461,43 +1461,36 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties; · 1377 unmodified lines | ||
| 1461 | 1461 | static int cxusb_probe(struct usb_interface *intf, |
| 1462 | 1462 | const struct usb_device_id *id) |
| 1463 | 1463 | { |
| 1464 | − struct dvb_usb_device *d; | |
| 1465 | − struct cxusb_state *st; | |
| 1466 | − | |
| 1467 | 1464 | if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties, |
| 1468 | − THIS_MODULE, &d, adapter_nr) || | |
| 1465 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1469 | 1466 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties, |
| 1470 | − THIS_MODULE, &d, adapter_nr) || | |
| 1467 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1471 | 1468 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties, |
| 1472 | − THIS_MODULE, &d, adapter_nr) || | |
| 1469 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1473 | 1470 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties, |
| 1474 | − THIS_MODULE, &d, adapter_nr) || | |
| 1471 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1475 | 1472 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties, |
| 1476 | − THIS_MODULE, &d, adapter_nr) || | |
| 1473 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1477 | 1474 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties, |
| 1478 | − THIS_MODULE, &d, adapter_nr) || | |
| 1475 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1479 | 1476 | 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties, |
| 1480 | − THIS_MODULE, &d, adapter_nr) || | |
| 1477 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1481 | 1478 | 0 == dvb_usb_device_init(intf, |
| 1482 | 1479 | &cxusb_bluebird_nano2_needsfirmware_properties, |
| 1483 | − THIS_MODULE, &d, adapter_nr) || | |
| 1480 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1484 | 1481 | 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, |
| 1485 | − THIS_MODULE, &d, adapter_nr) || | |
| 1482 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1486 | 1483 | 0 == dvb_usb_device_init(intf, |
| 1487 | 1484 | &cxusb_bluebird_dualdig4_rev2_properties, |
| 1488 | − THIS_MODULE, &d, adapter_nr) || | |
| 1485 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1489 | 1486 | 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, |
| 1490 | − THIS_MODULE, &d, adapter_nr) || | |
| 1487 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1491 | 1488 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, |
| 1492 | − THIS_MODULE, &d, adapter_nr) || | |
| 1489 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1493 | 1490 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, |
| 1494 | − THIS_MODULE, &d, adapter_nr) || | |
| 1495 | − 0) { | |
| 1496 | − st = d->priv; | |
| 1497 | − mutex_init(&st->data_mutex); | |
| 1498 | − | |
| 1491 | + THIS_MODULE, NULL, adapter_nr) || | |
| 1492 | + 0) | |
| 1499 | 1493 | return 0; |
| 1500 | − } | |
| 1501 | 1494 | |
| 1502 | 1495 | return -EINVAL; |
| 1503 | 1496 | } |
| @@ -37,7 +37,6 @@ struct cxusb_state { · 36 unmodified lines | ||
| 37 | 37 | struct i2c_client *i2c_client_tuner; |
| 38 | 38 | |
| 39 | 39 | unsigned char data[MAX_XFER_SIZE]; |
| 40 | − struct mutex data_mutex; | |
| 41 | 40 | }; |
| 42 | 41 | |
| 43 | 42 | #endif |
| @@ -704,7 +704,7 @@ static void dib0700_rc_urb_completion(struct urb *purb) · 703 unmodified lines | ||
| 704 | 704 | struct dvb_usb_device *d = purb->context; |
| 705 | 705 | struct dib0700_rc_response *poll_reply; |
| 706 | 706 | enum rc_type protocol; |
| 707 | − u32 uninitialized_var(keycode); | |
| 707 | + u32 keycode; | |
| 708 | 708 | u8 toggle; |
| 709 | 709 | |
| 710 | 710 | deb_info("%s()\n", __func__); |
| @@ -745,7 +745,8 @@ static void dib0700_rc_urb_completion(struct urb *purb) · 34 unmodified lines | ||
| 745 | 745 | poll_reply->nec.data == 0x00 && |
| 746 | 746 | poll_reply->nec.not_data == 0xff) { |
| 747 | 747 | poll_reply->data_state = 2; |
| 748 | − break; | |
| 748 | + rc_repeat(d->rc_dev); | |
| 749 | + goto resubmit; | |
| 749 | 750 | } |
| 750 | 751 | |
| 751 | 752 | if ((poll_reply->nec.data ^ poll_reply->nec.not_data) != 0xff) { |
| @@ -22,7 +22,6 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | struct dtt200u_state { |
| 24 | 24 | unsigned char data[80]; |
| 25 | − struct mutex data_mutex; | |
| 26 | 25 | }; |
| 27 | 26 | |
| 28 | 27 | static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff) |
| @@ -30,23 +29,24 @@ static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff) · 1 unmodified line | ||
| 30 | 29 | struct dtt200u_state *st = d->priv; |
| 31 | 30 | int ret = 0; |
| 32 | 31 | |
| 33 | − mutex_lock(&st->data_mutex); | |
| 32 | + mutex_lock(&d->data_mutex); | |
| 34 | 33 | |
| 35 | 34 | st->data[0] = SET_INIT; |
| 36 | 35 | |
| 37 | 36 | if (onoff) |
| 38 | 37 | ret = dvb_usb_generic_write(d, st->data, 2); |
| 39 | 38 | |
| 40 | − mutex_unlock(&st->data_mutex); | |
| 39 | + mutex_unlock(&d->data_mutex); | |
| 41 | 40 | return ret; |
| 42 | 41 | } |
| 43 | 42 | |
| 44 | 43 | static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) |
| 45 | 44 | { |
| 46 | − struct dtt200u_state *st = adap->dev->priv; | |
| 45 | + struct dvb_usb_device *d = adap->dev; | |
| 46 | + struct dtt200u_state *st = d->priv; | |
| 47 | 47 | int ret; |
| 48 | 48 | |
| 49 | − mutex_lock(&st->data_mutex); | |
| 49 | + mutex_lock(&d->data_mutex); | |
| 50 | 50 | st->data[0] = SET_STREAMING; |
| 51 | 51 | st->data[1] = onoff; |
| 52 | 52 | |
| @@ -61,26 +61,27 @@ static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) · 8 unmodified lines | ||
| 61 | 61 | ret = dvb_usb_generic_write(adap->dev, st->data, 1); |
| 62 | 62 | |
| 63 | 63 | ret: |
| 64 | − mutex_unlock(&st->data_mutex); | |
| 64 | + mutex_unlock(&d->data_mutex); | |
| 65 | 65 | |
| 66 | 66 | return ret; |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | 69 | static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) |
| 70 | 70 | { |
| 71 | − struct dtt200u_state *st = adap->dev->priv; | |
| 71 | + struct dvb_usb_device *d = adap->dev; | |
| 72 | + struct dtt200u_state *st = d->priv; | |
| 72 | 73 | int ret; |
| 73 | 74 | |
| 74 | 75 | pid = onoff ? pid : 0; |
| 75 | 76 | |
| 76 | − mutex_lock(&st->data_mutex); | |
| 77 | + mutex_lock(&d->data_mutex); | |
| 77 | 78 | st->data[0] = SET_PID_FILTER; |
| 78 | 79 | st->data[1] = index; |
| 79 | 80 | st->data[2] = pid & 0xff; |
| 80 | 81 | st->data[3] = (pid >> 8) & 0x1f; |
| 81 | 82 | |
| 82 | 83 | ret = dvb_usb_generic_write(adap->dev, st->data, 4); |
| 83 | − mutex_unlock(&st->data_mutex); | |
| 84 | + mutex_unlock(&d->data_mutex); | |
| 84 | 85 | |
| 85 | 86 | return ret; |
| 86 | 87 | } |
| @@ -91,7 +92,7 @@ static int dtt200u_rc_query(struct dvb_usb_device *d) · 4 unmodified lines | ||
| 91 | 92 | u32 scancode; |
| 92 | 93 | int ret; |
| 93 | 94 | |
| 94 | − mutex_lock(&st->data_mutex); | |
| 95 | + mutex_lock(&d->data_mutex); | |
| 95 | 96 | st->data[0] = GET_RC_CODE; |
| 96 | 97 | |
| 97 | 98 | ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 5, 0); |
| @@ -126,7 +127,7 @@ static int dtt200u_rc_query(struct dvb_usb_device *d) · 28 unmodified lines | ||
| 126 | 127 | deb_info("st->data: %*ph\n", 5, st->data); |
| 127 | 128 | |
| 128 | 129 | ret: |
| 129 | − mutex_unlock(&st->data_mutex); | |
| 130 | + mutex_unlock(&d->data_mutex); | |
| 130 | 131 | return ret; |
| 131 | 132 | } |
| 132 | 133 | |
| @@ -145,24 +146,17 @@ static struct dvb_usb_device_properties wt220u_miglia_properties; · 12 unmodified lines | ||
| 145 | 146 | static int dtt200u_usb_probe(struct usb_interface *intf, |
| 146 | 147 | const struct usb_device_id *id) |
| 147 | 148 | { |
| 148 | − struct dvb_usb_device *d; | |
| 149 | − struct dtt200u_state *st; | |
| 150 | − | |
| 151 | 149 | if (0 == dvb_usb_device_init(intf, &dtt200u_properties, |
| 152 | − THIS_MODULE, &d, adapter_nr) || | |
| 150 | + THIS_MODULE, NULL, adapter_nr) || | |
| 153 | 151 | 0 == dvb_usb_device_init(intf, &wt220u_properties, |
| 154 | − THIS_MODULE, &d, adapter_nr) || | |
| 152 | + THIS_MODULE, NULL, adapter_nr) || | |
| 155 | 153 | 0 == dvb_usb_device_init(intf, &wt220u_fc_properties, |
| 156 | − THIS_MODULE, &d, adapter_nr) || | |
| 154 | + THIS_MODULE, NULL, adapter_nr) || | |
| 157 | 155 | 0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties, |
| 158 | − THIS_MODULE, &d, adapter_nr) || | |
| 156 | + THIS_MODULE, NULL, adapter_nr) || | |
| 159 | 157 | 0 == dvb_usb_device_init(intf, &wt220u_miglia_properties, |
| 160 | − THIS_MODULE, &d, adapter_nr)) { | |
| 161 | − st = d->priv; | |
| 162 | − mutex_init(&st->data_mutex); | |
| 163 | − | |
| 158 | + THIS_MODULE, NULL, adapter_nr)) | |
| 164 | 159 | return 0; |
| 165 | − } | |
| 166 | 160 | |
| 167 | 161 | return -ENODEV; |
| 168 | 162 | } |
| @@ -142,6 +142,7 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums) · 141 unmodified lines | ||
| 142 | 142 | { |
| 143 | 143 | int ret = 0; |
| 144 | 144 | |
| 145 | + mutex_init(&d->data_mutex); | |
| 145 | 146 | mutex_init(&d->usb_mutex); |
| 146 | 147 | mutex_init(&d->i2c_mutex); |
| 147 | 148 | |
| @@ -404,8 +404,12 @@ struct dvb_usb_adapter { · 403 unmodified lines | ||
| 404 | 404 | * Powered is in/decremented for each call to modify the state. |
| 405 | 405 | * @udev: pointer to the device's struct usb_device. |
| 406 | 406 | * |
| 407 | − * @usb_mutex: semaphore of USB control messages (reading needs two messages) | |
| 408 | − * @i2c_mutex: semaphore for i2c-transfers | |
| 407 | + * @data_mutex: mutex to protect the data structure used to store URB data | |
| 408 | + * @usb_mutex: mutex of USB control messages (reading needs two messages). | |
| 409 | + * Please notice that this mutex is used internally at the generic | |
| 410 | + * URB control functions. So, drivers using dvb_usb_generic_rw() and | |
| 411 | + * derivated functions should not lock it internally. | |
| 412 | + * @i2c_mutex: mutex for i2c-transfers | |
| 409 | 413 | * |
| 410 | 414 | * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB |
| 411 | 415 | * |
| @@ -433,6 +437,7 @@ struct dvb_usb_device { · 21 unmodified lines | ||
| 433 | 437 | int powered; |
| 434 | 438 | |
| 435 | 439 | /* locking */ |
| 440 | + struct mutex data_mutex; | |
| 436 | 441 | struct mutex usb_mutex; |
| 437 | 442 | |
| 438 | 443 | /* i2c */ |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | * see Documentation/dvb/README.dvb-usb for more information |
| 16 | 16 | */ |
| 17 | 17 | #include "gp8psk.h" |
| 18 | +#include "gp8psk-fe.h" | |
| 18 | 19 | |
| 19 | 20 | /* debug */ |
| 20 | 21 | static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw"; |
| @@ -28,34 +29,8 @@ struct gp8psk_state { · 7 unmodified lines | ||
| 28 | 29 | unsigned char data[80]; |
| 29 | 30 | }; |
| 30 | 31 | |
| 31 | −static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers) | |
| 32 | −{ | |
| 33 | − return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6)); | |
| 34 | −} | |
| 35 | − | |
| 36 | −static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers) | |
| 37 | −{ | |
| 38 | − return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1)); | |
| 39 | −} | |
| 40 | − | |
| 41 | −static void gp8psk_info(struct dvb_usb_device *d) | |
| 42 | −{ | |
| 43 | − u8 fpga_vers, fw_vers[6]; | |
| 44 | − | |
| 45 | − if (!gp8psk_get_fw_version(d, fw_vers)) | |
| 46 | − info("FW Version = %i.%02i.%i (0x%x) Build %4i/%02i/%02i", | |
| 47 | − fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers), | |
| 48 | − 2000 + fw_vers[5], fw_vers[4], fw_vers[3]); | |
| 49 | − else | |
| 50 | − info("failed to get FW version"); | |
| 51 | − | |
| 52 | − if (!gp8psk_get_fpga_version(d, &fpga_vers)) | |
| 53 | − info("FPGA Version = %i", fpga_vers); | |
| 54 | − else | |
| 55 | − info("failed to get FPGA version"); | |
| 56 | −} | |
| 57 | − | |
| 58 | −int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) | |
| 32 | +static int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, | |
| 33 | + u16 index, u8 *b, int blen) | |
| 59 | 34 | { |
| 60 | 35 | struct gp8psk_state *st = d->priv; |
| 61 | 36 | int ret = 0,try = 0; |
| @@ -67,7 +42,6 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 · 5 unmodified lines | ||
| 67 | 42 | return ret; |
| 68 | 43 | |
| 69 | 44 | while (ret >= 0 && ret != blen && try < 3) { |
| 70 | − memcpy(st->data, b, blen); | |
| 71 | 45 | ret = usb_control_msg(d->udev, |
| 72 | 46 | usb_rcvctrlpipe(d->udev,0), |
| 73 | 47 | req, |
| @@ -81,8 +55,10 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 · 7 unmodified lines | ||
| 81 | 55 | if (ret < 0 || ret != blen) { |
| 82 | 56 | warn("usb in %d operation failed.", req); |
| 83 | 57 | ret = -EIO; |
| 84 | − } else | |
| 58 | + } else { | |
| 85 | 59 | ret = 0; |
| 60 | + memcpy(b, st->data, blen); | |
| 61 | + } | |
| 86 | 62 | |
| 87 | 63 | deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index); |
| 88 | 64 | debug_dump(b,blen,deb_xfer); |
| @@ -92,7 +68,7 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 · 3 unmodified lines | ||
| 92 | 68 | return ret; |
| 93 | 69 | } |
| 94 | 70 | |
| 95 | −int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, | |
| 71 | +static int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, | |
| 96 | 72 | u16 index, u8 *b, int blen) |
| 97 | 73 | { |
| 98 | 74 | struct gp8psk_state *st = d->priv; |
| @@ -123,6 +99,34 @@ int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, · 24 unmodified lines | ||
| 123 | 99 | return ret; |
| 124 | 100 | } |
| 125 | 101 | |
| 102 | + | |
| 103 | +static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers) | |
| 104 | +{ | |
| 105 | + return gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6); | |
| 106 | +} | |
| 107 | + | |
| 108 | +static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers) | |
| 109 | +{ | |
| 110 | + return gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1); | |
| 111 | +} | |
| 112 | + | |
| 113 | +static void gp8psk_info(struct dvb_usb_device *d) | |
| 114 | +{ | |
| 115 | + u8 fpga_vers, fw_vers[6]; | |
| 116 | + | |
| 117 | + if (!gp8psk_get_fw_version(d, fw_vers)) | |
| 118 | + info("FW Version = %i.%02i.%i (0x%x) Build %4i/%02i/%02i", | |
| 119 | + fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers), | |
| 120 | + 2000 + fw_vers[5], fw_vers[4], fw_vers[3]); | |
| 121 | + else | |
| 122 | + info("failed to get FW version"); | |
| 123 | + | |
| 124 | + if (!gp8psk_get_fpga_version(d, &fpga_vers)) | |
| 125 | + info("FPGA Version = %i", fpga_vers); | |
| 126 | + else | |
| 127 | + info("failed to get FPGA version"); | |
| 128 | +} | |
| 129 | + | |
| 126 | 130 | static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d) |
| 127 | 131 | { |
| 128 | 132 | int ret; |
| @@ -225,10 +229,13 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) · 96 unmodified lines | ||
| 225 | 229 | return 0; |
| 226 | 230 | } |
| 227 | 231 | |
| 228 | −int gp8psk_bcm4500_reload(struct dvb_usb_device *d) | |
| 232 | +static int gp8psk_bcm4500_reload(struct dvb_usb_device *d) | |
| 229 | 233 | { |
| 230 | 234 | u8 buf; |
| 231 | 235 | int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct); |
| 236 | + | |
| 237 | + deb_xfer("reloading firmware\n"); | |
| 238 | + | |
| 232 | 239 | /* Turn off 8psk power */ |
| 233 | 240 | if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) |
| 234 | 241 | return -EINVAL; |
| @@ -247,9 +254,47 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) · 12 unmodified lines | ||
| 247 | 254 | return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0); |
| 248 | 255 | } |
| 249 | 256 | |
| 257 | +/* Callbacks for gp8psk-fe.c */ | |
| 258 | + | |
| 259 | +static int gp8psk_fe_in(void *priv, u8 req, u16 value, | |
| 260 | + u16 index, u8 *b, int blen) | |
| 261 | +{ | |
| 262 | + struct dvb_usb_device *d = priv; | |
| 263 | + | |
| 264 | + return gp8psk_usb_in_op(d, req, value, index, b, blen); | |
| 265 | +} | |
| 266 | + | |
| 267 | +static int gp8psk_fe_out(void *priv, u8 req, u16 value, | |
| 268 | + u16 index, u8 *b, int blen) | |
| 269 | +{ | |
| 270 | + struct dvb_usb_device *d = priv; | |
| 271 | + | |
| 272 | + return gp8psk_usb_out_op(d, req, value, index, b, blen); | |
| 273 | +} | |
| 274 | + | |
| 275 | +static int gp8psk_fe_reload(void *priv) | |
| 276 | +{ | |
| 277 | + struct dvb_usb_device *d = priv; | |
| 278 | + | |
| 279 | + return gp8psk_bcm4500_reload(d); | |
| 280 | +} | |
| 281 | + | |
| 282 | +const struct gp8psk_fe_ops gp8psk_fe_ops = { | |
| 283 | + .in = gp8psk_fe_in, | |
| 284 | + .out = gp8psk_fe_out, | |
| 285 | + .reload = gp8psk_fe_reload, | |
| 286 | +}; | |
| 287 | + | |
| 250 | 288 | static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap) |
| 251 | 289 | { |
| 252 | − adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev); | |
| 290 | + struct dvb_usb_device *d = adap->dev; | |
| 291 | + int id = le16_to_cpu(d->udev->descriptor.idProduct); | |
| 292 | + int is_rev1; | |
| 293 | + | |
| 294 | + is_rev1 = (id == USB_PID_GENPIX_8PSK_REV_1_WARM) ? true : false; | |
| 295 | + | |
| 296 | + adap->fe_adap[0].fe = dvb_attach(gp8psk_fe_attach, | |
| 297 | + &gp8psk_fe_ops, d, is_rev1); | |
| 253 | 298 | return 0; |
| 254 | 299 | } |
| 255 | 300 | |
| @@ -24,58 +24,6 @@ extern int dvb_usb_gp8psk_debug; · 23 unmodified lines | ||
| 24 | 24 | #define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args) |
| 25 | 25 | #define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args) |
| 26 | 26 | #define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args) |
| 27 | −#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args) | |
| 28 | − | |
| 29 | −/* Twinhan Vendor requests */ | |
| 30 | −#define TH_COMMAND_IN 0xC0 | |
| 31 | −#define TH_COMMAND_OUT 0xC1 | |
| 32 | − | |
| 33 | −/* gp8psk commands */ | |
| 34 | − | |
| 35 | −#define GET_8PSK_CONFIG 0x80 /* in */ | |
| 36 | −#define SET_8PSK_CONFIG 0x81 | |
| 37 | −#define I2C_WRITE 0x83 | |
| 38 | −#define I2C_READ 0x84 | |
| 39 | −#define ARM_TRANSFER 0x85 | |
| 40 | −#define TUNE_8PSK 0x86 | |
| 41 | −#define GET_SIGNAL_STRENGTH 0x87 /* in */ | |
| 42 | −#define LOAD_BCM4500 0x88 | |
| 43 | −#define BOOT_8PSK 0x89 /* in */ | |
| 44 | −#define START_INTERSIL 0x8A /* in */ | |
| 45 | −#define SET_LNB_VOLTAGE 0x8B | |
| 46 | −#define SET_22KHZ_TONE 0x8C | |
| 47 | −#define SEND_DISEQC_COMMAND 0x8D | |
| 48 | −#define SET_DVB_MODE 0x8E | |
| 49 | −#define SET_DN_SWITCH 0x8F | |
| 50 | −#define GET_SIGNAL_LOCK 0x90 /* in */ | |
| 51 | −#define GET_FW_VERS 0x92 | |
| 52 | −#define GET_SERIAL_NUMBER 0x93 /* in */ | |
| 53 | −#define USE_EXTRA_VOLT 0x94 | |
| 54 | −#define GET_FPGA_VERS 0x95 | |
| 55 | −#define CW3K_INIT 0x9d | |
| 56 | − | |
| 57 | −/* PSK_configuration bits */ | |
| 58 | −#define bm8pskStarted 0x01 | |
| 59 | −#define bm8pskFW_Loaded 0x02 | |
| 60 | −#define bmIntersilOn 0x04 | |
| 61 | −#define bmDVBmode 0x08 | |
| 62 | −#define bm22kHz 0x10 | |
| 63 | −#define bmSEL18V 0x20 | |
| 64 | −#define bmDCtuned 0x40 | |
| 65 | −#define bmArmed 0x80 | |
| 66 | − | |
| 67 | −/* Satellite modulation modes */ | |
| 68 | −#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */ | |
| 69 | −#define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */ | |
| 70 | −#define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */ | |
| 71 | −#define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */ | |
| 72 | − | |
| 73 | −#define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */ | |
| 74 | −#define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */ | |
| 75 | −#define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */ | |
| 76 | −#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */ | |
| 77 | −#define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */ | |
| 78 | −#define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */ | |
| 79 | 27 | |
| 80 | 28 | #define GET_USB_SPEED 0x07 |
| 81 | 29 | |
| @@ -86,15 +34,4 @@ extern int dvb_usb_gp8psk_debug; · 4 unmodified lines | ||
| 86 | 34 | #define PRODUCT_STRING_READ 0x0D |
| 87 | 35 | #define FW_BCD_VERSION_READ 0x14 |
| 88 | 36 | |
| 89 | −/* firmware revision id's */ | |
| 90 | −#define GP8PSK_FW_REV1 0x020604 | |
| 91 | −#define GP8PSK_FW_REV2 0x020704 | |
| 92 | −#define GP8PSK_FW_VERS(_fw_vers) ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0]) | |
| 93 | − | |
| 94 | −extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d); | |
| 95 | −extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); | |
| 96 | −extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, | |
| 97 | − u16 index, u8 *b, int blen); | |
| 98 | −extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d); | |
| 99 | − | |
| 100 | 37 | #endif |
| @@ -123,19 +123,6 @@ static const struct intel_lpss_platform_info apl_i2c_info = { · 122 unmodified lines | ||
| 123 | 123 | .properties = apl_i2c_properties, |
| 124 | 124 | }; |
| 125 | 125 | |
| 126 | −static const struct intel_lpss_platform_info kbl_info = { | |
| 127 | − .clk_rate = 120000000, | |
| 128 | −}; | |
| 129 | − | |
| 130 | −static const struct intel_lpss_platform_info kbl_uart_info = { | |
| 131 | − .clk_rate = 120000000, | |
| 132 | − .clk_con_id = "baudclk", | |
| 133 | −}; | |
| 134 | − | |
| 135 | −static const struct intel_lpss_platform_info kbl_i2c_info = { | |
| 136 | − .clk_rate = 133000000, | |
| 137 | −}; | |
| 138 | − | |
| 139 | 126 | static const struct pci_device_id intel_lpss_pci_ids[] = { |
| 140 | 127 | /* BXT A-Step */ |
| 141 | 128 | { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info }, |
| @@ -207,15 +194,15 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { · 65 unmodified lines | ||
| 207 | 194 | { PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info }, |
| 208 | 195 | { PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info }, |
| 209 | 196 | /* KBL-H */ |
| 210 | − { PCI_VDEVICE(INTEL, 0xa2a7), (kernel_ulong_t)&kbl_uart_info }, | |
| 211 | − { PCI_VDEVICE(INTEL, 0xa2a8), (kernel_ulong_t)&kbl_uart_info }, | |
| 212 | − { PCI_VDEVICE(INTEL, 0xa2a9), (kernel_ulong_t)&kbl_info }, | |
| 213 | − { PCI_VDEVICE(INTEL, 0xa2aa), (kernel_ulong_t)&kbl_info }, | |
| 214 | − { PCI_VDEVICE(INTEL, 0xa2e0), (kernel_ulong_t)&kbl_i2c_info }, | |
| 215 | − { PCI_VDEVICE(INTEL, 0xa2e1), (kernel_ulong_t)&kbl_i2c_info }, | |
| 216 | − { PCI_VDEVICE(INTEL, 0xa2e2), (kernel_ulong_t)&kbl_i2c_info }, | |
| 217 | − { PCI_VDEVICE(INTEL, 0xa2e3), (kernel_ulong_t)&kbl_i2c_info }, | |
| 218 | − { PCI_VDEVICE(INTEL, 0xa2e6), (kernel_ulong_t)&kbl_uart_info }, | |
| 197 | + { PCI_VDEVICE(INTEL, 0xa2a7), (kernel_ulong_t)&spt_uart_info }, | |
| 198 | + { PCI_VDEVICE(INTEL, 0xa2a8), (kernel_ulong_t)&spt_uart_info }, | |
| 199 | + { PCI_VDEVICE(INTEL, 0xa2a9), (kernel_ulong_t)&spt_info }, | |
| 200 | + { PCI_VDEVICE(INTEL, 0xa2aa), (kernel_ulong_t)&spt_info }, | |
| 201 | + { PCI_VDEVICE(INTEL, 0xa2e0), (kernel_ulong_t)&spt_i2c_info }, | |
| 202 | + { PCI_VDEVICE(INTEL, 0xa2e1), (kernel_ulong_t)&spt_i2c_info }, | |
| 203 | + { PCI_VDEVICE(INTEL, 0xa2e2), (kernel_ulong_t)&spt_i2c_info }, | |
| 204 | + { PCI_VDEVICE(INTEL, 0xa2e3), (kernel_ulong_t)&spt_i2c_info }, | |
| 205 | + { PCI_VDEVICE(INTEL, 0xa2e6), (kernel_ulong_t)&spt_uart_info }, | |
| 219 | 206 | { } |
| 220 | 207 | }; |
| 221 | 208 | MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids); |
| @@ -502,9 +502,6 @@ int intel_lpss_suspend(struct device *dev) · 501 unmodified lines | ||
| 502 | 502 | for (i = 0; i < LPSS_PRIV_REG_COUNT; i++) |
| 503 | 503 | lpss->priv_ctx[i] = readl(lpss->priv + i * 4); |
| 504 | 504 | |
| 505 | − /* Put the device into reset state */ | |
| 506 | − writel(0, lpss->priv + LPSS_PRIV_RESETS); | |
| 507 | − | |
| 508 | 505 | return 0; |
| 509 | 506 | } |
| 510 | 507 | EXPORT_SYMBOL_GPL(intel_lpss_suspend); |
| @@ -86,6 +86,7 @@ enum bxtwc_irqs_level2 { · 85 unmodified lines | ||
| 86 | 86 | BXTWC_THRM2_IRQ, |
| 87 | 87 | BXTWC_BCU_IRQ, |
| 88 | 88 | BXTWC_ADC_IRQ, |
| 89 | + BXTWC_USBC_IRQ, | |
| 89 | 90 | BXTWC_CHGR0_IRQ, |
| 90 | 91 | BXTWC_CHGR1_IRQ, |
| 91 | 92 | BXTWC_GPIO0_IRQ, |
| @@ -111,7 +112,8 @@ static const struct regmap_irq bxtwc_regmap_irqs_level2[] = { · 19 unmodified lines | ||
| 111 | 112 | REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff), |
| 112 | 113 | REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f), |
| 113 | 114 | REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff), |
| 114 | − REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f), | |
| 115 | + REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 5, BIT(5)), | |
| 116 | + REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f), | |
| 115 | 117 | REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f), |
| 116 | 118 | REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff), |
| 117 | 119 | REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f), |
| @@ -146,7 +148,7 @@ static struct resource adc_resources[] = { · 28 unmodified lines | ||
| 146 | 148 | }; |
| 147 | 149 | |
| 148 | 150 | static struct resource usbc_resources[] = { |
| 149 | − DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "USBC"), | |
| 151 | + DEFINE_RES_IRQ(BXTWC_USBC_IRQ), | |
| 150 | 152 | }; |
| 151 | 153 | |
| 152 | 154 | static struct resource charger_resources[] = { |
| @@ -399,6 +399,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) · 398 unmodified lines | ||
| 399 | 399 | clones[i]); |
| 400 | 400 | } |
| 401 | 401 | |
| 402 | + put_device(dev); | |
| 403 | + | |
| 402 | 404 | return 0; |
| 403 | 405 | } |
| 404 | 406 | EXPORT_SYMBOL(mfd_clone_cell); |
| @@ -851,6 +851,8 @@ static int stmpe_reset(struct stmpe *stmpe) · 850 unmodified lines | ||
| 851 | 851 | if (ret < 0) |
| 852 | 852 | return ret; |
| 853 | 853 | |
| 854 | + msleep(10); | |
| 855 | + | |
| 854 | 856 | timeout = jiffies + msecs_to_jiffies(100); |
| 855 | 857 | while (time_before(jiffies, timeout)) { |
| 856 | 858 | ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]); |
| @@ -178,7 +178,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, · 177 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | ret = 0; |
| 180 | 180 | bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length); |
| 181 | − if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) { | |
| 181 | + if (bytes_recv < if_version_length) { | |
| 182 | 182 | dev_err(bus->dev, "Could not read IF version\n"); |
| 183 | 183 | ret = -EIO; |
| 184 | 184 | goto err; |
| @@ -2347,7 +2347,7 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, · 2346 unmodified lines | ||
| 2347 | 2347 | struct mmc_test_req *rq = mmc_test_req_alloc(); |
| 2348 | 2348 | struct mmc_host *host = test->card->host; |
| 2349 | 2349 | struct mmc_test_area *t = &test->area; |
| 2350 | − struct mmc_async_req areq; | |
| 2350 | + struct mmc_test_async_req test_areq = { .test = test }; | |
| 2351 | 2351 | struct mmc_request *mrq; |
| 2352 | 2352 | unsigned long timeout; |
| 2353 | 2353 | bool expired = false; |
| @@ -2363,8 +2363,8 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, · 9 unmodified lines | ||
| 2363 | 2363 | mrq->sbc = &rq->sbc; |
| 2364 | 2364 | mrq->cap_cmd_during_tfr = true; |
| 2365 | 2365 | |
| 2366 | − areq.mrq = mrq; | |
| 2367 | − areq.err_check = mmc_test_check_result_async; | |
| 2366 | + test_areq.areq.mrq = mrq; | |
| 2367 | + test_areq.areq.err_check = mmc_test_check_result_async; | |
| 2368 | 2368 | |
| 2369 | 2369 | mmc_test_prepare_mrq(test, mrq, t->sg, t->sg_len, dev_addr, t->blocks, |
| 2370 | 2370 | 512, write); |
| @@ -2378,7 +2378,7 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, · 7 unmodified lines | ||
| 2378 | 2378 | |
| 2379 | 2379 | /* Start ongoing data request */ |
| 2380 | 2380 | if (use_areq) { |
| 2381 | − mmc_start_req(host, &areq, &ret); | |
| 2381 | + mmc_start_req(host, &test_areq.areq, &ret); | |
| 2382 | 2382 | if (ret) |
| 2383 | 2383 | goto out_free; |
| 2384 | 2384 | } else { |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | #include "mmc_ops.h" |
| 27 | 27 | #include "sd_ops.h" |
| 28 | 28 | |
| 29 | +#define DEFAULT_CMD6_TIMEOUT_MS 500 | |
| 30 | + | |
| 29 | 31 | static const unsigned int tran_exp[] = { |
| 30 | 32 | 10000, 100000, 1000000, 10000000, |
| 31 | 33 | 0, 0, 0, 0 |
| @@ -571,6 +573,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) · 539 unmodified lines | ||
| 571 | 573 | card->erased_byte = 0x0; |
| 572 | 574 | |
| 573 | 575 | /* eMMC v4.5 or later */ |
| 576 | + card->ext_csd.generic_cmd6_time = DEFAULT_CMD6_TIMEOUT_MS; | |
| 574 | 577 | if (card->ext_csd.rev >= 6) { |
| 575 | 578 | card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; |
| 576 | 579 | |
| @@ -2940,7 +2940,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) · 2939 unmodified lines | ||
| 2940 | 2940 | return ERR_PTR(-ENOMEM); |
| 2941 | 2941 | |
| 2942 | 2942 | /* find reset controller when exist */ |
| 2943 | − pdata->rstc = devm_reset_control_get_optional(dev, NULL); | |
| 2943 | + pdata->rstc = devm_reset_control_get_optional(dev, "reset"); | |
| 2944 | 2944 | if (IS_ERR(pdata->rstc)) { |
| 2945 | 2945 | if (PTR_ERR(pdata->rstc) == -EPROBE_DEFER) |
| 2946 | 2946 | return ERR_PTR(-EPROBE_DEFER); |
| @@ -661,13 +661,13 @@ static int mxs_mmc_probe(struct platform_device *pdev) · 660 unmodified lines | ||
| 661 | 661 | |
| 662 | 662 | platform_set_drvdata(pdev, mmc); |
| 663 | 663 | |
| 664 | + spin_lock_init(&host->lock); | |
| 665 | + | |
| 664 | 666 | ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0, |
| 665 | 667 | dev_name(&pdev->dev), host); |
| 666 | 668 | if (ret) |
| 667 | 669 | goto out_free_dma; |
| 668 | 670 | |
| 669 | − spin_lock_init(&host->lock); | |
| 670 | − | |
| 671 | 671 | ret = mmc_add_host(mmc); |
| 672 | 672 | if (ret) |
| 673 | 673 | goto out_free_dma; |
| @@ -2086,6 +2086,10 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) · 2085 unmodified lines | ||
| 2086 | 2086 | |
| 2087 | 2087 | if (!host->tuning_done) { |
| 2088 | 2088 | pr_info(DRIVER_NAME ": Timeout waiting for Buffer Read Ready interrupt during tuning procedure, falling back to fixed sampling clock\n"); |
| 2089 | + | |
| 2090 | + sdhci_do_reset(host, SDHCI_RESET_CMD); | |
| 2091 | + sdhci_do_reset(host, SDHCI_RESET_DATA); | |
| 2092 | + | |
| 2089 | 2093 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| 2090 | 2094 | ctrl &= ~SDHCI_CTRL_TUNED_CLK; |
| 2091 | 2095 | ctrl &= ~SDHCI_CTRL_EXEC_TUNING; |
| @@ -2286,10 +2290,8 @@ static bool sdhci_request_done(struct sdhci_host *host) · 194 unmodified lines | ||
| 2286 | 2290 | |
| 2287 | 2291 | for (i = 0; i < SDHCI_MAX_MRQS; i++) { |
| 2288 | 2292 | mrq = host->mrqs_done[i]; |
| 2289 | − if (mrq) { | |
| 2290 | − host->mrqs_done[i] = NULL; | |
| 2293 | + if (mrq) | |
| 2291 | 2294 | break; |
| 2292 | − } | |
| 2293 | 2295 | } |
| 2294 | 2296 | |
| 2295 | 2297 | if (!mrq) { |
| @@ -2320,6 +2322,17 @@ static bool sdhci_request_done(struct sdhci_host *host) · 24 unmodified lines | ||
| 2320 | 2322 | * upon error conditions. |
| 2321 | 2323 | */ |
| 2322 | 2324 | if (sdhci_needs_reset(host, mrq)) { |
| 2325 | + /* | |
| 2326 | + * Do not finish until command and data lines are available for | |
| 2327 | + * reset. Note there can only be one other mrq, so it cannot | |
| 2328 | + * also be in mrqs_done, otherwise host->cmd and host->data_cmd | |
| 2329 | + * would both be null. | |
| 2330 | + */ | |
| 2331 | + if (host->cmd || host->data_cmd) { | |
| 2332 | + spin_unlock_irqrestore(&host->lock, flags); | |
| 2333 | + return true; | |
| 2334 | + } | |
| 2335 | + | |
| 2323 | 2336 | /* Some controllers need this kick or reset won't work here */ |
| 2324 | 2337 | if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) |
| 2325 | 2338 | /* This is to force an update */ |
| @@ -2327,10 +2340,8 @@ static bool sdhci_request_done(struct sdhci_host *host) · 1 unmodified line | ||
| 2327 | 2340 | |
| 2328 | 2341 | /* Spec says we should do both at the same time, but Ricoh |
| 2329 | 2342 | controllers do not like that. */ |
| 2330 | − if (!host->cmd) | |
| 2331 | − sdhci_do_reset(host, SDHCI_RESET_CMD); | |
| 2332 | − if (!host->data_cmd) | |
| 2333 | − sdhci_do_reset(host, SDHCI_RESET_DATA); | |
| 2343 | + sdhci_do_reset(host, SDHCI_RESET_CMD); | |
| 2344 | + sdhci_do_reset(host, SDHCI_RESET_DATA); | |
| 2334 | 2345 | |
| 2335 | 2346 | host->pending_reset = false; |
| 2336 | 2347 | } |
| @@ -2338,6 +2349,8 @@ static bool sdhci_request_done(struct sdhci_host *host) · 1 unmodified line | ||
| 2338 | 2349 | if (!sdhci_has_requests(host)) |
| 2339 | 2350 | sdhci_led_deactivate(host); |
| 2340 | 2351 | |
| 2352 | + host->mrqs_done[i] = NULL; | |
| 2353 | + | |
| 2341 | 2354 | mmiowb(); |
| 2342 | 2355 | spin_unlock_irqrestore(&host->lock, flags); |
| 2343 | 2356 | |
| @@ -2512,9 +2525,6 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) · 168 unmodified lines | ||
| 2512 | 2525 | if (!host->data) { |
| 2513 | 2526 | struct mmc_command *data_cmd = host->data_cmd; |
| 2514 | 2527 | |
| 2515 | − if (data_cmd) | |
| 2516 | − host->data_cmd = NULL; | |
| 2517 | − | |
| 2518 | 2528 | /* |
| 2519 | 2529 | * The "data complete" interrupt is also used to |
| 2520 | 2530 | * indicate that a busy state has ended. See comment |
| @@ -2522,11 +2532,13 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) · 1 unmodified line | ||
| 2522 | 2532 | */ |
| 2523 | 2533 | if (data_cmd && (data_cmd->flags & MMC_RSP_BUSY)) { |
| 2524 | 2534 | if (intmask & SDHCI_INT_DATA_TIMEOUT) { |
| 2535 | + host->data_cmd = NULL; | |
| 2525 | 2536 | data_cmd->error = -ETIMEDOUT; |
| 2526 | 2537 | sdhci_finish_mrq(host, data_cmd->mrq); |
| 2527 | 2538 | return; |
| 2528 | 2539 | } |
| 2529 | 2540 | if (intmask & SDHCI_INT_DATA_END) { |
| 2541 | + host->data_cmd = NULL; | |
| 2530 | 2542 | /* |
| 2531 | 2543 | * Some cards handle busy-end interrupt |
| 2532 | 2544 | * before the command completed, so make |
| @@ -2912,6 +2924,10 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) · 379 unmodified lines | ||
| 2912 | 2924 | spin_unlock_irqrestore(&host->lock, flags); |
| 2913 | 2925 | } |
| 2914 | 2926 | |
| 2927 | + if ((mmc->caps2 & MMC_CAP2_HS400_ES) && | |
| 2928 | + mmc->ops->hs400_enhanced_strobe) | |
| 2929 | + mmc->ops->hs400_enhanced_strobe(mmc, &mmc->ios); | |
| 2930 | + | |
| 2915 | 2931 | spin_lock_irqsave(&host->lock, flags); |
| 2916 | 2932 | |
| 2917 | 2933 | host->runtime_suspended = false; |
| @@ -142,6 +142,9 @@ struct plx_pci_card { · 141 unmodified lines | ||
| 142 | 142 | #define CTI_PCI_VENDOR_ID 0x12c4 |
| 143 | 143 | #define CTI_PCI_DEVICE_ID_CRG001 0x0900 |
| 144 | 144 | |
| 145 | +#define MOXA_PCI_VENDOR_ID 0x1393 | |
| 146 | +#define MOXA_PCI_DEVICE_ID 0x0100 | |
| 147 | + | |
| 145 | 148 | static void plx_pci_reset_common(struct pci_dev *pdev); |
| 146 | 149 | static void plx9056_pci_reset_common(struct pci_dev *pdev); |
| 147 | 150 | static void plx_pci_reset_marathon_pci(struct pci_dev *pdev); |
| @@ -258,6 +261,14 @@ static struct plx_pci_card_info plx_pci_card_info_elcus = { · 110 unmodified lines | ||
| 258 | 261 | /* based on PLX9030 */ |
| 259 | 262 | }; |
| 260 | 263 | |
| 264 | +static struct plx_pci_card_info plx_pci_card_info_moxa = { | |
| 265 | + "MOXA", 2, | |
| 266 | + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, | |
| 267 | + {0, 0x00, 0x00}, { {0, 0x00, 0x80}, {1, 0x00, 0x80} }, | |
| 268 | + &plx_pci_reset_common | |
| 269 | + /* based on PLX9052 */ | |
| 270 | +}; | |
| 271 | + | |
| 261 | 272 | static const struct pci_device_id plx_pci_tbl[] = { |
| 262 | 273 | { |
| 263 | 274 | /* Adlink PCI-7841/cPCI-7841 */ |
| @@ -357,6 +368,13 @@ static const struct pci_device_id plx_pci_tbl[] = { · 93 unmodified lines | ||
| 357 | 368 | 0, 0, |
| 358 | 369 | (kernel_ulong_t)&plx_pci_card_info_elcus |
| 359 | 370 | }, |
| 371 | + { | |
| 372 | + /* moxa */ | |
| 373 | + MOXA_PCI_VENDOR_ID, MOXA_PCI_DEVICE_ID, | |
| 374 | + PCI_ANY_ID, PCI_ANY_ID, | |
| 375 | + 0, 0, | |
| 376 | + (kernel_ulong_t)&plx_pci_card_info_moxa | |
| 377 | + }, | |
| 360 | 378 | { 0,} |
| 361 | 379 | }; |
| 362 | 380 | MODULE_DEVICE_TABLE(pci, plx_pci_tbl); |
| @@ -962,9 +962,10 @@ static void b53_vlan_add(struct dsa_switch *ds, int port, · 961 unmodified lines | ||
| 962 | 962 | |
| 963 | 963 | vl->members |= BIT(port) | BIT(cpu_port); |
| 964 | 964 | if (untagged) |
| 965 | − vl->untag |= BIT(port) | BIT(cpu_port); | |
| 965 | + vl->untag |= BIT(port); | |
| 966 | 966 | else |
| 967 | − vl->untag &= ~(BIT(port) | BIT(cpu_port)); | |
| 967 | + vl->untag &= ~BIT(port); | |
| 968 | + vl->untag &= ~BIT(cpu_port); | |
| 968 | 969 | |
| 969 | 970 | b53_set_vlan_entry(dev, vid, vl); |
| 970 | 971 | b53_fast_age_vlan(dev, vid); |
| @@ -973,8 +974,6 @@ static void b53_vlan_add(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 973 | 974 | if (pvid) { |
| 974 | 975 | b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), |
| 975 | 976 | vlan->vid_end); |
| 976 | − b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(cpu_port), | |
| 977 | − vlan->vid_end); | |
| 978 | 977 | b53_fast_age_vlan(dev, vid); |
| 979 | 978 | } |
| 980 | 979 | } |
| @@ -984,7 +983,6 @@ static int b53_vlan_del(struct dsa_switch *ds, int port, · 3 unmodified lines | ||
| 984 | 983 | { |
| 985 | 984 | struct b53_device *dev = ds->priv; |
| 986 | 985 | bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; |
| 987 | − unsigned int cpu_port = dev->cpu_port; | |
| 988 | 986 | struct b53_vlan *vl; |
| 989 | 987 | u16 vid; |
| 990 | 988 | u16 pvid; |
| @@ -997,8 +995,6 @@ static int b53_vlan_del(struct dsa_switch *ds, int port, · 6 unmodified lines | ||
| 997 | 995 | b53_get_vlan_entry(dev, vid, vl); |
| 998 | 996 | |
| 999 | 997 | vl->members &= ~BIT(port); |
| 1000 | − if ((vl->members & BIT(cpu_port)) == BIT(cpu_port)) | |
| 1001 | − vl->members = 0; | |
| 1002 | 998 | |
| 1003 | 999 | if (pvid == vid) { |
| 1004 | 1000 | if (is5325(dev) || is5365(dev)) |
| @@ -1007,18 +1003,14 @@ static int b53_vlan_del(struct dsa_switch *ds, int port, · 2 unmodified lines | ||
| 1007 | 1003 | pvid = 0; |
| 1008 | 1004 | } |
| 1009 | 1005 | |
| 1010 | − if (untagged) { | |
| 1006 | + if (untagged) | |
| 1011 | 1007 | vl->untag &= ~(BIT(port)); |
| 1012 | − if ((vl->untag & BIT(cpu_port)) == BIT(cpu_port)) | |
| 1013 | − vl->untag = 0; | |
| 1014 | − } | |
| 1015 | 1008 | |
| 1016 | 1009 | b53_set_vlan_entry(dev, vid, vl); |
| 1017 | 1010 | b53_fast_age_vlan(dev, vid); |
| 1018 | 1011 | } |
| 1019 | 1012 | |
| 1020 | 1013 | b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), pvid); |
| 1021 | − b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(cpu_port), pvid); | |
| 1022 | 1014 | b53_fast_age_vlan(dev, pvid); |
| 1023 | 1015 | |
| 1024 | 1016 | return 0; |
| @@ -204,17 +204,6 @@ static u32 xgene_enet_ring_len(struct xgene_enet_desc_ring *ring) · 203 unmodified lines | ||
| 204 | 204 | return num_msgs; |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | −static void xgene_enet_setup_coalescing(struct xgene_enet_desc_ring *ring) | |
| 208 | −{ | |
| 209 | − u32 data = 0x7777; | |
| 210 | − | |
| 211 | − xgene_enet_ring_wr32(ring, CSR_PBM_COAL, 0x8e); | |
| 212 | − xgene_enet_ring_wr32(ring, CSR_PBM_CTICK1, data); | |
| 213 | − xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data << 16); | |
| 214 | − xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x40); | |
| 215 | − xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x80); | |
| 216 | −} | |
| 217 | − | |
| 218 | 207 | void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring, |
| 219 | 208 | struct xgene_enet_pdata *pdata, |
| 220 | 209 | enum xgene_enet_err_code status) |
| @@ -929,5 +918,4 @@ struct xgene_ring_ops xgene_ring1_ops = { · 708 unmodified lines | ||
| 929 | 918 | .clear = xgene_enet_clear_ring, |
| 930 | 919 | .wr_cmd = xgene_enet_wr_cmd, |
| 931 | 920 | .len = xgene_enet_ring_len, |
| 932 | − .coalesce = xgene_enet_setup_coalescing, | |
| 933 | 921 | }; |
| @@ -55,8 +55,10 @@ enum xgene_enet_rm { · 54 unmodified lines | ||
| 55 | 55 | #define PREFETCH_BUF_EN BIT(21) |
| 56 | 56 | #define CSR_RING_ID_BUF 0x000c |
| 57 | 57 | #define CSR_PBM_COAL 0x0014 |
| 58 | +#define CSR_PBM_CTICK0 0x0018 | |
| 58 | 59 | #define CSR_PBM_CTICK1 0x001c |
| 59 | 60 | #define CSR_PBM_CTICK2 0x0020 |
| 61 | +#define CSR_PBM_CTICK3 0x0024 | |
| 60 | 62 | #define CSR_THRESHOLD0_SET1 0x0030 |
| 61 | 63 | #define CSR_THRESHOLD1_SET1 0x0034 |
| 62 | 64 | #define CSR_RING_NE_INT_MODE 0x017c |
| @@ -1188,7 +1188,8 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev) · 1187 unmodified lines | ||
| 1188 | 1188 | tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring); |
| 1189 | 1189 | } |
| 1190 | 1190 | |
| 1191 | − pdata->ring_ops->coalesce(pdata->tx_ring[0]); | |
| 1191 | + if (pdata->ring_ops->coalesce) | |
| 1192 | + pdata->ring_ops->coalesce(pdata->tx_ring[0]); | |
| 1192 | 1193 | pdata->tx_qcnt_hi = pdata->tx_ring[0]->slots - 128; |
| 1193 | 1194 | |
| 1194 | 1195 | return 0; |
| @@ -30,7 +30,7 @@ static void xgene_enet_ring_init(struct xgene_enet_desc_ring *ring) · 29 unmodified lines | ||
| 30 | 30 | ring_cfg[0] |= SET_VAL(X2_INTLINE, ring->id & RING_BUFNUM_MASK); |
| 31 | 31 | ring_cfg[3] |= SET_BIT(X2_DEQINTEN); |
| 32 | 32 | } |
| 33 | − ring_cfg[0] |= SET_VAL(X2_CFGCRID, 1); | |
| 33 | + ring_cfg[0] |= SET_VAL(X2_CFGCRID, 2); | |
| 34 | 34 | |
| 35 | 35 | addr >>= 8; |
| 36 | 36 | ring_cfg[2] |= QCOHERENT | SET_VAL(RINGADDRL, addr); |
| @@ -192,13 +192,15 @@ static u32 xgene_enet_ring_len(struct xgene_enet_desc_ring *ring) · 155 unmodified lines | ||
| 192 | 192 | |
| 193 | 193 | static void xgene_enet_setup_coalescing(struct xgene_enet_desc_ring *ring) |
| 194 | 194 | { |
| 195 | − u32 data = 0x7777; | |
| 195 | + u32 data = 0x77777777; | |
| 196 | 196 | |
| 197 | 197 | xgene_enet_ring_wr32(ring, CSR_PBM_COAL, 0x8e); |
| 198 | + xgene_enet_ring_wr32(ring, CSR_PBM_CTICK0, data); | |
| 198 | 199 | xgene_enet_ring_wr32(ring, CSR_PBM_CTICK1, data); |
| 199 | − xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data << 16); | |
| 200 | − xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x40); | |
| 201 | − xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x80); | |
| 200 | + xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data); | |
| 201 | + xgene_enet_ring_wr32(ring, CSR_PBM_CTICK3, data); | |
| 202 | + xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x08); | |
| 203 | + xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x10); | |
| 202 | 204 | } |
| 203 | 205 | |
| 204 | 206 | struct xgene_ring_ops xgene_ring2_ops = { |
| @@ -460,7 +460,7 @@ static void arc_emac_set_rx_mode(struct net_device *ndev) · 459 unmodified lines | ||
| 460 | 460 | if (ndev->flags & IFF_ALLMULTI) { |
| 461 | 461 | arc_reg_set(priv, R_LAFL, ~0); |
| 462 | 462 | arc_reg_set(priv, R_LAFH, ~0); |
| 463 | − } else { | |
| 463 | + } else if (ndev->flags & IFF_MULTICAST) { | |
| 464 | 464 | struct netdev_hw_addr *ha; |
| 465 | 465 | unsigned int filter[2] = { 0, 0 }; |
| 466 | 466 | int bit; |
| @@ -472,6 +472,9 @@ static void arc_emac_set_rx_mode(struct net_device *ndev) · 5 unmodified lines | ||
| 472 | 472 | |
| 473 | 473 | arc_reg_set(priv, R_LAFL, filter[0]); |
| 474 | 474 | arc_reg_set(priv, R_LAFH, filter[1]); |
| 475 | + } else { | |
| 476 | + arc_reg_set(priv, R_LAFL, 0); | |
| 477 | + arc_reg_set(priv, R_LAFH, 0); | |
| 475 | 478 | } |
| 476 | 479 | } |
| 477 | 480 | } |
| @@ -764,8 +767,6 @@ int arc_emac_probe(struct net_device *ndev, int interface) · 286 unmodified lines | ||
| 764 | 767 | ndev->netdev_ops = &arc_emac_netdev_ops; |
| 765 | 768 | ndev->ethtool_ops = &arc_emac_ethtool_ops; |
| 766 | 769 | ndev->watchdog_timeo = TX_TIMEOUT; |
| 767 | − /* FIXME :: no multicast support yet */ | |
| 768 | − ndev->flags &= ~IFF_MULTICAST; | |
| 769 | 770 | |
| 770 | 771 | priv = netdev_priv(ndev); |
| 771 | 772 | priv->dev = dev; |
| @@ -307,6 +307,10 @@ static void bgmac_dma_rx_enable(struct bgmac *bgmac, · 306 unmodified lines | ||
| 307 | 307 | u32 ctl; |
| 308 | 308 | |
| 309 | 309 | ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL); |
| 310 | + | |
| 311 | + /* preserve ONLY bits 16-17 from current hardware value */ | |
| 312 | + ctl &= BGMAC_DMA_RX_ADDREXT_MASK; | |
| 313 | + | |
| 310 | 314 | if (bgmac->feature_flags & BGMAC_FEAT_RX_MASK_SETUP) { |
| 311 | 315 | ctl &= ~BGMAC_DMA_RX_BL_MASK; |
| 312 | 316 | ctl |= BGMAC_DMA_RX_BL_128 << BGMAC_DMA_RX_BL_SHIFT; |
| @@ -317,7 +321,6 @@ static void bgmac_dma_rx_enable(struct bgmac *bgmac, · 4 unmodified lines | ||
| 317 | 321 | ctl &= ~BGMAC_DMA_RX_PT_MASK; |
| 318 | 322 | ctl |= BGMAC_DMA_RX_PT_1 << BGMAC_DMA_RX_PT_SHIFT; |
| 319 | 323 | } |
| 320 | − ctl &= BGMAC_DMA_RX_ADDREXT_MASK; | |
| 321 | 324 | ctl |= BGMAC_DMA_RX_ENABLE; |
| 322 | 325 | ctl |= BGMAC_DMA_RX_PARITY_DISABLE; |
| 323 | 326 | ctl |= BGMAC_DMA_RX_OVERFLOW_CONT; |
| @@ -1046,9 +1049,9 @@ static void bgmac_enable(struct bgmac *bgmac) · 722 unmodified lines | ||
| 1046 | 1049 | |
| 1047 | 1050 | mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >> |
| 1048 | 1051 | BGMAC_DS_MM_SHIFT; |
| 1049 | − if (!(bgmac->feature_flags & BGMAC_FEAT_CLKCTLST) || mode != 0) | |
| 1052 | + if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST || mode != 0) | |
| 1050 | 1053 | bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT); |
| 1051 | − if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST && mode == 2) | |
| 1054 | + if (!(bgmac->feature_flags & BGMAC_FEAT_CLKCTLST) && mode == 2) | |
| 1052 | 1055 | bgmac_cco_ctl_maskset(bgmac, 1, ~0, |
| 1053 | 1056 | BGMAC_CHIPCTL_1_RXC_DLL_BYPASS); |
| 1054 | 1057 | |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | #include <linux/firmware.h> |
| 50 | 50 | #include <linux/log2.h> |
| 51 | 51 | #include <linux/aer.h> |
| 52 | +#include <linux/crash_dump.h> | |
| 52 | 53 | |
| 53 | 54 | #if IS_ENABLED(CONFIG_CNIC) |
| 54 | 55 | #define BCM_CNIC 1 |
| @@ -4764,15 +4765,16 @@ bnx2_setup_msix_tbl(struct bnx2 *bp) · 4709 unmodified lines | ||
| 4764 | 4765 | BNX2_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR); |
| 4765 | 4766 | } |
| 4766 | 4767 | |
| 4767 | −static int | |
| 4768 | −bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | |
| 4768 | +static void | |
| 4769 | +bnx2_wait_dma_complete(struct bnx2 *bp) | |
| 4769 | 4770 | { |
| 4770 | 4771 | u32 val; |
| 4771 | − int i, rc = 0; | |
| 4772 | − u8 old_port; | |
| 4772 | + int i; | |
| 4773 | 4773 | |
| 4774 | − /* Wait for the current PCI transaction to complete before | |
| 4775 | − * issuing a reset. */ | |
| 4774 | + /* | |
| 4775 | + * Wait for the current PCI transaction to complete before | |
| 4776 | + * issuing a reset. | |
| 4777 | + */ | |
| 4776 | 4778 | if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) || |
| 4777 | 4779 | (BNX2_CHIP(bp) == BNX2_CHIP_5708)) { |
| 4778 | 4780 | BNX2_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, |
| @@ -4796,6 +4798,21 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) · 17 unmodified lines | ||
| 4796 | 4798 | } |
| 4797 | 4799 | } |
| 4798 | 4800 | |
| 4801 | + return; | |
| 4802 | +} | |
| 4803 | + | |
| 4804 | + | |
| 4805 | +static int | |
| 4806 | +bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | |
| 4807 | +{ | |
| 4808 | + u32 val; | |
| 4809 | + int i, rc = 0; | |
| 4810 | + u8 old_port; | |
| 4811 | + | |
| 4812 | + /* Wait for the current PCI transaction to complete before | |
| 4813 | + * issuing a reset. */ | |
| 4814 | + bnx2_wait_dma_complete(bp); | |
| 4815 | + | |
| 4799 | 4816 | /* Wait for the firmware to tell us it is ok to issue a reset. */ |
| 4800 | 4817 | bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1); |
| 4801 | 4818 | |
| @@ -6361,6 +6378,10 @@ bnx2_open(struct net_device *dev) · 1559 unmodified lines | ||
| 6361 | 6378 | struct bnx2 *bp = netdev_priv(dev); |
| 6362 | 6379 | int rc; |
| 6363 | 6380 | |
| 6381 | + rc = bnx2_request_firmware(bp); | |
| 6382 | + if (rc < 0) | |
| 6383 | + goto out; | |
| 6384 | + | |
| 6364 | 6385 | netif_carrier_off(dev); |
| 6365 | 6386 | |
| 6366 | 6387 | bnx2_disable_int(bp); |
| @@ -6429,6 +6450,7 @@ open_err: · 62 unmodified lines | ||
| 6429 | 6450 | bnx2_free_irq(bp); |
| 6430 | 6451 | bnx2_free_mem(bp); |
| 6431 | 6452 | bnx2_del_napi(bp); |
| 6453 | + bnx2_release_firmware(bp); | |
| 6432 | 6454 | goto out; |
| 6433 | 6455 | } |
| 6434 | 6456 | |
| @@ -8575,12 +8597,15 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 2140 unmodified lines | ||
| 8575 | 8597 | |
| 8576 | 8598 | pci_set_drvdata(pdev, dev); |
| 8577 | 8599 | |
| 8578 | − rc = bnx2_request_firmware(bp); | |
| 8579 | − if (rc < 0) | |
| 8580 | − goto error; | |
| 8581 | − | |
| 8600 | + /* | |
| 8601 | + * In-flight DMA from 1st kernel could continue going in kdump kernel. | |
| 8602 | + * New io-page table has been created before bnx2 does reset at open stage. | |
| 8603 | + * We have to wait for the in-flight DMA to complete to avoid it look up | |
| 8604 | + * into the newly created io-page table. | |
| 8605 | + */ | |
| 8606 | + if (is_kdump_kernel()) | |
| 8607 | + bnx2_wait_dma_complete(bp); | |
| 8582 | 8608 | |
| 8583 | − bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); | |
| 8584 | 8609 | memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN); |
| 8585 | 8610 | |
| 8586 | 8611 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | |
| @@ -8613,7 +8638,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 26 unmodified lines | ||
| 8613 | 8638 | return 0; |
| 8614 | 8639 | |
| 8615 | 8640 | error: |
| 8616 | − bnx2_release_firmware(bp); | |
| 8617 | 8641 | pci_iounmap(pdev, bp->regview); |
| 8618 | 8642 | pci_release_regions(pdev); |
| 8619 | 8643 | pci_disable_device(pdev); |
| @@ -4934,6 +4934,10 @@ static void bnxt_del_napi(struct bnxt *bp) · 4933 unmodified lines | ||
| 4934 | 4934 | napi_hash_del(&bnapi->napi); |
| 4935 | 4935 | netif_napi_del(&bnapi->napi); |
| 4936 | 4936 | } |
| 4937 | + /* We called napi_hash_del() before netif_napi_del(), we need | |
| 4938 | + * to respect an RCU grace period before freeing napi structures. | |
| 4939 | + */ | |
| 4940 | + synchronize_net(); | |
| 4937 | 4941 | } |
| 4938 | 4942 | |
| 4939 | 4943 | static void bnxt_init_napi(struct bnxt *bp) |
| @@ -6309,6 +6313,7 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto, · 1369 unmodified lines | ||
| 6309 | 6313 | struct tc_to_netdev *ntc) |
| 6310 | 6314 | { |
| 6311 | 6315 | struct bnxt *bp = netdev_priv(dev); |
| 6316 | + bool sh = false; | |
| 6312 | 6317 | u8 tc; |
| 6313 | 6318 | |
| 6314 | 6319 | if (ntc->type != TC_SETUP_MQPRIO) |
| @@ -6325,12 +6330,11 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto, · 10 unmodified lines | ||
| 6325 | 6330 | if (netdev_get_num_tc(dev) == tc) |
| 6326 | 6331 | return 0; |
| 6327 | 6332 | |
| 6333 | + if (bp->flags & BNXT_FLAG_SHARED_RINGS) | |
| 6334 | + sh = true; | |
| 6335 | + | |
| 6328 | 6336 | if (tc) { |
| 6329 | 6337 | int max_rx_rings, max_tx_rings, rc; |
| 6330 | − bool sh = false; | |
| 6331 | − | |
| 6332 | − if (bp->flags & BNXT_FLAG_SHARED_RINGS) | |
| 6333 | − sh = true; | |
| 6334 | 6338 | |
| 6335 | 6339 | rc = bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, sh); |
| 6336 | 6340 | if (rc || bp->tx_nr_rings_per_tc * tc > max_tx_rings) |
| @@ -6348,7 +6352,8 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto, · 11 unmodified lines | ||
| 6348 | 6352 | bp->tx_nr_rings = bp->tx_nr_rings_per_tc; |
| 6349 | 6353 | netdev_reset_tc(dev); |
| 6350 | 6354 | } |
| 6351 | − bp->cp_nr_rings = max_t(int, bp->tx_nr_rings, bp->rx_nr_rings); | |
| 6355 | + bp->cp_nr_rings = sh ? max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) : | |
| 6356 | + bp->tx_nr_rings + bp->rx_nr_rings; | |
| 6352 | 6357 | bp->num_stat_ctxs = bp->cp_nr_rings; |
| 6353 | 6358 | |
| 6354 | 6359 | if (netif_running(bp->dev)) |
| @@ -774,8 +774,8 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf) · 773 unmodified lines | ||
| 774 | 774 | |
| 775 | 775 | if (vf->flags & BNXT_VF_LINK_UP) { |
| 776 | 776 | /* if physical link is down, force link up on VF */ |
| 777 | − if (phy_qcfg_resp.link == | |
| 778 | − PORT_PHY_QCFG_RESP_LINK_NO_LINK) { | |
| 777 | + if (phy_qcfg_resp.link != | |
| 778 | + PORT_PHY_QCFG_RESP_LINK_LINK) { | |
| 779 | 779 | phy_qcfg_resp.link = |
| 780 | 780 | PORT_PHY_QCFG_RESP_LINK_LINK; |
| 781 | 781 | phy_qcfg_resp.link_speed = cpu_to_le16( |
| @@ -177,6 +177,7 @@ bnad_txcmpl_process(struct bnad *bnad, struct bna_tcb *tcb) · 176 unmodified lines | ||
| 177 | 177 | return 0; |
| 178 | 178 | |
| 179 | 179 | hw_cons = *(tcb->hw_consumer_index); |
| 180 | + rmb(); | |
| 180 | 181 | cons = tcb->consumer_index; |
| 181 | 182 | q_depth = tcb->q_depth; |
| 182 | 183 | |
| @@ -3094,7 +3095,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) · 2911 unmodified lines | ||
| 3094 | 3095 | BNA_QE_INDX_INC(prod, q_depth); |
| 3095 | 3096 | tcb->producer_index = prod; |
| 3096 | 3097 | |
| 3097 | − smp_mb(); | |
| 3098 | + wmb(); | |
| 3098 | 3099 | |
| 3099 | 3100 | if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))) |
| 3100 | 3101 | return NETDEV_TX_OK; |
| @@ -3102,7 +3103,6 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) · 1 unmodified line | ||
| 3102 | 3103 | skb_tx_timestamp(skb); |
| 3103 | 3104 | |
| 3104 | 3105 | bna_txq_prod_indx_doorbell(tcb); |
| 3105 | − smp_mb(); | |
| 3106 | 3106 | |
| 3107 | 3107 | return NETDEV_TX_OK; |
| 3108 | 3108 | } |
| @@ -2673,6 +2673,12 @@ static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev) · 2672 unmodified lines | ||
| 2673 | 2673 | lp->skb_length = skb->len; |
| 2674 | 2674 | lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, |
| 2675 | 2675 | DMA_TO_DEVICE); |
| 2676 | + if (dma_mapping_error(NULL, lp->skb_physaddr)) { | |
| 2677 | + dev_kfree_skb_any(skb); | |
| 2678 | + dev->stats.tx_dropped++; | |
| 2679 | + netdev_err(dev, "%s: DMA mapping error\n", __func__); | |
| 2680 | + return NETDEV_TX_OK; | |
| 2681 | + } | |
| 2676 | 2682 | |
| 2677 | 2683 | /* Set address of the data in the Transmit Address register */ |
| 2678 | 2684 | macb_writel(lp, TAR, lp->skb_physaddr); |
| @@ -47,7 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | /* Min/Max packet size */ |
| 49 | 49 | #define NIC_HW_MIN_FRS 64 |
| 50 | −#define NIC_HW_MAX_FRS 9200 /* 9216 max packet including FCS */ | |
| 50 | +#define NIC_HW_MAX_FRS 9190 /* Excluding L2 header and FCS */ | |
| 51 | 51 | |
| 52 | 52 | /* Max pkinds */ |
| 53 | 53 | #define NIC_MAX_PKIND 16 |
| @@ -178,11 +178,11 @@ enum tx_stats_reg_offset { · 124 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | struct nicvf_hw_stats { |
| 180 | 180 | u64 rx_bytes; |
| 181 | + u64 rx_frames; | |
| 181 | 182 | u64 rx_ucast_frames; |
| 182 | 183 | u64 rx_bcast_frames; |
| 183 | 184 | u64 rx_mcast_frames; |
| 184 | − u64 rx_fcs_errors; | |
| 185 | − u64 rx_l2_errors; | |
| 185 | + u64 rx_drops; | |
| 186 | 186 | u64 rx_drop_red; |
| 187 | 187 | u64 rx_drop_red_bytes; |
| 188 | 188 | u64 rx_drop_overrun; |
| @@ -191,6 +191,19 @@ struct nicvf_hw_stats { · 2 unmodified lines | ||
| 191 | 191 | u64 rx_drop_mcast; |
| 192 | 192 | u64 rx_drop_l3_bcast; |
| 193 | 193 | u64 rx_drop_l3_mcast; |
| 194 | + u64 rx_fcs_errors; | |
| 195 | + u64 rx_l2_errors; | |
| 196 | + | |
| 197 | + u64 tx_bytes; | |
| 198 | + u64 tx_frames; | |
| 199 | + u64 tx_ucast_frames; | |
| 200 | + u64 tx_bcast_frames; | |
| 201 | + u64 tx_mcast_frames; | |
| 202 | + u64 tx_drops; | |
| 203 | +}; | |
| 204 | + | |
| 205 | +struct nicvf_drv_stats { | |
| 206 | + /* CQE Rx errs */ | |
| 194 | 207 | u64 rx_bgx_truncated_pkts; |
| 195 | 208 | u64 rx_jabber_errs; |
| 196 | 209 | u64 rx_fcs_errs; |
| @@ -216,34 +229,30 @@ struct nicvf_hw_stats { · 19 unmodified lines | ||
| 216 | 229 | u64 rx_l4_pclp; |
| 217 | 230 | u64 rx_truncated_pkts; |
| 218 | 231 | |
| 219 | − u64 tx_bytes_ok; | |
| 220 | − u64 tx_ucast_frames_ok; | |
| 221 | − u64 tx_bcast_frames_ok; | |
| 222 | − u64 tx_mcast_frames_ok; | |
| 223 | − u64 tx_drops; | |
| 224 | −}; | |
| 225 | − | |
| 226 | −struct nicvf_drv_stats { | |
| 227 | − /* Rx */ | |
| 228 | − u64 rx_frames_ok; | |
| 229 | − u64 rx_frames_64; | |
| 230 | − u64 rx_frames_127; | |
| 231 | − u64 rx_frames_255; | |
| 232 | − u64 rx_frames_511; | |
| 233 | − u64 rx_frames_1023; | |
| 234 | − u64 rx_frames_1518; | |
| 235 | − u64 rx_frames_jumbo; | |
| 236 | − u64 rx_drops; | |
| 237 | − | |
| 232 | + /* CQE Tx errs */ | |
| 233 | + u64 tx_desc_fault; | |
| 234 | + u64 tx_hdr_cons_err; | |
| 235 | + u64 tx_subdesc_err; | |
| 236 | + u64 tx_max_size_exceeded; | |
| 237 | + u64 tx_imm_size_oflow; | |
| 238 | + u64 tx_data_seq_err; | |
| 239 | + u64 tx_mem_seq_err; | |
| 240 | + u64 tx_lock_viol; | |
| 241 | + u64 tx_data_fault; | |
| 242 | + u64 tx_tstmp_conflict; | |
| 243 | + u64 tx_tstmp_timeout; | |
| 244 | + u64 tx_mem_fault; | |
| 245 | + u64 tx_csum_overlap; | |
| 246 | + u64 tx_csum_overflow; | |
| 247 | + | |
| 248 | + /* driver debug stats */ | |
| 238 | 249 | u64 rcv_buffer_alloc_failures; |
| 239 | − | |
| 240 | − /* Tx */ | |
| 241 | − u64 tx_frames_ok; | |
| 242 | − u64 tx_drops; | |
| 243 | 250 | u64 tx_tso; |
| 244 | 251 | u64 tx_timeout; |
| 245 | 252 | u64 txq_stop; |
| 246 | 253 | u64 txq_wake; |
| 254 | + | |
| 255 | + struct u64_stats_sync syncp; | |
| 247 | 256 | }; |
| 248 | 257 | |
| 249 | 258 | struct nicvf { |
| @@ -282,7 +291,6 @@ struct nicvf { · 32 unmodified lines | ||
| 282 | 291 | |
| 283 | 292 | u8 node; |
| 284 | 293 | u8 cpi_alg; |
| 285 | − u16 mtu; | |
| 286 | 294 | bool link_up; |
| 287 | 295 | u8 duplex; |
| 288 | 296 | u32 speed; |
| @@ -298,7 +306,7 @@ struct nicvf { · 9 unmodified lines | ||
| 298 | 306 | |
| 299 | 307 | /* Stats */ |
| 300 | 308 | struct nicvf_hw_stats hw_stats; |
| 301 | − struct nicvf_drv_stats drv_stats; | |
| 309 | + struct nicvf_drv_stats __percpu *drv_stats; | |
| 302 | 310 | struct bgx_stats bgx_stats; |
| 303 | 311 | |
| 304 | 312 | /* MSI-X */ |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/pci.h> |
| 12 | 12 | #include <linux/etherdevice.h> |
| 13 | 13 | #include <linux/of.h> |
| 14 | +#include <linux/if_vlan.h> | |
| 14 | 15 | |
| 15 | 16 | #include "nic_reg.h" |
| 16 | 17 | #include "nic.h" |
| @@ -260,18 +261,31 @@ static void nic_get_bgx_stats(struct nicpf *nic, struct bgx_stats_msg *bgx) · 243 unmodified lines | ||
| 260 | 261 | /* Update hardware min/max frame size */ |
| 261 | 262 | static int nic_update_hw_frs(struct nicpf *nic, int new_frs, int vf) |
| 262 | 263 | { |
| 263 | − if ((new_frs > NIC_HW_MAX_FRS) || (new_frs < NIC_HW_MIN_FRS)) { | |
| 264 | − dev_err(&nic->pdev->dev, | |
| 265 | − "Invalid MTU setting from VF%d rejected, should be between %d and %d\n", | |
| 266 | − vf, NIC_HW_MIN_FRS, NIC_HW_MAX_FRS); | |
| 264 | + int bgx, lmac, lmac_cnt; | |
| 265 | + u64 lmac_credits; | |
| 266 | + | |
| 267 | + if ((new_frs > NIC_HW_MAX_FRS) || (new_frs < NIC_HW_MIN_FRS)) | |
| 267 | 268 | return 1; |
| 268 | − } | |
| 269 | − new_frs += ETH_HLEN; | |
| 270 | − if (new_frs <= nic->pkind.maxlen) | |
| 271 | − return 0; | |
| 272 | 269 | |
| 273 | − nic->pkind.maxlen = new_frs; | |
| 274 | − nic_reg_write(nic, NIC_PF_PKIND_0_15_CFG, *(u64 *)&nic->pkind); | |
| 270 | + bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); | |
| 271 | + lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]); | |
| 272 | + lmac += bgx * MAX_LMAC_PER_BGX; | |
| 273 | + | |
| 274 | + new_frs += VLAN_ETH_HLEN + ETH_FCS_LEN + 4; | |
| 275 | + | |
| 276 | + /* Update corresponding LMAC credits */ | |
| 277 | + lmac_cnt = bgx_get_lmac_count(nic->node, bgx); | |
| 278 | + lmac_credits = nic_reg_read(nic, NIC_PF_LMAC_0_7_CREDIT + (lmac * 8)); | |
| 279 | + lmac_credits &= ~(0xFFFFFULL << 12); | |
| 280 | + lmac_credits |= (((((48 * 1024) / lmac_cnt) - new_frs) / 16) << 12); | |
| 281 | + nic_reg_write(nic, NIC_PF_LMAC_0_7_CREDIT + (lmac * 8), lmac_credits); | |
| 282 | + | |
| 283 | + /* Enforce MTU in HW | |
| 284 | + * This config is supported only from 88xx pass 2.0 onwards. | |
| 285 | + */ | |
| 286 | + if (!pass1_silicon(nic->pdev)) | |
| 287 | + nic_reg_write(nic, | |
| 288 | + NIC_PF_LMAC_0_7_CFG2 + (lmac * 8), new_frs); | |
| 275 | 289 | return 0; |
| 276 | 290 | } |
| 277 | 291 | |
| @@ -464,7 +478,7 @@ static int nic_init_hw(struct nicpf *nic) · 186 unmodified lines | ||
| 464 | 478 | |
| 465 | 479 | /* PKIND configuration */ |
| 466 | 480 | nic->pkind.minlen = 0; |
| 467 | − nic->pkind.maxlen = NIC_HW_MAX_FRS + ETH_HLEN; | |
| 481 | + nic->pkind.maxlen = NIC_HW_MAX_FRS + VLAN_ETH_HLEN + ETH_FCS_LEN + 4; | |
| 468 | 482 | nic->pkind.lenerr_en = 1; |
| 469 | 483 | nic->pkind.rx_hdr = 0; |
| 470 | 484 | nic->pkind.hdr_sl = 0; |
| @@ -837,6 +851,7 @@ static int nic_reset_stat_counters(struct nicpf *nic, · 366 unmodified lines | ||
| 837 | 851 | nic_reg_write(nic, reg_addr, 0); |
| 838 | 852 | } |
| 839 | 853 | } |
| 854 | + | |
| 840 | 855 | return 0; |
| 841 | 856 | } |
| 842 | 857 | |
| @@ -106,6 +106,7 @@ · 105 unmodified lines | ||
| 106 | 106 | #define NIC_PF_MPI_0_2047_CFG (0x210000) |
| 107 | 107 | #define NIC_PF_RSSI_0_4097_RQ (0x220000) |
| 108 | 108 | #define NIC_PF_LMAC_0_7_CFG (0x240000) |
| 109 | +#define NIC_PF_LMAC_0_7_CFG2 (0x240100) | |
| 109 | 110 | #define NIC_PF_LMAC_0_7_SW_XOFF (0x242000) |
| 110 | 111 | #define NIC_PF_LMAC_0_7_CREDIT (0x244000) |
| 111 | 112 | #define NIC_PF_CHAN_0_255_TX_CFG (0x400000) |
| @@ -36,11 +36,11 @@ struct nicvf_stat { · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | static const struct nicvf_stat nicvf_hw_stats[] = { |
| 38 | 38 | NICVF_HW_STAT(rx_bytes), |
| 39 | + NICVF_HW_STAT(rx_frames), | |
| 39 | 40 | NICVF_HW_STAT(rx_ucast_frames), |
| 40 | 41 | NICVF_HW_STAT(rx_bcast_frames), |
| 41 | 42 | NICVF_HW_STAT(rx_mcast_frames), |
| 42 | − NICVF_HW_STAT(rx_fcs_errors), | |
| 43 | − NICVF_HW_STAT(rx_l2_errors), | |
| 43 | + NICVF_HW_STAT(rx_drops), | |
| 44 | 44 | NICVF_HW_STAT(rx_drop_red), |
| 45 | 45 | NICVF_HW_STAT(rx_drop_red_bytes), |
| 46 | 46 | NICVF_HW_STAT(rx_drop_overrun), |
| @@ -49,50 +49,59 @@ static const struct nicvf_stat nicvf_hw_stats[] = { · 2 unmodified lines | ||
| 49 | 49 | NICVF_HW_STAT(rx_drop_mcast), |
| 50 | 50 | NICVF_HW_STAT(rx_drop_l3_bcast), |
| 51 | 51 | NICVF_HW_STAT(rx_drop_l3_mcast), |
| 52 | − NICVF_HW_STAT(rx_bgx_truncated_pkts), | |
| 53 | − NICVF_HW_STAT(rx_jabber_errs), | |
| 54 | − NICVF_HW_STAT(rx_fcs_errs), | |
| 55 | − NICVF_HW_STAT(rx_bgx_errs), | |
| 56 | − NICVF_HW_STAT(rx_prel2_errs), | |
| 57 | − NICVF_HW_STAT(rx_l2_hdr_malformed), | |
| 58 | − NICVF_HW_STAT(rx_oversize), | |
| 59 | − NICVF_HW_STAT(rx_undersize), | |
| 60 | − NICVF_HW_STAT(rx_l2_len_mismatch), | |
| 61 | − NICVF_HW_STAT(rx_l2_pclp), | |
| 62 | − NICVF_HW_STAT(rx_ip_ver_errs), | |
| 63 | − NICVF_HW_STAT(rx_ip_csum_errs), | |
| 64 | − NICVF_HW_STAT(rx_ip_hdr_malformed), | |
| 65 | − NICVF_HW_STAT(rx_ip_payload_malformed), | |
| 66 | − NICVF_HW_STAT(rx_ip_ttl_errs), | |
| 67 | − NICVF_HW_STAT(rx_l3_pclp), | |
| 68 | − NICVF_HW_STAT(rx_l4_malformed), | |
| 69 | − NICVF_HW_STAT(rx_l4_csum_errs), | |
| 70 | − NICVF_HW_STAT(rx_udp_len_errs), | |
| 71 | − NICVF_HW_STAT(rx_l4_port_errs), | |
| 72 | − NICVF_HW_STAT(rx_tcp_flag_errs), | |
| 73 | − NICVF_HW_STAT(rx_tcp_offset_errs), | |
| 74 | − NICVF_HW_STAT(rx_l4_pclp), | |
| 75 | − NICVF_HW_STAT(rx_truncated_pkts), | |
| 76 | − NICVF_HW_STAT(tx_bytes_ok), | |
| 77 | − NICVF_HW_STAT(tx_ucast_frames_ok), | |
| 78 | − NICVF_HW_STAT(tx_bcast_frames_ok), | |
| 79 | − NICVF_HW_STAT(tx_mcast_frames_ok), | |
| 52 | + NICVF_HW_STAT(rx_fcs_errors), | |
| 53 | + NICVF_HW_STAT(rx_l2_errors), | |
| 54 | + NICVF_HW_STAT(tx_bytes), | |
| 55 | + NICVF_HW_STAT(tx_frames), | |
| 56 | + NICVF_HW_STAT(tx_ucast_frames), | |
| 57 | + NICVF_HW_STAT(tx_bcast_frames), | |
| 58 | + NICVF_HW_STAT(tx_mcast_frames), | |
| 59 | + NICVF_HW_STAT(tx_drops), | |
| 80 | 60 | }; |
| 81 | 61 | |
| 82 | 62 | static const struct nicvf_stat nicvf_drv_stats[] = { |
| 83 | − NICVF_DRV_STAT(rx_frames_ok), | |
| 84 | − NICVF_DRV_STAT(rx_frames_64), | |
| 85 | − NICVF_DRV_STAT(rx_frames_127), | |
| 86 | − NICVF_DRV_STAT(rx_frames_255), | |
| 87 | − NICVF_DRV_STAT(rx_frames_511), | |
| 88 | − NICVF_DRV_STAT(rx_frames_1023), | |
| 89 | − NICVF_DRV_STAT(rx_frames_1518), | |
| 90 | − NICVF_DRV_STAT(rx_frames_jumbo), | |
| 91 | − NICVF_DRV_STAT(rx_drops), | |
| 63 | + NICVF_DRV_STAT(rx_bgx_truncated_pkts), | |
| 64 | + NICVF_DRV_STAT(rx_jabber_errs), | |
| 65 | + NICVF_DRV_STAT(rx_fcs_errs), | |
| 66 | + NICVF_DRV_STAT(rx_bgx_errs), | |
| 67 | + NICVF_DRV_STAT(rx_prel2_errs), | |
| 68 | + NICVF_DRV_STAT(rx_l2_hdr_malformed), | |
| 69 | + NICVF_DRV_STAT(rx_oversize), | |
| 70 | + NICVF_DRV_STAT(rx_undersize), | |
| 71 | + NICVF_DRV_STAT(rx_l2_len_mismatch), | |
| 72 | + NICVF_DRV_STAT(rx_l2_pclp), | |
| 73 | + NICVF_DRV_STAT(rx_ip_ver_errs), | |
| 74 | + NICVF_DRV_STAT(rx_ip_csum_errs), | |
| 75 | + NICVF_DRV_STAT(rx_ip_hdr_malformed), | |
| 76 | + NICVF_DRV_STAT(rx_ip_payload_malformed), | |
| 77 | + NICVF_DRV_STAT(rx_ip_ttl_errs), | |
| 78 | + NICVF_DRV_STAT(rx_l3_pclp), | |
| 79 | + NICVF_DRV_STAT(rx_l4_malformed), | |
| 80 | + NICVF_DRV_STAT(rx_l4_csum_errs), | |
| 81 | + NICVF_DRV_STAT(rx_udp_len_errs), | |
| 82 | + NICVF_DRV_STAT(rx_l4_port_errs), | |
| 83 | + NICVF_DRV_STAT(rx_tcp_flag_errs), | |
| 84 | + NICVF_DRV_STAT(rx_tcp_offset_errs), | |
| 85 | + NICVF_DRV_STAT(rx_l4_pclp), | |
| 86 | + NICVF_DRV_STAT(rx_truncated_pkts), | |
| 87 | + | |
| 88 | + NICVF_DRV_STAT(tx_desc_fault), | |
| 89 | + NICVF_DRV_STAT(tx_hdr_cons_err), | |
| 90 | + NICVF_DRV_STAT(tx_subdesc_err), | |
| 91 | + NICVF_DRV_STAT(tx_max_size_exceeded), | |
| 92 | + NICVF_DRV_STAT(tx_imm_size_oflow), | |
| 93 | + NICVF_DRV_STAT(tx_data_seq_err), | |
| 94 | + NICVF_DRV_STAT(tx_mem_seq_err), | |
| 95 | + NICVF_DRV_STAT(tx_lock_viol), | |
| 96 | + NICVF_DRV_STAT(tx_data_fault), | |
| 97 | + NICVF_DRV_STAT(tx_tstmp_conflict), | |
| 98 | + NICVF_DRV_STAT(tx_tstmp_timeout), | |
| 99 | + NICVF_DRV_STAT(tx_mem_fault), | |
| 100 | + NICVF_DRV_STAT(tx_csum_overlap), | |
| 101 | + NICVF_DRV_STAT(tx_csum_overflow), | |
| 102 | + | |
| 92 | 103 | NICVF_DRV_STAT(rcv_buffer_alloc_failures), |
| 93 | − NICVF_DRV_STAT(tx_frames_ok), | |
| 94 | 104 | NICVF_DRV_STAT(tx_tso), |
| 95 | − NICVF_DRV_STAT(tx_drops), | |
| 96 | 105 | NICVF_DRV_STAT(tx_timeout), |
| 97 | 106 | NICVF_DRV_STAT(txq_stop), |
| 98 | 107 | NICVF_DRV_STAT(txq_wake), |
| @@ -278,8 +287,8 @@ static void nicvf_get_ethtool_stats(struct net_device *netdev, · 179 unmodified lines | ||
| 278 | 287 | struct ethtool_stats *stats, u64 *data) |
| 279 | 288 | { |
| 280 | 289 | struct nicvf *nic = netdev_priv(netdev); |
| 281 | − int stat; | |
| 282 | − int sqs; | |
| 290 | + int stat, tmp_stats; | |
| 291 | + int sqs, cpu; | |
| 283 | 292 | |
| 284 | 293 | nicvf_update_stats(nic); |
| 285 | 294 | |
| @@ -289,9 +298,13 @@ static void nicvf_get_ethtool_stats(struct net_device *netdev, · 3 unmodified lines | ||
| 289 | 298 | for (stat = 0; stat < nicvf_n_hw_stats; stat++) |
| 290 | 299 | *(data++) = ((u64 *)&nic->hw_stats) |
| 291 | 300 | [nicvf_hw_stats[stat].index]; |
| 292 | − for (stat = 0; stat < nicvf_n_drv_stats; stat++) | |
| 293 | − *(data++) = ((u64 *)&nic->drv_stats) | |
| 294 | − [nicvf_drv_stats[stat].index]; | |
| 301 | + for (stat = 0; stat < nicvf_n_drv_stats; stat++) { | |
| 302 | + tmp_stats = 0; | |
| 303 | + for_each_possible_cpu(cpu) | |
| 304 | + tmp_stats += ((u64 *)per_cpu_ptr(nic->drv_stats, cpu)) | |
| 305 | + [nicvf_drv_stats[stat].index]; | |
| 306 | + *(data++) = tmp_stats; | |
| 307 | + } | |
| 295 | 308 | |
| 296 | 309 | nicvf_get_qset_stats(nic, stats, &data); |
| 297 | 310 | |
| @@ -69,25 +69,6 @@ static inline u8 nicvf_netdev_qidx(struct nicvf *nic, u8 qidx) · 68 unmodified lines | ||
| 69 | 69 | return qidx; |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | −static inline void nicvf_set_rx_frame_cnt(struct nicvf *nic, | |
| 73 | − struct sk_buff *skb) | |
| 74 | −{ | |
| 75 | − if (skb->len <= 64) | |
| 76 | − nic->drv_stats.rx_frames_64++; | |
| 77 | − else if (skb->len <= 127) | |
| 78 | − nic->drv_stats.rx_frames_127++; | |
| 79 | − else if (skb->len <= 255) | |
| 80 | − nic->drv_stats.rx_frames_255++; | |
| 81 | − else if (skb->len <= 511) | |
| 82 | − nic->drv_stats.rx_frames_511++; | |
| 83 | − else if (skb->len <= 1023) | |
| 84 | − nic->drv_stats.rx_frames_1023++; | |
| 85 | − else if (skb->len <= 1518) | |
| 86 | − nic->drv_stats.rx_frames_1518++; | |
| 87 | − else | |
| 88 | − nic->drv_stats.rx_frames_jumbo++; | |
| 89 | −} | |
| 90 | − | |
| 91 | 72 | /* The Cavium ThunderX network controller can *only* be found in SoCs |
| 92 | 73 | * containing the ThunderX ARM64 CPU implementation. All accesses to the device |
| 93 | 74 | * registers on this platform are implicitly strongly ordered with respect |
| @@ -492,9 +473,6 @@ int nicvf_set_real_num_queues(struct net_device *netdev, · 398 unmodified lines | ||
| 492 | 473 | static int nicvf_init_resources(struct nicvf *nic) |
| 493 | 474 | { |
| 494 | 475 | int err; |
| 495 | − union nic_mbx mbx = {}; | |
| 496 | − | |
| 497 | − mbx.msg.msg = NIC_MBOX_MSG_CFG_DONE; | |
| 498 | 476 | |
| 499 | 477 | /* Enable Qset */ |
| 500 | 478 | nicvf_qset_config(nic, true); |
| @@ -507,14 +485,10 @@ static int nicvf_init_resources(struct nicvf *nic) · 6 unmodified lines | ||
| 507 | 485 | return err; |
| 508 | 486 | } |
| 509 | 487 | |
| 510 | − /* Send VF config done msg to PF */ | |
| 511 | − nicvf_write_to_mbx(nic, &mbx); | |
| 512 | − | |
| 513 | 488 | return 0; |
| 514 | 489 | } |
| 515 | 490 | |
| 516 | 491 | static void nicvf_snd_pkt_handler(struct net_device *netdev, |
| 517 | − struct cmp_queue *cq, | |
| 518 | 492 | struct cqe_send_t *cqe_tx, |
| 519 | 493 | int cqe_type, int budget, |
| 520 | 494 | unsigned int *tx_pkts, unsigned int *tx_bytes) |
| @@ -536,7 +510,7 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev, · 15 unmodified lines | ||
| 536 | 510 | __func__, cqe_tx->sq_qs, cqe_tx->sq_idx, |
| 537 | 511 | cqe_tx->sqe_ptr, hdr->subdesc_cnt); |
| 538 | 512 | |
| 539 | − nicvf_check_cqe_tx_errs(nic, cq, cqe_tx); | |
| 513 | + nicvf_check_cqe_tx_errs(nic, cqe_tx); | |
| 540 | 514 | skb = (struct sk_buff *)sq->skbuff[cqe_tx->sqe_ptr]; |
| 541 | 515 | if (skb) { |
| 542 | 516 | /* Check for dummy descriptor used for HW TSO offload on 88xx */ |
| @@ -630,8 +604,6 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev, · 87 unmodified lines | ||
| 630 | 604 | return; |
| 631 | 605 | } |
| 632 | 606 | |
| 633 | − nicvf_set_rx_frame_cnt(nic, skb); | |
| 634 | − | |
| 635 | 607 | nicvf_set_rxhash(netdev, cqe_rx, skb); |
| 636 | 608 | |
| 637 | 609 | skb_record_rx_queue(skb, rq_idx); |
| @@ -703,7 +675,7 @@ loop: · 65 unmodified lines | ||
| 703 | 675 | work_done++; |
| 704 | 676 | break; |
| 705 | 677 | case CQE_TYPE_SEND: |
| 706 | − nicvf_snd_pkt_handler(netdev, cq, | |
| 678 | + nicvf_snd_pkt_handler(netdev, | |
| 707 | 679 | (void *)cq_desc, CQE_TYPE_SEND, |
| 708 | 680 | budget, &tx_pkts, &tx_bytes); |
| 709 | 681 | tx_done++; |
| @@ -740,7 +712,7 @@ done: · 30 unmodified lines | ||
| 740 | 712 | nic = nic->pnicvf; |
| 741 | 713 | if (netif_tx_queue_stopped(txq) && netif_carrier_ok(netdev)) { |
| 742 | 714 | netif_tx_start_queue(txq); |
| 743 | − nic->drv_stats.txq_wake++; | |
| 715 | + this_cpu_inc(nic->drv_stats->txq_wake); | |
| 744 | 716 | if (netif_msg_tx_err(nic)) |
| 745 | 717 | netdev_warn(netdev, |
| 746 | 718 | "%s: Transmit queue wakeup SQ%d\n", |
| @@ -1084,7 +1056,7 @@ static netdev_tx_t nicvf_xmit(struct sk_buff *skb, struct net_device *netdev) · 337 unmodified lines | ||
| 1084 | 1056 | |
| 1085 | 1057 | if (!netif_tx_queue_stopped(txq) && !nicvf_sq_append_skb(nic, skb)) { |
| 1086 | 1058 | netif_tx_stop_queue(txq); |
| 1087 | − nic->drv_stats.txq_stop++; | |
| 1059 | + this_cpu_inc(nic->drv_stats->txq_stop); | |
| 1088 | 1060 | if (netif_msg_tx_err(nic)) |
| 1089 | 1061 | netdev_warn(netdev, |
| 1090 | 1062 | "%s: Transmit ring full, stopping SQ%d\n", |
| @@ -1189,14 +1161,24 @@ int nicvf_stop(struct net_device *netdev) · 98 unmodified lines | ||
| 1189 | 1161 | return 0; |
| 1190 | 1162 | } |
| 1191 | 1163 | |
| 1164 | +static int nicvf_update_hw_max_frs(struct nicvf *nic, int mtu) | |
| 1165 | +{ | |
| 1166 | + union nic_mbx mbx = {}; | |
| 1167 | + | |
| 1168 | + mbx.frs.msg = NIC_MBOX_MSG_SET_MAX_FRS; | |
| 1169 | + mbx.frs.max_frs = mtu; | |
| 1170 | + mbx.frs.vf_id = nic->vf_id; | |
| 1171 | + | |
| 1172 | + return nicvf_send_msg_to_pf(nic, &mbx); | |
| 1173 | +} | |
| 1174 | + | |
| 1192 | 1175 | int nicvf_open(struct net_device *netdev) |
| 1193 | 1176 | { |
| 1194 | − int err, qidx; | |
| 1177 | + int cpu, err, qidx; | |
| 1195 | 1178 | struct nicvf *nic = netdev_priv(netdev); |
| 1196 | 1179 | struct queue_set *qs = nic->qs; |
| 1197 | 1180 | struct nicvf_cq_poll *cq_poll = NULL; |
| 1198 | − | |
| 1199 | − nic->mtu = netdev->mtu; | |
| 1181 | + union nic_mbx mbx = {}; | |
| 1200 | 1182 | |
| 1201 | 1183 | netif_carrier_off(netdev); |
| 1202 | 1184 | |
| @@ -1248,9 +1230,17 @@ int nicvf_open(struct net_device *netdev) · 45 unmodified lines | ||
| 1248 | 1230 | if (nic->sqs_mode) |
| 1249 | 1231 | nicvf_get_primary_vf_struct(nic); |
| 1250 | 1232 | |
| 1251 | − /* Configure receive side scaling */ | |
| 1252 | − if (!nic->sqs_mode) | |
| 1233 | + /* Configure receive side scaling and MTU */ | |
| 1234 | + if (!nic->sqs_mode) { | |
| 1253 | 1235 | nicvf_rss_init(nic); |
| 1236 | + if (nicvf_update_hw_max_frs(nic, netdev->mtu)) | |
| 1237 | + goto cleanup; | |
| 1238 | + | |
| 1239 | + /* Clear percpu stats */ | |
| 1240 | + for_each_possible_cpu(cpu) | |
| 1241 | + memset(per_cpu_ptr(nic->drv_stats, cpu), 0, | |
| 1242 | + sizeof(struct nicvf_drv_stats)); | |
| 1243 | + } | |
| 1254 | 1244 | |
| 1255 | 1245 | err = nicvf_register_interrupts(nic); |
| 1256 | 1246 | if (err) |
| @@ -1276,8 +1266,9 @@ int nicvf_open(struct net_device *netdev) · 19 unmodified lines | ||
| 1276 | 1266 | for (qidx = 0; qidx < qs->rbdr_cnt; qidx++) |
| 1277 | 1267 | nicvf_enable_intr(nic, NICVF_INTR_RBDR, qidx); |
| 1278 | 1268 | |
| 1279 | − nic->drv_stats.txq_stop = 0; | |
| 1280 | − nic->drv_stats.txq_wake = 0; | |
| 1269 | + /* Send VF config done msg to PF */ | |
| 1270 | + mbx.msg.msg = NIC_MBOX_MSG_CFG_DONE; | |
| 1271 | + nicvf_write_to_mbx(nic, &mbx); | |
| 1281 | 1272 | |
| 1282 | 1273 | return 0; |
| 1283 | 1274 | cleanup: |
| @@ -1297,17 +1288,6 @@ napi_del: · 13 unmodified lines | ||
| 1297 | 1288 | return err; |
| 1298 | 1289 | } |
| 1299 | 1290 | |
| 1300 | −static int nicvf_update_hw_max_frs(struct nicvf *nic, int mtu) | |
| 1301 | −{ | |
| 1302 | − union nic_mbx mbx = {}; | |
| 1303 | − | |
| 1304 | − mbx.frs.msg = NIC_MBOX_MSG_SET_MAX_FRS; | |
| 1305 | − mbx.frs.max_frs = mtu; | |
| 1306 | − mbx.frs.vf_id = nic->vf_id; | |
| 1307 | − | |
| 1308 | − return nicvf_send_msg_to_pf(nic, &mbx); | |
| 1309 | −} | |
| 1310 | − | |
| 1311 | 1291 | static int nicvf_change_mtu(struct net_device *netdev, int new_mtu) |
| 1312 | 1292 | { |
| 1313 | 1293 | struct nicvf *nic = netdev_priv(netdev); |
| @@ -1318,10 +1298,13 @@ static int nicvf_change_mtu(struct net_device *netdev, int new_mtu) · 4 unmodified lines | ||
| 1318 | 1298 | if (new_mtu < NIC_HW_MIN_FRS) |
| 1319 | 1299 | return -EINVAL; |
| 1320 | 1300 | |
| 1301 | + netdev->mtu = new_mtu; | |
| 1302 | + | |
| 1303 | + if (!netif_running(netdev)) | |
| 1304 | + return 0; | |
| 1305 | + | |
| 1321 | 1306 | if (nicvf_update_hw_max_frs(nic, new_mtu)) |
| 1322 | 1307 | return -EINVAL; |
| 1323 | − netdev->mtu = new_mtu; | |
| 1324 | − nic->mtu = new_mtu; | |
| 1325 | 1308 | |
| 1326 | 1309 | return 0; |
| 1327 | 1310 | } |
| @@ -1379,9 +1362,10 @@ void nicvf_update_lmac_stats(struct nicvf *nic) · 51 unmodified lines | ||
| 1379 | 1362 | |
| 1380 | 1363 | void nicvf_update_stats(struct nicvf *nic) |
| 1381 | 1364 | { |
| 1382 | − int qidx; | |
| 1365 | + int qidx, cpu; | |
| 1366 | + u64 tmp_stats = 0; | |
| 1383 | 1367 | struct nicvf_hw_stats *stats = &nic->hw_stats; |
| 1384 | − struct nicvf_drv_stats *drv_stats = &nic->drv_stats; | |
| 1368 | + struct nicvf_drv_stats *drv_stats; | |
| 1385 | 1369 | struct queue_set *qs = nic->qs; |
| 1386 | 1370 | |
| 1387 | 1371 | #define GET_RX_STATS(reg) \ |
| @@ -1404,21 +1388,33 @@ void nicvf_update_stats(struct nicvf *nic) · 16 unmodified lines | ||
| 1404 | 1388 | stats->rx_drop_l3_bcast = GET_RX_STATS(RX_DRP_L3BCAST); |
| 1405 | 1389 | stats->rx_drop_l3_mcast = GET_RX_STATS(RX_DRP_L3MCAST); |
| 1406 | 1390 | |
| 1407 | − stats->tx_bytes_ok = GET_TX_STATS(TX_OCTS); | |
| 1408 | − stats->tx_ucast_frames_ok = GET_TX_STATS(TX_UCAST); | |
| 1409 | − stats->tx_bcast_frames_ok = GET_TX_STATS(TX_BCAST); | |
| 1410 | − stats->tx_mcast_frames_ok = GET_TX_STATS(TX_MCAST); | |
| 1391 | + stats->tx_bytes = GET_TX_STATS(TX_OCTS); | |
| 1392 | + stats->tx_ucast_frames = GET_TX_STATS(TX_UCAST); | |
| 1393 | + stats->tx_bcast_frames = GET_TX_STATS(TX_BCAST); | |
| 1394 | + stats->tx_mcast_frames = GET_TX_STATS(TX_MCAST); | |
| 1411 | 1395 | stats->tx_drops = GET_TX_STATS(TX_DROP); |
| 1412 | 1396 | |
| 1413 | − drv_stats->tx_frames_ok = stats->tx_ucast_frames_ok + | |
| 1414 | − stats->tx_bcast_frames_ok + | |
| 1415 | − stats->tx_mcast_frames_ok; | |
| 1416 | − drv_stats->rx_frames_ok = stats->rx_ucast_frames + | |
| 1417 | − stats->rx_bcast_frames + | |
| 1418 | − stats->rx_mcast_frames; | |
| 1419 | − drv_stats->rx_drops = stats->rx_drop_red + | |
| 1420 | − stats->rx_drop_overrun; | |
| 1421 | − drv_stats->tx_drops = stats->tx_drops; | |
| 1397 | + /* On T88 pass 2.0, the dummy SQE added for TSO notification | |
| 1398 | + * via CQE has 'dont_send' set. Hence HW drops the pkt pointed | |
| 1399 | + * pointed by dummy SQE and results in tx_drops counter being | |
| 1400 | + * incremented. Subtracting it from tx_tso counter will give | |
| 1401 | + * exact tx_drops counter. | |
| 1402 | + */ | |
| 1403 | + if (nic->t88 && nic->hw_tso) { | |
| 1404 | + for_each_possible_cpu(cpu) { | |
| 1405 | + drv_stats = per_cpu_ptr(nic->drv_stats, cpu); | |
| 1406 | + tmp_stats += drv_stats->tx_tso; | |
| 1407 | + } | |
| 1408 | + stats->tx_drops = tmp_stats - stats->tx_drops; | |
| 1409 | + } | |
| 1410 | + stats->tx_frames = stats->tx_ucast_frames + | |
| 1411 | + stats->tx_bcast_frames + | |
| 1412 | + stats->tx_mcast_frames; | |
| 1413 | + stats->rx_frames = stats->rx_ucast_frames + | |
| 1414 | + stats->rx_bcast_frames + | |
| 1415 | + stats->rx_mcast_frames; | |
| 1416 | + stats->rx_drops = stats->rx_drop_red + | |
| 1417 | + stats->rx_drop_overrun; | |
| 1422 | 1418 | |
| 1423 | 1419 | /* Update RQ and SQ stats */ |
| 1424 | 1420 | for (qidx = 0; qidx < qs->rq_cnt; qidx++) |
| @@ -1432,18 +1428,17 @@ static struct rtnl_link_stats64 *nicvf_get_stats64(struct net_device *netdev, · 7 unmodified lines | ||
| 1432 | 1428 | { |
| 1433 | 1429 | struct nicvf *nic = netdev_priv(netdev); |
| 1434 | 1430 | struct nicvf_hw_stats *hw_stats = &nic->hw_stats; |
| 1435 | − struct nicvf_drv_stats *drv_stats = &nic->drv_stats; | |
| 1436 | 1431 | |
| 1437 | 1432 | nicvf_update_stats(nic); |
| 1438 | 1433 | |
| 1439 | 1434 | stats->rx_bytes = hw_stats->rx_bytes; |
| 1440 | − stats->rx_packets = drv_stats->rx_frames_ok; | |
| 1441 | − stats->rx_dropped = drv_stats->rx_drops; | |
| 1435 | + stats->rx_packets = hw_stats->rx_frames; | |
| 1436 | + stats->rx_dropped = hw_stats->rx_drops; | |
| 1442 | 1437 | stats->multicast = hw_stats->rx_mcast_frames; |
| 1443 | 1438 | |
| 1444 | − stats->tx_bytes = hw_stats->tx_bytes_ok; | |
| 1445 | − stats->tx_packets = drv_stats->tx_frames_ok; | |
| 1446 | − stats->tx_dropped = drv_stats->tx_drops; | |
| 1439 | + stats->tx_bytes = hw_stats->tx_bytes; | |
| 1440 | + stats->tx_packets = hw_stats->tx_frames; | |
| 1441 | + stats->tx_dropped = hw_stats->tx_drops; | |
| 1447 | 1442 | |
| 1448 | 1443 | return stats; |
| 1449 | 1444 | } |
| @@ -1456,7 +1451,7 @@ static void nicvf_tx_timeout(struct net_device *dev) · 6 unmodified lines | ||
| 1456 | 1451 | netdev_warn(dev, "%s: Transmit timed out, resetting\n", |
| 1457 | 1452 | dev->name); |
| 1458 | 1453 | |
| 1459 | − nic->drv_stats.tx_timeout++; | |
| 1454 | + this_cpu_inc(nic->drv_stats->tx_timeout); | |
| 1460 | 1455 | schedule_work(&nic->reset_task); |
| 1461 | 1456 | } |
| 1462 | 1457 | |
| @@ -1590,6 +1585,12 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 127 unmodified lines | ||
| 1590 | 1585 | goto err_free_netdev; |
| 1591 | 1586 | } |
| 1592 | 1587 | |
| 1588 | + nic->drv_stats = netdev_alloc_pcpu_stats(struct nicvf_drv_stats); | |
| 1589 | + if (!nic->drv_stats) { | |
| 1590 | + err = -ENOMEM; | |
| 1591 | + goto err_free_netdev; | |
| 1592 | + } | |
| 1593 | + | |
| 1593 | 1594 | err = nicvf_set_qset_resources(nic); |
| 1594 | 1595 | if (err) |
| 1595 | 1596 | goto err_free_netdev; |
| @@ -1648,6 +1649,8 @@ err_unregister_interrupts: · 52 unmodified lines | ||
| 1648 | 1649 | nicvf_unregister_interrupts(nic); |
| 1649 | 1650 | err_free_netdev: |
| 1650 | 1651 | pci_set_drvdata(pdev, NULL); |
| 1652 | + if (nic->drv_stats) | |
| 1653 | + free_percpu(nic->drv_stats); | |
| 1651 | 1654 | free_netdev(netdev); |
| 1652 | 1655 | err_release_regions: |
| 1653 | 1656 | pci_release_regions(pdev); |
| @@ -1675,6 +1678,8 @@ static void nicvf_remove(struct pci_dev *pdev) · 21 unmodified lines | ||
| 1675 | 1678 | unregister_netdev(pnetdev); |
| 1676 | 1679 | nicvf_unregister_interrupts(nic); |
| 1677 | 1680 | pci_set_drvdata(pdev, NULL); |
| 1681 | + if (nic->drv_stats) | |
| 1682 | + free_percpu(nic->drv_stats); | |
| 1678 | 1683 | free_netdev(netdev); |
| 1679 | 1684 | pci_release_regions(pdev); |
| 1680 | 1685 | pci_disable_device(pdev); |
| @@ -104,7 +104,8 @@ static inline int nicvf_alloc_rcv_buffer(struct nicvf *nic, gfp_t gfp, · 103 unmodified lines | ||
| 104 | 104 | nic->rb_page = alloc_pages(gfp | __GFP_COMP | __GFP_NOWARN, |
| 105 | 105 | order); |
| 106 | 106 | if (!nic->rb_page) { |
| 107 | − nic->drv_stats.rcv_buffer_alloc_failures++; | |
| 107 | + this_cpu_inc(nic->pnicvf->drv_stats-> | |
| 108 | + rcv_buffer_alloc_failures); | |
| 108 | 109 | return -ENOMEM; |
| 109 | 110 | } |
| 110 | 111 | nic->rb_page_offset = 0; |
| @@ -270,7 +271,8 @@ refill: · 159 unmodified lines | ||
| 270 | 271 | rbdr_idx, new_rb); |
| 271 | 272 | next_rbdr: |
| 272 | 273 | /* Re-enable RBDR interrupts only if buffer allocation is success */ |
| 273 | − if (!nic->rb_alloc_fail && rbdr->enable) | |
| 274 | + if (!nic->rb_alloc_fail && rbdr->enable && | |
| 275 | + netif_running(nic->pnicvf->netdev)) | |
| 274 | 276 | nicvf_enable_intr(nic, NICVF_INTR_RBDR, rbdr_idx); |
| 275 | 277 | |
| 276 | 278 | if (rbdr_idx) |
| @@ -361,6 +363,8 @@ static int nicvf_init_snd_queue(struct nicvf *nic, · 84 unmodified lines | ||
| 361 | 363 | |
| 362 | 364 | static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq) |
| 363 | 365 | { |
| 366 | + struct sk_buff *skb; | |
| 367 | + | |
| 364 | 368 | if (!sq) |
| 365 | 369 | return; |
| 366 | 370 | if (!sq->dmem.base) |
| @@ -371,6 +375,15 @@ static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq) · 4 unmodified lines | ||
| 371 | 375 | sq->dmem.q_len * TSO_HEADER_SIZE, |
| 372 | 376 | sq->tso_hdrs, sq->tso_hdrs_phys); |
| 373 | 377 | |
| 378 | + /* Free pending skbs in the queue */ | |
| 379 | + smp_rmb(); | |
| 380 | + while (sq->head != sq->tail) { | |
| 381 | + skb = (struct sk_buff *)sq->skbuff[sq->head]; | |
| 382 | + if (skb) | |
| 383 | + dev_kfree_skb_any(skb); | |
| 384 | + sq->head++; | |
| 385 | + sq->head &= (sq->dmem.q_len - 1); | |
| 386 | + } | |
| 374 | 387 | kfree(sq->skbuff); |
| 375 | 388 | nicvf_free_q_desc_mem(nic, &sq->dmem); |
| 376 | 389 | } |
| @@ -483,9 +496,12 @@ static void nicvf_reset_rcv_queue_stats(struct nicvf *nic) · 106 unmodified lines | ||
| 483 | 496 | { |
| 484 | 497 | union nic_mbx mbx = {}; |
| 485 | 498 | |
| 486 | − /* Reset all RXQ's stats */ | |
| 499 | + /* Reset all RQ/SQ and VF stats */ | |
| 487 | 500 | mbx.reset_stat.msg = NIC_MBOX_MSG_RESET_STAT_COUNTER; |
| 501 | + mbx.reset_stat.rx_stat_mask = 0x3FFF; | |
| 502 | + mbx.reset_stat.tx_stat_mask = 0x1F; | |
| 488 | 503 | mbx.reset_stat.rq_stat_mask = 0xFFFF; |
| 504 | + mbx.reset_stat.sq_stat_mask = 0xFFFF; | |
| 489 | 505 | nicvf_send_msg_to_pf(nic, &mbx); |
| 490 | 506 | } |
| 491 | 507 | |
| @@ -538,9 +554,12 @@ static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs, · 46 unmodified lines | ||
| 538 | 554 | mbx.rq.cfg = (1ULL << 62) | (RQ_CQ_DROP << 8); |
| 539 | 555 | nicvf_send_msg_to_pf(nic, &mbx); |
| 540 | 556 | |
| 541 | − nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, 0x00); | |
| 542 | − if (!nic->sqs_mode) | |
| 557 | + if (!nic->sqs_mode && (qidx == 0)) { | |
| 558 | + /* Enable checking L3/L4 length and TCP/UDP checksums */ | |
| 559 | + nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, | |
| 560 | + (BIT(24) | BIT(23) | BIT(21))); | |
| 543 | 561 | nicvf_config_vlan_stripping(nic, nic->netdev->features); |
| 562 | + } | |
| 544 | 563 | |
| 545 | 564 | /* Enable Receive queue */ |
| 546 | 565 | memset(&rq_cfg, 0, sizeof(struct rq_cfg)); |
| @@ -1029,7 +1048,7 @@ nicvf_sq_add_hdr_subdesc(struct nicvf *nic, struct snd_queue *sq, int qentry, · 482 unmodified lines | ||
| 1029 | 1048 | hdr->tso_max_paysize = skb_shinfo(skb)->gso_size; |
| 1030 | 1049 | /* For non-tunneled pkts, point this to L2 ethertype */ |
| 1031 | 1050 | hdr->inner_l3_offset = skb_network_offset(skb) - 2; |
| 1032 | − nic->drv_stats.tx_tso++; | |
| 1051 | + this_cpu_inc(nic->pnicvf->drv_stats->tx_tso); | |
| 1033 | 1052 | } |
| 1034 | 1053 | } |
| 1035 | 1054 | |
| @@ -1161,7 +1180,7 @@ static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq, · 125 unmodified lines | ||
| 1161 | 1180 | |
| 1162 | 1181 | nicvf_sq_doorbell(nic, skb, sq_num, desc_cnt); |
| 1163 | 1182 | |
| 1164 | − nic->drv_stats.tx_tso++; | |
| 1183 | + this_cpu_inc(nic->pnicvf->drv_stats->tx_tso); | |
| 1165 | 1184 | return 1; |
| 1166 | 1185 | } |
| 1167 | 1186 | |
| @@ -1422,8 +1441,6 @@ void nicvf_update_sq_stats(struct nicvf *nic, int sq_idx) · 254 unmodified lines | ||
| 1422 | 1441 | /* Check for errors in the receive cmp.queue entry */ |
| 1423 | 1442 | int nicvf_check_cqe_rx_errs(struct nicvf *nic, struct cqe_rx_t *cqe_rx) |
| 1424 | 1443 | { |
| 1425 | − struct nicvf_hw_stats *stats = &nic->hw_stats; | |
| 1426 | − | |
| 1427 | 1444 | if (!cqe_rx->err_level && !cqe_rx->err_opcode) |
| 1428 | 1445 | return 0; |
| 1429 | 1446 | |
| @@ -1435,76 +1452,76 @@ int nicvf_check_cqe_rx_errs(struct nicvf *nic, struct cqe_rx_t *cqe_rx) · 5 unmodified lines | ||
| 1435 | 1452 | |
| 1436 | 1453 | switch (cqe_rx->err_opcode) { |
| 1437 | 1454 | case CQ_RX_ERROP_RE_PARTIAL: |
| 1438 | − stats->rx_bgx_truncated_pkts++; | |
| 1455 | + this_cpu_inc(nic->drv_stats->rx_bgx_truncated_pkts); | |
| 1439 | 1456 | break; |
| 1440 | 1457 | case CQ_RX_ERROP_RE_JABBER: |
| 1441 | − stats->rx_jabber_errs++; | |
| 1458 | + this_cpu_inc(nic->drv_stats->rx_jabber_errs); | |
| 1442 | 1459 | break; |
| 1443 | 1460 | case CQ_RX_ERROP_RE_FCS: |
| 1444 | − stats->rx_fcs_errs++; | |
| 1461 | + this_cpu_inc(nic->drv_stats->rx_fcs_errs); | |
| 1445 | 1462 | break; |
| 1446 | 1463 | case CQ_RX_ERROP_RE_RX_CTL: |
| 1447 | − stats->rx_bgx_errs++; | |
| 1464 | + this_cpu_inc(nic->drv_stats->rx_bgx_errs); | |
| 1448 | 1465 | break; |
| 1449 | 1466 | case CQ_RX_ERROP_PREL2_ERR: |
| 1450 | − stats->rx_prel2_errs++; | |
| 1467 | + this_cpu_inc(nic->drv_stats->rx_prel2_errs); | |
| 1451 | 1468 | break; |
| 1452 | 1469 | case CQ_RX_ERROP_L2_MAL: |
| 1453 | − stats->rx_l2_hdr_malformed++; | |
| 1470 | + this_cpu_inc(nic->drv_stats->rx_l2_hdr_malformed); | |
| 1454 | 1471 | break; |
| 1455 | 1472 | case CQ_RX_ERROP_L2_OVERSIZE: |
| 1456 | − stats->rx_oversize++; | |
| 1473 | + this_cpu_inc(nic->drv_stats->rx_oversize); | |
| 1457 | 1474 | break; |
| 1458 | 1475 | case CQ_RX_ERROP_L2_UNDERSIZE: |
| 1459 | − stats->rx_undersize++; | |
| 1476 | + this_cpu_inc(nic->drv_stats->rx_undersize); | |
| 1460 | 1477 | break; |
| 1461 | 1478 | case CQ_RX_ERROP_L2_LENMISM: |
| 1462 | − stats->rx_l2_len_mismatch++; | |
| 1479 | + this_cpu_inc(nic->drv_stats->rx_l2_len_mismatch); | |
| 1463 | 1480 | break; |
| 1464 | 1481 | case CQ_RX_ERROP_L2_PCLP: |
| 1465 | − stats->rx_l2_pclp++; | |
| 1482 | + this_cpu_inc(nic->drv_stats->rx_l2_pclp); | |
| 1466 | 1483 | break; |
| 1467 | 1484 | case CQ_RX_ERROP_IP_NOT: |
| 1468 | − stats->rx_ip_ver_errs++; | |
| 1485 | + this_cpu_inc(nic->drv_stats->rx_ip_ver_errs); | |
| 1469 | 1486 | break; |
| 1470 | 1487 | case CQ_RX_ERROP_IP_CSUM_ERR: |
| 1471 | − stats->rx_ip_csum_errs++; | |
| 1488 | + this_cpu_inc(nic->drv_stats->rx_ip_csum_errs); | |
| 1472 | 1489 | break; |
| 1473 | 1490 | case CQ_RX_ERROP_IP_MAL: |
| 1474 | − stats->rx_ip_hdr_malformed++; | |
| 1491 | + this_cpu_inc(nic->drv_stats->rx_ip_hdr_malformed); | |
| 1475 | 1492 | break; |
| 1476 | 1493 | case CQ_RX_ERROP_IP_MALD: |
| 1477 | − stats->rx_ip_payload_malformed++; | |
| 1494 | + this_cpu_inc(nic->drv_stats->rx_ip_payload_malformed); | |
| 1478 | 1495 | break; |
| 1479 | 1496 | case CQ_RX_ERROP_IP_HOP: |
| 1480 | − stats->rx_ip_ttl_errs++; | |
| 1497 | + this_cpu_inc(nic->drv_stats->rx_ip_ttl_errs); | |
| 1481 | 1498 | break; |
| 1482 | 1499 | case CQ_RX_ERROP_L3_PCLP: |
| 1483 | − stats->rx_l3_pclp++; | |
| 1500 | + this_cpu_inc(nic->drv_stats->rx_l3_pclp); | |
| 1484 | 1501 | break; |
| 1485 | 1502 | case CQ_RX_ERROP_L4_MAL: |
| 1486 | − stats->rx_l4_malformed++; | |
| 1503 | + this_cpu_inc(nic->drv_stats->rx_l4_malformed); | |
| 1487 | 1504 | break; |
| 1488 | 1505 | case CQ_RX_ERROP_L4_CHK: |
| 1489 | − stats->rx_l4_csum_errs++; | |
| 1506 | + this_cpu_inc(nic->drv_stats->rx_l4_csum_errs); | |
| 1490 | 1507 | break; |
| 1491 | 1508 | case CQ_RX_ERROP_UDP_LEN: |
| 1492 | − stats->rx_udp_len_errs++; | |
| 1509 | + this_cpu_inc(nic->drv_stats->rx_udp_len_errs); | |
| 1493 | 1510 | break; |
| 1494 | 1511 | case CQ_RX_ERROP_L4_PORT: |
| 1495 | − stats->rx_l4_port_errs++; | |
| 1512 | + this_cpu_inc(nic->drv_stats->rx_l4_port_errs); | |
| 1496 | 1513 | break; |
| 1497 | 1514 | case CQ_RX_ERROP_TCP_FLAG: |
| 1498 | − stats->rx_tcp_flag_errs++; | |
| 1515 | + this_cpu_inc(nic->drv_stats->rx_tcp_flag_errs); | |
| 1499 | 1516 | break; |
| 1500 | 1517 | case CQ_RX_ERROP_TCP_OFFSET: |
| 1501 | − stats->rx_tcp_offset_errs++; | |
| 1518 | + this_cpu_inc(nic->drv_stats->rx_tcp_offset_errs); | |
| 1502 | 1519 | break; |
| 1503 | 1520 | case CQ_RX_ERROP_L4_PCLP: |
| 1504 | − stats->rx_l4_pclp++; | |
| 1521 | + this_cpu_inc(nic->drv_stats->rx_l4_pclp); | |
| 1505 | 1522 | break; |
| 1506 | 1523 | case CQ_RX_ERROP_RBDR_TRUNC: |
| 1507 | − stats->rx_truncated_pkts++; | |
| 1524 | + this_cpu_inc(nic->drv_stats->rx_truncated_pkts); | |
| 1508 | 1525 | break; |
| 1509 | 1526 | } |
| 1510 | 1527 | |
| @@ -1512,53 +1529,52 @@ int nicvf_check_cqe_rx_errs(struct nicvf *nic, struct cqe_rx_t *cqe_rx) · 1 unmodified line | ||
| 1512 | 1529 | } |
| 1513 | 1530 | |
| 1514 | 1531 | /* Check for errors in the send cmp.queue entry */ |
| 1515 | −int nicvf_check_cqe_tx_errs(struct nicvf *nic, | |
| 1516 | − struct cmp_queue *cq, struct cqe_send_t *cqe_tx) | |
| 1532 | +int nicvf_check_cqe_tx_errs(struct nicvf *nic, struct cqe_send_t *cqe_tx) | |
| 1517 | 1533 | { |
| 1518 | − struct cmp_queue_stats *stats = &cq->stats; | |
| 1519 | − | |
| 1520 | 1534 | switch (cqe_tx->send_status) { |
| 1521 | 1535 | case CQ_TX_ERROP_GOOD: |
| 1522 | − stats->tx.good++; | |
| 1523 | 1536 | return 0; |
| 1524 | 1537 | case CQ_TX_ERROP_DESC_FAULT: |
| 1525 | − stats->tx.desc_fault++; | |
| 1538 | + this_cpu_inc(nic->drv_stats->tx_desc_fault); | |
| 1526 | 1539 | break; |
| 1527 | 1540 | case CQ_TX_ERROP_HDR_CONS_ERR: |
| 1528 | − stats->tx.hdr_cons_err++; | |
| 1541 | + this_cpu_inc(nic->drv_stats->tx_hdr_cons_err); | |
| 1529 | 1542 | break; |
| 1530 | 1543 | case CQ_TX_ERROP_SUBDC_ERR: |
| 1531 | − stats->tx.subdesc_err++; | |
| 1544 | + this_cpu_inc(nic->drv_stats->tx_subdesc_err); | |
| 1545 | + break; | |
| 1546 | + case CQ_TX_ERROP_MAX_SIZE_VIOL: | |
| 1547 | + this_cpu_inc(nic->drv_stats->tx_max_size_exceeded); | |
| 1532 | 1548 | break; |
| 1533 | 1549 | case CQ_TX_ERROP_IMM_SIZE_OFLOW: |
| 1534 | − stats->tx.imm_size_oflow++; | |
| 1550 | + this_cpu_inc(nic->drv_stats->tx_imm_size_oflow); | |
| 1535 | 1551 | break; |
| 1536 | 1552 | case CQ_TX_ERROP_DATA_SEQUENCE_ERR: |
| 1537 | − stats->tx.data_seq_err++; | |
| 1553 | + this_cpu_inc(nic->drv_stats->tx_data_seq_err); | |
| 1538 | 1554 | break; |
| 1539 | 1555 | case CQ_TX_ERROP_MEM_SEQUENCE_ERR: |
| 1540 | − stats->tx.mem_seq_err++; | |
| 1556 | + this_cpu_inc(nic->drv_stats->tx_mem_seq_err); | |
| 1541 | 1557 | break; |
| 1542 | 1558 | case CQ_TX_ERROP_LOCK_VIOL: |
| 1543 | − stats->tx.lock_viol++; | |
| 1559 | + this_cpu_inc(nic->drv_stats->tx_lock_viol); | |
| 1544 | 1560 | break; |
| 1545 | 1561 | case CQ_TX_ERROP_DATA_FAULT: |
| 1546 | − stats->tx.data_fault++; | |
| 1562 | + this_cpu_inc(nic->drv_stats->tx_data_fault); | |
| 1547 | 1563 | break; |
| 1548 | 1564 | case CQ_TX_ERROP_TSTMP_CONFLICT: |
| 1549 | − stats->tx.tstmp_conflict++; | |
| 1565 | + this_cpu_inc(nic->drv_stats->tx_tstmp_conflict); | |
| 1550 | 1566 | break; |
| 1551 | 1567 | case CQ_TX_ERROP_TSTMP_TIMEOUT: |
| 1552 | − stats->tx.tstmp_timeout++; | |
| 1568 | + this_cpu_inc(nic->drv_stats->tx_tstmp_timeout); | |
| 1553 | 1569 | break; |
| 1554 | 1570 | case CQ_TX_ERROP_MEM_FAULT: |
| 1555 | − stats->tx.mem_fault++; | |
| 1571 | + this_cpu_inc(nic->drv_stats->tx_mem_fault); | |
| 1556 | 1572 | break; |
| 1557 | 1573 | case CQ_TX_ERROP_CK_OVERLAP: |
| 1558 | − stats->tx.csum_overlap++; | |
| 1574 | + this_cpu_inc(nic->drv_stats->tx_csum_overlap); | |
| 1559 | 1575 | break; |
| 1560 | 1576 | case CQ_TX_ERROP_CK_OFLOW: |
| 1561 | − stats->tx.csum_overflow++; | |
| 1577 | + this_cpu_inc(nic->drv_stats->tx_csum_overflow); | |
| 1562 | 1578 | break; |
| 1563 | 1579 | } |
| 1564 | 1580 | |
| @@ -158,6 +158,7 @@ enum CQ_TX_ERROP_E { · 157 unmodified lines | ||
| 158 | 158 | CQ_TX_ERROP_DESC_FAULT = 0x10, |
| 159 | 159 | CQ_TX_ERROP_HDR_CONS_ERR = 0x11, |
| 160 | 160 | CQ_TX_ERROP_SUBDC_ERR = 0x12, |
| 161 | + CQ_TX_ERROP_MAX_SIZE_VIOL = 0x13, | |
| 161 | 162 | CQ_TX_ERROP_IMM_SIZE_OFLOW = 0x80, |
| 162 | 163 | CQ_TX_ERROP_DATA_SEQUENCE_ERR = 0x81, |
| 163 | 164 | CQ_TX_ERROP_MEM_SEQUENCE_ERR = 0x82, |
| @@ -171,25 +172,6 @@ enum CQ_TX_ERROP_E { · 7 unmodified lines | ||
| 171 | 172 | CQ_TX_ERROP_ENUM_LAST = 0x8a, |
| 172 | 173 | }; |
| 173 | 174 | |
| 174 | −struct cmp_queue_stats { | |
| 175 | − struct tx_stats { | |
| 176 | − u64 good; | |
| 177 | − u64 desc_fault; | |
| 178 | − u64 hdr_cons_err; | |
| 179 | − u64 subdesc_err; | |
| 180 | − u64 imm_size_oflow; | |
| 181 | − u64 data_seq_err; | |
| 182 | − u64 mem_seq_err; | |
| 183 | − u64 lock_viol; | |
| 184 | − u64 data_fault; | |
| 185 | − u64 tstmp_conflict; | |
| 186 | − u64 tstmp_timeout; | |
| 187 | − u64 mem_fault; | |
| 188 | − u64 csum_overlap; | |
| 189 | − u64 csum_overflow; | |
| 190 | − } tx; | |
| 191 | −} ____cacheline_aligned_in_smp; | |
| 192 | − | |
| 193 | 175 | enum RQ_SQ_STATS { |
| 194 | 176 | RQ_SQ_STATS_OCTS, |
| 195 | 177 | RQ_SQ_STATS_PKTS, |
| @@ -241,7 +223,6 @@ struct cmp_queue { · 45 unmodified lines | ||
| 241 | 223 | spinlock_t lock; /* lock to serialize processing CQEs */ |
| 242 | 224 | void *desc; |
| 243 | 225 | struct q_desc_mem dmem; |
| 244 | − struct cmp_queue_stats stats; | |
| 245 | 226 | int irq; |
| 246 | 227 | } ____cacheline_aligned_in_smp; |
| 247 | 228 | |
| @@ -336,6 +317,5 @@ u64 nicvf_queue_reg_read(struct nicvf *nic, · 88 unmodified lines | ||
| 336 | 317 | void nicvf_update_rq_stats(struct nicvf *nic, int rq_idx); |
| 337 | 318 | void nicvf_update_sq_stats(struct nicvf *nic, int sq_idx); |
| 338 | 319 | int nicvf_check_cqe_rx_errs(struct nicvf *nic, struct cqe_rx_t *cqe_rx); |
| 339 | −int nicvf_check_cqe_tx_errs(struct nicvf *nic, | |
| 340 | − struct cmp_queue *cq, struct cqe_send_t *cqe_tx); | |
| 320 | +int nicvf_check_cqe_tx_errs(struct nicvf *nic, struct cqe_send_t *cqe_tx); | |
| 341 | 321 | #endif /* NICVF_QUEUES_H */ |
| @@ -1242,8 +1242,8 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 1241 unmodified lines | ||
| 1242 | 1242 | |
| 1243 | 1243 | pci_read_config_word(pdev, PCI_DEVICE_ID, &sdevid); |
| 1244 | 1244 | if (sdevid != PCI_DEVICE_ID_THUNDER_RGX) { |
| 1245 | − bgx->bgx_id = | |
| 1246 | − (pci_resource_start(pdev, PCI_CFG_REG_BAR_NUM) >> 24) & 1; | |
| 1245 | + bgx->bgx_id = (pci_resource_start(pdev, | |
| 1246 | + PCI_CFG_REG_BAR_NUM) >> 24) & BGX_ID_MASK; | |
| 1247 | 1247 | bgx->bgx_id += nic_get_node_id(pdev) * MAX_BGX_PER_NODE; |
| 1248 | 1248 | bgx->max_lmac = MAX_LMAC_PER_BGX; |
| 1249 | 1249 | bgx_vnic[bgx->bgx_id] = bgx; |
| @@ -28,6 +28,8 @@ · 27 unmodified lines | ||
| 28 | 28 | #define MAX_DMAC_PER_LMAC 8 |
| 29 | 29 | #define MAX_FRAME_SIZE 9216 |
| 30 | 30 | |
| 31 | +#define BGX_ID_MASK 0x3 | |
| 32 | + | |
| 31 | 33 | #define MAX_DMAC_PER_LMAC_TNS_BYPASS_MODE 2 |
| 32 | 34 | |
| 33 | 35 | /* Registers */ |
| @@ -2951,7 +2951,6 @@ void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, · 2950 unmodified lines | ||
| 2951 | 2951 | rq->cntxt_id, fl_id, 0xffff); |
| 2952 | 2952 | dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len, |
| 2953 | 2953 | rq->desc, rq->phys_addr); |
| 2954 | − napi_hash_del(&rq->napi); | |
| 2955 | 2954 | netif_napi_del(&rq->napi); |
| 2956 | 2955 | rq->netdev = NULL; |
| 2957 | 2956 | rq->cntxt_id = rq->abs_id = 0; |
| @@ -178,9 +178,9 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN · 177 unmodified lines | ||
| 178 | 178 | CH_PCI_ID_TABLE_FENTRY(0x6005), |
| 179 | 179 | CH_PCI_ID_TABLE_FENTRY(0x6006), |
| 180 | 180 | CH_PCI_ID_TABLE_FENTRY(0x6007), |
| 181 | + CH_PCI_ID_TABLE_FENTRY(0x6008), | |
| 181 | 182 | CH_PCI_ID_TABLE_FENTRY(0x6009), |
| 182 | 183 | CH_PCI_ID_TABLE_FENTRY(0x600d), |
| 183 | − CH_PCI_ID_TABLE_FENTRY(0x6010), | |
| 184 | 184 | CH_PCI_ID_TABLE_FENTRY(0x6011), |
| 185 | 185 | CH_PCI_ID_TABLE_FENTRY(0x6014), |
| 186 | 186 | CH_PCI_ID_TABLE_FENTRY(0x6015), |
| @@ -2813,7 +2813,6 @@ static void be_evt_queues_destroy(struct be_adapter *adapter) · 2812 unmodified lines | ||
| 2813 | 2813 | if (eqo->q.created) { |
| 2814 | 2814 | be_eq_clean(eqo); |
| 2815 | 2815 | be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ); |
| 2816 | − napi_hash_del(&eqo->napi); | |
| 2817 | 2816 | netif_napi_del(&eqo->napi); |
| 2818 | 2817 | free_cpumask_var(eqo->affinity_mask); |
| 2819 | 2818 | } |
| @@ -332,8 +332,10 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev, · 331 unmodified lines | ||
| 332 | 332 | return ERR_PTR(-ENODEV); |
| 333 | 333 | |
| 334 | 334 | handle = dev->ops->get_handle(dev, port_id); |
| 335 | − if (IS_ERR(handle)) | |
| 335 | + if (IS_ERR(handle)) { | |
| 336 | + put_device(&dev->cls_dev); | |
| 336 | 337 | return handle; |
| 338 | + } | |
| 337 | 339 | |
| 338 | 340 | handle->dev = dev; |
| 339 | 341 | handle->owner_dev = owner_dev; |
| @@ -356,6 +358,8 @@ out_when_init_queue: · 16 unmodified lines | ||
| 356 | 358 | for (j = i - 1; j >= 0; j--) |
| 357 | 359 | hnae_fini_queue(handle->qs[j]); |
| 358 | 360 | |
| 361 | + put_device(&dev->cls_dev); | |
| 362 | + | |
| 359 | 363 | return ERR_PTR(-ENOMEM); |
| 360 | 364 | } |
| 361 | 365 | EXPORT_SYMBOL(hnae_get_handle); |
| @@ -377,6 +381,8 @@ void hnae_put_handle(struct hnae_handle *h) · 15 unmodified lines | ||
| 377 | 381 | dev->ops->put_handle(h); |
| 378 | 382 | |
| 379 | 383 | module_put(dev->owner); |
| 384 | + | |
| 385 | + put_device(&dev->cls_dev); | |
| 380 | 386 | } |
| 381 | 387 | EXPORT_SYMBOL(hnae_put_handle); |
| 382 | 388 | |
| @@ -2446,6 +2446,8 @@ static int ehea_open(struct net_device *dev) · 2445 unmodified lines | ||
| 2446 | 2446 | |
| 2447 | 2447 | netif_info(port, ifup, dev, "enabling port\n"); |
| 2448 | 2448 | |
| 2449 | + netif_carrier_off(dev); | |
| 2450 | + | |
| 2449 | 2451 | ret = ehea_up(dev); |
| 2450 | 2452 | if (!ret) { |
| 2451 | 2453 | port_napi_enable(port); |
| @@ -1505,9 +1505,8 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry) · 1504 unmodified lines | ||
| 1505 | 1505 | adapter->max_rx_add_entries_per_subcrq > entries_page ? |
| 1506 | 1506 | entries_page : adapter->max_rx_add_entries_per_subcrq; |
| 1507 | 1507 | |
| 1508 | − /* Choosing the maximum number of queues supported by firmware*/ | |
| 1509 | − adapter->req_tx_queues = adapter->max_tx_queues; | |
| 1510 | − adapter->req_rx_queues = adapter->max_rx_queues; | |
| 1508 | + adapter->req_tx_queues = adapter->opt_tx_comp_sub_queues; | |
| 1509 | + adapter->req_rx_queues = adapter->opt_rx_comp_queues; | |
| 1511 | 1510 | adapter->req_rx_add_queues = adapter->max_rx_add_queues; |
| 1512 | 1511 | |
| 1513 | 1512 | adapter->req_mtu = adapter->max_mtu; |
| @@ -3706,7 +3705,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) · 2192 unmodified lines | ||
| 3706 | 3705 | struct net_device *netdev; |
| 3707 | 3706 | unsigned char *mac_addr_p; |
| 3708 | 3707 | struct dentry *ent; |
| 3709 | − char buf[16]; /* debugfs name buf */ | |
| 3708 | + char buf[17]; /* debugfs name buf */ | |
| 3710 | 3709 | int rc; |
| 3711 | 3710 | |
| 3712 | 3711 | dev_dbg(&dev->dev, "entering ibmvnic_probe for UA 0x%x\n", |
| @@ -3845,6 +3844,9 @@ static int ibmvnic_remove(struct vio_dev *dev) · 132 unmodified lines | ||
| 3845 | 3844 | if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir)) |
| 3846 | 3845 | debugfs_remove_recursive(adapter->debugfs_dir); |
| 3847 | 3846 | |
| 3847 | + dma_unmap_single(&dev->dev, adapter->stats_token, | |
| 3848 | + sizeof(struct ibmvnic_statistics), DMA_FROM_DEVICE); | |
| 3849 | + | |
| 3848 | 3850 | if (adapter->ras_comps) |
| 3849 | 3851 | dma_free_coherent(&dev->dev, |
| 3850 | 3852 | adapter->ras_comp_num * |
| @@ -1381,6 +1381,7 @@ static unsigned int get_rx_coal(struct mv643xx_eth_private *mp) · 1380 unmodified lines | ||
| 1381 | 1381 | temp = (val & 0x003fff00) >> 8; |
| 1382 | 1382 | |
| 1383 | 1383 | temp *= 64000000; |
| 1384 | + temp += mp->t_clk / 2; | |
| 1384 | 1385 | do_div(temp, mp->t_clk); |
| 1385 | 1386 | |
| 1386 | 1387 | return (unsigned int)temp; |
| @@ -1417,6 +1418,7 @@ static unsigned int get_tx_coal(struct mv643xx_eth_private *mp) · 30 unmodified lines | ||
| 1417 | 1418 | |
| 1418 | 1419 | temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4; |
| 1419 | 1420 | temp *= 64000000; |
| 1421 | + temp += mp->t_clk / 2; | |
| 1420 | 1422 | do_div(temp, mp->t_clk); |
| 1421 | 1423 | |
| 1422 | 1424 | return (unsigned int)temp; |
| @@ -5220,6 +5220,19 @@ static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume); · 5219 unmodified lines | ||
| 5220 | 5220 | |
| 5221 | 5221 | static void sky2_shutdown(struct pci_dev *pdev) |
| 5222 | 5222 | { |
| 5223 | + struct sky2_hw *hw = pci_get_drvdata(pdev); | |
| 5224 | + int port; | |
| 5225 | + | |
| 5226 | + for (port = 0; port < hw->ports; port++) { | |
| 5227 | + struct net_device *ndev = hw->dev[port]; | |
| 5228 | + | |
| 5229 | + rtnl_lock(); | |
| 5230 | + if (netif_running(ndev)) { | |
| 5231 | + dev_close(ndev); | |
| 5232 | + netif_device_detach(ndev); | |
| 5233 | + } | |
| 5234 | + rtnl_unlock(); | |
| 5235 | + } | |
| 5223 | 5236 | sky2_suspend(&pdev->dev); |
| 5224 | 5237 | pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev)); |
| 5225 | 5238 | pci_set_power_state(pdev, PCI_D3hot); |
| @@ -2202,7 +2202,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev) · 2201 unmodified lines | ||
| 2202 | 2202 | |
| 2203 | 2203 | if (!shutdown) |
| 2204 | 2204 | free_netdev(dev); |
| 2205 | − dev->ethtool_ops = NULL; | |
| 2206 | 2205 | } |
| 2207 | 2206 | |
| 2208 | 2207 | static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu) |
| @@ -1445,6 +1445,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, · 1444 unmodified lines | ||
| 1445 | 1445 | c->netdev = priv->netdev; |
| 1446 | 1446 | c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key); |
| 1447 | 1447 | c->num_tc = priv->params.num_tc; |
| 1448 | + c->xdp = !!priv->xdp_prog; | |
| 1448 | 1449 | |
| 1449 | 1450 | if (priv->params.rx_am_enabled) |
| 1450 | 1451 | rx_cq_profile = mlx5e_am_get_def_profile(priv->params.rx_cq_period_mode); |
| @@ -1468,6 +1469,12 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, · 17 unmodified lines | ||
| 1468 | 1469 | if (err) |
| 1469 | 1470 | goto err_close_tx_cqs; |
| 1470 | 1471 | |
| 1472 | + /* XDP SQ CQ params are same as normal TXQ sq CQ params */ | |
| 1473 | + err = c->xdp ? mlx5e_open_cq(c, &cparam->tx_cq, &c->xdp_sq.cq, | |
| 1474 | + priv->params.tx_cq_moderation) : 0; | |
| 1475 | + if (err) | |
| 1476 | + goto err_close_rx_cq; | |
| 1477 | + | |
| 1471 | 1478 | napi_enable(&c->napi); |
| 1472 | 1479 | |
| 1473 | 1480 | err = mlx5e_open_sq(c, 0, &cparam->icosq, &c->icosq); |
| @@ -1488,21 +1495,10 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, · 14 unmodified lines | ||
| 1488 | 1495 | } |
| 1489 | 1496 | } |
| 1490 | 1497 | |
| 1491 | − if (priv->xdp_prog) { | |
| 1492 | − /* XDP SQ CQ params are same as normal TXQ sq CQ params */ | |
| 1493 | − err = mlx5e_open_cq(c, &cparam->tx_cq, &c->xdp_sq.cq, | |
| 1494 | − priv->params.tx_cq_moderation); | |
| 1495 | − if (err) | |
| 1496 | − goto err_close_sqs; | |
| 1497 | − | |
| 1498 | − err = mlx5e_open_sq(c, 0, &cparam->xdp_sq, &c->xdp_sq); | |
| 1499 | − if (err) { | |
| 1500 | − mlx5e_close_cq(&c->xdp_sq.cq); | |
| 1501 | − goto err_close_sqs; | |
| 1502 | − } | |
| 1503 | − } | |
| 1498 | + err = c->xdp ? mlx5e_open_sq(c, 0, &cparam->xdp_sq, &c->xdp_sq) : 0; | |
| 1499 | + if (err) | |
| 1500 | + goto err_close_sqs; | |
| 1504 | 1501 | |
| 1505 | − c->xdp = !!priv->xdp_prog; | |
| 1506 | 1502 | err = mlx5e_open_rq(c, &cparam->rq, &c->rq); |
| 1507 | 1503 | if (err) |
| 1508 | 1504 | goto err_close_xdp_sq; |
| @@ -1512,7 +1508,8 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, · 3 unmodified lines | ||
| 1512 | 1508 | |
| 1513 | 1509 | return 0; |
| 1514 | 1510 | err_close_xdp_sq: |
| 1515 | − mlx5e_close_sq(&c->xdp_sq); | |
| 1511 | + if (c->xdp) | |
| 1512 | + mlx5e_close_sq(&c->xdp_sq); | |
| 1516 | 1513 | |
| 1517 | 1514 | err_close_sqs: |
| 1518 | 1515 | mlx5e_close_sqs(c); |
| @@ -1522,6 +1519,10 @@ err_close_icosq: · 3 unmodified lines | ||
| 1522 | 1519 | |
| 1523 | 1520 | err_disable_napi: |
| 1524 | 1521 | napi_disable(&c->napi); |
| 1522 | + if (c->xdp) | |
| 1523 | + mlx5e_close_cq(&c->xdp_sq.cq); | |
| 1524 | + | |
| 1525 | +err_close_rx_cq: | |
| 1525 | 1526 | mlx5e_close_cq(&c->rq.cq); |
| 1526 | 1527 | |
| 1527 | 1528 | err_close_tx_cqs: |
| @@ -308,7 +308,7 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev) · 307 unmodified lines | ||
| 308 | 308 | netdev->switchdev_ops = &mlx5e_rep_switchdev_ops; |
| 309 | 309 | #endif |
| 310 | 310 | |
| 311 | − netdev->features |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC; | |
| 311 | + netdev->features |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL; | |
| 312 | 312 | netdev->hw_features |= NETIF_F_HW_TC; |
| 313 | 313 | |
| 314 | 314 | eth_hw_addr_random(netdev); |
| @@ -237,12 +237,15 @@ static int parse_cls_flower(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec · 236 unmodified lines | ||
| 237 | 237 | skb_flow_dissector_target(f->dissector, |
| 238 | 238 | FLOW_DISSECTOR_KEY_VLAN, |
| 239 | 239 | f->mask); |
| 240 | − if (mask->vlan_id) { | |
| 240 | + if (mask->vlan_id || mask->vlan_priority) { | |
| 241 | 241 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, vlan_tag, 1); |
| 242 | 242 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, vlan_tag, 1); |
| 243 | 243 | |
| 244 | 244 | MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_vid, mask->vlan_id); |
| 245 | 245 | MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, key->vlan_id); |
| 246 | + | |
| 247 | + MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_prio, mask->vlan_priority); | |
| 248 | + MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_prio, key->vlan_priority); | |
| 246 | 249 | } |
| 247 | 250 | } |
| 248 | 251 | |
| @@ -57,7 +57,8 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, · 56 unmodified lines | ||
| 57 | 57 | if (esw->mode != SRIOV_OFFLOADS) |
| 58 | 58 | return ERR_PTR(-EOPNOTSUPP); |
| 59 | 59 | |
| 60 | − action = attr->action; | |
| 60 | + /* per flow vlan pop/push is emulated, don't set that into the firmware */ | |
| 61 | + action = attr->action & ~(MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH | MLX5_FLOW_CONTEXT_ACTION_VLAN_POP); | |
| 61 | 62 | |
| 62 | 63 | if (action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { |
| 63 | 64 | dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT; |
| @@ -1690,7 +1690,7 @@ static int init_root_ns(struct mlx5_flow_steering *steering) · 1689 unmodified lines | ||
| 1690 | 1690 | { |
| 1691 | 1691 | |
| 1692 | 1692 | steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX); |
| 1693 | − if (IS_ERR_OR_NULL(steering->root_ns)) | |
| 1693 | + if (!steering->root_ns) | |
| 1694 | 1694 | goto cleanup; |
| 1695 | 1695 | |
| 1696 | 1696 | if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node)) |
| @@ -1226,6 +1226,9 @@ static int init_one(struct pci_dev *pdev, · 1225 unmodified lines | ||
| 1226 | 1226 | |
| 1227 | 1227 | pci_set_drvdata(pdev, dev); |
| 1228 | 1228 | |
| 1229 | + dev->pdev = pdev; | |
| 1230 | + dev->event = mlx5_core_event; | |
| 1231 | + | |
| 1229 | 1232 | if (prof_sel < 0 || prof_sel >= ARRAY_SIZE(profile)) { |
| 1230 | 1233 | mlx5_core_warn(dev, |
| 1231 | 1234 | "selected profile out of range, selecting default (%d)\n", |
| @@ -1233,8 +1236,6 @@ static int init_one(struct pci_dev *pdev, · 1 unmodified line | ||
| 1233 | 1236 | prof_sel = MLX5_DEFAULT_PROF; |
| 1234 | 1237 | } |
| 1235 | 1238 | dev->profile = &profile[prof_sel]; |
| 1236 | − dev->pdev = pdev; | |
| 1237 | − dev->event = mlx5_core_event; | |
| 1238 | 1239 | |
| 1239 | 1240 | INIT_LIST_HEAD(&priv->ctx_list); |
| 1240 | 1241 | spin_lock_init(&priv->ctx_lock); |
| @@ -231,7 +231,7 @@ mlxsw_sp_span_entry_create(struct mlxsw_sp_port *port) · 230 unmodified lines | ||
| 231 | 231 | |
| 232 | 232 | span_entry->used = true; |
| 233 | 233 | span_entry->id = index; |
| 234 | − span_entry->ref_count = 0; | |
| 234 | + span_entry->ref_count = 1; | |
| 235 | 235 | span_entry->local_port = local_port; |
| 236 | 236 | return span_entry; |
| 237 | 237 | } |
| @@ -270,6 +270,7 @@ static struct mlxsw_sp_span_entry · 32 unmodified lines | ||
| 270 | 270 | |
| 271 | 271 | span_entry = mlxsw_sp_span_entry_find(port); |
| 272 | 272 | if (span_entry) { |
| 273 | + /* Already exists, just take a reference */ | |
| 273 | 274 | span_entry->ref_count++; |
| 274 | 275 | return span_entry; |
| 275 | 276 | } |
| @@ -280,6 +281,7 @@ static struct mlxsw_sp_span_entry · 4 unmodified lines | ||
| 280 | 281 | static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp, |
| 281 | 282 | struct mlxsw_sp_span_entry *span_entry) |
| 282 | 283 | { |
| 284 | + WARN_ON(!span_entry->ref_count); | |
| 283 | 285 | if (--span_entry->ref_count == 0) |
| 284 | 286 | mlxsw_sp_span_entry_destroy(mlxsw_sp, span_entry); |
| 285 | 287 | return 0; |
| @@ -115,7 +115,7 @@ struct mlxsw_sp_rif { · 114 unmodified lines | ||
| 115 | 115 | struct mlxsw_sp_mid { |
| 116 | 116 | struct list_head list; |
| 117 | 117 | unsigned char addr[ETH_ALEN]; |
| 118 | − u16 vid; | |
| 118 | + u16 fid; | |
| 119 | 119 | u16 mid; |
| 120 | 120 | unsigned int ref_count; |
| 121 | 121 | }; |
| @@ -594,21 +594,22 @@ static int mlxsw_sp_vrs_init(struct mlxsw_sp *mlxsw_sp) · 593 unmodified lines | ||
| 594 | 594 | return 0; |
| 595 | 595 | } |
| 596 | 596 | |
| 597 | +static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp); | |
| 598 | + | |
| 597 | 599 | static void mlxsw_sp_vrs_fini(struct mlxsw_sp *mlxsw_sp) |
| 598 | 600 | { |
| 601 | + mlxsw_sp_router_fib_flush(mlxsw_sp); | |
| 599 | 602 | kfree(mlxsw_sp->router.vrs); |
| 600 | 603 | } |
| 601 | 604 | |
| 602 | 605 | struct mlxsw_sp_neigh_key { |
| 603 | − unsigned char addr[sizeof(struct in6_addr)]; | |
| 604 | − struct net_device *dev; | |
| 606 | + struct neighbour *n; | |
| 605 | 607 | }; |
| 606 | 608 | |
| 607 | 609 | struct mlxsw_sp_neigh_entry { |
| 608 | 610 | struct rhash_head ht_node; |
| 609 | 611 | struct mlxsw_sp_neigh_key key; |
| 610 | 612 | u16 rif; |
| 611 | − struct neighbour *n; | |
| 612 | 613 | bool offloaded; |
| 613 | 614 | struct delayed_work dw; |
| 614 | 615 | struct mlxsw_sp_port *mlxsw_sp_port; |
| @@ -646,19 +647,15 @@ mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp, · 31 unmodified lines | ||
| 646 | 647 | static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work); |
| 647 | 648 | |
| 648 | 649 | static struct mlxsw_sp_neigh_entry * |
| 649 | −mlxsw_sp_neigh_entry_create(const void *addr, size_t addr_len, | |
| 650 | − struct net_device *dev, u16 rif, | |
| 651 | − struct neighbour *n) | |
| 650 | +mlxsw_sp_neigh_entry_create(struct neighbour *n, u16 rif) | |
| 652 | 651 | { |
| 653 | 652 | struct mlxsw_sp_neigh_entry *neigh_entry; |
| 654 | 653 | |
| 655 | 654 | neigh_entry = kzalloc(sizeof(*neigh_entry), GFP_ATOMIC); |
| 656 | 655 | if (!neigh_entry) |
| 657 | 656 | return NULL; |
| 658 | − memcpy(neigh_entry->key.addr, addr, addr_len); | |
| 659 | − neigh_entry->key.dev = dev; | |
| 657 | + neigh_entry->key.n = n; | |
| 660 | 658 | neigh_entry->rif = rif; |
| 661 | − neigh_entry->n = n; | |
| 662 | 659 | INIT_DELAYED_WORK(&neigh_entry->dw, mlxsw_sp_router_neigh_update_hw); |
| 663 | 660 | INIT_LIST_HEAD(&neigh_entry->nexthop_list); |
| 664 | 661 | return neigh_entry; |
| @@ -671,13 +668,11 @@ mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp_neigh_entry *neigh_entry) · 6 unmodified lines | ||
| 671 | 668 | } |
| 672 | 669 | |
| 673 | 670 | static struct mlxsw_sp_neigh_entry * |
| 674 | −mlxsw_sp_neigh_entry_lookup(struct mlxsw_sp *mlxsw_sp, const void *addr, | |
| 675 | − size_t addr_len, struct net_device *dev) | |
| 671 | +mlxsw_sp_neigh_entry_lookup(struct mlxsw_sp *mlxsw_sp, struct neighbour *n) | |
| 676 | 672 | { |
| 677 | − struct mlxsw_sp_neigh_key key = {{ 0 } }; | |
| 673 | + struct mlxsw_sp_neigh_key key; | |
| 678 | 674 | |
| 679 | − memcpy(key.addr, addr, addr_len); | |
| 680 | − key.dev = dev; | |
| 675 | + key.n = n; | |
| 681 | 676 | return rhashtable_lookup_fast(&mlxsw_sp->router.neigh_ht, |
| 682 | 677 | &key, mlxsw_sp_neigh_ht_params); |
| 683 | 678 | } |
| @@ -689,26 +684,20 @@ int mlxsw_sp_router_neigh_construct(struct net_device *dev, · 5 unmodified lines | ||
| 689 | 684 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; |
| 690 | 685 | struct mlxsw_sp_neigh_entry *neigh_entry; |
| 691 | 686 | struct mlxsw_sp_rif *r; |
| 692 | − u32 dip; | |
| 693 | 687 | int err; |
| 694 | 688 | |
| 695 | 689 | if (n->tbl != &arp_tbl) |
| 696 | 690 | return 0; |
| 697 | 691 | |
| 698 | − dip = ntohl(*((__be32 *) n->primary_key)); | |
| 699 | − neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, &dip, sizeof(dip), | |
| 700 | − n->dev); | |
| 701 | − if (neigh_entry) { | |
| 702 | − WARN_ON(neigh_entry->n != n); | |
| 692 | + neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n); | |
| 693 | + if (neigh_entry) | |
| 703 | 694 | return 0; |
| 704 | − } | |
| 705 | 695 | |
| 706 | 696 | r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, n->dev); |
| 707 | 697 | if (WARN_ON(!r)) |
| 708 | 698 | return -EINVAL; |
| 709 | 699 | |
| 710 | − neigh_entry = mlxsw_sp_neigh_entry_create(&dip, sizeof(dip), n->dev, | |
| 711 | − r->rif, n); | |
| 700 | + neigh_entry = mlxsw_sp_neigh_entry_create(n, r->rif); | |
| 712 | 701 | if (!neigh_entry) |
| 713 | 702 | return -ENOMEM; |
| 714 | 703 | err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry); |
| @@ -727,14 +716,11 @@ void mlxsw_sp_router_neigh_destroy(struct net_device *dev, · 12 unmodified lines | ||
| 727 | 716 | struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); |
| 728 | 717 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; |
| 729 | 718 | struct mlxsw_sp_neigh_entry *neigh_entry; |
| 730 | − u32 dip; | |
| 731 | 719 | |
| 732 | 720 | if (n->tbl != &arp_tbl) |
| 733 | 721 | return; |
| 734 | 722 | |
| 735 | − dip = ntohl(*((__be32 *) n->primary_key)); | |
| 736 | − neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, &dip, sizeof(dip), | |
| 737 | − n->dev); | |
| 723 | + neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n); | |
| 738 | 724 | if (!neigh_entry) |
| 739 | 725 | return; |
| 740 | 726 | mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry); |
| @@ -817,6 +803,26 @@ static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp, · 76 unmodified lines | ||
| 817 | 803 | } |
| 818 | 804 | } |
| 819 | 805 | |
| 806 | +static bool mlxsw_sp_router_rauhtd_is_full(char *rauhtd_pl) | |
| 807 | +{ | |
| 808 | + u8 num_rec, last_rec_index, num_entries; | |
| 809 | + | |
| 810 | + num_rec = mlxsw_reg_rauhtd_num_rec_get(rauhtd_pl); | |
| 811 | + last_rec_index = num_rec - 1; | |
| 812 | + | |
| 813 | + if (num_rec < MLXSW_REG_RAUHTD_REC_MAX_NUM) | |
| 814 | + return false; | |
| 815 | + if (mlxsw_reg_rauhtd_rec_type_get(rauhtd_pl, last_rec_index) == | |
| 816 | + MLXSW_REG_RAUHTD_TYPE_IPV6) | |
| 817 | + return true; | |
| 818 | + | |
| 819 | + num_entries = mlxsw_reg_rauhtd_ipv4_rec_num_entries_get(rauhtd_pl, | |
| 820 | + last_rec_index); | |
| 821 | + if (++num_entries == MLXSW_REG_RAUHTD_IPV4_ENT_PER_REC) | |
| 822 | + return true; | |
| 823 | + return false; | |
| 824 | +} | |
| 825 | + | |
| 820 | 826 | static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp) |
| 821 | 827 | { |
| 822 | 828 | char *rauhtd_pl; |
| @@ -843,7 +849,7 @@ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp) · 20 unmodified lines | ||
| 843 | 849 | for (i = 0; i < num_rec; i++) |
| 844 | 850 | mlxsw_sp_router_neigh_rec_process(mlxsw_sp, rauhtd_pl, |
| 845 | 851 | i); |
| 846 | − } while (num_rec); | |
| 852 | + } while (mlxsw_sp_router_rauhtd_is_full(rauhtd_pl)); | |
| 847 | 853 | rtnl_unlock(); |
| 848 | 854 | |
| 849 | 855 | kfree(rauhtd_pl); |
| @@ -862,7 +868,7 @@ static void mlxsw_sp_router_neighs_update_nh(struct mlxsw_sp *mlxsw_sp) · 12 unmodified lines | ||
| 862 | 868 | * is active regardless of the traffic. |
| 863 | 869 | */ |
| 864 | 870 | if (!list_empty(&neigh_entry->nexthop_list)) |
| 865 | − neigh_event_send(neigh_entry->n, NULL); | |
| 871 | + neigh_event_send(neigh_entry->key.n, NULL); | |
| 866 | 872 | } |
| 867 | 873 | rtnl_unlock(); |
| 868 | 874 | } |
| @@ -908,9 +914,9 @@ static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work) · 39 unmodified lines | ||
| 908 | 914 | rtnl_lock(); |
| 909 | 915 | list_for_each_entry(neigh_entry, &mlxsw_sp->router.nexthop_neighs_list, |
| 910 | 916 | nexthop_neighs_list_node) { |
| 911 | − if (!(neigh_entry->n->nud_state & NUD_VALID) && | |
| 917 | + if (!(neigh_entry->key.n->nud_state & NUD_VALID) && | |
| 912 | 918 | !list_empty(&neigh_entry->nexthop_list)) |
| 913 | − neigh_event_send(neigh_entry->n, NULL); | |
| 919 | + neigh_event_send(neigh_entry->key.n, NULL); | |
| 914 | 920 | } |
| 915 | 921 | rtnl_unlock(); |
| 916 | 922 | |
| @@ -927,7 +933,7 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work) · 10 unmodified lines | ||
| 927 | 933 | { |
| 928 | 934 | struct mlxsw_sp_neigh_entry *neigh_entry = |
| 929 | 935 | container_of(work, struct mlxsw_sp_neigh_entry, dw.work); |
| 930 | − struct neighbour *n = neigh_entry->n; | |
| 936 | + struct neighbour *n = neigh_entry->key.n; | |
| 931 | 937 | struct mlxsw_sp_port *mlxsw_sp_port = neigh_entry->mlxsw_sp_port; |
| 932 | 938 | struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; |
| 933 | 939 | char rauht_pl[MLXSW_REG_RAUHT_LEN]; |
| @@ -1030,11 +1036,8 @@ int mlxsw_sp_router_netevent_event(struct notifier_block *unused, · 96 unmodified lines | ||
| 1030 | 1036 | |
| 1031 | 1037 | mlxsw_sp = mlxsw_sp_port->mlxsw_sp; |
| 1032 | 1038 | dip = ntohl(*((__be32 *) n->primary_key)); |
| 1033 | − neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, | |
| 1034 | − &dip, | |
| 1035 | − sizeof(__be32), | |
| 1036 | − dev); | |
| 1037 | − if (WARN_ON(!neigh_entry) || WARN_ON(neigh_entry->n != n)) { | |
| 1039 | + neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n); | |
| 1040 | + if (WARN_ON(!neigh_entry)) { | |
| 1038 | 1041 | mlxsw_sp_port_dev_put(mlxsw_sp_port); |
| 1039 | 1042 | return NOTIFY_DONE; |
| 1040 | 1043 | } |
| @@ -1343,33 +1346,26 @@ static int mlxsw_sp_nexthop_init(struct mlxsw_sp *mlxsw_sp, · 302 unmodified lines | ||
| 1343 | 1346 | struct fib_nh *fib_nh) |
| 1344 | 1347 | { |
| 1345 | 1348 | struct mlxsw_sp_neigh_entry *neigh_entry; |
| 1346 | − u32 gwip = ntohl(fib_nh->nh_gw); | |
| 1347 | 1349 | struct net_device *dev = fib_nh->nh_dev; |
| 1348 | 1350 | struct neighbour *n; |
| 1349 | 1351 | u8 nud_state; |
| 1350 | 1352 | |
| 1351 | − neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, &gwip, | |
| 1352 | − sizeof(gwip), dev); | |
| 1353 | − if (!neigh_entry) { | |
| 1354 | − __be32 gwipn = htonl(gwip); | |
| 1355 | − | |
| 1356 | − n = neigh_create(&arp_tbl, &gwipn, dev); | |
| 1353 | + /* Take a reference of neigh here ensuring that neigh would | |
| 1354 | + * not be detructed before the nexthop entry is finished. | |
| 1355 | + * The reference is taken either in neigh_lookup() or | |
| 1356 | + * in neith_create() in case n is not found. | |
| 1357 | + */ | |
| 1358 | + n = neigh_lookup(&arp_tbl, &fib_nh->nh_gw, dev); | |
| 1359 | + if (!n) { | |
| 1360 | + n = neigh_create(&arp_tbl, &fib_nh->nh_gw, dev); | |
| 1357 | 1361 | if (IS_ERR(n)) |
| 1358 | 1362 | return PTR_ERR(n); |
| 1359 | 1363 | neigh_event_send(n, NULL); |
| 1360 | − neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, &gwip, | |
| 1361 | − sizeof(gwip), dev); | |
| 1362 | − if (!neigh_entry) { | |
| 1363 | − neigh_release(n); | |
| 1364 | − return -EINVAL; | |
| 1365 | − } | |
| 1366 | − } else { | |
| 1367 | − /* Take a reference of neigh here ensuring that neigh would | |
| 1368 | − * not be detructed before the nexthop entry is finished. | |
| 1369 | − * The second branch takes the reference in neith_create() | |
| 1370 | − */ | |
| 1371 | − n = neigh_entry->n; | |
| 1372 | − neigh_clone(n); | |
| 1364 | + } | |
| 1365 | + neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n); | |
| 1366 | + if (!neigh_entry) { | |
| 1367 | + neigh_release(n); | |
| 1368 | + return -EINVAL; | |
| 1373 | 1369 | } |
| 1374 | 1370 | |
| 1375 | 1371 | /* If that is the first nexthop connected to that neigh, add to |
| @@ -1403,7 +1399,7 @@ static void mlxsw_sp_nexthop_fini(struct mlxsw_sp *mlxsw_sp, · 27 unmodified lines | ||
| 1403 | 1399 | if (list_empty(&nh->neigh_entry->nexthop_list)) |
| 1404 | 1400 | list_del(&nh->neigh_entry->nexthop_neighs_list_node); |
| 1405 | 1401 | |
| 1406 | − neigh_release(neigh_entry->n); | |
| 1402 | + neigh_release(neigh_entry->key.n); | |
| 1407 | 1403 | } |
| 1408 | 1404 | |
| 1409 | 1405 | static struct mlxsw_sp_nexthop_group * |
| @@ -1463,11 +1459,11 @@ static bool mlxsw_sp_nexthop_match(struct mlxsw_sp_nexthop *nh, · 53 unmodified lines | ||
| 1463 | 1459 | |
| 1464 | 1460 | for (i = 0; i < fi->fib_nhs; i++) { |
| 1465 | 1461 | struct fib_nh *fib_nh = &fi->fib_nh[i]; |
| 1466 | − u32 gwip = ntohl(fib_nh->nh_gw); | |
| 1462 | + struct neighbour *n = nh->neigh_entry->key.n; | |
| 1467 | 1463 | |
| 1468 | − if (memcmp(nh->neigh_entry->key.addr, | |
| 1469 | − &gwip, sizeof(u32)) == 0 && | |
| 1470 | − nh->neigh_entry->key.dev == fib_nh->nh_dev) | |
| 1464 | + if (memcmp(n->primary_key, &fib_nh->nh_gw, | |
| 1465 | + sizeof(fib_nh->nh_gw)) == 0 && | |
| 1466 | + n->dev == fib_nh->nh_dev) | |
| 1471 | 1467 | return true; |
| 1472 | 1468 | } |
| 1473 | 1469 | return false; |
| @@ -1874,18 +1870,18 @@ static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp) · 400 unmodified lines | ||
| 1874 | 1870 | return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl); |
| 1875 | 1871 | } |
| 1876 | 1872 | |
| 1877 | −static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp) | |
| 1873 | +static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp) | |
| 1878 | 1874 | { |
| 1879 | 1875 | struct mlxsw_resources *resources; |
| 1880 | 1876 | struct mlxsw_sp_fib_entry *fib_entry; |
| 1881 | 1877 | struct mlxsw_sp_fib_entry *tmp; |
| 1882 | 1878 | struct mlxsw_sp_vr *vr; |
| 1883 | 1879 | int i; |
| 1884 | − int err; | |
| 1885 | 1880 | |
| 1886 | 1881 | resources = mlxsw_core_resources_get(mlxsw_sp->core); |
| 1887 | 1882 | for (i = 0; i < resources->max_virtual_routers; i++) { |
| 1888 | 1883 | vr = &mlxsw_sp->router.vrs[i]; |
| 1884 | + | |
| 1889 | 1885 | if (!vr->used) |
| 1890 | 1886 | continue; |
| 1891 | 1887 | |
| @@ -1901,6 +1897,13 @@ static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp) · 9 unmodified lines | ||
| 1901 | 1897 | break; |
| 1902 | 1898 | } |
| 1903 | 1899 | } |
| 1900 | +} | |
| 1901 | + | |
| 1902 | +static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp) | |
| 1903 | +{ | |
| 1904 | + int err; | |
| 1905 | + | |
| 1906 | + mlxsw_sp_router_fib_flush(mlxsw_sp); | |
| 1904 | 1907 | mlxsw_sp->router.aborted = true; |
| 1905 | 1908 | err = mlxsw_sp_router_set_abort_trap(mlxsw_sp); |
| 1906 | 1909 | if (err) |
| @@ -1958,6 +1961,9 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb, · 51 unmodified lines | ||
| 1958 | 1961 | struct fib_entry_notifier_info *fen_info = ptr; |
| 1959 | 1962 | int err; |
| 1960 | 1963 | |
| 1964 | + if (!net_eq(fen_info->info.net, &init_net)) | |
| 1965 | + return NOTIFY_DONE; | |
| 1966 | + | |
| 1961 | 1967 | switch (event) { |
| 1962 | 1968 | case FIB_EVENT_ENTRY_ADD: |
| 1963 | 1969 | err = mlxsw_sp_router_fib4_add(mlxsw_sp, fen_info); |
| @@ -929,12 +929,12 @@ static int mlxsw_sp_port_smid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mid, · 928 unmodified lines | ||
| 929 | 929 | |
| 930 | 930 | static struct mlxsw_sp_mid *__mlxsw_sp_mc_get(struct mlxsw_sp *mlxsw_sp, |
| 931 | 931 | const unsigned char *addr, |
| 932 | − u16 vid) | |
| 932 | + u16 fid) | |
| 933 | 933 | { |
| 934 | 934 | struct mlxsw_sp_mid *mid; |
| 935 | 935 | |
| 936 | 936 | list_for_each_entry(mid, &mlxsw_sp->br_mids.list, list) { |
| 937 | − if (ether_addr_equal(mid->addr, addr) && mid->vid == vid) | |
| 937 | + if (ether_addr_equal(mid->addr, addr) && mid->fid == fid) | |
| 938 | 938 | return mid; |
| 939 | 939 | } |
| 940 | 940 | return NULL; |
| @@ -942,7 +942,7 @@ static struct mlxsw_sp_mid *__mlxsw_sp_mc_get(struct mlxsw_sp *mlxsw_sp, · 1 unmodified line | ||
| 942 | 942 | |
| 943 | 943 | static struct mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp, |
| 944 | 944 | const unsigned char *addr, |
| 945 | − u16 vid) | |
| 945 | + u16 fid) | |
| 946 | 946 | { |
| 947 | 947 | struct mlxsw_sp_mid *mid; |
| 948 | 948 | u16 mid_idx; |
| @@ -958,7 +958,7 @@ static struct mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp, · 9 unmodified lines | ||
| 958 | 958 | |
| 959 | 959 | set_bit(mid_idx, mlxsw_sp->br_mids.mapped); |
| 960 | 960 | ether_addr_copy(mid->addr, addr); |
| 961 | − mid->vid = vid; | |
| 961 | + mid->fid = fid; | |
| 962 | 962 | mid->mid = mid_idx; |
| 963 | 963 | mid->ref_count = 0; |
| 964 | 964 | list_add_tail(&mid->list, &mlxsw_sp->br_mids.list); |
| @@ -991,9 +991,9 @@ static int mlxsw_sp_port_mdb_add(struct mlxsw_sp_port *mlxsw_sp_port, · 26 unmodified lines | ||
| 991 | 991 | if (switchdev_trans_ph_prepare(trans)) |
| 992 | 992 | return 0; |
| 993 | 993 | |
| 994 | − mid = __mlxsw_sp_mc_get(mlxsw_sp, mdb->addr, mdb->vid); | |
| 994 | + mid = __mlxsw_sp_mc_get(mlxsw_sp, mdb->addr, fid); | |
| 995 | 995 | if (!mid) { |
| 996 | − mid = __mlxsw_sp_mc_alloc(mlxsw_sp, mdb->addr, mdb->vid); | |
| 996 | + mid = __mlxsw_sp_mc_alloc(mlxsw_sp, mdb->addr, fid); | |
| 997 | 997 | if (!mid) { |
| 998 | 998 | netdev_err(dev, "Unable to allocate MC group\n"); |
| 999 | 999 | return -ENOMEM; |
| @@ -1137,7 +1137,7 @@ static int mlxsw_sp_port_mdb_del(struct mlxsw_sp_port *mlxsw_sp_port, · 137 unmodified lines | ||
| 1137 | 1137 | u16 mid_idx; |
| 1138 | 1138 | int err = 0; |
| 1139 | 1139 | |
| 1140 | − mid = __mlxsw_sp_mc_get(mlxsw_sp, mdb->addr, mdb->vid); | |
| 1140 | + mid = __mlxsw_sp_mc_get(mlxsw_sp, mdb->addr, fid); | |
| 1141 | 1141 | if (!mid) { |
| 1142 | 1142 | netdev_err(dev, "Unable to remove port from MC DB\n"); |
| 1143 | 1143 | return -EINVAL; |
| @@ -727,9 +727,6 @@ struct core_tx_bd_flags { · 726 unmodified lines | ||
| 727 | 727 | #define CORE_TX_BD_FLAGS_L4_PROTOCOL_SHIFT 6 |
| 728 | 728 | #define CORE_TX_BD_FLAGS_L4_PSEUDO_CSUM_MODE_MASK 0x1 |
| 729 | 729 | #define CORE_TX_BD_FLAGS_L4_PSEUDO_CSUM_MODE_SHIFT 7 |
| 730 | −#define CORE_TX_BD_FLAGS_ROCE_FLAV_MASK 0x1 | |
| 731 | −#define CORE_TX_BD_FLAGS_ROCE_FLAV_SHIFT 12 | |
| 732 | − | |
| 733 | 730 | }; |
| 734 | 731 | |
| 735 | 732 | struct core_tx_bd { |
| @@ -1119,6 +1119,7 @@ static void qed_ll2_prepare_tx_packet_set_bd(struct qed_hwfn *p_hwfn, · 1118 unmodified lines | ||
| 1119 | 1119 | start_bd->bd_flags.as_bitfield |= CORE_TX_BD_FLAGS_START_BD_MASK << |
| 1120 | 1120 | CORE_TX_BD_FLAGS_START_BD_SHIFT; |
| 1121 | 1121 | SET_FIELD(start_bd->bitfield0, CORE_TX_BD_NBDS, num_of_bds); |
| 1122 | + SET_FIELD(start_bd->bitfield0, CORE_TX_BD_ROCE_FLAV, type); | |
| 1122 | 1123 | DMA_REGPAIR_LE(start_bd->addr, first_frag); |
| 1123 | 1124 | start_bd->nbytes = cpu_to_le16(first_frag_len); |
| 1124 | 1125 | |
| @@ -839,20 +839,19 @@ static void qed_update_pf_params(struct qed_dev *cdev, · 838 unmodified lines | ||
| 839 | 839 | { |
| 840 | 840 | int i; |
| 841 | 841 | |
| 842 | + if (IS_ENABLED(CONFIG_QED_RDMA)) { | |
| 843 | + params->rdma_pf_params.num_qps = QED_ROCE_QPS; | |
| 844 | + params->rdma_pf_params.min_dpis = QED_ROCE_DPIS; | |
| 845 | + /* divide by 3 the MRs to avoid MF ILT overflow */ | |
| 846 | + params->rdma_pf_params.num_mrs = RDMA_MAX_TIDS; | |
| 847 | + params->rdma_pf_params.gl_pi = QED_ROCE_PROTOCOL_INDEX; | |
| 848 | + } | |
| 849 | + | |
| 842 | 850 | for (i = 0; i < cdev->num_hwfns; i++) { |
| 843 | 851 | struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; |
| 844 | 852 | |
| 845 | 853 | p_hwfn->pf_params = *params; |
| 846 | 854 | } |
| 847 | − | |
| 848 | − if (!IS_ENABLED(CONFIG_QED_RDMA)) | |
| 849 | − return; | |
| 850 | − | |
| 851 | − params->rdma_pf_params.num_qps = QED_ROCE_QPS; | |
| 852 | − params->rdma_pf_params.min_dpis = QED_ROCE_DPIS; | |
| 853 | − /* divide by 3 the MRs to avoid MF ILT overflow */ | |
| 854 | − params->rdma_pf_params.num_mrs = RDMA_MAX_TIDS; | |
| 855 | − params->rdma_pf_params.gl_pi = QED_ROCE_PROTOCOL_INDEX; | |
| 856 | 855 | } |
| 857 | 856 | |
| 858 | 857 | static int qed_slowpath_start(struct qed_dev *cdev, |
| @@ -175,16 +175,23 @@ static void qede_get_strings_stats(struct qede_dev *edev, u8 *buf) · 174 unmodified lines | ||
| 175 | 175 | for (i = 0, k = 0; i < QEDE_QUEUE_CNT(edev); i++) { |
| 176 | 176 | int tc; |
| 177 | 177 | |
| 178 | − for (j = 0; j < QEDE_NUM_RQSTATS; j++) | |
| 179 | − sprintf(buf + (k + j) * ETH_GSTRING_LEN, | |
| 180 | − "%d: %s", i, qede_rqstats_arr[j].string); | |
| 181 | − k += QEDE_NUM_RQSTATS; | |
| 182 | − for (tc = 0; tc < edev->num_tc; tc++) { | |
| 183 | − for (j = 0; j < QEDE_NUM_TQSTATS; j++) | |
| 178 | + if (edev->fp_array[i].type & QEDE_FASTPATH_RX) { | |
| 179 | + for (j = 0; j < QEDE_NUM_RQSTATS; j++) | |
| 184 | 180 | sprintf(buf + (k + j) * ETH_GSTRING_LEN, |
| 185 | − "%d.%d: %s", i, tc, | |
| 186 | − qede_tqstats_arr[j].string); | |
| 187 | − k += QEDE_NUM_TQSTATS; | |
| 181 | + "%d: %s", i, | |
| 182 | + qede_rqstats_arr[j].string); | |
| 183 | + k += QEDE_NUM_RQSTATS; | |
| 184 | + } | |
| 185 | + | |
| 186 | + if (edev->fp_array[i].type & QEDE_FASTPATH_TX) { | |
| 187 | + for (tc = 0; tc < edev->num_tc; tc++) { | |
| 188 | + for (j = 0; j < QEDE_NUM_TQSTATS; j++) | |
| 189 | + sprintf(buf + (k + j) * | |
| 190 | + ETH_GSTRING_LEN, | |
| 191 | + "%d.%d: %s", i, tc, | |
| 192 | + qede_tqstats_arr[j].string); | |
| 193 | + k += QEDE_NUM_TQSTATS; | |
| 194 | + } | |
| 188 | 195 | } |
| 189 | 196 | } |
| 190 | 197 | |
| @@ -2839,7 +2839,7 @@ static int qede_alloc_sge_mem(struct qede_dev *edev, struct qede_rx_queue *rxq) · 2838 unmodified lines | ||
| 2839 | 2839 | } |
| 2840 | 2840 | |
| 2841 | 2841 | mapping = dma_map_page(&edev->pdev->dev, replace_buf->data, 0, |
| 2842 | − rxq->rx_buf_size, DMA_FROM_DEVICE); | |
| 2842 | + PAGE_SIZE, DMA_FROM_DEVICE); | |
| 2843 | 2843 | if (unlikely(dma_mapping_error(&edev->pdev->dev, mapping))) { |
| 2844 | 2844 | DP_NOTICE(edev, |
| 2845 | 2845 | "Failed to map TPA replacement buffer\n"); |
| @@ -575,10 +575,11 @@ void emac_mac_start(struct emac_adapter *adpt) · 574 unmodified lines | ||
| 575 | 575 | |
| 576 | 576 | mac |= TXEN | RXEN; /* enable RX/TX */ |
| 577 | 577 | |
| 578 | − /* We don't have ethtool support yet, so force flow-control mode | |
| 579 | − * to 'full' always. | |
| 580 | − */ | |
| 581 | − mac |= TXFC | RXFC; | |
| 578 | + /* Configure MAC flow control to match the PHY's settings. */ | |
| 579 | + if (phydev->pause) | |
| 580 | + mac |= RXFC; | |
| 581 | + if (phydev->pause != phydev->asym_pause) | |
| 582 | + mac |= TXFC; | |
| 582 | 583 | |
| 583 | 584 | /* setup link speed */ |
| 584 | 585 | mac &= ~SPEED_MASK; |
| @@ -1003,6 +1004,12 @@ int emac_mac_up(struct emac_adapter *adpt) · 418 unmodified lines | ||
| 1003 | 1004 | writel((u32)~DIS_INT, adpt->base + EMAC_INT_STATUS); |
| 1004 | 1005 | writel(adpt->irq.mask, adpt->base + EMAC_INT_MASK); |
| 1005 | 1006 | |
| 1007 | + /* Enable pause frames. Without this feature, the EMAC has been shown | |
| 1008 | + * to receive (and drop) frames with FCS errors at gigabit connections. | |
| 1009 | + */ | |
| 1010 | + adpt->phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | |
| 1011 | + adpt->phydev->advertising |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | |
| 1012 | + | |
| 1006 | 1013 | adpt->phydev->irq = PHY_IGNORE_INTERRUPT; |
| 1007 | 1014 | phy_start(adpt->phydev); |
| 1008 | 1015 | |
| @@ -421,7 +421,7 @@ static const struct emac_reg_write sgmii_v2_laned[] = { · 420 unmodified lines | ||
| 421 | 421 | /* CDR Settings */ |
| 422 | 422 | {EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0, |
| 423 | 423 | UCDR_STEP_BY_TWO_MODE0 | UCDR_xO_GAIN_MODE(10)}, |
| 424 | − {EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0, UCDR_xO_GAIN_MODE(6)}, | |
| 424 | + {EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0, UCDR_xO_GAIN_MODE(0)}, | |
| 425 | 425 | {EMAC_SGMII_LN_UCDR_SO_CONFIG, UCDR_ENABLE | UCDR_SO_SATURATION(12)}, |
| 426 | 426 | |
| 427 | 427 | /* TX/RX Settings */ |
| @@ -485,6 +485,9 @@ efx_copy_channel(const struct efx_channel *old_channel) · 484 unmodified lines | ||
| 485 | 485 | *channel = *old_channel; |
| 486 | 486 | |
| 487 | 487 | channel->napi_dev = NULL; |
| 488 | + INIT_HLIST_NODE(&channel->napi_str.napi_hash_node); | |
| 489 | + channel->napi_str.napi_id = 0; | |
| 490 | + channel->napi_str.state = 0; | |
| 488 | 491 | memset(&channel->eventq, 0, sizeof(channel->eventq)); |
| 489 | 492 | |
| 490 | 493 | for (j = 0; j < EFX_TXQ_TYPES; j++) { |
| @@ -107,7 +107,7 @@ config DWMAC_STI · 106 unmodified lines | ||
| 107 | 107 | config DWMAC_STM32 |
| 108 | 108 | tristate "STM32 DWMAC support" |
| 109 | 109 | default ARCH_STM32 |
| 110 | − depends on OF && HAS_IOMEM | |
| 110 | + depends on OF && HAS_IOMEM && (ARCH_STM32 || COMPILE_TEST) | |
| 111 | 111 | select MFD_SYSCON |
| 112 | 112 | ---help--- |
| 113 | 113 | Support for ethernet controller on STM32 SOCs. |
| @@ -63,8 +63,8 @@ · 62 unmodified lines | ||
| 63 | 63 | #define TSE_PCS_SGMII_LINK_TIMER_0 0x0D40 |
| 64 | 64 | #define TSE_PCS_SGMII_LINK_TIMER_1 0x0003 |
| 65 | 65 | #define TSE_PCS_SW_RESET_TIMEOUT 100 |
| 66 | −#define TSE_PCS_USE_SGMII_AN_MASK BIT(2) | |
| 67 | −#define TSE_PCS_USE_SGMII_ENA BIT(1) | |
| 66 | +#define TSE_PCS_USE_SGMII_AN_MASK BIT(1) | |
| 67 | +#define TSE_PCS_USE_SGMII_ENA BIT(0) | |
| 68 | 68 | |
| 69 | 69 | #define SGMII_ADAPTER_CTRL_REG 0x00 |
| 70 | 70 | #define SGMII_ADAPTER_DISABLE 0x0001 |
| @@ -120,14 +120,17 @@ struct stmmac_extra_stats { · 119 unmodified lines | ||
| 120 | 120 | unsigned long ip_csum_bypassed; |
| 121 | 121 | unsigned long ipv4_pkt_rcvd; |
| 122 | 122 | unsigned long ipv6_pkt_rcvd; |
| 123 | − unsigned long rx_msg_type_ext_no_ptp; | |
| 124 | − unsigned long rx_msg_type_sync; | |
| 125 | − unsigned long rx_msg_type_follow_up; | |
| 126 | − unsigned long rx_msg_type_delay_req; | |
| 127 | − unsigned long rx_msg_type_delay_resp; | |
| 128 | − unsigned long rx_msg_type_pdelay_req; | |
| 129 | − unsigned long rx_msg_type_pdelay_resp; | |
| 130 | − unsigned long rx_msg_type_pdelay_follow_up; | |
| 123 | + unsigned long no_ptp_rx_msg_type_ext; | |
| 124 | + unsigned long ptp_rx_msg_type_sync; | |
| 125 | + unsigned long ptp_rx_msg_type_follow_up; | |
| 126 | + unsigned long ptp_rx_msg_type_delay_req; | |
| 127 | + unsigned long ptp_rx_msg_type_delay_resp; | |
| 128 | + unsigned long ptp_rx_msg_type_pdelay_req; | |
| 129 | + unsigned long ptp_rx_msg_type_pdelay_resp; | |
| 130 | + unsigned long ptp_rx_msg_type_pdelay_follow_up; | |
| 131 | + unsigned long ptp_rx_msg_type_announce; | |
| 132 | + unsigned long ptp_rx_msg_type_management; | |
| 133 | + unsigned long ptp_rx_msg_pkt_reserved_type; | |
| 131 | 134 | unsigned long ptp_frame_type; |
| 132 | 135 | unsigned long ptp_ver; |
| 133 | 136 | unsigned long timestamp_dropped; |
| @@ -482,11 +485,12 @@ struct stmmac_ops { · 348 unmodified lines | ||
| 482 | 485 | /* PTP and HW Timer helpers */ |
| 483 | 486 | struct stmmac_hwtimestamp { |
| 484 | 487 | void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data); |
| 485 | − u32 (*config_sub_second_increment) (void __iomem *ioaddr, u32 clk_rate); | |
| 488 | + u32 (*config_sub_second_increment)(void __iomem *ioaddr, u32 ptp_clock, | |
| 489 | + int gmac4); | |
| 486 | 490 | int (*init_systime) (void __iomem *ioaddr, u32 sec, u32 nsec); |
| 487 | 491 | int (*config_addend) (void __iomem *ioaddr, u32 addend); |
| 488 | 492 | int (*adjust_systime) (void __iomem *ioaddr, u32 sec, u32 nsec, |
| 489 | − int add_sub); | |
| 493 | + int add_sub, int gmac4); | |
| 490 | 494 | u64(*get_systime) (void __iomem *ioaddr); |
| 491 | 495 | }; |
| 492 | 496 | |
| @@ -155,14 +155,18 @@ · 154 unmodified lines | ||
| 155 | 155 | #define ERDES4_L3_L4_FILT_NO_MATCH_MASK GENMASK(27, 26) |
| 156 | 156 | |
| 157 | 157 | /* Extended RDES4 message type definitions */ |
| 158 | −#define RDES_EXT_NO_PTP 0 | |
| 159 | −#define RDES_EXT_SYNC 1 | |
| 160 | −#define RDES_EXT_FOLLOW_UP 2 | |
| 161 | −#define RDES_EXT_DELAY_REQ 3 | |
| 162 | −#define RDES_EXT_DELAY_RESP 4 | |
| 163 | −#define RDES_EXT_PDELAY_REQ 5 | |
| 164 | −#define RDES_EXT_PDELAY_RESP 6 | |
| 165 | −#define RDES_EXT_PDELAY_FOLLOW_UP 7 | |
| 158 | +#define RDES_EXT_NO_PTP 0x0 | |
| 159 | +#define RDES_EXT_SYNC 0x1 | |
| 160 | +#define RDES_EXT_FOLLOW_UP 0x2 | |
| 161 | +#define RDES_EXT_DELAY_REQ 0x3 | |
| 162 | +#define RDES_EXT_DELAY_RESP 0x4 | |
| 163 | +#define RDES_EXT_PDELAY_REQ 0x5 | |
| 164 | +#define RDES_EXT_PDELAY_RESP 0x6 | |
| 165 | +#define RDES_EXT_PDELAY_FOLLOW_UP 0x7 | |
| 166 | +#define RDES_PTP_ANNOUNCE 0x8 | |
| 167 | +#define RDES_PTP_MANAGEMENT 0x9 | |
| 168 | +#define RDES_PTP_SIGNALING 0xa | |
| 169 | +#define RDES_PTP_PKT_RESERVED_TYPE 0xf | |
| 166 | 170 | |
| 167 | 171 | /* Basic descriptor structure for normal and alternate descriptors */ |
| 168 | 172 | struct dma_desc { |
| @@ -123,22 +123,29 @@ static int dwmac4_wrback_get_rx_status(void *data, struct stmmac_extra_stats *x, · 122 unmodified lines | ||
| 123 | 123 | x->ipv4_pkt_rcvd++; |
| 124 | 124 | if (rdes1 & RDES1_IPV6_HEADER) |
| 125 | 125 | x->ipv6_pkt_rcvd++; |
| 126 | − if (message_type == RDES_EXT_SYNC) | |
| 127 | − x->rx_msg_type_sync++; | |
| 126 | + | |
| 127 | + if (message_type == RDES_EXT_NO_PTP) | |
| 128 | + x->no_ptp_rx_msg_type_ext++; | |
| 129 | + else if (message_type == RDES_EXT_SYNC) | |
| 130 | + x->ptp_rx_msg_type_sync++; | |
| 128 | 131 | else if (message_type == RDES_EXT_FOLLOW_UP) |
| 129 | − x->rx_msg_type_follow_up++; | |
| 132 | + x->ptp_rx_msg_type_follow_up++; | |
| 130 | 133 | else if (message_type == RDES_EXT_DELAY_REQ) |
| 131 | − x->rx_msg_type_delay_req++; | |
| 134 | + x->ptp_rx_msg_type_delay_req++; | |
| 132 | 135 | else if (message_type == RDES_EXT_DELAY_RESP) |
| 133 | − x->rx_msg_type_delay_resp++; | |
| 136 | + x->ptp_rx_msg_type_delay_resp++; | |
| 134 | 137 | else if (message_type == RDES_EXT_PDELAY_REQ) |
| 135 | − x->rx_msg_type_pdelay_req++; | |
| 138 | + x->ptp_rx_msg_type_pdelay_req++; | |
| 136 | 139 | else if (message_type == RDES_EXT_PDELAY_RESP) |
| 137 | − x->rx_msg_type_pdelay_resp++; | |
| 140 | + x->ptp_rx_msg_type_pdelay_resp++; | |
| 138 | 141 | else if (message_type == RDES_EXT_PDELAY_FOLLOW_UP) |
| 139 | − x->rx_msg_type_pdelay_follow_up++; | |
| 140 | − else | |
| 141 | − x->rx_msg_type_ext_no_ptp++; | |
| 142 | + x->ptp_rx_msg_type_pdelay_follow_up++; | |
| 143 | + else if (message_type == RDES_PTP_ANNOUNCE) | |
| 144 | + x->ptp_rx_msg_type_announce++; | |
| 145 | + else if (message_type == RDES_PTP_MANAGEMENT) | |
| 146 | + x->ptp_rx_msg_type_management++; | |
| 147 | + else if (message_type == RDES_PTP_PKT_RESERVED_TYPE) | |
| 148 | + x->ptp_rx_msg_pkt_reserved_type++; | |
| 142 | 149 | |
| 143 | 150 | if (rdes1 & RDES1_PTP_PACKET_TYPE) |
| 144 | 151 | x->ptp_frame_type++; |
| @@ -204,14 +211,18 @@ static void dwmac4_rd_enable_tx_timestamp(struct dma_desc *p) · 59 unmodified lines | ||
| 204 | 211 | |
| 205 | 212 | static int dwmac4_wrback_get_tx_timestamp_status(struct dma_desc *p) |
| 206 | 213 | { |
| 207 | − return (p->des3 & TDES3_TIMESTAMP_STATUS) | |
| 208 | − >> TDES3_TIMESTAMP_STATUS_SHIFT; | |
| 214 | + /* Context type from W/B descriptor must be zero */ | |
| 215 | + if (p->des3 & TDES3_CONTEXT_TYPE) | |
| 216 | + return -EINVAL; | |
| 217 | + | |
| 218 | + /* Tx Timestamp Status is 1 so des0 and des1'll have valid values */ | |
| 219 | + if (p->des3 & TDES3_TIMESTAMP_STATUS) | |
| 220 | + return 0; | |
| 221 | + | |
| 222 | + return 1; | |
| 209 | 223 | } |
| 210 | 224 | |
| 211 | −/* NOTE: For RX CTX bit has to be checked before | |
| 212 | − * HAVE a specific function for TX and another one for RX | |
| 213 | − */ | |
| 214 | −static u64 dwmac4_wrback_get_timestamp(void *desc, u32 ats) | |
| 225 | +static inline u64 dwmac4_get_timestamp(void *desc, u32 ats) | |
| 215 | 226 | { |
| 216 | 227 | struct dma_desc *p = (struct dma_desc *)desc; |
| 217 | 228 | u64 ns; |
| @@ -223,12 +234,54 @@ static u64 dwmac4_wrback_get_timestamp(void *desc, u32 ats) · 5 unmodified lines | ||
| 223 | 234 | return ns; |
| 224 | 235 | } |
| 225 | 236 | |
| 226 | −static int dwmac4_context_get_rx_timestamp_status(void *desc, u32 ats) | |
| 237 | +static int dwmac4_rx_check_timestamp(void *desc) | |
| 238 | +{ | |
| 239 | + struct dma_desc *p = (struct dma_desc *)desc; | |
| 240 | + u32 own, ctxt; | |
| 241 | + int ret = 1; | |
| 242 | + | |
| 243 | + own = p->des3 & RDES3_OWN; | |
| 244 | + ctxt = ((p->des3 & RDES3_CONTEXT_DESCRIPTOR) | |
| 245 | + >> RDES3_CONTEXT_DESCRIPTOR_SHIFT); | |
| 246 | + | |
| 247 | + if (likely(!own && ctxt)) { | |
| 248 | + if ((p->des0 == 0xffffffff) && (p->des1 == 0xffffffff)) | |
| 249 | + /* Corrupted value */ | |
| 250 | + ret = -EINVAL; | |
| 251 | + else | |
| 252 | + /* A valid Timestamp is ready to be read */ | |
| 253 | + ret = 0; | |
| 254 | + } | |
| 255 | + | |
| 256 | + /* Timestamp not ready */ | |
| 257 | + return ret; | |
| 258 | +} | |
| 259 | + | |
| 260 | +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats) | |
| 227 | 261 | { |
| 228 | 262 | struct dma_desc *p = (struct dma_desc *)desc; |
| 263 | + int ret = -EINVAL; | |
| 264 | + | |
| 265 | + /* Get the status from normal w/b descriptor */ | |
| 266 | + if (likely(p->des3 & TDES3_RS1V)) { | |
| 267 | + if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) { | |
| 268 | + int i = 0; | |
| 269 | + | |
| 270 | + /* Check if timestamp is OK from context descriptor */ | |
| 271 | + do { | |
| 272 | + ret = dwmac4_rx_check_timestamp(desc); | |
| 273 | + if (ret < 0) | |
| 274 | + goto exit; | |
| 275 | + i++; | |
| 229 | 276 | |
| 230 | − return (p->des1 & RDES1_TIMESTAMP_AVAILABLE) | |
| 231 | − >> RDES1_TIMESTAMP_AVAILABLE_SHIFT; | |
| 277 | + } while ((ret == 1) || (i < 10)); | |
| 278 | + | |
| 279 | + if (i == 10) | |
| 280 | + ret = -EBUSY; | |
| 281 | + } | |
| 282 | + } | |
| 283 | +exit: | |
| 284 | + return ret; | |
| 232 | 285 | } |
| 233 | 286 | |
| 234 | 287 | static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic, |
| @@ -373,8 +426,8 @@ const struct stmmac_desc_ops dwmac4_desc_ops = { · 138 unmodified lines | ||
| 373 | 426 | .get_rx_frame_len = dwmac4_wrback_get_rx_frame_len, |
| 374 | 427 | .enable_tx_timestamp = dwmac4_rd_enable_tx_timestamp, |
| 375 | 428 | .get_tx_timestamp_status = dwmac4_wrback_get_tx_timestamp_status, |
| 376 | − .get_timestamp = dwmac4_wrback_get_timestamp, | |
| 377 | − .get_rx_timestamp_status = dwmac4_context_get_rx_timestamp_status, | |
| 429 | + .get_rx_timestamp_status = dwmac4_wrback_get_rx_timestamp_status, | |
| 430 | + .get_timestamp = dwmac4_get_timestamp, | |
| 378 | 431 | .set_tx_ic = dwmac4_rd_set_tx_ic, |
| 379 | 432 | .prepare_tx_desc = dwmac4_rd_prepare_tx_desc, |
| 380 | 433 | .prepare_tso_tx_desc = dwmac4_rd_prepare_tso_tx_desc, |
| @@ -59,10 +59,13 @@ · 58 unmodified lines | ||
| 59 | 59 | #define TDES3_CTXT_TCMSSV BIT(26) |
| 60 | 60 | |
| 61 | 61 | /* TDES3 Common */ |
| 62 | +#define TDES3_RS1V BIT(26) | |
| 63 | +#define TDES3_RS1V_SHIFT 26 | |
| 62 | 64 | #define TDES3_LAST_DESCRIPTOR BIT(28) |
| 63 | 65 | #define TDES3_LAST_DESCRIPTOR_SHIFT 28 |
| 64 | 66 | #define TDES3_FIRST_DESCRIPTOR BIT(29) |
| 65 | 67 | #define TDES3_CONTEXT_TYPE BIT(30) |
| 68 | +#define TDES3_CONTEXT_TYPE_SHIFT 30 | |
| 66 | 69 | |
| 67 | 70 | /* TDS3 use for both format (read and write back) */ |
| 68 | 71 | #define TDES3_OWN BIT(31) |
| @@ -117,6 +120,7 @@ · 48 unmodified lines | ||
| 117 | 120 | #define RDES3_LAST_DESCRIPTOR BIT(28) |
| 118 | 121 | #define RDES3_FIRST_DESCRIPTOR BIT(29) |
| 119 | 122 | #define RDES3_CONTEXT_DESCRIPTOR BIT(30) |
| 123 | +#define RDES3_CONTEXT_DESCRIPTOR_SHIFT 30 | |
| 120 | 124 | |
| 121 | 125 | /* RDES3 (read format) */ |
| 122 | 126 | #define RDES3_BUFFER1_VALID_ADDR BIT(24) |
| @@ -150,22 +150,30 @@ static void enh_desc_get_ext_status(void *data, struct stmmac_extra_stats *x, · 149 unmodified lines | ||
| 150 | 150 | x->ipv4_pkt_rcvd++; |
| 151 | 151 | if (rdes4 & ERDES4_IPV6_PKT_RCVD) |
| 152 | 152 | x->ipv6_pkt_rcvd++; |
| 153 | − if (message_type == RDES_EXT_SYNC) | |
| 154 | − x->rx_msg_type_sync++; | |
| 153 | + | |
| 154 | + if (message_type == RDES_EXT_NO_PTP) | |
| 155 | + x->no_ptp_rx_msg_type_ext++; | |
| 156 | + else if (message_type == RDES_EXT_SYNC) | |
| 157 | + x->ptp_rx_msg_type_sync++; | |
| 155 | 158 | else if (message_type == RDES_EXT_FOLLOW_UP) |
| 156 | − x->rx_msg_type_follow_up++; | |
| 159 | + x->ptp_rx_msg_type_follow_up++; | |
| 157 | 160 | else if (message_type == RDES_EXT_DELAY_REQ) |
| 158 | − x->rx_msg_type_delay_req++; | |
| 161 | + x->ptp_rx_msg_type_delay_req++; | |
| 159 | 162 | else if (message_type == RDES_EXT_DELAY_RESP) |
| 160 | − x->rx_msg_type_delay_resp++; | |
| 163 | + x->ptp_rx_msg_type_delay_resp++; | |
| 161 | 164 | else if (message_type == RDES_EXT_PDELAY_REQ) |
| 162 | − x->rx_msg_type_pdelay_req++; | |
| 165 | + x->ptp_rx_msg_type_pdelay_req++; | |
| 163 | 166 | else if (message_type == RDES_EXT_PDELAY_RESP) |
| 164 | − x->rx_msg_type_pdelay_resp++; | |
| 167 | + x->ptp_rx_msg_type_pdelay_resp++; | |
| 165 | 168 | else if (message_type == RDES_EXT_PDELAY_FOLLOW_UP) |
| 166 | − x->rx_msg_type_pdelay_follow_up++; | |
| 167 | − else | |
| 168 | − x->rx_msg_type_ext_no_ptp++; | |
| 169 | + x->ptp_rx_msg_type_pdelay_follow_up++; | |
| 170 | + else if (message_type == RDES_PTP_ANNOUNCE) | |
| 171 | + x->ptp_rx_msg_type_announce++; | |
| 172 | + else if (message_type == RDES_PTP_MANAGEMENT) | |
| 173 | + x->ptp_rx_msg_type_management++; | |
| 174 | + else if (message_type == RDES_PTP_PKT_RESERVED_TYPE) | |
| 175 | + x->ptp_rx_msg_pkt_reserved_type++; | |
| 176 | + | |
| 169 | 177 | if (rdes4 & ERDES4_PTP_FRAME_TYPE) |
| 170 | 178 | x->ptp_frame_type++; |
| 171 | 179 | if (rdes4 & ERDES4_PTP_VER) |
| @@ -129,6 +129,7 @@ struct stmmac_priv { · 128 unmodified lines | ||
| 129 | 129 | int irq_wake; |
| 130 | 130 | spinlock_t ptp_lock; |
| 131 | 131 | void __iomem *mmcaddr; |
| 132 | + void __iomem *ptpaddr; | |
| 132 | 133 | u32 rx_tail_addr; |
| 133 | 134 | u32 tx_tail_addr; |
| 134 | 135 | u32 mss; |
| @@ -115,14 +115,17 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { · 114 unmodified lines | ||
| 115 | 115 | STMMAC_STAT(ip_csum_bypassed), |
| 116 | 116 | STMMAC_STAT(ipv4_pkt_rcvd), |
| 117 | 117 | STMMAC_STAT(ipv6_pkt_rcvd), |
| 118 | − STMMAC_STAT(rx_msg_type_ext_no_ptp), | |
| 119 | − STMMAC_STAT(rx_msg_type_sync), | |
| 120 | − STMMAC_STAT(rx_msg_type_follow_up), | |
| 121 | − STMMAC_STAT(rx_msg_type_delay_req), | |
| 122 | − STMMAC_STAT(rx_msg_type_delay_resp), | |
| 123 | − STMMAC_STAT(rx_msg_type_pdelay_req), | |
| 124 | − STMMAC_STAT(rx_msg_type_pdelay_resp), | |
| 125 | − STMMAC_STAT(rx_msg_type_pdelay_follow_up), | |
| 118 | + STMMAC_STAT(no_ptp_rx_msg_type_ext), | |
| 119 | + STMMAC_STAT(ptp_rx_msg_type_sync), | |
| 120 | + STMMAC_STAT(ptp_rx_msg_type_follow_up), | |
| 121 | + STMMAC_STAT(ptp_rx_msg_type_delay_req), | |
| 122 | + STMMAC_STAT(ptp_rx_msg_type_delay_resp), | |
| 123 | + STMMAC_STAT(ptp_rx_msg_type_pdelay_req), | |
| 124 | + STMMAC_STAT(ptp_rx_msg_type_pdelay_resp), | |
| 125 | + STMMAC_STAT(ptp_rx_msg_type_pdelay_follow_up), | |
| 126 | + STMMAC_STAT(ptp_rx_msg_type_announce), | |
| 127 | + STMMAC_STAT(ptp_rx_msg_type_management), | |
| 128 | + STMMAC_STAT(ptp_rx_msg_pkt_reserved_type), | |
| 126 | 129 | STMMAC_STAT(ptp_frame_type), |
| 127 | 130 | STMMAC_STAT(ptp_ver), |
| 128 | 131 | STMMAC_STAT(timestamp_dropped), |
| @@ -34,21 +34,29 @@ static void stmmac_config_hw_tstamping(void __iomem *ioaddr, u32 data) · 33 unmodified lines | ||
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, |
| 37 | − u32 ptp_clock) | |
| 37 | + u32 ptp_clock, int gmac4) | |
| 38 | 38 | { |
| 39 | 39 | u32 value = readl(ioaddr + PTP_TCR); |
| 40 | 40 | unsigned long data; |
| 41 | 41 | |
| 42 | − /* Convert the ptp_clock to nano second | |
| 43 | − * formula = (2/ptp_clock) * 1000000000 | |
| 44 | − * where, ptp_clock = 50MHz. | |
| 42 | + /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second | |
| 43 | + * formula = (1/ptp_clock) * 1000000000 | |
| 44 | + * where ptp_clock is 50MHz if fine method is used to update system | |
| 45 | 45 | */ |
| 46 | − data = (2000000000ULL / ptp_clock); | |
| 46 | + if (value & PTP_TCR_TSCFUPDT) | |
| 47 | + data = (1000000000ULL / 50000000); | |
| 48 | + else | |
| 49 | + data = (1000000000ULL / ptp_clock); | |
| 47 | 50 | |
| 48 | 51 | /* 0.465ns accuracy */ |
| 49 | 52 | if (!(value & PTP_TCR_TSCTRLSSR)) |
| 50 | 53 | data = (data * 1000) / 465; |
| 51 | 54 | |
| 55 | + data &= PTP_SSIR_SSINC_MASK; | |
| 56 | + | |
| 57 | + if (gmac4) | |
| 58 | + data = data << GMAC4_PTP_SSIR_SSINC_SHIFT; | |
| 59 | + | |
| 52 | 60 | writel(data, ioaddr + PTP_SSIR); |
| 53 | 61 | |
| 54 | 62 | return data; |
| @@ -104,14 +112,30 @@ static int stmmac_config_addend(void __iomem *ioaddr, u32 addend) · 49 unmodified lines | ||
| 104 | 112 | } |
| 105 | 113 | |
| 106 | 114 | static int stmmac_adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec, |
| 107 | − int add_sub) | |
| 115 | + int add_sub, int gmac4) | |
| 108 | 116 | { |
| 109 | 117 | u32 value; |
| 110 | 118 | int limit; |
| 111 | 119 | |
| 120 | + if (add_sub) { | |
| 121 | + /* If the new sec value needs to be subtracted with | |
| 122 | + * the system time, then MAC_STSUR reg should be | |
| 123 | + * programmed with (2^32 – <new_sec_value>) | |
| 124 | + */ | |
| 125 | + if (gmac4) | |
| 126 | + sec = (100000000ULL - sec); | |
| 127 | + | |
| 128 | + value = readl(ioaddr + PTP_TCR); | |
| 129 | + if (value & PTP_TCR_TSCTRLSSR) | |
| 130 | + nsec = (PTP_DIGITAL_ROLLOVER_MODE - nsec); | |
| 131 | + else | |
| 132 | + nsec = (PTP_BINARY_ROLLOVER_MODE - nsec); | |
| 133 | + } | |
| 134 | + | |
| 112 | 135 | writel(sec, ioaddr + PTP_STSUR); |
| 113 | − writel(((add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec), | |
| 114 | − ioaddr + PTP_STNSUR); | |
| 136 | + value = (add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec; | |
| 137 | + writel(value, ioaddr + PTP_STNSUR); | |
| 138 | + | |
| 115 | 139 | /* issue command to initialize the system time value */ |
| 116 | 140 | value = readl(ioaddr + PTP_TCR); |
| 117 | 141 | value |= PTP_TCR_TSUPDT; |
| @@ -134,8 +158,9 @@ static u64 stmmac_get_systime(void __iomem *ioaddr) · 16 unmodified lines | ||
| 134 | 158 | { |
| 135 | 159 | u64 ns; |
| 136 | 160 | |
| 161 | + /* Get the TSSS value */ | |
| 137 | 162 | ns = readl(ioaddr + PTP_STNSR); |
| 138 | − /* convert sec time value to nanosecond */ | |
| 163 | + /* Get the TSS and convert sec time value to nanosecond */ | |
| 139 | 164 | ns += readl(ioaddr + PTP_STSR) * 1000000000ULL; |
| 140 | 165 | |
| 141 | 166 | return ns; |
| @@ -340,18 +340,17 @@ out: · 339 unmodified lines | ||
| 340 | 340 | |
| 341 | 341 | /* stmmac_get_tx_hwtstamp - get HW TX timestamps |
| 342 | 342 | * @priv: driver private structure |
| 343 | − * @entry : descriptor index to be used. | |
| 343 | + * @p : descriptor pointer | |
| 344 | 344 | * @skb : the socket buffer |
| 345 | 345 | * Description : |
| 346 | 346 | * This function will read timestamp from the descriptor & pass it to stack. |
| 347 | 347 | * and also perform some sanity checks. |
| 348 | 348 | */ |
| 349 | 349 | static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, |
| 350 | − unsigned int entry, struct sk_buff *skb) | |
| 350 | + struct dma_desc *p, struct sk_buff *skb) | |
| 351 | 351 | { |
| 352 | 352 | struct skb_shared_hwtstamps shhwtstamp; |
| 353 | 353 | u64 ns; |
| 354 | − void *desc = NULL; | |
| 355 | 354 | |
| 356 | 355 | if (!priv->hwts_tx_en) |
| 357 | 356 | return; |
| @@ -360,58 +359,55 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, · 2 unmodified lines | ||
| 360 | 359 | if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))) |
| 361 | 360 | return; |
| 362 | 361 | |
| 363 | − if (priv->adv_ts) | |
| 364 | − desc = (priv->dma_etx + entry); | |
| 365 | − else | |
| 366 | − desc = (priv->dma_tx + entry); | |
| 367 | − | |
| 368 | 362 | /* check tx tstamp status */ |
| 369 | − if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc)) | |
| 370 | − return; | |
| 363 | + if (!priv->hw->desc->get_tx_timestamp_status(p)) { | |
| 364 | + /* get the valid tstamp */ | |
| 365 | + ns = priv->hw->desc->get_timestamp(p, priv->adv_ts); | |
| 371 | 366 | |
| 372 | − /* get the valid tstamp */ | |
| 373 | − ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); | |
| 367 | + memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); | |
| 368 | + shhwtstamp.hwtstamp = ns_to_ktime(ns); | |
| 374 | 369 | |
| 375 | − memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); | |
| 376 | − shhwtstamp.hwtstamp = ns_to_ktime(ns); | |
| 377 | − /* pass tstamp to stack */ | |
| 378 | − skb_tstamp_tx(skb, &shhwtstamp); | |
| 370 | + netdev_info(priv->dev, "get valid TX hw timestamp %llu\n", ns); | |
| 371 | + /* pass tstamp to stack */ | |
| 372 | + skb_tstamp_tx(skb, &shhwtstamp); | |
| 373 | + } | |
| 379 | 374 | |
| 380 | 375 | return; |
| 381 | 376 | } |
| 382 | 377 | |
| 383 | 378 | /* stmmac_get_rx_hwtstamp - get HW RX timestamps |
| 384 | 379 | * @priv: driver private structure |
| 385 | − * @entry : descriptor index to be used. | |
| 380 | + * @p : descriptor pointer | |
| 381 | + * @np : next descriptor pointer | |
| 386 | 382 | * @skb : the socket buffer |
| 387 | 383 | * Description : |
| 388 | 384 | * This function will read received packet's timestamp from the descriptor |
| 389 | 385 | * and pass it to stack. It also perform some sanity checks. |
| 390 | 386 | */ |
| 391 | −static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, | |
| 392 | − unsigned int entry, struct sk_buff *skb) | |
| 387 | +static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p, | |
| 388 | + struct dma_desc *np, struct sk_buff *skb) | |
| 393 | 389 | { |
| 394 | 390 | struct skb_shared_hwtstamps *shhwtstamp = NULL; |
| 395 | 391 | u64 ns; |
| 396 | − void *desc = NULL; | |
| 397 | 392 | |
| 398 | 393 | if (!priv->hwts_rx_en) |
| 399 | 394 | return; |
| 400 | 395 | |
| 401 | − if (priv->adv_ts) | |
| 402 | − desc = (priv->dma_erx + entry); | |
| 403 | − else | |
| 404 | − desc = (priv->dma_rx + entry); | |
| 405 | − | |
| 406 | − /* exit if rx tstamp is not valid */ | |
| 407 | − if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) | |
| 408 | − return; | |
| 396 | + /* Check if timestamp is available */ | |
| 397 | + if (!priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) { | |
| 398 | + /* For GMAC4, the valid timestamp is from CTX next desc. */ | |
| 399 | + if (priv->plat->has_gmac4) | |
| 400 | + ns = priv->hw->desc->get_timestamp(np, priv->adv_ts); | |
| 401 | + else | |
| 402 | + ns = priv->hw->desc->get_timestamp(p, priv->adv_ts); | |
| 409 | 403 | |
| 410 | − /* get valid tstamp */ | |
| 411 | − ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); | |
| 412 | − shhwtstamp = skb_hwtstamps(skb); | |
| 413 | − memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); | |
| 414 | − shhwtstamp->hwtstamp = ns_to_ktime(ns); | |
| 404 | + netdev_info(priv->dev, "get valid RX hw timestamp %llu\n", ns); | |
| 405 | + shhwtstamp = skb_hwtstamps(skb); | |
| 406 | + memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); | |
| 407 | + shhwtstamp->hwtstamp = ns_to_ktime(ns); | |
| 408 | + } else { | |
| 409 | + netdev_err(priv->dev, "cannot get RX hw timestamp\n"); | |
| 410 | + } | |
| 415 | 411 | } |
| 416 | 412 | |
| 417 | 413 | /** |
| @@ -598,17 +594,18 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) · 180 unmodified lines | ||
| 598 | 594 | priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON; |
| 599 | 595 | |
| 600 | 596 | if (!priv->hwts_tx_en && !priv->hwts_rx_en) |
| 601 | − priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0); | |
| 597 | + priv->hw->ptp->config_hw_tstamping(priv->ptpaddr, 0); | |
| 602 | 598 | else { |
| 603 | 599 | value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR | |
| 604 | 600 | tstamp_all | ptp_v2 | ptp_over_ethernet | |
| 605 | 601 | ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en | |
| 606 | 602 | ts_master_en | snap_type_sel); |
| 607 | − priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value); | |
| 603 | + priv->hw->ptp->config_hw_tstamping(priv->ptpaddr, value); | |
| 608 | 604 | |
| 609 | 605 | /* program Sub Second Increment reg */ |
| 610 | 606 | sec_inc = priv->hw->ptp->config_sub_second_increment( |
| 611 | − priv->ioaddr, priv->clk_ptp_rate); | |
| 607 | + priv->ptpaddr, priv->clk_ptp_rate, | |
| 608 | + priv->plat->has_gmac4); | |
| 612 | 609 | temp = div_u64(1000000000ULL, sec_inc); |
| 613 | 610 | |
| 614 | 611 | /* calculate default added value: |
| @@ -618,14 +615,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) · 3 unmodified lines | ||
| 618 | 615 | */ |
| 619 | 616 | temp = (u64)(temp << 32); |
| 620 | 617 | priv->default_addend = div_u64(temp, priv->clk_ptp_rate); |
| 621 | − priv->hw->ptp->config_addend(priv->ioaddr, | |
| 618 | + priv->hw->ptp->config_addend(priv->ptpaddr, | |
| 622 | 619 | priv->default_addend); |
| 623 | 620 | |
| 624 | 621 | /* initialize system time */ |
| 625 | 622 | ktime_get_real_ts64(&now); |
| 626 | 623 | |
| 627 | 624 | /* lower 32 bits of tv_sec are safe until y2106 */ |
| 628 | − priv->hw->ptp->init_systime(priv->ioaddr, (u32)now.tv_sec, | |
| 625 | + priv->hw->ptp->init_systime(priv->ptpaddr, (u32)now.tv_sec, | |
| 629 | 626 | now.tv_nsec); |
| 630 | 627 | } |
| 631 | 628 | |
| @@ -880,6 +877,13 @@ static int stmmac_init_phy(struct net_device *dev) · 248 unmodified lines | ||
| 880 | 877 | return -ENODEV; |
| 881 | 878 | } |
| 882 | 879 | |
| 880 | + /* stmmac_adjust_link will change this to PHY_IGNORE_INTERRUPT to avoid | |
| 881 | + * subsequent PHY polling, make sure we force a link transition if | |
| 882 | + * we have a UP/DOWN/UP transition | |
| 883 | + */ | |
| 884 | + if (phydev->is_pseudo_fixed_link) | |
| 885 | + phydev->irq = PHY_POLL; | |
| 886 | + | |
| 883 | 887 | pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" |
| 884 | 888 | " Link = %d\n", dev->name, phydev->phy_id, phydev->link); |
| 885 | 889 | |
| @@ -1333,7 +1337,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) · 447 unmodified lines | ||
| 1333 | 1337 | priv->dev->stats.tx_packets++; |
| 1334 | 1338 | priv->xstats.tx_pkt_n++; |
| 1335 | 1339 | } |
| 1336 | − stmmac_get_tx_hwtstamp(priv, entry, skb); | |
| 1340 | + stmmac_get_tx_hwtstamp(priv, p, skb); | |
| 1337 | 1341 | } |
| 1338 | 1342 | |
| 1339 | 1343 | if (likely(priv->tx_skbuff_dma[entry].buf)) { |
| @@ -1479,10 +1483,13 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv) · 139 unmodified lines | ||
| 1479 | 1483 | unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | |
| 1480 | 1484 | MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; |
| 1481 | 1485 | |
| 1482 | − if (priv->synopsys_id >= DWMAC_CORE_4_00) | |
| 1486 | + if (priv->synopsys_id >= DWMAC_CORE_4_00) { | |
| 1487 | + priv->ptpaddr = priv->ioaddr + PTP_GMAC4_OFFSET; | |
| 1483 | 1488 | priv->mmcaddr = priv->ioaddr + MMC_GMAC4_OFFSET; |
| 1484 | − else | |
| 1489 | + } else { | |
| 1490 | + priv->ptpaddr = priv->ioaddr + PTP_GMAC3_X_OFFSET; | |
| 1485 | 1491 | priv->mmcaddr = priv->ioaddr + MMC_GMAC3_X_OFFSET; |
| 1492 | + } | |
| 1486 | 1493 | |
| 1487 | 1494 | dwmac_mmc_intr_all_mask(priv->mmcaddr); |
| 1488 | 1495 | |
| @@ -2477,7 +2484,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) · 988 unmodified lines | ||
| 2477 | 2484 | if (netif_msg_rx_status(priv)) { |
| 2478 | 2485 | void *rx_head; |
| 2479 | 2486 | |
| 2480 | − pr_debug("%s: descriptor ring:\n", __func__); | |
| 2487 | + pr_info(">>>>>> %s: descriptor ring:\n", __func__); | |
| 2481 | 2488 | if (priv->extend_desc) |
| 2482 | 2489 | rx_head = (void *)priv->dma_erx; |
| 2483 | 2490 | else |
| @@ -2488,6 +2495,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) · 4 unmodified lines | ||
| 2488 | 2495 | while (count < limit) { |
| 2489 | 2496 | int status; |
| 2490 | 2497 | struct dma_desc *p; |
| 2498 | + struct dma_desc *np; | |
| 2491 | 2499 | |
| 2492 | 2500 | if (priv->extend_desc) |
| 2493 | 2501 | p = (struct dma_desc *)(priv->dma_erx + entry); |
| @@ -2507,9 +2515,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) · 13 unmodified lines | ||
| 2507 | 2515 | next_entry = priv->cur_rx; |
| 2508 | 2516 | |
| 2509 | 2517 | if (priv->extend_desc) |
| 2510 | − prefetch(priv->dma_erx + next_entry); | |
| 2518 | + np = (struct dma_desc *)(priv->dma_erx + next_entry); | |
| 2511 | 2519 | else |
| 2512 | − prefetch(priv->dma_rx + next_entry); | |
| 2520 | + np = priv->dma_rx + next_entry; | |
| 2521 | + | |
| 2522 | + prefetch(np); | |
| 2513 | 2523 | |
| 2514 | 2524 | if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status)) |
| 2515 | 2525 | priv->hw->desc->rx_extended_status(&priv->dev->stats, |
| @@ -2561,7 +2571,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) · 45 unmodified lines | ||
| 2561 | 2571 | frame_len -= ETH_FCS_LEN; |
| 2562 | 2572 | |
| 2563 | 2573 | if (netif_msg_rx_status(priv)) { |
| 2564 | − pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", | |
| 2574 | + pr_info("\tdesc: %p [entry %d] buff=0x%x\n", | |
| 2565 | 2575 | p, entry, des); |
| 2566 | 2576 | if (frame_len > ETH_FRAME_LEN) |
| 2567 | 2577 | pr_debug("\tframe size %d, COE: %d\n", |
| @@ -2618,13 +2628,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) · 50 unmodified lines | ||
| 2618 | 2628 | DMA_FROM_DEVICE); |
| 2619 | 2629 | } |
| 2620 | 2630 | |
| 2621 | − stmmac_get_rx_hwtstamp(priv, entry, skb); | |
| 2622 | − | |
| 2623 | 2631 | if (netif_msg_pktdata(priv)) { |
| 2624 | 2632 | pr_debug("frame received (%dbytes)", frame_len); |
| 2625 | 2633 | print_pkt(skb->data, frame_len); |
| 2626 | 2634 | } |
| 2627 | 2635 | |
| 2636 | + stmmac_get_rx_hwtstamp(priv, p, np, skb); | |
| 2637 | + | |
| 2628 | 2638 | stmmac_rx_vlan(priv->dev, skb); |
| 2629 | 2639 | |
| 2630 | 2640 | skb->protocol = eth_type_trans(skb, priv->dev); |
| @@ -54,7 +54,7 @@ static int stmmac_adjust_freq(struct ptp_clock_info *ptp, s32 ppb) · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | spin_lock_irqsave(&priv->ptp_lock, flags); |
| 56 | 56 | |
| 57 | − priv->hw->ptp->config_addend(priv->ioaddr, addend); | |
| 57 | + priv->hw->ptp->config_addend(priv->ptpaddr, addend); | |
| 58 | 58 | |
| 59 | 59 | spin_unlock_irqrestore(&priv->ptp_lock, flags); |
| 60 | 60 | |
| @@ -89,7 +89,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta) · 28 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | spin_lock_irqsave(&priv->ptp_lock, flags); |
| 91 | 91 | |
| 92 | − priv->hw->ptp->adjust_systime(priv->ioaddr, sec, nsec, neg_adj); | |
| 92 | + priv->hw->ptp->adjust_systime(priv->ptpaddr, sec, nsec, neg_adj, | |
| 93 | + priv->plat->has_gmac4); | |
| 93 | 94 | |
| 94 | 95 | spin_unlock_irqrestore(&priv->ptp_lock, flags); |
| 95 | 96 | |
| @@ -114,7 +115,7 @@ static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts) · 18 unmodified lines | ||
| 114 | 115 | |
| 115 | 116 | spin_lock_irqsave(&priv->ptp_lock, flags); |
| 116 | 117 | |
| 117 | − ns = priv->hw->ptp->get_systime(priv->ioaddr); | |
| 118 | + ns = priv->hw->ptp->get_systime(priv->ptpaddr); | |
| 118 | 119 | |
| 119 | 120 | spin_unlock_irqrestore(&priv->ptp_lock, flags); |
| 120 | 121 | |
| @@ -141,7 +142,7 @@ static int stmmac_set_time(struct ptp_clock_info *ptp, · 20 unmodified lines | ||
| 141 | 142 | |
| 142 | 143 | spin_lock_irqsave(&priv->ptp_lock, flags); |
| 143 | 144 | |
| 144 | − priv->hw->ptp->init_systime(priv->ioaddr, ts->tv_sec, ts->tv_nsec); | |
| 145 | + priv->hw->ptp->init_systime(priv->ptpaddr, ts->tv_sec, ts->tv_nsec); | |
| 145 | 146 | |
| 146 | 147 | spin_unlock_irqrestore(&priv->ptp_lock, flags); |
| 147 | 148 | |
| @@ -22,51 +22,53 @@ · 21 unmodified lines | ||
| 22 | 22 | Author: Rayagond Kokatanur <rayagond@vayavyalabs.com> |
| 23 | 23 | ******************************************************************************/ |
| 24 | 24 | |
| 25 | −#ifndef __STMMAC_PTP_H__ | |
| 26 | −#define __STMMAC_PTP_H__ | |
| 25 | +#ifndef __STMMAC_PTP_H__ | |
| 26 | +#define __STMMAC_PTP_H__ | |
| 27 | 27 | |
| 28 | −/* IEEE 1588 PTP register offsets */ | |
| 29 | −#define PTP_TCR 0x0700 /* Timestamp Control Reg */ | |
| 30 | −#define PTP_SSIR 0x0704 /* Sub-Second Increment Reg */ | |
| 31 | −#define PTP_STSR 0x0708 /* System Time – Seconds Regr */ | |
| 32 | −#define PTP_STNSR 0x070C /* System Time – Nanoseconds Reg */ | |
| 33 | −#define PTP_STSUR 0x0710 /* System Time – Seconds Update Reg */ | |
| 34 | −#define PTP_STNSUR 0x0714 /* System Time – Nanoseconds Update Reg */ | |
| 35 | −#define PTP_TAR 0x0718 /* Timestamp Addend Reg */ | |
| 36 | −#define PTP_TTSR 0x071C /* Target Time Seconds Reg */ | |
| 37 | −#define PTP_TTNSR 0x0720 /* Target Time Nanoseconds Reg */ | |
| 38 | −#define PTP_STHWSR 0x0724 /* System Time - Higher Word Seconds Reg */ | |
| 39 | −#define PTP_TSR 0x0728 /* Timestamp Status */ | |
| 28 | +#define PTP_GMAC4_OFFSET 0xb00 | |
| 29 | +#define PTP_GMAC3_X_OFFSET 0x700 | |
| 40 | 30 | |
| 41 | −#define PTP_STNSUR_ADDSUB_SHIFT 31 | |
| 31 | +/* IEEE 1588 PTP register offsets */ | |
| 32 | +#define PTP_TCR 0x00 /* Timestamp Control Reg */ | |
| 33 | +#define PTP_SSIR 0x04 /* Sub-Second Increment Reg */ | |
| 34 | +#define PTP_STSR 0x08 /* System Time – Seconds Regr */ | |
| 35 | +#define PTP_STNSR 0x0c /* System Time – Nanoseconds Reg */ | |
| 36 | +#define PTP_STSUR 0x10 /* System Time – Seconds Update Reg */ | |
| 37 | +#define PTP_STNSUR 0x14 /* System Time – Nanoseconds Update Reg */ | |
| 38 | +#define PTP_TAR 0x18 /* Timestamp Addend Reg */ | |
| 42 | 39 | |
| 43 | −/* PTP TCR defines */ | |
| 44 | −#define PTP_TCR_TSENA 0x00000001 /* Timestamp Enable */ | |
| 45 | −#define PTP_TCR_TSCFUPDT 0x00000002 /* Timestamp Fine/Coarse Update */ | |
| 46 | −#define PTP_TCR_TSINIT 0x00000004 /* Timestamp Initialize */ | |
| 47 | −#define PTP_TCR_TSUPDT 0x00000008 /* Timestamp Update */ | |
| 48 | −/* Timestamp Interrupt Trigger Enable */ | |
| 49 | −#define PTP_TCR_TSTRIG 0x00000010 | |
| 50 | −#define PTP_TCR_TSADDREG 0x00000020 /* Addend Reg Update */ | |
| 51 | −#define PTP_TCR_TSENALL 0x00000100 /* Enable Timestamp for All Frames */ | |
| 52 | −/* Timestamp Digital or Binary Rollover Control */ | |
| 53 | −#define PTP_TCR_TSCTRLSSR 0x00000200 | |
| 40 | +#define PTP_STNSUR_ADDSUB_SHIFT 31 | |
| 41 | +#define PTP_DIGITAL_ROLLOVER_MODE 0x3B9ACA00 /* 10e9-1 ns */ | |
| 42 | +#define PTP_BINARY_ROLLOVER_MODE 0x80000000 /* ~0.466 ns */ | |
| 54 | 43 | |
| 44 | +/* PTP Timestamp control register defines */ | |
| 45 | +#define PTP_TCR_TSENA BIT(0) /* Timestamp Enable */ | |
| 46 | +#define PTP_TCR_TSCFUPDT BIT(1) /* Timestamp Fine/Coarse Update */ | |
| 47 | +#define PTP_TCR_TSINIT BIT(2) /* Timestamp Initialize */ | |
| 48 | +#define PTP_TCR_TSUPDT BIT(3) /* Timestamp Update */ | |
| 49 | +#define PTP_TCR_TSTRIG BIT(4) /* Timestamp Interrupt Trigger Enable */ | |
| 50 | +#define PTP_TCR_TSADDREG BIT(5) /* Addend Reg Update */ | |
| 51 | +#define PTP_TCR_TSENALL BIT(8) /* Enable Timestamp for All Frames */ | |
| 52 | +#define PTP_TCR_TSCTRLSSR BIT(9) /* Digital or Binary Rollover Control */ | |
| 55 | 53 | /* Enable PTP packet Processing for Version 2 Format */ |
| 56 | −#define PTP_TCR_TSVER2ENA 0x00000400 | |
| 54 | +#define PTP_TCR_TSVER2ENA BIT(10) | |
| 57 | 55 | /* Enable Processing of PTP over Ethernet Frames */ |
| 58 | −#define PTP_TCR_TSIPENA 0x00000800 | |
| 56 | +#define PTP_TCR_TSIPENA BIT(11) | |
| 59 | 57 | /* Enable Processing of PTP Frames Sent over IPv6-UDP */ |
| 60 | −#define PTP_TCR_TSIPV6ENA 0x00001000 | |
| 58 | +#define PTP_TCR_TSIPV6ENA BIT(12) | |
| 61 | 59 | /* Enable Processing of PTP Frames Sent over IPv4-UDP */ |
| 62 | −#define PTP_TCR_TSIPV4ENA 0x00002000 | |
| 60 | +#define PTP_TCR_TSIPV4ENA BIT(13) | |
| 63 | 61 | /* Enable Timestamp Snapshot for Event Messages */ |
| 64 | −#define PTP_TCR_TSEVNTENA 0x00004000 | |
| 62 | +#define PTP_TCR_TSEVNTENA BIT(14) | |
| 65 | 63 | /* Enable Snapshot for Messages Relevant to Master */ |
| 66 | −#define PTP_TCR_TSMSTRENA 0x00008000 | |
| 64 | +#define PTP_TCR_TSMSTRENA BIT(15) | |
| 67 | 65 | /* Select PTP packets for Taking Snapshots */ |
| 68 | −#define PTP_TCR_SNAPTYPSEL_1 0x00010000 | |
| 66 | +#define PTP_TCR_SNAPTYPSEL_1 GENMASK(17, 16) | |
| 69 | 67 | /* Enable MAC address for PTP Frame Filtering */ |
| 70 | −#define PTP_TCR_TSENMACADDR 0x00040000 | |
| 68 | +#define PTP_TCR_TSENMACADDR BIT(18) | |
| 69 | + | |
| 70 | +/* SSIR defines */ | |
| 71 | +#define PTP_SSIR_SSINC_MASK 0xff | |
| 72 | +#define GMAC4_PTP_SSIR_SSINC_SHIFT 16 | |
| 71 | 73 | |
| 72 | −#endif /* __STMMAC_PTP_H__ */ | |
| 74 | +#endif /* __STMMAC_PTP_H__ */ | |
| @@ -623,6 +623,7 @@ static int bigmac_init_hw(struct bigmac *bp, int from_irq) · 622 unmodified lines | ||
| 623 | 623 | void __iomem *gregs = bp->gregs; |
| 624 | 624 | void __iomem *cregs = bp->creg; |
| 625 | 625 | void __iomem *bregs = bp->bregs; |
| 626 | + __u32 bblk_dvma = (__u32)bp->bblock_dvma; | |
| 626 | 627 | unsigned char *e = &bp->dev->dev_addr[0]; |
| 627 | 628 | |
| 628 | 629 | /* Latch current counters into statistics. */ |
| @@ -671,9 +672,9 @@ static int bigmac_init_hw(struct bigmac *bp, int from_irq) · 42 unmodified lines | ||
| 671 | 672 | bregs + BMAC_XIFCFG); |
| 672 | 673 | |
| 673 | 674 | /* Tell the QEC where the ring descriptors are. */ |
| 674 | − sbus_writel(bp->bblock_dvma + bib_offset(be_rxd, 0), | |
| 675 | + sbus_writel(bblk_dvma + bib_offset(be_rxd, 0), | |
| 675 | 676 | cregs + CREG_RXDS); |
| 676 | − sbus_writel(bp->bblock_dvma + bib_offset(be_txd, 0), | |
| 677 | + sbus_writel(bblk_dvma + bib_offset(be_txd, 0), | |
| 677 | 678 | cregs + CREG_TXDS); |
| 678 | 679 | |
| 679 | 680 | /* Setup the FIFO pointers into QEC local memory. */ |
| @@ -291,7 +291,7 @@ struct bigmac { · 290 unmodified lines | ||
| 291 | 291 | void __iomem *bregs; /* BigMAC Registers */ |
| 292 | 292 | void __iomem *tregs; /* BigMAC Transceiver */ |
| 293 | 293 | struct bmac_init_block *bmac_block; /* RX and TX descriptors */ |
| 294 | − __u32 bblock_dvma; /* RX and TX descriptors */ | |
| 294 | + dma_addr_t bblock_dvma; /* RX and TX descriptors */ | |
| 295 | 295 | |
| 296 | 296 | spinlock_t lock; |
| 297 | 297 | |
| @@ -124,7 +124,7 @@ static void qe_init_rings(struct sunqe *qep) · 123 unmodified lines | ||
| 124 | 124 | { |
| 125 | 125 | struct qe_init_block *qb = qep->qe_block; |
| 126 | 126 | struct sunqe_buffers *qbufs = qep->buffers; |
| 127 | − __u32 qbufs_dvma = qep->buffers_dvma; | |
| 127 | + __u32 qbufs_dvma = (__u32)qep->buffers_dvma; | |
| 128 | 128 | int i; |
| 129 | 129 | |
| 130 | 130 | qep->rx_new = qep->rx_old = qep->tx_new = qep->tx_old = 0; |
| @@ -144,6 +144,7 @@ static int qe_init(struct sunqe *qep, int from_irq) · 13 unmodified lines | ||
| 144 | 144 | void __iomem *mregs = qep->mregs; |
| 145 | 145 | void __iomem *gregs = qecp->gregs; |
| 146 | 146 | unsigned char *e = &qep->dev->dev_addr[0]; |
| 147 | + __u32 qblk_dvma = (__u32)qep->qblock_dvma; | |
| 147 | 148 | u32 tmp; |
| 148 | 149 | int i; |
| 149 | 150 | |
| @@ -152,8 +153,8 @@ static int qe_init(struct sunqe *qep, int from_irq) · 2 unmodified lines | ||
| 152 | 153 | return -EAGAIN; |
| 153 | 154 | |
| 154 | 155 | /* Setup initial rx/tx init block pointers. */ |
| 155 | − sbus_writel(qep->qblock_dvma + qib_offset(qe_rxd, 0), cregs + CREG_RXDS); | |
| 156 | − sbus_writel(qep->qblock_dvma + qib_offset(qe_txd, 0), cregs + CREG_TXDS); | |
| 156 | + sbus_writel(qblk_dvma + qib_offset(qe_rxd, 0), cregs + CREG_RXDS); | |
| 157 | + sbus_writel(qblk_dvma + qib_offset(qe_txd, 0), cregs + CREG_TXDS); | |
| 157 | 158 | |
| 158 | 159 | /* Enable/mask the various irq's. */ |
| 159 | 160 | sbus_writel(0, cregs + CREG_RIMASK); |
| @@ -413,7 +414,7 @@ static void qe_rx(struct sunqe *qep) · 253 unmodified lines | ||
| 413 | 414 | struct net_device *dev = qep->dev; |
| 414 | 415 | struct qe_rxd *this; |
| 415 | 416 | struct sunqe_buffers *qbufs = qep->buffers; |
| 416 | − __u32 qbufs_dvma = qep->buffers_dvma; | |
| 417 | + __u32 qbufs_dvma = (__u32)qep->buffers_dvma; | |
| 417 | 418 | int elem = qep->rx_new; |
| 418 | 419 | u32 flags; |
| 419 | 420 | |
| @@ -572,7 +573,7 @@ static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev) · 152 unmodified lines | ||
| 572 | 573 | { |
| 573 | 574 | struct sunqe *qep = netdev_priv(dev); |
| 574 | 575 | struct sunqe_buffers *qbufs = qep->buffers; |
| 575 | − __u32 txbuf_dvma, qbufs_dvma = qep->buffers_dvma; | |
| 576 | + __u32 txbuf_dvma, qbufs_dvma = (__u32)qep->buffers_dvma; | |
| 576 | 577 | unsigned char *txbuf; |
| 577 | 578 | int len, entry; |
| 578 | 579 | |
| @@ -334,12 +334,12 @@ struct sunqe { · 333 unmodified lines | ||
| 334 | 334 | void __iomem *qcregs; /* QEC per-channel Registers */ |
| 335 | 335 | void __iomem *mregs; /* Per-channel MACE Registers */ |
| 336 | 336 | struct qe_init_block *qe_block; /* RX and TX descriptors */ |
| 337 | − __u32 qblock_dvma; /* RX and TX descriptors */ | |
| 337 | + dma_addr_t qblock_dvma; /* RX and TX descriptors */ | |
| 338 | 338 | spinlock_t lock; /* Protects txfull state */ |
| 339 | 339 | int rx_new, rx_old; /* RX ring extents */ |
| 340 | 340 | int tx_new, tx_old; /* TX ring extents */ |
| 341 | 341 | struct sunqe_buffers *buffers; /* CPU visible address. */ |
| 342 | − __u32 buffers_dvma; /* DVMA visible address. */ | |
| 342 | + dma_addr_t buffers_dvma; /* DVMA visible address. */ | |
| 343 | 343 | struct sunqec *parent; |
| 344 | 344 | u8 mconfig; /* Base MACE mconfig value */ |
| 345 | 345 | struct platform_device *op; /* QE's OF device struct */ |
| @@ -176,9 +176,12 @@ void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave) · 175 unmodified lines | ||
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | dev = bus_find_device(&platform_bus_type, NULL, node, match); |
| 179 | + of_node_put(node); | |
| 179 | 180 | priv = dev_get_drvdata(dev); |
| 180 | 181 | |
| 181 | 182 | priv->cpsw_phy_sel(priv, phy_mode, slave); |
| 183 | + | |
| 184 | + put_device(dev); | |
| 182 | 185 | } |
| 183 | 186 | EXPORT_SYMBOL_GPL(cpsw_phy_sel); |
| 184 | 187 | |
| @@ -2375,8 +2375,11 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, · 2374 unmodified lines | ||
| 2375 | 2375 | * to the PHY is the Ethernet MAC DT node. |
| 2376 | 2376 | */ |
| 2377 | 2377 | ret = of_phy_register_fixed_link(slave_node); |
| 2378 | − if (ret) | |
| 2378 | + if (ret) { | |
| 2379 | + if (ret != -EPROBE_DEFER) | |
| 2380 | + dev_err(&pdev->dev, "failed to register fixed-link phy: %d\n", ret); | |
| 2379 | 2381 | return ret; |
| 2382 | + } | |
| 2380 | 2383 | slave_data->phy_node = of_node_get(slave_node); |
| 2381 | 2384 | } else if (parp) { |
| 2382 | 2385 | u32 phyid; |
| @@ -2397,6 +2400,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, · 14 unmodified lines | ||
| 2397 | 2400 | } |
| 2398 | 2401 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), |
| 2399 | 2402 | PHY_ID_FMT, mdio->name, phyid); |
| 2403 | + put_device(&mdio->dev); | |
| 2400 | 2404 | } else { |
| 2401 | 2405 | dev_err(&pdev->dev, |
| 2402 | 2406 | "No slave[%d] phy_id, phy-handle, or fixed-link property\n", |
| @@ -2440,6 +2444,46 @@ no_phy_slave: · 37 unmodified lines | ||
| 2440 | 2444 | return 0; |
| 2441 | 2445 | } |
| 2442 | 2446 | |
| 2447 | +static void cpsw_remove_dt(struct platform_device *pdev) | |
| 2448 | +{ | |
| 2449 | + struct net_device *ndev = platform_get_drvdata(pdev); | |
| 2450 | + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); | |
| 2451 | + struct cpsw_platform_data *data = &cpsw->data; | |
| 2452 | + struct device_node *node = pdev->dev.of_node; | |
| 2453 | + struct device_node *slave_node; | |
| 2454 | + int i = 0; | |
| 2455 | + | |
| 2456 | + for_each_available_child_of_node(node, slave_node) { | |
| 2457 | + struct cpsw_slave_data *slave_data = &data->slave_data[i]; | |
| 2458 | + | |
| 2459 | + if (strcmp(slave_node->name, "slave")) | |
| 2460 | + continue; | |
| 2461 | + | |
| 2462 | + if (of_phy_is_fixed_link(slave_node)) { | |
| 2463 | + struct phy_device *phydev; | |
| 2464 | + | |
| 2465 | + phydev = of_phy_find_device(slave_node); | |
| 2466 | + if (phydev) { | |
| 2467 | + fixed_phy_unregister(phydev); | |
| 2468 | + /* Put references taken by | |
| 2469 | + * of_phy_find_device() and | |
| 2470 | + * of_phy_register_fixed_link(). | |
| 2471 | + */ | |
| 2472 | + phy_device_free(phydev); | |
| 2473 | + phy_device_free(phydev); | |
| 2474 | + } | |
| 2475 | + } | |
| 2476 | + | |
| 2477 | + of_node_put(slave_data->phy_node); | |
| 2478 | + | |
| 2479 | + i++; | |
| 2480 | + if (i == data->slaves) | |
| 2481 | + break; | |
| 2482 | + } | |
| 2483 | + | |
| 2484 | + of_platform_depopulate(&pdev->dev); | |
| 2485 | +} | |
| 2486 | + | |
| 2443 | 2487 | static int cpsw_probe_dual_emac(struct cpsw_priv *priv) |
| 2444 | 2488 | { |
| 2445 | 2489 | struct cpsw_common *cpsw = priv->cpsw; |
| @@ -2547,6 +2591,9 @@ static int cpsw_probe(struct platform_device *pdev) · 101 unmodified lines | ||
| 2547 | 2591 | int irq; |
| 2548 | 2592 | |
| 2549 | 2593 | cpsw = devm_kzalloc(&pdev->dev, sizeof(struct cpsw_common), GFP_KERNEL); |
| 2594 | + if (!cpsw) | |
| 2595 | + return -ENOMEM; | |
| 2596 | + | |
| 2550 | 2597 | cpsw->dev = &pdev->dev; |
| 2551 | 2598 | |
| 2552 | 2599 | ndev = alloc_etherdev_mq(sizeof(struct cpsw_priv), CPSW_MAX_QUEUES); |
| @@ -2584,11 +2631,19 @@ static int cpsw_probe(struct platform_device *pdev) · 31 unmodified lines | ||
| 2584 | 2631 | /* Select default pin state */ |
| 2585 | 2632 | pinctrl_pm_select_default_state(&pdev->dev); |
| 2586 | 2633 | |
| 2587 | − if (cpsw_probe_dt(&cpsw->data, pdev)) { | |
| 2588 | − dev_err(&pdev->dev, "cpsw: platform data missing\n"); | |
| 2589 | − ret = -ENODEV; | |
| 2634 | + /* Need to enable clocks with runtime PM api to access module | |
| 2635 | + * registers | |
| 2636 | + */ | |
| 2637 | + ret = pm_runtime_get_sync(&pdev->dev); | |
| 2638 | + if (ret < 0) { | |
| 2639 | + pm_runtime_put_noidle(&pdev->dev); | |
| 2590 | 2640 | goto clean_runtime_disable_ret; |
| 2591 | 2641 | } |
| 2642 | + | |
| 2643 | + ret = cpsw_probe_dt(&cpsw->data, pdev); | |
| 2644 | + if (ret) | |
| 2645 | + goto clean_dt_ret; | |
| 2646 | + | |
| 2592 | 2647 | data = &cpsw->data; |
| 2593 | 2648 | cpsw->rx_ch_num = 1; |
| 2594 | 2649 | cpsw->tx_ch_num = 1; |
| @@ -2608,7 +2663,7 @@ static int cpsw_probe(struct platform_device *pdev) · 13 unmodified lines | ||
| 2608 | 2663 | GFP_KERNEL); |
| 2609 | 2664 | if (!cpsw->slaves) { |
| 2610 | 2665 | ret = -ENOMEM; |
| 2611 | − goto clean_runtime_disable_ret; | |
| 2666 | + goto clean_dt_ret; | |
| 2612 | 2667 | } |
| 2613 | 2668 | for (i = 0; i < data->slaves; i++) |
| 2614 | 2669 | cpsw->slaves[i].slave_num = i; |
| @@ -2620,7 +2675,7 @@ static int cpsw_probe(struct platform_device *pdev) · 5 unmodified lines | ||
| 2620 | 2675 | if (IS_ERR(clk)) { |
| 2621 | 2676 | dev_err(priv->dev, "fck is not found\n"); |
| 2622 | 2677 | ret = -ENODEV; |
| 2623 | − goto clean_runtime_disable_ret; | |
| 2678 | + goto clean_dt_ret; | |
| 2624 | 2679 | } |
| 2625 | 2680 | cpsw->bus_freq_mhz = clk_get_rate(clk) / 1000000; |
| 2626 | 2681 | |
| @@ -2628,26 +2683,17 @@ static int cpsw_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 2628 | 2683 | ss_regs = devm_ioremap_resource(&pdev->dev, ss_res); |
| 2629 | 2684 | if (IS_ERR(ss_regs)) { |
| 2630 | 2685 | ret = PTR_ERR(ss_regs); |
| 2631 | − goto clean_runtime_disable_ret; | |
| 2686 | + goto clean_dt_ret; | |
| 2632 | 2687 | } |
| 2633 | 2688 | cpsw->regs = ss_regs; |
| 2634 | 2689 | |
| 2635 | − /* Need to enable clocks with runtime PM api to access module | |
| 2636 | − * registers | |
| 2637 | − */ | |
| 2638 | − ret = pm_runtime_get_sync(&pdev->dev); | |
| 2639 | − if (ret < 0) { | |
| 2640 | − pm_runtime_put_noidle(&pdev->dev); | |
| 2641 | − goto clean_runtime_disable_ret; | |
| 2642 | − } | |
| 2643 | 2690 | cpsw->version = readl(&cpsw->regs->id_ver); |
| 2644 | − pm_runtime_put_sync(&pdev->dev); | |
| 2645 | 2691 | |
| 2646 | 2692 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 2647 | 2693 | cpsw->wr_regs = devm_ioremap_resource(&pdev->dev, res); |
| 2648 | 2694 | if (IS_ERR(cpsw->wr_regs)) { |
| 2649 | 2695 | ret = PTR_ERR(cpsw->wr_regs); |
| 2650 | − goto clean_runtime_disable_ret; | |
| 2696 | + goto clean_dt_ret; | |
| 2651 | 2697 | } |
| 2652 | 2698 | |
| 2653 | 2699 | memset(&dma_params, 0, sizeof(dma_params)); |
| @@ -2684,7 +2730,7 @@ static int cpsw_probe(struct platform_device *pdev) · 30 unmodified lines | ||
| 2684 | 2730 | default: |
| 2685 | 2731 | dev_err(priv->dev, "unknown version 0x%08x\n", cpsw->version); |
| 2686 | 2732 | ret = -ENODEV; |
| 2687 | − goto clean_runtime_disable_ret; | |
| 2733 | + goto clean_dt_ret; | |
| 2688 | 2734 | } |
| 2689 | 2735 | for (i = 0; i < cpsw->data.slaves; i++) { |
| 2690 | 2736 | struct cpsw_slave *slave = &cpsw->slaves[i]; |
| @@ -2713,7 +2759,7 @@ static int cpsw_probe(struct platform_device *pdev) · 22 unmodified lines | ||
| 2713 | 2759 | if (!cpsw->dma) { |
| 2714 | 2760 | dev_err(priv->dev, "error initializing dma\n"); |
| 2715 | 2761 | ret = -ENOMEM; |
| 2716 | − goto clean_runtime_disable_ret; | |
| 2762 | + goto clean_dt_ret; | |
| 2717 | 2763 | } |
| 2718 | 2764 | |
| 2719 | 2765 | cpsw->txch[0] = cpdma_chan_create(cpsw->dma, 0, cpsw_tx_handler, 0); |
| @@ -2811,16 +2857,23 @@ static int cpsw_probe(struct platform_device *pdev) · 91 unmodified lines | ||
| 2811 | 2857 | ret = cpsw_probe_dual_emac(priv); |
| 2812 | 2858 | if (ret) { |
| 2813 | 2859 | cpsw_err(priv, probe, "error probe slave 2 emac interface\n"); |
| 2814 | − goto clean_ale_ret; | |
| 2860 | + goto clean_unregister_netdev_ret; | |
| 2815 | 2861 | } |
| 2816 | 2862 | } |
| 2817 | 2863 | |
| 2864 | + pm_runtime_put(&pdev->dev); | |
| 2865 | + | |
| 2818 | 2866 | return 0; |
| 2819 | 2867 | |
| 2868 | +clean_unregister_netdev_ret: | |
| 2869 | + unregister_netdev(ndev); | |
| 2820 | 2870 | clean_ale_ret: |
| 2821 | 2871 | cpsw_ale_destroy(cpsw->ale); |
| 2822 | 2872 | clean_dma_ret: |
| 2823 | 2873 | cpdma_ctlr_destroy(cpsw->dma); |
| 2874 | +clean_dt_ret: | |
| 2875 | + cpsw_remove_dt(pdev); | |
| 2876 | + pm_runtime_put_sync(&pdev->dev); | |
| 2824 | 2877 | clean_runtime_disable_ret: |
| 2825 | 2878 | pm_runtime_disable(&pdev->dev); |
| 2826 | 2879 | clean_ndev_ret: |
| @@ -2846,7 +2899,7 @@ static int cpsw_remove(struct platform_device *pdev) · 19 unmodified lines | ||
| 2846 | 2899 | |
| 2847 | 2900 | cpsw_ale_destroy(cpsw->ale); |
| 2848 | 2901 | cpdma_ctlr_destroy(cpsw->dma); |
| 2849 | − of_platform_depopulate(&pdev->dev); | |
| 2902 | + cpsw_remove_dt(pdev); | |
| 2850 | 2903 | pm_runtime_put_sync(&pdev->dev); |
| 2851 | 2904 | pm_runtime_disable(&pdev->dev); |
| 2852 | 2905 | if (cpsw->data.dual_emac) |
| @@ -1410,6 +1410,7 @@ static int emac_dev_open(struct net_device *ndev) · 1409 unmodified lines | ||
| 1410 | 1410 | int i = 0; |
| 1411 | 1411 | struct emac_priv *priv = netdev_priv(ndev); |
| 1412 | 1412 | struct phy_device *phydev = NULL; |
| 1413 | + struct device *phy = NULL; | |
| 1413 | 1414 | |
| 1414 | 1415 | ret = pm_runtime_get_sync(&priv->pdev->dev); |
| 1415 | 1416 | if (ret < 0) { |
| @@ -1488,19 +1489,20 @@ static int emac_dev_open(struct net_device *ndev) · 72 unmodified lines | ||
| 1488 | 1489 | |
| 1489 | 1490 | /* use the first phy on the bus if pdata did not give us a phy id */ |
| 1490 | 1491 | if (!phydev && !priv->phy_id) { |
| 1491 | − struct device *phy; | |
| 1492 | − | |
| 1493 | 1492 | phy = bus_find_device(&mdio_bus_type, NULL, NULL, |
| 1494 | 1493 | match_first_device); |
| 1495 | − if (phy) | |
| 1494 | + if (phy) { | |
| 1496 | 1495 | priv->phy_id = dev_name(phy); |
| 1496 | + if (!priv->phy_id || !*priv->phy_id) | |
| 1497 | + put_device(phy); | |
| 1498 | + } | |
| 1497 | 1499 | } |
| 1498 | 1500 | |
| 1499 | 1501 | if (!phydev && priv->phy_id && *priv->phy_id) { |
| 1500 | 1502 | phydev = phy_connect(ndev, priv->phy_id, |
| 1501 | 1503 | &emac_adjust_link, |
| 1502 | 1504 | PHY_INTERFACE_MODE_MII); |
| 1503 | − | |
| 1505 | + put_device(phy); /* reference taken by bus_find_device */ | |
| 1504 | 1506 | if (IS_ERR(phydev)) { |
| 1505 | 1507 | dev_err(emac_dev, "could not connect to phy %s\n", |
| 1506 | 1508 | priv->phy_id); |
| @@ -1694,7 +1694,7 @@ struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl) · 1693 unmodified lines | ||
| 1694 | 1694 | pr_debug("%s: bssid matched\n", __func__); |
| 1695 | 1695 | break; |
| 1696 | 1696 | } else { |
| 1697 | − pr_debug("%s: bssid unmached\n", __func__); | |
| 1697 | + pr_debug("%s: bssid unmatched\n", __func__); | |
| 1698 | 1698 | continue; |
| 1699 | 1699 | } |
| 1700 | 1700 | } |
| @@ -708,8 +708,7 @@ static int eth_poll(struct napi_struct *napi, int budget) · 707 unmodified lines | ||
| 708 | 708 | if (!qmgr_stat_below_low_watermark(rxq) && |
| 709 | 709 | napi_reschedule(napi)) { /* not empty again */ |
| 710 | 710 | #if DEBUG_RX |
| 711 | − printk(KERN_DEBUG "%s: eth_poll" | |
| 712 | − " napi_reschedule successed\n", | |
| 711 | + printk(KERN_DEBUG "%s: eth_poll napi_reschedule succeeded\n", | |
| 713 | 712 | dev->name); |
| 714 | 713 | #endif |
| 715 | 714 | qmgr_disable_irq(rxq); |
| @@ -1278,6 +1278,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, · 1277 unmodified lines | ||
| 1278 | 1278 | struct net_device *lowerdev; |
| 1279 | 1279 | int err; |
| 1280 | 1280 | int macmode; |
| 1281 | + bool create = false; | |
| 1281 | 1282 | |
| 1282 | 1283 | if (!tb[IFLA_LINK]) |
| 1283 | 1284 | return -EINVAL; |
| @@ -1304,12 +1305,18 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, · 20 unmodified lines | ||
| 1304 | 1305 | err = macvlan_port_create(lowerdev); |
| 1305 | 1306 | if (err < 0) |
| 1306 | 1307 | return err; |
| 1308 | + create = true; | |
| 1307 | 1309 | } |
| 1308 | 1310 | port = macvlan_port_get_rtnl(lowerdev); |
| 1309 | 1311 | |
| 1310 | 1312 | /* Only 1 macvlan device can be created in passthru mode */ |
| 1311 | − if (port->passthru) | |
| 1312 | − return -EINVAL; | |
| 1313 | + if (port->passthru) { | |
| 1314 | + /* The macvlan port must be not created this time, | |
| 1315 | + * still goto destroy_macvlan_port for readability. | |
| 1316 | + */ | |
| 1317 | + err = -EINVAL; | |
| 1318 | + goto destroy_macvlan_port; | |
| 1319 | + } | |
| 1313 | 1320 | |
| 1314 | 1321 | vlan->lowerdev = lowerdev; |
| 1315 | 1322 | vlan->dev = dev; |
| @@ -1325,24 +1332,28 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, · 9 unmodified lines | ||
| 1325 | 1332 | vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); |
| 1326 | 1333 | |
| 1327 | 1334 | if (vlan->mode == MACVLAN_MODE_PASSTHRU) { |
| 1328 | − if (port->count) | |
| 1329 | − return -EINVAL; | |
| 1335 | + if (port->count) { | |
| 1336 | + err = -EINVAL; | |
| 1337 | + goto destroy_macvlan_port; | |
| 1338 | + } | |
| 1330 | 1339 | port->passthru = true; |
| 1331 | 1340 | eth_hw_addr_inherit(dev, lowerdev); |
| 1332 | 1341 | } |
| 1333 | 1342 | |
| 1334 | 1343 | if (data && data[IFLA_MACVLAN_MACADDR_MODE]) { |
| 1335 | − if (vlan->mode != MACVLAN_MODE_SOURCE) | |
| 1336 | − return -EINVAL; | |
| 1344 | + if (vlan->mode != MACVLAN_MODE_SOURCE) { | |
| 1345 | + err = -EINVAL; | |
| 1346 | + goto destroy_macvlan_port; | |
| 1347 | + } | |
| 1337 | 1348 | macmode = nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE]); |
| 1338 | 1349 | err = macvlan_changelink_sources(vlan, macmode, data); |
| 1339 | 1350 | if (err) |
| 1340 | − return err; | |
| 1351 | + goto destroy_macvlan_port; | |
| 1341 | 1352 | } |
| 1342 | 1353 | |
| 1343 | 1354 | err = register_netdevice(dev); |
| 1344 | 1355 | if (err < 0) |
| 1345 | − return err; | |
| 1356 | + goto destroy_macvlan_port; | |
| 1346 | 1357 | |
| 1347 | 1358 | dev->priv_flags |= IFF_MACVLAN; |
| 1348 | 1359 | err = netdev_upper_dev_link(lowerdev, dev); |
| @@ -1357,7 +1368,9 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, · 8 unmodified lines | ||
| 1357 | 1368 | |
| 1358 | 1369 | unregister_netdev: |
| 1359 | 1370 | unregister_netdevice(dev); |
| 1360 | − | |
| 1371 | +destroy_macvlan_port: | |
| 1372 | + if (create) | |
| 1373 | + macvlan_port_destroy(port->dev); | |
| 1361 | 1374 | return err; |
| 1362 | 1375 | } |
| 1363 | 1376 | EXPORT_SYMBOL_GPL(macvlan_common_newlink); |
| @@ -279,7 +279,7 @@ EXPORT_SYMBOL_GPL(fixed_phy_register); · 278 unmodified lines | ||
| 279 | 279 | void fixed_phy_unregister(struct phy_device *phy) |
| 280 | 280 | { |
| 281 | 281 | phy_device_remove(phy); |
| 282 | − | |
| 282 | + of_node_put(phy->mdio.dev.of_node); | |
| 283 | 283 | fixed_phy_del(phy->mdio.addr); |
| 284 | 284 | } |
| 285 | 285 | EXPORT_SYMBOL_GPL(fixed_phy_unregister); |
| @@ -723,6 +723,7 @@ struct phy_device *phy_connect(struct net_device *dev, const char *bus_id, · 722 unmodified lines | ||
| 723 | 723 | phydev = to_phy_device(d); |
| 724 | 724 | |
| 725 | 725 | rc = phy_connect_direct(dev, phydev, handler, interface); |
| 726 | + put_device(d); | |
| 726 | 727 | if (rc) |
| 727 | 728 | return ERR_PTR(rc); |
| 728 | 729 | |
| @@ -953,6 +954,7 @@ struct phy_device *phy_attach(struct net_device *dev, const char *bus_id, · 224 unmodified lines | ||
| 953 | 954 | phydev = to_phy_device(d); |
| 954 | 955 | |
| 955 | 956 | rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface); |
| 957 | + put_device(d); | |
| 956 | 958 | if (rc) |
| 957 | 959 | return ERR_PTR(rc); |
| 958 | 960 | |
| @@ -62,6 +62,10 @@ · 61 unmodified lines | ||
| 62 | 62 | /* Vitesse Extended Page Access Register */ |
| 63 | 63 | #define MII_VSC82X4_EXT_PAGE_ACCESS 0x1f |
| 64 | 64 | |
| 65 | +/* Vitesse VSC8601 Extended PHY Control Register 1 */ | |
| 66 | +#define MII_VSC8601_EPHY_CTL 0x17 | |
| 67 | +#define MII_VSC8601_EPHY_CTL_RGMII_SKEW (1 << 8) | |
| 68 | + | |
| 65 | 69 | #define PHY_ID_VSC8234 0x000fc620 |
| 66 | 70 | #define PHY_ID_VSC8244 0x000fc6c0 |
| 67 | 71 | #define PHY_ID_VSC8514 0x00070670 |
| @@ -111,6 +115,34 @@ static int vsc824x_config_init(struct phy_device *phydev) · 43 unmodified lines | ||
| 111 | 115 | return err; |
| 112 | 116 | } |
| 113 | 117 | |
| 118 | +/* This adds a skew for both TX and RX clocks, so the skew should only be | |
| 119 | + * applied to "rgmii-id" interfaces. It may not work as expected | |
| 120 | + * on "rgmii-txid", "rgmii-rxid" or "rgmii" interfaces. */ | |
| 121 | +static int vsc8601_add_skew(struct phy_device *phydev) | |
| 122 | +{ | |
| 123 | + int ret; | |
| 124 | + | |
| 125 | + ret = phy_read(phydev, MII_VSC8601_EPHY_CTL); | |
| 126 | + if (ret < 0) | |
| 127 | + return ret; | |
| 128 | + | |
| 129 | + ret |= MII_VSC8601_EPHY_CTL_RGMII_SKEW; | |
| 130 | + return phy_write(phydev, MII_VSC8601_EPHY_CTL, ret); | |
| 131 | +} | |
| 132 | + | |
| 133 | +static int vsc8601_config_init(struct phy_device *phydev) | |
| 134 | +{ | |
| 135 | + int ret = 0; | |
| 136 | + | |
| 137 | + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) | |
| 138 | + ret = vsc8601_add_skew(phydev); | |
| 139 | + | |
| 140 | + if (ret < 0) | |
| 141 | + return ret; | |
| 142 | + | |
| 143 | + return genphy_config_init(phydev); | |
| 144 | +} | |
| 145 | + | |
| 114 | 146 | static int vsc824x_ack_interrupt(struct phy_device *phydev) |
| 115 | 147 | { |
| 116 | 148 | int err = 0; |
| @@ -275,7 +307,7 @@ static struct phy_driver vsc82xx_driver[] = { · 158 unmodified lines | ||
| 275 | 307 | .phy_id_mask = 0x000ffff0, |
| 276 | 308 | .features = PHY_GBIT_FEATURES, |
| 277 | 309 | .flags = PHY_HAS_INTERRUPT, |
| 278 | − .config_init = &genphy_config_init, | |
| 310 | + .config_init = &vsc8601_config_init, | |
| 279 | 311 | .config_aneg = &genphy_config_aneg, |
| 280 | 312 | .read_status = &genphy_read_status, |
| 281 | 313 | .ack_interrupt = &vsc824x_ack_interrupt, |
| @@ -1656,6 +1656,19 @@ static const struct driver_info ax88178a_info = { · 1655 unmodified lines | ||
| 1656 | 1656 | .tx_fixup = ax88179_tx_fixup, |
| 1657 | 1657 | }; |
| 1658 | 1658 | |
| 1659 | +static const struct driver_info cypress_GX3_info = { | |
| 1660 | + .description = "Cypress GX3 SuperSpeed to Gigabit Ethernet Controller", | |
| 1661 | + .bind = ax88179_bind, | |
| 1662 | + .unbind = ax88179_unbind, | |
| 1663 | + .status = ax88179_status, | |
| 1664 | + .link_reset = ax88179_link_reset, | |
| 1665 | + .reset = ax88179_reset, | |
| 1666 | + .stop = ax88179_stop, | |
| 1667 | + .flags = FLAG_ETHER | FLAG_FRAMING_AX, | |
| 1668 | + .rx_fixup = ax88179_rx_fixup, | |
| 1669 | + .tx_fixup = ax88179_tx_fixup, | |
| 1670 | +}; | |
| 1671 | + | |
| 1659 | 1672 | static const struct driver_info dlink_dub1312_info = { |
| 1660 | 1673 | .description = "D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter", |
| 1661 | 1674 | .bind = ax88179_bind, |
| @@ -1717,6 +1730,10 @@ static const struct usb_device_id products[] = { · 55 unmodified lines | ||
| 1717 | 1730 | /* ASIX AX88178A 10/100/1000 */ |
| 1718 | 1731 | USB_DEVICE(0x0b95, 0x178a), |
| 1719 | 1732 | .driver_info = (unsigned long)&ax88178a_info, |
| 1733 | +}, { | |
| 1734 | + /* Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller */ | |
| 1735 | + USB_DEVICE(0x04b4, 0x3610), | |
| 1736 | + .driver_info = (unsigned long)&cypress_GX3_info, | |
| 1720 | 1737 | }, { |
| 1721 | 1738 | /* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */ |
| 1722 | 1739 | USB_DEVICE(0x2001, 0x4a00), |
| @@ -1730,7 +1730,7 @@ static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc) · 1729 unmodified lines | ||
| 1730 | 1730 | u8 checksum = CHECKSUM_NONE; |
| 1731 | 1731 | u32 opts2, opts3; |
| 1732 | 1732 | |
| 1733 | − if (tp->version == RTL_VER_01) | |
| 1733 | + if (tp->version == RTL_VER_01 || tp->version == RTL_VER_02) | |
| 1734 | 1734 | goto return_result; |
| 1735 | 1735 | |
| 1736 | 1736 | opts2 = le32_to_cpu(rx_desc->opts2); |
| @@ -1745,7 +1745,7 @@ static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc) · 8 unmodified lines | ||
| 1745 | 1745 | checksum = CHECKSUM_NONE; |
| 1746 | 1746 | else |
| 1747 | 1747 | checksum = CHECKSUM_UNNECESSARY; |
| 1748 | − } else if (RD_IPV6_CS) { | |
| 1748 | + } else if (opts2 & RD_IPV6_CS) { | |
| 1749 | 1749 | if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF)) |
| 1750 | 1750 | checksum = CHECKSUM_UNNECESSARY; |
| 1751 | 1751 | else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF)) |
| @@ -3266,10 +3266,8 @@ static int rtl8152_open(struct net_device *netdev) · 1514 unmodified lines | ||
| 3266 | 3266 | goto out; |
| 3267 | 3267 | |
| 3268 | 3268 | res = usb_autopm_get_interface(tp->intf); |
| 3269 | − if (res < 0) { | |
| 3270 | − free_all_mem(tp); | |
| 3271 | − goto out; | |
| 3272 | − } | |
| 3269 | + if (res < 0) | |
| 3270 | + goto out_free; | |
| 3273 | 3271 | |
| 3274 | 3272 | mutex_lock(&tp->control); |
| 3275 | 3273 | |
| @@ -3285,10 +3283,9 @@ static int rtl8152_open(struct net_device *netdev) · 9 unmodified lines | ||
| 3285 | 3283 | netif_device_detach(tp->netdev); |
| 3286 | 3284 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", |
| 3287 | 3285 | res); |
| 3288 | − free_all_mem(tp); | |
| 3289 | − } else { | |
| 3290 | − napi_enable(&tp->napi); | |
| 3286 | + goto out_unlock; | |
| 3291 | 3287 | } |
| 3288 | + napi_enable(&tp->napi); | |
| 3292 | 3289 | |
| 3293 | 3290 | mutex_unlock(&tp->control); |
| 3294 | 3291 | |
| @@ -3297,7 +3294,13 @@ static int rtl8152_open(struct net_device *netdev) · 2 unmodified lines | ||
| 3297 | 3294 | tp->pm_notifier.notifier_call = rtl_notifier; |
| 3298 | 3295 | register_pm_notifier(&tp->pm_notifier); |
| 3299 | 3296 | #endif |
| 3297 | + return 0; | |
| 3300 | 3298 | |
| 3299 | +out_unlock: | |
| 3300 | + mutex_unlock(&tp->control); | |
| 3301 | + usb_autopm_put_interface(tp->intf); | |
| 3302 | +out_free: | |
| 3303 | + free_all_mem(tp); | |
| 3301 | 3304 | out: |
| 3302 | 3305 | return res; |
| 3303 | 3306 | } |
| @@ -1497,6 +1497,11 @@ static void virtnet_free_queues(struct virtnet_info *vi) · 1496 unmodified lines | ||
| 1497 | 1497 | netif_napi_del(&vi->rq[i].napi); |
| 1498 | 1498 | } |
| 1499 | 1499 | |
| 1500 | + /* We called napi_hash_del() before netif_napi_del(), | |
| 1501 | + * we need to respect an RCU grace period before freeing vi->rq | |
| 1502 | + */ | |
| 1503 | + synchronize_net(); | |
| 1504 | + | |
| 1500 | 1505 | kfree(vi->rq); |
| 1501 | 1506 | kfree(vi->sq); |
| 1502 | 1507 | } |
| @@ -2038,23 +2043,33 @@ static struct virtio_device_id id_table[] = { · 535 unmodified lines | ||
| 2038 | 2043 | { 0 }, |
| 2039 | 2044 | }; |
| 2040 | 2045 | |
| 2046 | +#define VIRTNET_FEATURES \ | |
| 2047 | + VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, \ | |
| 2048 | + VIRTIO_NET_F_MAC, \ | |
| 2049 | + VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, \ | |
| 2050 | + VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, \ | |
| 2051 | + VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, \ | |
| 2052 | + VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, \ | |
| 2053 | + VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \ | |
| 2054 | + VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \ | |
| 2055 | + VIRTIO_NET_F_CTRL_MAC_ADDR, \ | |
| 2056 | + VIRTIO_NET_F_MTU | |
| 2057 | + | |
| 2041 | 2058 | static unsigned int features[] = { |
| 2042 | − VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, | |
| 2043 | − VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, | |
| 2044 | − VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, | |
| 2045 | − VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, | |
| 2046 | − VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, | |
| 2047 | − VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, | |
| 2048 | − VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, | |
| 2049 | − VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, | |
| 2050 | − VIRTIO_NET_F_CTRL_MAC_ADDR, | |
| 2059 | + VIRTNET_FEATURES, | |
| 2060 | +}; | |
| 2061 | + | |
| 2062 | +static unsigned int features_legacy[] = { | |
| 2063 | + VIRTNET_FEATURES, | |
| 2064 | + VIRTIO_NET_F_GSO, | |
| 2051 | 2065 | VIRTIO_F_ANY_LAYOUT, |
| 2052 | − VIRTIO_NET_F_MTU, | |
| 2053 | 2066 | }; |
| 2054 | 2067 | |
| 2055 | 2068 | static struct virtio_driver virtio_net_driver = { |
| 2056 | 2069 | .feature_table = features, |
| 2057 | 2070 | .feature_table_size = ARRAY_SIZE(features), |
| 2071 | + .feature_table_legacy = features_legacy, | |
| 2072 | + .feature_table_size_legacy = ARRAY_SIZE(features_legacy), | |
| 2058 | 2073 | .driver.name = KBUILD_MODNAME, |
| 2059 | 2074 | .driver.owner = THIS_MODULE, |
| 2060 | 2075 | .id_table = id_table, |
| @@ -944,7 +944,9 @@ static bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev) · 943 unmodified lines | ||
| 944 | 944 | { |
| 945 | 945 | struct vxlan_dev *vxlan; |
| 946 | 946 | struct vxlan_sock *sock4; |
| 947 | − struct vxlan_sock *sock6 = NULL; | |
| 947 | +#if IS_ENABLED(CONFIG_IPV6) | |
| 948 | + struct vxlan_sock *sock6; | |
| 949 | +#endif | |
| 948 | 950 | unsigned short family = dev->default_dst.remote_ip.sa.sa_family; |
| 949 | 951 | |
| 950 | 952 | sock4 = rtnl_dereference(dev->vn4_sock); |
| @@ -4516,7 +4516,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, · 4515 unmodified lines | ||
| 4516 | 4516 | /* store current 11d setting */ |
| 4517 | 4517 | if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, |
| 4518 | 4518 | &ifp->vif->is_11d)) { |
| 4519 | − supports_11d = false; | |
| 4519 | + is_11d = supports_11d = false; | |
| 4520 | 4520 | } else { |
| 4521 | 4521 | country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, |
| 4522 | 4522 | settings->beacon.tail_len, |
| @@ -1087,6 +1087,15 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm, · 1086 unmodified lines | ||
| 1087 | 1087 | ret = iwl_mvm_switch_to_d3(mvm); |
| 1088 | 1088 | if (ret) |
| 1089 | 1089 | return ret; |
| 1090 | + } else { | |
| 1091 | + /* In theory, we wouldn't have to stop a running sched | |
| 1092 | + * scan in order to start another one (for | |
| 1093 | + * net-detect). But in practice this doesn't seem to | |
| 1094 | + * work properly, so stop any running sched_scan now. | |
| 1095 | + */ | |
| 1096 | + ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true); | |
| 1097 | + if (ret) | |
| 1098 | + return ret; | |
| 1090 | 1099 | } |
| 1091 | 1100 | |
| 1092 | 1101 | /* rfkill release can be either for wowlan or netdetect */ |
| @@ -1254,7 +1263,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, · 161 unmodified lines | ||
| 1254 | 1263 | out: |
| 1255 | 1264 | if (ret < 0) { |
| 1256 | 1265 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); |
| 1257 | − ieee80211_restart_hw(mvm->hw); | |
| 1266 | + if (mvm->restart_fw > 0) { | |
| 1267 | + mvm->restart_fw--; | |
| 1268 | + ieee80211_restart_hw(mvm->hw); | |
| 1269 | + } | |
| 1258 | 1270 | iwl_mvm_free_nd(mvm); |
| 1259 | 1271 | } |
| 1260 | 1272 | out_noreset: |
| @@ -2088,6 +2100,16 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) · 827 unmodified lines | ||
| 2088 | 2100 | iwl_mvm_update_changed_regdom(mvm); |
| 2089 | 2101 | |
| 2090 | 2102 | if (mvm->net_detect) { |
| 2103 | + /* If this is a non-unified image, we restart the FW, | |
| 2104 | + * so no need to stop the netdetect scan. If that | |
| 2105 | + * fails, continue and try to get the wake-up reasons, | |
| 2106 | + * but trigger a HW restart by keeping a failure code | |
| 2107 | + * in ret. | |
| 2108 | + */ | |
| 2109 | + if (unified_image) | |
| 2110 | + ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT, | |
| 2111 | + false); | |
| 2112 | + | |
| 2091 | 2113 | iwl_mvm_query_netdetect_reasons(mvm, vif); |
| 2092 | 2114 | /* has unlocked the mutex, so skip that */ |
| 2093 | 2115 | goto out; |
| @@ -2271,7 +2293,8 @@ static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac, · 177 unmodified lines | ||
| 2271 | 2293 | static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) |
| 2272 | 2294 | { |
| 2273 | 2295 | struct iwl_mvm *mvm = inode->i_private; |
| 2274 | − int remaining_time = 10; | |
| 2296 | + bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, | |
| 2297 | + IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); | |
| 2275 | 2298 | |
| 2276 | 2299 | mvm->d3_test_active = false; |
| 2277 | 2300 | |
| @@ -2282,17 +2305,21 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) · 4 unmodified lines | ||
| 2282 | 2305 | mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; |
| 2283 | 2306 | |
| 2284 | 2307 | iwl_abort_notification_waits(&mvm->notif_wait); |
| 2285 | − ieee80211_restart_hw(mvm->hw); | |
| 2308 | + if (!unified_image) { | |
| 2309 | + int remaining_time = 10; | |
| 2286 | 2310 | |
| 2287 | − /* wait for restart and disconnect all interfaces */ | |
| 2288 | − while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && | |
| 2289 | − remaining_time > 0) { | |
| 2290 | − remaining_time--; | |
| 2291 | − msleep(1000); | |
| 2292 | − } | |
| 2311 | + ieee80211_restart_hw(mvm->hw); | |
| 2312 | + | |
| 2313 | + /* wait for restart and disconnect all interfaces */ | |
| 2314 | + while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && | |
| 2315 | + remaining_time > 0) { | |
| 2316 | + remaining_time--; | |
| 2317 | + msleep(1000); | |
| 2318 | + } | |
| 2293 | 2319 | |
| 2294 | − if (remaining_time == 0) | |
| 2295 | − IWL_ERR(mvm, "Timed out waiting for HW restart to finish!\n"); | |
| 2320 | + if (remaining_time == 0) | |
| 2321 | + IWL_ERR(mvm, "Timed out waiting for HW restart!\n"); | |
| 2322 | + } | |
| 2296 | 2323 | |
| 2297 | 2324 | ieee80211_iterate_active_interfaces_atomic( |
| 2298 | 2325 | mvm->hw, IEEE80211_IFACE_ITER_NORMAL, |
| @@ -1529,8 +1529,8 @@ static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, · 1528 unmodified lines | ||
| 1529 | 1529 | .data = { &cmd, }, |
| 1530 | 1530 | .len = { sizeof(cmd) }, |
| 1531 | 1531 | }; |
| 1532 | − size_t delta, len; | |
| 1533 | − ssize_t ret; | |
| 1532 | + size_t delta; | |
| 1533 | + ssize_t ret, len; | |
| 1534 | 1534 | |
| 1535 | 1535 | hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR, |
| 1536 | 1536 | DEBUG_GROUP, 0); |
| @@ -4121,7 +4121,6 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, · 4120 unmodified lines | ||
| 4121 | 4121 | struct iwl_mvm_internal_rxq_notif *notif, |
| 4122 | 4122 | u32 size) |
| 4123 | 4123 | { |
| 4124 | − DECLARE_WAIT_QUEUE_HEAD_ONSTACK(notif_waitq); | |
| 4125 | 4124 | u32 qmask = BIT(mvm->trans->num_rx_queues) - 1; |
| 4126 | 4125 | int ret; |
| 4127 | 4126 | |
| @@ -4143,7 +4142,7 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, · 15 unmodified lines | ||
| 4143 | 4142 | } |
| 4144 | 4143 | |
| 4145 | 4144 | if (notif->sync) |
| 4146 | − ret = wait_event_timeout(notif_waitq, | |
| 4145 | + ret = wait_event_timeout(mvm->rx_sync_waitq, | |
| 4147 | 4146 | atomic_read(&mvm->queue_sync_counter) == 0, |
| 4148 | 4147 | HZ); |
| 4149 | 4148 | WARN_ON_ONCE(!ret); |
| @@ -937,6 +937,7 @@ struct iwl_mvm { · 936 unmodified lines | ||
| 937 | 937 | /* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */ |
| 938 | 938 | spinlock_t d0i3_tx_lock; |
| 939 | 939 | wait_queue_head_t d0i3_exit_waitq; |
| 940 | + wait_queue_head_t rx_sync_waitq; | |
| 940 | 941 | |
| 941 | 942 | /* BT-Coex */ |
| 942 | 943 | struct iwl_bt_coex_profile_notif last_bt_notif; |
| @@ -619,6 +619,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, · 618 unmodified lines | ||
| 619 | 619 | spin_lock_init(&mvm->refs_lock); |
| 620 | 620 | skb_queue_head_init(&mvm->d0i3_tx); |
| 621 | 621 | init_waitqueue_head(&mvm->d0i3_exit_waitq); |
| 622 | + init_waitqueue_head(&mvm->rx_sync_waitq); | |
| 622 | 623 | |
| 623 | 624 | atomic_set(&mvm->queue_sync_counter, 0); |
| 624 | 625 | |
| @@ -547,7 +547,8 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, · 546 unmodified lines | ||
| 547 | 547 | "Received expired RX queue sync message\n"); |
| 548 | 548 | return; |
| 549 | 549 | } |
| 550 | − atomic_dec(&mvm->queue_sync_counter); | |
| 550 | + if (!atomic_dec_return(&mvm->queue_sync_counter)) | |
| 551 | + wake_up(&mvm->rx_sync_waitq); | |
| 551 | 552 | } |
| 552 | 553 | |
| 553 | 554 | switch (internal_notif->type) { |
| @@ -1199,6 +1199,9 @@ static int iwl_mvm_num_scans(struct iwl_mvm *mvm) · 1198 unmodified lines | ||
| 1199 | 1199 | |
| 1200 | 1200 | static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type) |
| 1201 | 1201 | { |
| 1202 | + bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, | |
| 1203 | + IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); | |
| 1204 | + | |
| 1202 | 1205 | /* This looks a bit arbitrary, but the idea is that if we run |
| 1203 | 1206 | * out of possible simultaneous scans and the userspace is |
| 1204 | 1207 | * trying to run a scan type that is already running, we |
| @@ -1225,12 +1228,30 @@ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type) · 20 unmodified lines | ||
| 1225 | 1228 | return -EBUSY; |
| 1226 | 1229 | return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true); |
| 1227 | 1230 | case IWL_MVM_SCAN_NETDETECT: |
| 1228 | − /* No need to stop anything for net-detect since the | |
| 1229 | − * firmware is restarted anyway. This way, any sched | |
| 1230 | − * scans that were running will be restarted when we | |
| 1231 | − * resume. | |
| 1232 | − */ | |
| 1233 | − return 0; | |
| 1231 | + /* For non-unified images, there's no need to stop | |
| 1232 | + * anything for net-detect since the firmware is | |
| 1233 | + * restarted anyway. This way, any sched scans that | |
| 1234 | + * were running will be restarted when we resume. | |
| 1235 | + */ | |
| 1236 | + if (!unified_image) | |
| 1237 | + return 0; | |
| 1238 | + | |
| 1239 | + /* If this is a unified image and we ran out of scans, | |
| 1240 | + * we need to stop something. Prefer stopping regular | |
| 1241 | + * scans, because the results are useless at this | |
| 1242 | + * point, and we should be able to keep running | |
| 1243 | + * another scheduled scan while suspended. | |
| 1244 | + */ | |
| 1245 | + if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK) | |
| 1246 | + return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, | |
| 1247 | + true); | |
| 1248 | + if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK) | |
| 1249 | + return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, | |
| 1250 | + true); | |
| 1251 | + | |
| 1252 | + /* fall through, something is wrong if no scan was | |
| 1253 | + * running but we ran out of scans. | |
| 1254 | + */ | |
| 1234 | 1255 | default: |
| 1235 | 1256 | WARN_ON(1); |
| 1236 | 1257 | break; |
| @@ -541,48 +541,64 @@ static const struct pci_device_id iwl_hw_card_ids[] = { · 540 unmodified lines | ||
| 541 | 541 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); |
| 542 | 542 | |
| 543 | 543 | #ifdef CONFIG_ACPI |
| 544 | −#define SPL_METHOD "SPLC" | |
| 545 | −#define SPL_DOMAINTYPE_MODULE BIT(0) | |
| 546 | −#define SPL_DOMAINTYPE_WIFI BIT(1) | |
| 547 | −#define SPL_DOMAINTYPE_WIGIG BIT(2) | |
| 548 | −#define SPL_DOMAINTYPE_RFEM BIT(3) | |
| 544 | +#define ACPI_SPLC_METHOD "SPLC" | |
| 545 | +#define ACPI_SPLC_DOMAIN_WIFI (0x07) | |
| 549 | 546 | |
| 550 | −static u64 splx_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splx) | |
| 547 | +static u64 splc_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splc) | |
| 551 | 548 | { |
| 552 | − union acpi_object *limits, *domain_type, *power_limit; | |
| 553 | − | |
| 554 | − if (splx->type != ACPI_TYPE_PACKAGE || | |
| 555 | − splx->package.count != 2 || | |
| 556 | − splx->package.elements[0].type != ACPI_TYPE_INTEGER || | |
| 557 | − splx->package.elements[0].integer.value != 0) { | |
| 558 | − IWL_ERR(trans, "Unsupported splx structure\n"); | |
| 549 | + union acpi_object *data_pkg, *dflt_pwr_limit; | |
| 550 | + int i; | |
| 551 | + | |
| 552 | + /* We need at least two elements, one for the revision and one | |
| 553 | + * for the data itself. Also check that the revision is | |
| 554 | + * supported (currently only revision 0). | |
| 555 | + */ | |
| 556 | + if (splc->type != ACPI_TYPE_PACKAGE || | |
| 557 | + splc->package.count < 2 || | |
| 558 | + splc->package.elements[0].type != ACPI_TYPE_INTEGER || | |
| 559 | + splc->package.elements[0].integer.value != 0) { | |
| 560 | + IWL_DEBUG_INFO(trans, | |
| 561 | + "Unsupported structure returned by the SPLC method. Ignoring.\n"); | |
| 559 | 562 | return 0; |
| 560 | 563 | } |
| 561 | 564 | |
| 562 | − limits = &splx->package.elements[1]; | |
| 563 | − if (limits->type != ACPI_TYPE_PACKAGE || | |
| 564 | − limits->package.count < 2 || | |
| 565 | − limits->package.elements[0].type != ACPI_TYPE_INTEGER || | |
| 566 | − limits->package.elements[1].type != ACPI_TYPE_INTEGER) { | |
| 567 | − IWL_ERR(trans, "Invalid limits element\n"); | |
| 568 | − return 0; | |
| 565 | + /* loop through all the packages to find the one for WiFi */ | |
| 566 | + for (i = 1; i < splc->package.count; i++) { | |
| 567 | + union acpi_object *domain; | |
| 568 | + | |
| 569 | + data_pkg = &splc->package.elements[i]; | |
| 570 | + | |
| 571 | + /* Skip anything that is not a package with the right | |
| 572 | + * amount of elements (i.e. at least 2 integers). | |
| 573 | + */ | |
| 574 | + if (data_pkg->type != ACPI_TYPE_PACKAGE || | |
| 575 | + data_pkg->package.count < 2 || | |
| 576 | + data_pkg->package.elements[0].type != ACPI_TYPE_INTEGER || | |
| 577 | + data_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) | |
| 578 | + continue; | |
| 579 | + | |
| 580 | + domain = &data_pkg->package.elements[0]; | |
| 581 | + if (domain->integer.value == ACPI_SPLC_DOMAIN_WIFI) | |
| 582 | + break; | |
| 583 | + | |
| 584 | + data_pkg = NULL; | |
| 569 | 585 | } |
| 570 | 586 | |
| 571 | − domain_type = &limits->package.elements[0]; | |
| 572 | − power_limit = &limits->package.elements[1]; | |
| 573 | − if (!(domain_type->integer.value & SPL_DOMAINTYPE_WIFI)) { | |
| 574 | − IWL_DEBUG_INFO(trans, "WiFi power is not limited\n"); | |
| 587 | + if (!data_pkg) { | |
| 588 | + IWL_DEBUG_INFO(trans, | |
| 589 | + "No element for the WiFi domain returned by the SPLC method.\n"); | |
| 575 | 590 | return 0; |
| 576 | 591 | } |
| 577 | 592 | |
| 578 | − return power_limit->integer.value; | |
| 593 | + dflt_pwr_limit = &data_pkg->package.elements[1]; | |
| 594 | + return dflt_pwr_limit->integer.value; | |
| 579 | 595 | } |
| 580 | 596 | |
| 581 | 597 | static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev) |
| 582 | 598 | { |
| 583 | 599 | acpi_handle pxsx_handle; |
| 584 | 600 | acpi_handle handle; |
| 585 | − struct acpi_buffer splx = {ACPI_ALLOCATE_BUFFER, NULL}; | |
| 601 | + struct acpi_buffer splc = {ACPI_ALLOCATE_BUFFER, NULL}; | |
| 586 | 602 | acpi_status status; |
| 587 | 603 | |
| 588 | 604 | pxsx_handle = ACPI_HANDLE(&pdev->dev); |
| @@ -593,23 +609,24 @@ static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev) · 4 unmodified lines | ||
| 593 | 609 | } |
| 594 | 610 | |
| 595 | 611 | /* Get the method's handle */ |
| 596 | − status = acpi_get_handle(pxsx_handle, (acpi_string)SPL_METHOD, &handle); | |
| 612 | + status = acpi_get_handle(pxsx_handle, (acpi_string)ACPI_SPLC_METHOD, | |
| 613 | + &handle); | |
| 597 | 614 | if (ACPI_FAILURE(status)) { |
| 598 | − IWL_DEBUG_INFO(trans, "SPL method not found\n"); | |
| 615 | + IWL_DEBUG_INFO(trans, "SPLC method not found\n"); | |
| 599 | 616 | return; |
| 600 | 617 | } |
| 601 | 618 | |
| 602 | 619 | /* Call SPLC with no arguments */ |
| 603 | − status = acpi_evaluate_object(handle, NULL, NULL, &splx); | |
| 620 | + status = acpi_evaluate_object(handle, NULL, NULL, &splc); | |
| 604 | 621 | if (ACPI_FAILURE(status)) { |
| 605 | 622 | IWL_ERR(trans, "SPLC invocation failed (0x%x)\n", status); |
| 606 | 623 | return; |
| 607 | 624 | } |
| 608 | 625 | |
| 609 | − trans->dflt_pwr_limit = splx_get_pwr_limit(trans, splx.pointer); | |
| 626 | + trans->dflt_pwr_limit = splc_get_pwr_limit(trans, splc.pointer); | |
| 610 | 627 | IWL_DEBUG_INFO(trans, "Default power limit set to %lld\n", |
| 611 | 628 | trans->dflt_pwr_limit); |
| 612 | − kfree(splx.pointer); | |
| 629 | + kfree(splc.pointer); | |
| 613 | 630 | } |
| 614 | 631 | |
| 615 | 632 | #else /* CONFIG_ACPI */ |
| @@ -592,6 +592,7 @@ error: · 591 unmodified lines | ||
| 592 | 592 | static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, |
| 593 | 593 | int slots_num, u32 txq_id) |
| 594 | 594 | { |
| 595 | + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | |
| 595 | 596 | int ret; |
| 596 | 597 | |
| 597 | 598 | txq->need_update = false; |
| @@ -606,6 +607,13 @@ static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, · 8 unmodified lines | ||
| 606 | 607 | return ret; |
| 607 | 608 | |
| 608 | 609 | spin_lock_init(&txq->lock); |
| 610 | + | |
| 611 | + if (txq_id == trans_pcie->cmd_queue) { | |
| 612 | + static struct lock_class_key iwl_pcie_cmd_queue_lock_class; | |
| 613 | + | |
| 614 | + lockdep_set_class(&txq->lock, &iwl_pcie_cmd_queue_lock_class); | |
| 615 | + } | |
| 616 | + | |
| 609 | 617 | __skb_queue_head_init(&txq->overflow_q); |
| 610 | 618 | |
| 611 | 619 | /* |
| @@ -826,7 +826,7 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, · 825 unmodified lines | ||
| 826 | 826 | data->bcn_delta = do_div(delta, bcn_int); |
| 827 | 827 | } else { |
| 828 | 828 | data->tsf_offset -= delta; |
| 829 | − data->bcn_delta = -do_div(delta, bcn_int); | |
| 829 | + data->bcn_delta = -(s64)do_div(delta, bcn_int); | |
| 830 | 830 | } |
| 831 | 831 | } |
| 832 | 832 | |
| @@ -304,7 +304,7 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue) · 303 unmodified lines | ||
| 304 | 304 | queue->rx_skbs[id] = skb; |
| 305 | 305 | |
| 306 | 306 | ref = gnttab_claim_grant_reference(&queue->gref_rx_head); |
| 307 | − BUG_ON((signed short)ref < 0); | |
| 307 | + WARN_ON_ONCE(IS_ERR_VALUE((unsigned long)(int)ref)); | |
| 308 | 308 | queue->grant_rx_ref[id] = ref; |
| 309 | 309 | |
| 310 | 310 | page = skb_frag_page(&skb_shinfo(skb)->frags[0]); |
| @@ -428,7 +428,7 @@ static void xennet_tx_setup_grant(unsigned long gfn, unsigned int offset, · 117 unmodified lines | ||
| 428 | 428 | id = get_id_from_freelist(&queue->tx_skb_freelist, queue->tx_skbs); |
| 429 | 429 | tx = RING_GET_REQUEST(&queue->tx, queue->tx.req_prod_pvt++); |
| 430 | 430 | ref = gnttab_claim_grant_reference(&queue->gref_tx_head); |
| 431 | − BUG_ON((signed short)ref < 0); | |
| 431 | + WARN_ON_ONCE(IS_ERR_VALUE((unsigned long)(int)ref)); | |
| 432 | 432 | |
| 433 | 433 | gnttab_grant_foreign_access_ref(ref, queue->info->xbdev->otherend_id, |
| 434 | 434 | gfn, GNTMAP_readonly); |
| @@ -133,7 +133,7 @@ static int mei_nfc_if_version(struct nfc_mei_phy *phy) · 132 unmodified lines | ||
| 133 | 133 | return -ENOMEM; |
| 134 | 134 | |
| 135 | 135 | bytes_recv = mei_cldev_recv(phy->cldev, (u8 *)reply, if_version_length); |
| 136 | − if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) { | |
| 136 | + if (bytes_recv < 0 || bytes_recv < if_version_length) { | |
| 137 | 137 | pr_err("Could not read IF version\n"); |
| 138 | 138 | r = -EIO; |
| 139 | 139 | goto err; |
| @@ -112,17 +112,17 @@ MODULE_PARM_DESC(xeon_b2b_usd_bar2_addr64, · 111 unmodified lines | ||
| 112 | 112 | |
| 113 | 113 | module_param_named(xeon_b2b_usd_bar4_addr64, |
| 114 | 114 | xeon_b2b_usd_addr.bar4_addr64, ullong, 0644); |
| 115 | −MODULE_PARM_DESC(xeon_b2b_usd_bar2_addr64, | |
| 115 | +MODULE_PARM_DESC(xeon_b2b_usd_bar4_addr64, | |
| 116 | 116 | "XEON B2B USD BAR 4 64-bit address"); |
| 117 | 117 | |
| 118 | 118 | module_param_named(xeon_b2b_usd_bar4_addr32, |
| 119 | 119 | xeon_b2b_usd_addr.bar4_addr32, ullong, 0644); |
| 120 | −MODULE_PARM_DESC(xeon_b2b_usd_bar2_addr64, | |
| 120 | +MODULE_PARM_DESC(xeon_b2b_usd_bar4_addr32, | |
| 121 | 121 | "XEON B2B USD split-BAR 4 32-bit address"); |
| 122 | 122 | |
| 123 | 123 | module_param_named(xeon_b2b_usd_bar5_addr32, |
| 124 | 124 | xeon_b2b_usd_addr.bar5_addr32, ullong, 0644); |
| 125 | −MODULE_PARM_DESC(xeon_b2b_usd_bar2_addr64, | |
| 125 | +MODULE_PARM_DESC(xeon_b2b_usd_bar5_addr32, | |
| 126 | 126 | "XEON B2B USD split-BAR 5 32-bit address"); |
| 127 | 127 | |
| 128 | 128 | module_param_named(xeon_b2b_dsd_bar2_addr64, |
| @@ -132,17 +132,17 @@ MODULE_PARM_DESC(xeon_b2b_dsd_bar2_addr64, · 3 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | module_param_named(xeon_b2b_dsd_bar4_addr64, |
| 134 | 134 | xeon_b2b_dsd_addr.bar4_addr64, ullong, 0644); |
| 135 | −MODULE_PARM_DESC(xeon_b2b_dsd_bar2_addr64, | |
| 135 | +MODULE_PARM_DESC(xeon_b2b_dsd_bar4_addr64, | |
| 136 | 136 | "XEON B2B DSD BAR 4 64-bit address"); |
| 137 | 137 | |
| 138 | 138 | module_param_named(xeon_b2b_dsd_bar4_addr32, |
| 139 | 139 | xeon_b2b_dsd_addr.bar4_addr32, ullong, 0644); |
| 140 | −MODULE_PARM_DESC(xeon_b2b_dsd_bar2_addr64, | |
| 140 | +MODULE_PARM_DESC(xeon_b2b_dsd_bar4_addr32, | |
| 141 | 141 | "XEON B2B DSD split-BAR 4 32-bit address"); |
| 142 | 142 | |
| 143 | 143 | module_param_named(xeon_b2b_dsd_bar5_addr32, |
| 144 | 144 | xeon_b2b_dsd_addr.bar5_addr32, ullong, 0644); |
| 145 | −MODULE_PARM_DESC(xeon_b2b_dsd_bar2_addr64, | |
| 145 | +MODULE_PARM_DESC(xeon_b2b_dsd_bar5_addr32, | |
| 146 | 146 | "XEON B2B DSD split-BAR 5 32-bit address"); |
| 147 | 147 | |
| 148 | 148 | #ifndef ioread64 |
| @@ -1755,6 +1755,8 @@ static int xeon_setup_b2b_mw(struct intel_ntb_dev *ndev, · 1606 unmodified lines | ||
| 1755 | 1755 | XEON_B2B_MIN_SIZE); |
| 1756 | 1756 | if (!ndev->peer_mmio) |
| 1757 | 1757 | return -EIO; |
| 1758 | + | |
| 1759 | + ndev->peer_addr = pci_resource_start(pdev, b2b_bar); | |
| 1758 | 1760 | } |
| 1759 | 1761 | |
| 1760 | 1762 | return 0; |
| @@ -2019,6 +2021,7 @@ static int intel_ntb_init_pci(struct intel_ntb_dev *ndev, struct pci_dev *pdev) · 258 unmodified lines | ||
| 2019 | 2021 | goto err_mmio; |
| 2020 | 2022 | } |
| 2021 | 2023 | ndev->peer_mmio = ndev->self_mmio; |
| 2024 | + ndev->peer_addr = pci_resource_start(pdev, 0); | |
| 2022 | 2025 | |
| 2023 | 2026 | return 0; |
| 2024 | 2027 | |
| @@ -257,7 +257,7 @@ enum { · 256 unmodified lines | ||
| 257 | 257 | #define NTB_QP_DEF_NUM_ENTRIES 100 |
| 258 | 258 | #define NTB_LINK_DOWN_TIMEOUT 10 |
| 259 | 259 | #define DMA_RETRIES 20 |
| 260 | −#define DMA_OUT_RESOURCE_TO 50 | |
| 260 | +#define DMA_OUT_RESOURCE_TO msecs_to_jiffies(50) | |
| 261 | 261 | |
| 262 | 262 | static void ntb_transport_rxc_db(unsigned long data); |
| 263 | 263 | static const struct ntb_ctx_ops ntb_transport_ops; |
| @@ -72,7 +72,7 @@ · 71 unmodified lines | ||
| 72 | 72 | #define MAX_THREADS 32 |
| 73 | 73 | #define MAX_TEST_SIZE SZ_1M |
| 74 | 74 | #define MAX_SRCS 32 |
| 75 | −#define DMA_OUT_RESOURCE_TO 50 | |
| 75 | +#define DMA_OUT_RESOURCE_TO msecs_to_jiffies(50) | |
| 76 | 76 | #define DMA_RETRIES 20 |
| 77 | 77 | #define SZ_4G (1ULL << 32) |
| 78 | 78 | #define MAX_SEG_ORDER 20 /* no larger than 1M for kmalloc buffer */ |
| @@ -589,7 +589,7 @@ static ssize_t debugfs_run_read(struct file *filp, char __user *ubuf, · 510 unmodified lines | ||
| 589 | 589 | return -ENOMEM; |
| 590 | 590 | |
| 591 | 591 | if (mutex_is_locked(&perf->run_mutex)) { |
| 592 | − out_off = snprintf(buf, 64, "running\n"); | |
| 592 | + out_off = scnprintf(buf, 64, "running\n"); | |
| 593 | 593 | goto read_from_buf; |
| 594 | 594 | } |
| 595 | 595 | |
| @@ -600,14 +600,14 @@ static ssize_t debugfs_run_read(struct file *filp, char __user *ubuf, · 4 unmodified lines | ||
| 600 | 600 | break; |
| 601 | 601 | |
| 602 | 602 | if (pctx->status) { |
| 603 | − out_off += snprintf(buf + out_off, 1024 - out_off, | |
| 603 | + out_off += scnprintf(buf + out_off, 1024 - out_off, | |
| 604 | 604 | "%d: error %d\n", i, |
| 605 | 605 | pctx->status); |
| 606 | 606 | continue; |
| 607 | 607 | } |
| 608 | 608 | |
| 609 | 609 | rate = div64_u64(pctx->copied, pctx->diff_us); |
| 610 | − out_off += snprintf(buf + out_off, 1024 - out_off, | |
| 610 | + out_off += scnprintf(buf + out_off, 1024 - out_off, | |
| 611 | 611 | "%d: copied %llu bytes in %llu usecs, %llu MBytes/s\n", |
| 612 | 612 | i, pctx->copied, pctx->diff_us, rate); |
| 613 | 613 | } |
| @@ -88,7 +88,7 @@ MODULE_PARM_DESC(delay_ms, "Milliseconds to delay the response to peer"); · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | static unsigned long db_init = 0x7; |
| 90 | 90 | module_param(db_init, ulong, 0644); |
| 91 | −MODULE_PARM_DESC(delay_ms, "Initial doorbell bits to ring on the peer"); | |
| 91 | +MODULE_PARM_DESC(db_init, "Initial doorbell bits to ring on the peer"); | |
| 92 | 92 | |
| 93 | 93 | struct pp_ctx { |
| 94 | 94 | struct ntb_dev *ntb; |
| @@ -612,7 +612,7 @@ int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node, · 611 unmodified lines | ||
| 612 | 612 | |
| 613 | 613 | ret = nvm_register(dev); |
| 614 | 614 | |
| 615 | − ns->lba_shift = ilog2(dev->sec_size) - 9; | |
| 615 | + ns->lba_shift = ilog2(dev->sec_size); | |
| 616 | 616 | |
| 617 | 617 | if (sysfs_create_group(&dev->dev.kobj, attrs)) |
| 618 | 618 | pr_warn("%s: failed to create sysfs group for identification\n", |
| @@ -1242,20 +1242,16 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) · 1241 unmodified lines | ||
| 1242 | 1242 | |
| 1243 | 1243 | result = nvme_enable_ctrl(&dev->ctrl, cap); |
| 1244 | 1244 | if (result) |
| 1245 | − goto free_nvmeq; | |
| 1245 | + return result; | |
| 1246 | 1246 | |
| 1247 | 1247 | nvmeq->cq_vector = 0; |
| 1248 | 1248 | result = queue_request_irq(nvmeq); |
| 1249 | 1249 | if (result) { |
| 1250 | 1250 | nvmeq->cq_vector = -1; |
| 1251 | − goto free_nvmeq; | |
| 1251 | + return result; | |
| 1252 | 1252 | } |
| 1253 | 1253 | |
| 1254 | 1254 | return result; |
| 1255 | − | |
| 1256 | − free_nvmeq: | |
| 1257 | − nvme_free_queues(dev, 0); | |
| 1258 | − return result; | |
| 1259 | 1255 | } |
| 1260 | 1256 | |
| 1261 | 1257 | static bool nvme_should_reset(struct nvme_dev *dev, u32 csts) |
| @@ -1317,10 +1313,8 @@ static int nvme_create_io_queues(struct nvme_dev *dev) · 55 unmodified lines | ||
| 1317 | 1313 | max = min(dev->max_qid, dev->queue_count - 1); |
| 1318 | 1314 | for (i = dev->online_queues; i <= max; i++) { |
| 1319 | 1315 | ret = nvme_create_queue(dev->queues[i], i); |
| 1320 | − if (ret) { | |
| 1321 | − nvme_free_queues(dev, i); | |
| 1316 | + if (ret) | |
| 1322 | 1317 | break; |
| 1323 | − } | |
| 1324 | 1318 | } |
| 1325 | 1319 | |
| 1326 | 1320 | /* |
| @@ -1460,13 +1454,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) · 133 unmodified lines | ||
| 1460 | 1454 | result = queue_request_irq(adminq); |
| 1461 | 1455 | if (result) { |
| 1462 | 1456 | adminq->cq_vector = -1; |
| 1463 | − goto free_queues; | |
| 1457 | + return result; | |
| 1464 | 1458 | } |
| 1465 | 1459 | return nvme_create_io_queues(dev); |
| 1466 | − | |
| 1467 | − free_queues: | |
| 1468 | − nvme_free_queues(dev, 1); | |
| 1469 | − return result; | |
| 1470 | 1460 | } |
| 1471 | 1461 | |
| 1472 | 1462 | static void nvme_del_queue_end(struct request *req, int error) |
| @@ -83,6 +83,7 @@ enum nvme_rdma_queue_flags { · 82 unmodified lines | ||
| 83 | 83 | NVME_RDMA_Q_CONNECTED = (1 << 0), |
| 84 | 84 | NVME_RDMA_IB_QUEUE_ALLOCATED = (1 << 1), |
| 85 | 85 | NVME_RDMA_Q_DELETING = (1 << 2), |
| 86 | + NVME_RDMA_Q_LIVE = (1 << 3), | |
| 86 | 87 | }; |
| 87 | 88 | |
| 88 | 89 | struct nvme_rdma_queue { |
| @@ -624,10 +625,18 @@ static int nvme_rdma_connect_io_queues(struct nvme_rdma_ctrl *ctrl) · 535 unmodified lines | ||
| 624 | 625 | |
| 625 | 626 | for (i = 1; i < ctrl->queue_count; i++) { |
| 626 | 627 | ret = nvmf_connect_io_queue(&ctrl->ctrl, i); |
| 627 | − if (ret) | |
| 628 | − break; | |
| 628 | + if (ret) { | |
| 629 | + dev_info(ctrl->ctrl.device, | |
| 630 | + "failed to connect i/o queue: %d\n", ret); | |
| 631 | + goto out_free_queues; | |
| 632 | + } | |
| 633 | + set_bit(NVME_RDMA_Q_LIVE, &ctrl->queues[i].flags); | |
| 629 | 634 | } |
| 630 | 635 | |
| 636 | + return 0; | |
| 637 | + | |
| 638 | +out_free_queues: | |
| 639 | + nvme_rdma_free_io_queues(ctrl); | |
| 631 | 640 | return ret; |
| 632 | 641 | } |
| 633 | 642 | |
| @@ -712,6 +721,8 @@ static void nvme_rdma_reconnect_ctrl_work(struct work_struct *work) · 78 unmodified lines | ||
| 712 | 721 | if (ret) |
| 713 | 722 | goto stop_admin_q; |
| 714 | 723 | |
| 724 | + set_bit(NVME_RDMA_Q_LIVE, &ctrl->queues[0].flags); | |
| 725 | + | |
| 715 | 726 | ret = nvme_enable_ctrl(&ctrl->ctrl, ctrl->cap); |
| 716 | 727 | if (ret) |
| 717 | 728 | goto stop_admin_q; |
| @@ -761,8 +772,10 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work) · 43 unmodified lines | ||
| 761 | 772 | |
| 762 | 773 | nvme_stop_keep_alive(&ctrl->ctrl); |
| 763 | 774 | |
| 764 | − for (i = 0; i < ctrl->queue_count; i++) | |
| 775 | + for (i = 0; i < ctrl->queue_count; i++) { | |
| 765 | 776 | clear_bit(NVME_RDMA_Q_CONNECTED, &ctrl->queues[i].flags); |
| 777 | + clear_bit(NVME_RDMA_Q_LIVE, &ctrl->queues[i].flags); | |
| 778 | + } | |
| 766 | 779 | |
| 767 | 780 | if (ctrl->queue_count > 1) |
| 768 | 781 | nvme_stop_queues(&ctrl->ctrl); |
| @@ -1378,6 +1391,24 @@ nvme_rdma_timeout(struct request *rq, bool reserved) · 609 unmodified lines | ||
| 1378 | 1391 | return BLK_EH_HANDLED; |
| 1379 | 1392 | } |
| 1380 | 1393 | |
| 1394 | +/* | |
| 1395 | + * We cannot accept any other command until the Connect command has completed. | |
| 1396 | + */ | |
| 1397 | +static inline bool nvme_rdma_queue_is_ready(struct nvme_rdma_queue *queue, | |
| 1398 | + struct request *rq) | |
| 1399 | +{ | |
| 1400 | + if (unlikely(!test_bit(NVME_RDMA_Q_LIVE, &queue->flags))) { | |
| 1401 | + struct nvme_command *cmd = (struct nvme_command *)rq->cmd; | |
| 1402 | + | |
| 1403 | + if (rq->cmd_type != REQ_TYPE_DRV_PRIV || | |
| 1404 | + cmd->common.opcode != nvme_fabrics_command || | |
| 1405 | + cmd->fabrics.fctype != nvme_fabrics_type_connect) | |
| 1406 | + return false; | |
| 1407 | + } | |
| 1408 | + | |
| 1409 | + return true; | |
| 1410 | +} | |
| 1411 | + | |
| 1381 | 1412 | static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, |
| 1382 | 1413 | const struct blk_mq_queue_data *bd) |
| 1383 | 1414 | { |
| @@ -1394,6 +1425,9 @@ static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, · 10 unmodified lines | ||
| 1394 | 1425 | |
| 1395 | 1426 | WARN_ON_ONCE(rq->tag < 0); |
| 1396 | 1427 | |
| 1428 | + if (!nvme_rdma_queue_is_ready(queue, rq)) | |
| 1429 | + return BLK_MQ_RQ_QUEUE_BUSY; | |
| 1430 | + | |
| 1397 | 1431 | dev = queue->device->dev; |
| 1398 | 1432 | ib_dma_sync_single_for_cpu(dev, sqe->dma, |
| 1399 | 1433 | sizeof(struct nvme_command), DMA_TO_DEVICE); |
| @@ -1544,6 +1578,8 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl) · 144 unmodified lines | ||
| 1544 | 1578 | if (error) |
| 1545 | 1579 | goto out_cleanup_queue; |
| 1546 | 1580 | |
| 1581 | + set_bit(NVME_RDMA_Q_LIVE, &ctrl->queues[0].flags); | |
| 1582 | + | |
| 1547 | 1583 | error = nvmf_reg_read64(&ctrl->ctrl, NVME_REG_CAP, &ctrl->cap); |
| 1548 | 1584 | if (error) { |
| 1549 | 1585 | dev_err(ctrl->ctrl.device, |
| @@ -838,9 +838,13 @@ static void nvmet_fatal_error_handler(struct work_struct *work) · 837 unmodified lines | ||
| 838 | 838 | |
| 839 | 839 | void nvmet_ctrl_fatal_error(struct nvmet_ctrl *ctrl) |
| 840 | 840 | { |
| 841 | − ctrl->csts |= NVME_CSTS_CFS; | |
| 842 | − INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler); | |
| 843 | − schedule_work(&ctrl->fatal_err_work); | |
| 841 | + mutex_lock(&ctrl->lock); | |
| 842 | + if (!(ctrl->csts & NVME_CSTS_CFS)) { | |
| 843 | + ctrl->csts |= NVME_CSTS_CFS; | |
| 844 | + INIT_WORK(&ctrl->fatal_err_work, nvmet_fatal_error_handler); | |
| 845 | + schedule_work(&ctrl->fatal_err_work); | |
| 846 | + } | |
| 847 | + mutex_unlock(&ctrl->lock); | |
| 844 | 848 | } |
| 845 | 849 | EXPORT_SYMBOL_GPL(nvmet_ctrl_fatal_error); |
| 846 | 850 | |
| @@ -951,6 +951,7 @@ err_destroy_cq: · 950 unmodified lines | ||
| 951 | 951 | |
| 952 | 952 | static void nvmet_rdma_destroy_queue_ib(struct nvmet_rdma_queue *queue) |
| 953 | 953 | { |
| 954 | + ib_drain_qp(queue->cm_id->qp); | |
| 954 | 955 | rdma_destroy_qp(queue->cm_id); |
| 955 | 956 | ib_free_cq(queue->cq); |
| 956 | 957 | } |
| @@ -1066,6 +1067,7 @@ nvmet_rdma_alloc_queue(struct nvmet_rdma_device *ndev, · 109 unmodified lines | ||
| 1066 | 1067 | spin_lock_init(&queue->rsp_wr_wait_lock); |
| 1067 | 1068 | INIT_LIST_HEAD(&queue->free_rsps); |
| 1068 | 1069 | spin_lock_init(&queue->rsps_lock); |
| 1070 | + INIT_LIST_HEAD(&queue->queue_list); | |
| 1069 | 1071 | |
| 1070 | 1072 | queue->idx = ida_simple_get(&nvmet_rdma_queue_ida, 0, 0, GFP_KERNEL); |
| 1071 | 1073 | if (queue->idx < 0) { |
| @@ -1244,7 +1246,6 @@ static void __nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue) · 172 unmodified lines | ||
| 1244 | 1246 | |
| 1245 | 1247 | if (disconnect) { |
| 1246 | 1248 | rdma_disconnect(queue->cm_id); |
| 1247 | − ib_drain_qp(queue->cm_id->qp); | |
| 1248 | 1249 | schedule_work(&queue->release_work); |
| 1249 | 1250 | } |
| 1250 | 1251 | } |
| @@ -1269,7 +1270,12 @@ static void nvmet_rdma_queue_connect_fail(struct rdma_cm_id *cm_id, · 18 unmodified lines | ||
| 1269 | 1270 | { |
| 1270 | 1271 | WARN_ON_ONCE(queue->state != NVMET_RDMA_Q_CONNECTING); |
| 1271 | 1272 | |
| 1272 | − pr_err("failed to connect queue\n"); | |
| 1273 | + mutex_lock(&nvmet_rdma_queue_mutex); | |
| 1274 | + if (!list_empty(&queue->queue_list)) | |
| 1275 | + list_del_init(&queue->queue_list); | |
| 1276 | + mutex_unlock(&nvmet_rdma_queue_mutex); | |
| 1277 | + | |
| 1278 | + pr_err("failed to connect queue %d\n", queue->idx); | |
| 1273 | 1279 | schedule_work(&queue->release_work); |
| 1274 | 1280 | } |
| 1275 | 1281 | |
| @@ -1352,7 +1358,13 @@ static int nvmet_rdma_cm_handler(struct rdma_cm_id *cm_id, · 76 unmodified lines | ||
| 1352 | 1358 | case RDMA_CM_EVENT_ADDR_CHANGE: |
| 1353 | 1359 | case RDMA_CM_EVENT_DISCONNECTED: |
| 1354 | 1360 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: |
| 1355 | − nvmet_rdma_queue_disconnect(queue); | |
| 1361 | + /* | |
| 1362 | + * We might end up here when we already freed the qp | |
| 1363 | + * which means queue release sequence is in progress, | |
| 1364 | + * so don't get in the way... | |
| 1365 | + */ | |
| 1366 | + if (queue) | |
| 1367 | + nvmet_rdma_queue_disconnect(queue); | |
| 1356 | 1368 | break; |
| 1357 | 1369 | case RDMA_CM_EVENT_DEVICE_REMOVAL: |
| 1358 | 1370 | ret = nvmet_rdma_device_removal(cm_id, queue); |
| @@ -2077,8 +2077,6 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) · 2076 unmodified lines | ||
| 2077 | 2077 | name = of_get_property(of_aliases, "stdout", NULL); |
| 2078 | 2078 | if (name) |
| 2079 | 2079 | of_stdout = of_find_node_opts_by_path(name, &of_stdout_options); |
| 2080 | − if (of_stdout) | |
| 2081 | − console_set_by_of(); | |
| 2082 | 2080 | } |
| 2083 | 2081 | |
| 2084 | 2082 | if (!of_aliases) |
| @@ -292,6 +292,7 @@ struct phy_device *of_phy_find_device(struct device_node *phy_np) · 291 unmodified lines | ||
| 292 | 292 | mdiodev = to_mdio_device(d); |
| 293 | 293 | if (mdiodev->flags & MDIO_DEVICE_FLAG_PHY) |
| 294 | 294 | return to_phy_device(d); |
| 295 | + put_device(d); | |
| 295 | 296 | } |
| 296 | 297 | |
| 297 | 298 | return NULL; |
| @@ -456,8 +457,11 @@ int of_phy_register_fixed_link(struct device_node *np) · 158 unmodified lines | ||
| 456 | 457 | status.link = 1; |
| 457 | 458 | status.duplex = of_property_read_bool(fixed_link_node, |
| 458 | 459 | "full-duplex"); |
| 459 | − if (of_property_read_u32(fixed_link_node, "speed", &status.speed)) | |
| 460 | + if (of_property_read_u32(fixed_link_node, "speed", | |
| 461 | + &status.speed)) { | |
| 462 | + of_node_put(fixed_link_node); | |
| 460 | 463 | return -EINVAL; |
| 464 | + } | |
| 461 | 465 | status.pause = of_property_read_bool(fixed_link_node, "pause"); |
| 462 | 466 | status.asym_pause = of_property_read_bool(fixed_link_node, |
| 463 | 467 | "asym-pause"); |
| @@ -190,6 +190,9 @@ struct rockchip_pcie { · 189 unmodified lines | ||
| 190 | 190 | struct reset_control *mgmt_rst; |
| 191 | 191 | struct reset_control *mgmt_sticky_rst; |
| 192 | 192 | struct reset_control *pipe_rst; |
| 193 | + struct reset_control *pm_rst; | |
| 194 | + struct reset_control *aclk_rst; | |
| 195 | + struct reset_control *pclk_rst; | |
| 193 | 196 | struct clk *aclk_pcie; |
| 194 | 197 | struct clk *aclk_perf_pcie; |
| 195 | 198 | struct clk *hclk_pcie; |
| @@ -408,6 +411,44 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) · 212 unmodified lines | ||
| 408 | 411 | |
| 409 | 412 | gpiod_set_value(rockchip->ep_gpio, 0); |
| 410 | 413 | |
| 414 | + err = reset_control_assert(rockchip->aclk_rst); | |
| 415 | + if (err) { | |
| 416 | + dev_err(dev, "assert aclk_rst err %d\n", err); | |
| 417 | + return err; | |
| 418 | + } | |
| 419 | + | |
| 420 | + err = reset_control_assert(rockchip->pclk_rst); | |
| 421 | + if (err) { | |
| 422 | + dev_err(dev, "assert pclk_rst err %d\n", err); | |
| 423 | + return err; | |
| 424 | + } | |
| 425 | + | |
| 426 | + err = reset_control_assert(rockchip->pm_rst); | |
| 427 | + if (err) { | |
| 428 | + dev_err(dev, "assert pm_rst err %d\n", err); | |
| 429 | + return err; | |
| 430 | + } | |
| 431 | + | |
| 432 | + udelay(10); | |
| 433 | + | |
| 434 | + err = reset_control_deassert(rockchip->pm_rst); | |
| 435 | + if (err) { | |
| 436 | + dev_err(dev, "deassert pm_rst err %d\n", err); | |
| 437 | + return err; | |
| 438 | + } | |
| 439 | + | |
| 440 | + err = reset_control_deassert(rockchip->aclk_rst); | |
| 441 | + if (err) { | |
| 442 | + dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err); | |
| 443 | + return err; | |
| 444 | + } | |
| 445 | + | |
| 446 | + err = reset_control_deassert(rockchip->pclk_rst); | |
| 447 | + if (err) { | |
| 448 | + dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err); | |
| 449 | + return err; | |
| 450 | + } | |
| 451 | + | |
| 411 | 452 | err = phy_init(rockchip->phy); |
| 412 | 453 | if (err < 0) { |
| 413 | 454 | dev_err(dev, "fail to init phy, err %d\n", err); |
| @@ -781,6 +822,27 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) · 367 unmodified lines | ||
| 781 | 822 | return PTR_ERR(rockchip->pipe_rst); |
| 782 | 823 | } |
| 783 | 824 | |
| 825 | + rockchip->pm_rst = devm_reset_control_get(dev, "pm"); | |
| 826 | + if (IS_ERR(rockchip->pm_rst)) { | |
| 827 | + if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER) | |
| 828 | + dev_err(dev, "missing pm reset property in node\n"); | |
| 829 | + return PTR_ERR(rockchip->pm_rst); | |
| 830 | + } | |
| 831 | + | |
| 832 | + rockchip->pclk_rst = devm_reset_control_get(dev, "pclk"); | |
| 833 | + if (IS_ERR(rockchip->pclk_rst)) { | |
| 834 | + if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER) | |
| 835 | + dev_err(dev, "missing pclk reset property in node\n"); | |
| 836 | + return PTR_ERR(rockchip->pclk_rst); | |
| 837 | + } | |
| 838 | + | |
| 839 | + rockchip->aclk_rst = devm_reset_control_get(dev, "aclk"); | |
| 840 | + if (IS_ERR(rockchip->aclk_rst)) { | |
| 841 | + if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER) | |
| 842 | + dev_err(dev, "missing aclk reset property in node\n"); | |
| 843 | + return PTR_ERR(rockchip->aclk_rst); | |
| 844 | + } | |
| 845 | + | |
| 784 | 846 | rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH); |
| 785 | 847 | if (IS_ERR(rockchip->ep_gpio)) { |
| 786 | 848 | dev_err(dev, "missing ep-gpios property in node\n"); |
| @@ -29,6 +29,11 @@ static int mid_pci_set_power_state(struct pci_dev *pdev, pci_power_t state) · 28 unmodified lines | ||
| 29 | 29 | return intel_mid_pci_set_power_state(pdev, state); |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | +static pci_power_t mid_pci_get_power_state(struct pci_dev *pdev) | |
| 33 | +{ | |
| 34 | + return intel_mid_pci_get_power_state(pdev); | |
| 35 | +} | |
| 36 | + | |
| 32 | 37 | static pci_power_t mid_pci_choose_state(struct pci_dev *pdev) |
| 33 | 38 | { |
| 34 | 39 | return PCI_D3hot; |
| @@ -52,6 +57,7 @@ static bool mid_pci_need_resume(struct pci_dev *dev) · 17 unmodified lines | ||
| 52 | 57 | static struct pci_platform_pm_ops mid_pci_platform_pm = { |
| 53 | 58 | .is_manageable = mid_pci_power_manageable, |
| 54 | 59 | .set_state = mid_pci_set_power_state, |
| 60 | + .get_state = mid_pci_get_power_state, | |
| 55 | 61 | .choose_state = mid_pci_choose_state, |
| 56 | 62 | .sleep_wake = mid_pci_sleep_wake, |
| 57 | 63 | .run_wake = mid_pci_run_wake, |
| @@ -121,6 +121,14 @@ int pci_claim_resource(struct pci_dev *dev, int resource) · 120 unmodified lines | ||
| 121 | 121 | return -EINVAL; |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | + /* | |
| 125 | + * If we have a shadow copy in RAM, the PCI device doesn't respond | |
| 126 | + * to the shadow range, so we don't need to claim it, and upstream | |
| 127 | + * bridges don't need to route the range to the device. | |
| 128 | + */ | |
| 129 | + if (res->flags & IORESOURCE_ROM_SHADOW) | |
| 130 | + return 0; | |
| 131 | + | |
| 124 | 132 | root = pci_find_parent_resource(dev, res); |
| 125 | 133 | if (!root) { |
| 126 | 134 | dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", |
| @@ -107,7 +107,7 @@ int soc_pcmcia_regulator_set(struct soc_pcmcia_socket *skt, · 106 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | ret = regulator_enable(r->reg); |
| 109 | 109 | } else { |
| 110 | − regulator_disable(r->reg); | |
| 110 | + ret = regulator_disable(r->reg); | |
| 111 | 111 | } |
| 112 | 112 | if (ret == 0) |
| 113 | 113 | r->on = on; |
| @@ -198,7 +198,8 @@ static int da8xx_usb_phy_probe(struct platform_device *pdev) · 197 unmodified lines | ||
| 198 | 198 | } else { |
| 199 | 199 | int ret; |
| 200 | 200 | |
| 201 | − ret = phy_create_lookup(d_phy->usb11_phy, "usb-phy", "ohci.0"); | |
| 201 | + ret = phy_create_lookup(d_phy->usb11_phy, "usb-phy", | |
| 202 | + "ohci-da8xx"); | |
| 202 | 203 | if (ret) |
| 203 | 204 | dev_warn(dev, "Failed to create usb11 phy lookup\n"); |
| 204 | 205 | ret = phy_create_lookup(d_phy->usb20_phy, "usb-phy", |
| @@ -216,7 +217,7 @@ static int da8xx_usb_phy_remove(struct platform_device *pdev) · 11 unmodified lines | ||
| 216 | 217 | |
| 217 | 218 | if (!pdev->dev.of_node) { |
| 218 | 219 | phy_remove_lookup(d_phy->usb20_phy, "usb-phy", "musb-da8xx"); |
| 219 | − phy_remove_lookup(d_phy->usb11_phy, "usb-phy", "ohci.0"); | |
| 220 | + phy_remove_lookup(d_phy->usb11_phy, "usb-phy", "ohci-da8xx"); | |
| 220 | 221 | } |
| 221 | 222 | |
| 222 | 223 | return 0; |
| @@ -249,21 +249,10 @@ err_refclk: · 248 unmodified lines | ||
| 249 | 249 | static int rockchip_pcie_phy_exit(struct phy *phy) |
| 250 | 250 | { |
| 251 | 251 | struct rockchip_pcie_phy *rk_phy = phy_get_drvdata(phy); |
| 252 | − int err = 0; | |
| 253 | 252 | |
| 254 | 253 | clk_disable_unprepare(rk_phy->clk_pciephy_ref); |
| 255 | 254 | |
| 256 | − err = reset_control_deassert(rk_phy->phy_rst); | |
| 257 | − if (err) { | |
| 258 | − dev_err(&phy->dev, "deassert phy_rst err %d\n", err); | |
| 259 | − goto err_reset; | |
| 260 | − } | |
| 261 | − | |
| 262 | − return err; | |
| 263 | − | |
| 264 | −err_reset: | |
| 265 | − clk_prepare_enable(rk_phy->clk_pciephy_ref); | |
| 266 | − return err; | |
| 255 | + return 0; | |
| 267 | 256 | } |
| 268 | 257 | |
| 269 | 258 | static const struct phy_ops ops = { |
| @@ -264,7 +264,7 @@ static int sun4i_usb_phy_init(struct phy *_phy) · 263 unmodified lines | ||
| 264 | 264 | return ret; |
| 265 | 265 | } |
| 266 | 266 | |
| 267 | − if (data->cfg->enable_pmu_unk1) { | |
| 267 | + if (phy->pmu && data->cfg->enable_pmu_unk1) { | |
| 268 | 268 | val = readl(phy->pmu + REG_PMU_UNK1); |
| 269 | 269 | writel(val & ~2, phy->pmu + REG_PMU_UNK1); |
| 270 | 270 | } |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #define ASPEED_G5_NR_PINS 228 |
| 28 | 28 | |
| 29 | −#define COND1 SIG_DESC_BIT(SCU90, 6, 0) | |
| 29 | +#define COND1 { SCU90, BIT(6), 0, 0 } | |
| 30 | 30 | #define COND2 { SCU94, GENMASK(1, 0), 0, 0 } |
| 31 | 31 | |
| 32 | 32 | #define B14 0 |
| @@ -844,6 +844,6 @@ static struct platform_driver iproc_gpio_driver = { · 843 unmodified lines | ||
| 844 | 844 | |
| 845 | 845 | static int __init iproc_gpio_init(void) |
| 846 | 846 | { |
| 847 | − return platform_driver_probe(&iproc_gpio_driver, iproc_gpio_probe); | |
| 847 | + return platform_driver_register(&iproc_gpio_driver); | |
| 848 | 848 | } |
| 849 | 849 | arch_initcall_sync(iproc_gpio_init); |
| @@ -741,6 +741,6 @@ static struct platform_driver nsp_gpio_driver = { · 740 unmodified lines | ||
| 741 | 741 | |
| 742 | 742 | static int __init nsp_gpio_init(void) |
| 743 | 743 | { |
| 744 | − return platform_driver_probe(&nsp_gpio_driver, nsp_gpio_probe); | |
| 744 | + return platform_driver_register(&nsp_gpio_driver); | |
| 745 | 745 | } |
| 746 | 746 | arch_initcall_sync(nsp_gpio_init); |
| @@ -687,6 +687,7 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev, · 686 unmodified lines | ||
| 687 | 687 | if (!info->functions) |
| 688 | 688 | return -ENOMEM; |
| 689 | 689 | |
| 690 | + info->group_index = 0; | |
| 690 | 691 | if (flat_funcs) { |
| 691 | 692 | info->ngroups = of_get_child_count(np); |
| 692 | 693 | } else { |
| @@ -1652,12 +1652,15 @@ static int chv_pinctrl_probe(struct platform_device *pdev) · 1651 unmodified lines | ||
| 1652 | 1652 | } |
| 1653 | 1653 | |
| 1654 | 1654 | #ifdef CONFIG_PM_SLEEP |
| 1655 | −static int chv_pinctrl_suspend(struct device *dev) | |
| 1655 | +static int chv_pinctrl_suspend_noirq(struct device *dev) | |
| 1656 | 1656 | { |
| 1657 | 1657 | struct platform_device *pdev = to_platform_device(dev); |
| 1658 | 1658 | struct chv_pinctrl *pctrl = platform_get_drvdata(pdev); |
| 1659 | + unsigned long flags; | |
| 1659 | 1660 | int i; |
| 1660 | 1661 | |
| 1662 | + raw_spin_lock_irqsave(&chv_lock, flags); | |
| 1663 | + | |
| 1661 | 1664 | pctrl->saved_intmask = readl(pctrl->regs + CHV_INTMASK); |
| 1662 | 1665 | |
| 1663 | 1666 | for (i = 0; i < pctrl->community->npins; i++) { |
| @@ -1678,15 +1681,20 @@ static int chv_pinctrl_suspend(struct device *dev) · 14 unmodified lines | ||
| 1678 | 1681 | ctx->padctrl1 = readl(reg); |
| 1679 | 1682 | } |
| 1680 | 1683 | |
| 1684 | + raw_spin_unlock_irqrestore(&chv_lock, flags); | |
| 1685 | + | |
| 1681 | 1686 | return 0; |
| 1682 | 1687 | } |
| 1683 | 1688 | |
| 1684 | −static int chv_pinctrl_resume(struct device *dev) | |
| 1689 | +static int chv_pinctrl_resume_noirq(struct device *dev) | |
| 1685 | 1690 | { |
| 1686 | 1691 | struct platform_device *pdev = to_platform_device(dev); |
| 1687 | 1692 | struct chv_pinctrl *pctrl = platform_get_drvdata(pdev); |
| 1693 | + unsigned long flags; | |
| 1688 | 1694 | int i; |
| 1689 | 1695 | |
| 1696 | + raw_spin_lock_irqsave(&chv_lock, flags); | |
| 1697 | + | |
| 1690 | 1698 | /* |
| 1691 | 1699 | * Mask all interrupts before restoring per-pin configuration |
| 1692 | 1700 | * registers because we don't know in which state BIOS left them |
| @@ -1731,12 +1739,15 @@ static int chv_pinctrl_resume(struct device *dev) · 38 unmodified lines | ||
| 1731 | 1739 | chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); |
| 1732 | 1740 | chv_writel(pctrl->saved_intmask, pctrl->regs + CHV_INTMASK); |
| 1733 | 1741 | |
| 1742 | + raw_spin_unlock_irqrestore(&chv_lock, flags); | |
| 1743 | + | |
| 1734 | 1744 | return 0; |
| 1735 | 1745 | } |
| 1736 | 1746 | #endif |
| 1737 | 1747 | |
| 1738 | 1748 | static const struct dev_pm_ops chv_pinctrl_pm_ops = { |
| 1739 | − SET_LATE_SYSTEM_SLEEP_PM_OPS(chv_pinctrl_suspend, chv_pinctrl_resume) | |
| 1749 | + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(chv_pinctrl_suspend_noirq, | |
| 1750 | + chv_pinctrl_resume_noirq) | |
| 1740 | 1751 | }; |
| 1741 | 1752 | |
| 1742 | 1753 | static const struct acpi_device_id chv_pinctrl_acpi_match[] = { |
| @@ -1512,7 +1512,7 @@ static int st_gpiolib_register_bank(struct st_pinctrl *info, · 1511 unmodified lines | ||
| 1512 | 1512 | if (info->irqmux_base || gpio_irq > 0) { |
| 1513 | 1513 | err = gpiochip_irqchip_add(&bank->gpio_chip, &st_gpio_irqchip, |
| 1514 | 1514 | 0, handle_simple_irq, |
| 1515 | − IRQ_TYPE_LEVEL_LOW); | |
| 1515 | + IRQ_TYPE_NONE); | |
| 1516 | 1516 | if (err) { |
| 1517 | 1517 | gpiochip_remove(&bank->gpio_chip); |
| 1518 | 1518 | dev_info(dev, "could not add irqchip\n"); |
| @@ -1092,9 +1092,11 @@ int stm32_pctl_probe(struct platform_device *pdev) · 1091 unmodified lines | ||
| 1092 | 1092 | return -EINVAL; |
| 1093 | 1093 | } |
| 1094 | 1094 | |
| 1095 | − ret = stm32_pctrl_dt_setup_irq(pdev, pctl); | |
| 1096 | − if (ret) | |
| 1097 | − return ret; | |
| 1095 | + if (of_find_property(np, "interrupt-parent", NULL)) { | |
| 1096 | + ret = stm32_pctrl_dt_setup_irq(pdev, pctl); | |
| 1097 | + if (ret) | |
| 1098 | + return ret; | |
| 1099 | + } | |
| 1098 | 1100 | |
| 1099 | 1101 | for_each_child_of_node(np, child) |
| 1100 | 1102 | if (of_property_read_bool(child, "gpio-controller")) |
| @@ -933,6 +933,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = { · 932 unmodified lines | ||
| 933 | 933 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 900"), |
| 934 | 934 | }, |
| 935 | 935 | }, |
| 936 | + { | |
| 937 | + .ident = "Lenovo Yoga 900", | |
| 938 | + .matches = { | |
| 939 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 940 | + DMI_MATCH(DMI_BOARD_NAME, "VIUU4"), | |
| 941 | + }, | |
| 942 | + }, | |
| 936 | 943 | { |
| 937 | 944 | .ident = "Lenovo YOGA 910-13IKB", |
| 938 | 945 | .matches = { |
| @@ -264,7 +264,7 @@ check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv) · 263 unmodified lines | ||
| 264 | 264 | return AE_OK; |
| 265 | 265 | |
| 266 | 266 | if (acpi_match_device_ids(dev, ids) == 0) |
| 267 | − if (acpi_create_platform_device(dev)) | |
| 267 | + if (acpi_create_platform_device(dev, NULL)) | |
| 268 | 268 | dev_info(&dev->dev, |
| 269 | 269 | "intel-hid: created platform device\n"); |
| 270 | 270 | |
| @@ -164,7 +164,7 @@ check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv) · 163 unmodified lines | ||
| 164 | 164 | return AE_OK; |
| 165 | 165 | |
| 166 | 166 | if (acpi_match_device_ids(dev, ids) == 0) |
| 167 | − if (acpi_create_platform_device(dev)) | |
| 167 | + if (acpi_create_platform_device(dev, NULL)) | |
| 168 | 168 | dev_info(&dev->dev, |
| 169 | 169 | "intel-vbtn: created platform device\n"); |
| 170 | 170 | |
| @@ -24,14 +24,15 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <linux/acpi.h> |
| 25 | 25 | #include <linux/input.h> |
| 26 | 26 | #include <linux/input/sparse-keymap.h> |
| 27 | +#include <linux/dmi.h> | |
| 27 | 28 | |
| 28 | 29 | MODULE_AUTHOR("Azael Avalos"); |
| 29 | 30 | MODULE_DESCRIPTION("Toshiba WMI Hotkey Driver"); |
| 30 | 31 | MODULE_LICENSE("GPL"); |
| 31 | 32 | |
| 32 | −#define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100" | |
| 33 | +#define WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100" | |
| 33 | 34 | |
| 34 | −MODULE_ALIAS("wmi:"TOSHIBA_WMI_EVENT_GUID); | |
| 35 | +MODULE_ALIAS("wmi:"WMI_EVENT_GUID); | |
| 35 | 36 | |
| 36 | 37 | static struct input_dev *toshiba_wmi_input_dev; |
| 37 | 38 | |
| @@ -63,6 +64,16 @@ static void toshiba_wmi_notify(u32 value, void *context) · 25 unmodified lines | ||
| 63 | 64 | kfree(response.pointer); |
| 64 | 65 | } |
| 65 | 66 | |
| 67 | +static struct dmi_system_id toshiba_wmi_dmi_table[] __initdata = { | |
| 68 | + { | |
| 69 | + .ident = "Toshiba laptop", | |
| 70 | + .matches = { | |
| 71 | + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | |
| 72 | + }, | |
| 73 | + }, | |
| 74 | + {} | |
| 75 | +}; | |
| 76 | + | |
| 66 | 77 | static int __init toshiba_wmi_input_setup(void) |
| 67 | 78 | { |
| 68 | 79 | acpi_status status; |
| @@ -81,7 +92,7 @@ static int __init toshiba_wmi_input_setup(void) · 12 unmodified lines | ||
| 81 | 92 | if (err) |
| 82 | 93 | goto err_free_dev; |
| 83 | 94 | |
| 84 | − status = wmi_install_notify_handler(TOSHIBA_WMI_EVENT_GUID, | |
| 95 | + status = wmi_install_notify_handler(WMI_EVENT_GUID, | |
| 85 | 96 | toshiba_wmi_notify, NULL); |
| 86 | 97 | if (ACPI_FAILURE(status)) { |
| 87 | 98 | err = -EIO; |
| @@ -95,7 +106,7 @@ static int __init toshiba_wmi_input_setup(void) · 7 unmodified lines | ||
| 95 | 106 | return 0; |
| 96 | 107 | |
| 97 | 108 | err_remove_notifier: |
| 98 | − wmi_remove_notify_handler(TOSHIBA_WMI_EVENT_GUID); | |
| 109 | + wmi_remove_notify_handler(WMI_EVENT_GUID); | |
| 99 | 110 | err_free_keymap: |
| 100 | 111 | sparse_keymap_free(toshiba_wmi_input_dev); |
| 101 | 112 | err_free_dev: |
| @@ -105,7 +116,7 @@ static int __init toshiba_wmi_input_setup(void) · 3 unmodified lines | ||
| 105 | 116 | |
| 106 | 117 | static void toshiba_wmi_input_destroy(void) |
| 107 | 118 | { |
| 108 | − wmi_remove_notify_handler(TOSHIBA_WMI_EVENT_GUID); | |
| 119 | + wmi_remove_notify_handler(WMI_EVENT_GUID); | |
| 109 | 120 | sparse_keymap_free(toshiba_wmi_input_dev); |
| 110 | 121 | input_unregister_device(toshiba_wmi_input_dev); |
| 111 | 122 | } |
| @@ -114,7 +125,8 @@ static int __init toshiba_wmi_init(void) · 2 unmodified lines | ||
| 114 | 125 | { |
| 115 | 126 | int ret; |
| 116 | 127 | |
| 117 | − if (!wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) | |
| 128 | + if (!wmi_has_guid(WMI_EVENT_GUID) || | |
| 129 | + !dmi_check_system(toshiba_wmi_dmi_table)) | |
| 118 | 130 | return -ENODEV; |
| 119 | 131 | |
| 120 | 132 | ret = toshiba_wmi_input_setup(); |
| @@ -130,7 +142,7 @@ static int __init toshiba_wmi_init(void) · 9 unmodified lines | ||
| 130 | 142 | |
| 131 | 143 | static void __exit toshiba_wmi_exit(void) |
| 132 | 144 | { |
| 133 | − if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) | |
| 145 | + if (wmi_has_guid(WMI_EVENT_GUID)) | |
| 134 | 146 | toshiba_wmi_input_destroy(); |
| 135 | 147 | } |
| 136 | 148 | |
| @@ -327,6 +327,7 @@ static const struct of_device_id asm9260_dt_ids[] = { · 326 unmodified lines | ||
| 327 | 327 | { .compatible = "alphascale,asm9260-rtc", }, |
| 328 | 328 | {} |
| 329 | 329 | }; |
| 330 | +MODULE_DEVICE_TABLE(of, asm9260_dt_ids); | |
| 330 | 331 | |
| 331 | 332 | static struct platform_driver asm9260_rtc_driver = { |
| 332 | 333 | .probe = asm9260_rtc_probe, |
| @@ -776,7 +776,7 @@ static void cmos_do_shutdown(int rtc_irq) · 775 unmodified lines | ||
| 776 | 776 | spin_unlock_irq(&rtc_lock); |
| 777 | 777 | } |
| 778 | 778 | |
| 779 | −static void __exit cmos_do_remove(struct device *dev) | |
| 779 | +static void cmos_do_remove(struct device *dev) | |
| 780 | 780 | { |
| 781 | 781 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
| 782 | 782 | struct resource *ports; |
| @@ -996,8 +996,9 @@ static u32 rtc_handler(void *context) · 213 unmodified lines | ||
| 996 | 996 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
| 997 | 997 | unsigned char rtc_control = 0; |
| 998 | 998 | unsigned char rtc_intr; |
| 999 | + unsigned long flags; | |
| 999 | 1000 | |
| 1000 | − spin_lock_irq(&rtc_lock); | |
| 1001 | + spin_lock_irqsave(&rtc_lock, flags); | |
| 1001 | 1002 | if (cmos_rtc.suspend_ctrl) |
| 1002 | 1003 | rtc_control = CMOS_READ(RTC_CONTROL); |
| 1003 | 1004 | if (rtc_control & RTC_AIE) { |
| @@ -1006,7 +1007,7 @@ static u32 rtc_handler(void *context) · 2 unmodified lines | ||
| 1006 | 1007 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); |
| 1007 | 1008 | rtc_update_irq(cmos->rtc, 1, rtc_intr); |
| 1008 | 1009 | } |
| 1009 | − spin_unlock_irq(&rtc_lock); | |
| 1010 | + spin_unlock_irqrestore(&rtc_lock, flags); | |
| 1010 | 1011 | |
| 1011 | 1012 | pm_wakeup_event(dev, 0); |
| 1012 | 1013 | acpi_clear_event(ACPI_EVENT_RTC); |
| @@ -1129,7 +1130,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) · 116 unmodified lines | ||
| 1129 | 1130 | pnp_irq(pnp, 0)); |
| 1130 | 1131 | } |
| 1131 | 1132 | |
| 1132 | −static void __exit cmos_pnp_remove(struct pnp_dev *pnp) | |
| 1133 | +static void cmos_pnp_remove(struct pnp_dev *pnp) | |
| 1133 | 1134 | { |
| 1134 | 1135 | cmos_do_remove(&pnp->dev); |
| 1135 | 1136 | } |
| @@ -1161,7 +1162,7 @@ static struct pnp_driver cmos_pnp_driver = { · 25 unmodified lines | ||
| 1161 | 1162 | .name = (char *) driver_name, |
| 1162 | 1163 | .id_table = rtc_ids, |
| 1163 | 1164 | .probe = cmos_pnp_probe, |
| 1164 | − .remove = __exit_p(cmos_pnp_remove), | |
| 1165 | + .remove = cmos_pnp_remove, | |
| 1165 | 1166 | .shutdown = cmos_pnp_shutdown, |
| 1166 | 1167 | |
| 1167 | 1168 | /* flag ensures resume() gets called, and stops syslog spam */ |
| @@ -1238,7 +1239,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev) · 70 unmodified lines | ||
| 1238 | 1239 | return cmos_do_probe(&pdev->dev, resource, irq); |
| 1239 | 1240 | } |
| 1240 | 1241 | |
| 1241 | −static int __exit cmos_platform_remove(struct platform_device *pdev) | |
| 1242 | +static int cmos_platform_remove(struct platform_device *pdev) | |
| 1242 | 1243 | { |
| 1243 | 1244 | cmos_do_remove(&pdev->dev); |
| 1244 | 1245 | return 0; |
| @@ -1263,7 +1264,7 @@ static void cmos_platform_shutdown(struct platform_device *pdev) · 18 unmodified lines | ||
| 1263 | 1264 | MODULE_ALIAS("platform:rtc_cmos"); |
| 1264 | 1265 | |
| 1265 | 1266 | static struct platform_driver cmos_platform_driver = { |
| 1266 | − .remove = __exit_p(cmos_platform_remove), | |
| 1267 | + .remove = cmos_platform_remove, | |
| 1267 | 1268 | .shutdown = cmos_platform_shutdown, |
| 1268 | 1269 | .driver = { |
| 1269 | 1270 | .name = driver_name, |
| @@ -113,6 +113,7 @@ · 112 unmodified lines | ||
| 113 | 113 | /* OMAP_RTC_OSC_REG bit fields: */ |
| 114 | 114 | #define OMAP_RTC_OSC_32KCLK_EN BIT(6) |
| 115 | 115 | #define OMAP_RTC_OSC_SEL_32KCLK_SRC BIT(3) |
| 116 | +#define OMAP_RTC_OSC_OSC32K_GZ_DISABLE BIT(4) | |
| 116 | 117 | |
| 117 | 118 | /* OMAP_RTC_IRQWAKEEN bit fields: */ |
| 118 | 119 | #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) |
| @@ -146,6 +147,7 @@ struct omap_rtc { · 27 unmodified lines | ||
| 146 | 147 | u8 interrupts_reg; |
| 147 | 148 | bool is_pmic_controller; |
| 148 | 149 | bool has_ext_clk; |
| 150 | + bool is_suspending; | |
| 149 | 151 | const struct omap_rtc_device_type *type; |
| 150 | 152 | struct pinctrl_dev *pctldev; |
| 151 | 153 | }; |
| @@ -786,8 +788,9 @@ static int omap_rtc_probe(struct platform_device *pdev) · 634 unmodified lines | ||
| 786 | 788 | */ |
| 787 | 789 | if (rtc->has_ext_clk) { |
| 788 | 790 | reg = rtc_read(rtc, OMAP_RTC_OSC_REG); |
| 789 | − rtc_write(rtc, OMAP_RTC_OSC_REG, | |
| 790 | − reg | OMAP_RTC_OSC_SEL_32KCLK_SRC); | |
| 791 | + reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE; | |
| 792 | + reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC; | |
| 793 | + rtc_writel(rtc, OMAP_RTC_OSC_REG, reg); | |
| 791 | 794 | } |
| 792 | 795 | |
| 793 | 796 | rtc->type->lock(rtc); |
| @@ -898,8 +901,7 @@ static int omap_rtc_suspend(struct device *dev) · 104 unmodified lines | ||
| 898 | 901 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); |
| 899 | 902 | rtc->type->lock(rtc); |
| 900 | 903 | |
| 901 | − /* Disable the clock/module */ | |
| 902 | − pm_runtime_put_sync(dev); | |
| 904 | + rtc->is_suspending = true; | |
| 903 | 905 | |
| 904 | 906 | return 0; |
| 905 | 907 | } |
| @@ -908,9 +910,6 @@ static int omap_rtc_resume(struct device *dev) · 2 unmodified lines | ||
| 908 | 910 | { |
| 909 | 911 | struct omap_rtc *rtc = dev_get_drvdata(dev); |
| 910 | 912 | |
| 911 | − /* Enable the clock/module so that we can access the registers */ | |
| 912 | − pm_runtime_get_sync(dev); | |
| 913 | − | |
| 914 | 913 | rtc->type->unlock(rtc); |
| 915 | 914 | if (device_may_wakeup(dev)) |
| 916 | 915 | disable_irq_wake(rtc->irq_alarm); |
| @@ -918,11 +917,34 @@ static int omap_rtc_resume(struct device *dev) · 1 unmodified line | ||
| 918 | 917 | rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg); |
| 919 | 918 | rtc->type->lock(rtc); |
| 920 | 919 | |
| 920 | + rtc->is_suspending = false; | |
| 921 | + | |
| 921 | 922 | return 0; |
| 922 | 923 | } |
| 923 | 924 | #endif |
| 924 | 925 | |
| 925 | −static SIMPLE_DEV_PM_OPS(omap_rtc_pm_ops, omap_rtc_suspend, omap_rtc_resume); | |
| 926 | +#ifdef CONFIG_PM | |
| 927 | +static int omap_rtc_runtime_suspend(struct device *dev) | |
| 928 | +{ | |
| 929 | + struct omap_rtc *rtc = dev_get_drvdata(dev); | |
| 930 | + | |
| 931 | + if (rtc->is_suspending && !rtc->has_ext_clk) | |
| 932 | + return -EBUSY; | |
| 933 | + | |
| 934 | + return 0; | |
| 935 | +} | |
| 936 | + | |
| 937 | +static int omap_rtc_runtime_resume(struct device *dev) | |
| 938 | +{ | |
| 939 | + return 0; | |
| 940 | +} | |
| 941 | +#endif | |
| 942 | + | |
| 943 | +static const struct dev_pm_ops omap_rtc_pm_ops = { | |
| 944 | + SET_SYSTEM_SLEEP_PM_OPS(omap_rtc_suspend, omap_rtc_resume) | |
| 945 | + SET_RUNTIME_PM_OPS(omap_rtc_runtime_suspend, | |
| 946 | + omap_rtc_runtime_resume, NULL) | |
| 947 | +}; | |
| 926 | 948 | |
| 927 | 949 | static void omap_rtc_shutdown(struct platform_device *pdev) |
| 928 | 950 | { |
| @@ -2081,9 +2081,10 @@ void cxgbi_cleanup_task(struct iscsi_task *task) · 2080 unmodified lines | ||
| 2081 | 2081 | /* never reached the xmit task callout */ |
| 2082 | 2082 | if (tdata->skb) |
| 2083 | 2083 | __kfree_skb(tdata->skb); |
| 2084 | − memset(tdata, 0, sizeof(*tdata)); | |
| 2085 | 2084 | |
| 2086 | 2085 | task_release_itt(task, task->hdr_itt); |
| 2086 | + memset(tdata, 0, sizeof(*tdata)); | |
| 2087 | + | |
| 2087 | 2088 | iscsi_tcp_cleanup_task(task); |
| 2088 | 2089 | } |
| 2089 | 2090 | EXPORT_SYMBOL_GPL(cxgbi_cleanup_task); |
| @@ -793,6 +793,7 @@ static void alua_rtpg_work(struct work_struct *work) · 792 unmodified lines | ||
| 793 | 793 | WARN_ON(pg->flags & ALUA_PG_RUN_RTPG); |
| 794 | 794 | WARN_ON(pg->flags & ALUA_PG_RUN_STPG); |
| 795 | 795 | spin_unlock_irqrestore(&pg->lock, flags); |
| 796 | + kref_put(&pg->kref, release_port_group); | |
| 796 | 797 | return; |
| 797 | 798 | } |
| 798 | 799 | if (pg->flags & ALUA_SYNC_STPG) |
| @@ -890,6 +891,7 @@ static void alua_rtpg_queue(struct alua_port_group *pg, · 91 unmodified lines | ||
| 890 | 891 | /* Do not queue if the worker is already running */ |
| 891 | 892 | if (!(pg->flags & ALUA_PG_RUNNING)) { |
| 892 | 893 | kref_get(&pg->kref); |
| 894 | + sdev = NULL; | |
| 893 | 895 | start_queue = 1; |
| 894 | 896 | } |
| 895 | 897 | } |
| @@ -901,7 +903,8 @@ static void alua_rtpg_queue(struct alua_port_group *pg, · 5 unmodified lines | ||
| 901 | 903 | if (start_queue && |
| 902 | 904 | !queue_delayed_work(alua_wq, &pg->rtpg_work, |
| 903 | 905 | msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS))) { |
| 904 | − scsi_device_put(sdev); | |
| 906 | + if (sdev) | |
| 907 | + scsi_device_put(sdev); | |
| 905 | 908 | kref_put(&pg->kref, release_port_group); |
| 906 | 909 | } |
| 907 | 910 | } |
| @@ -2233,7 +2233,7 @@ struct megasas_instance_template { · 2232 unmodified lines | ||
| 2233 | 2233 | }; |
| 2234 | 2234 | |
| 2235 | 2235 | #define MEGASAS_IS_LOGICAL(scp) \ |
| 2236 | − (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1 | |
| 2236 | + ((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) | |
| 2237 | 2237 | |
| 2238 | 2238 | #define MEGASAS_DEV_INDEX(scp) \ |
| 2239 | 2239 | (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \ |
| @@ -1273,9 +1273,9 @@ scsih_target_alloc(struct scsi_target *starget) · 1272 unmodified lines | ||
| 1273 | 1273 | sas_target_priv_data->handle = raid_device->handle; |
| 1274 | 1274 | sas_target_priv_data->sas_address = raid_device->wwid; |
| 1275 | 1275 | sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME; |
| 1276 | − sas_target_priv_data->raid_device = raid_device; | |
| 1277 | 1276 | if (ioc->is_warpdrive) |
| 1278 | − raid_device->starget = starget; | |
| 1277 | + sas_target_priv_data->raid_device = raid_device; | |
| 1278 | + raid_device->starget = starget; | |
| 1279 | 1279 | } |
| 1280 | 1280 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
| 1281 | 1281 | return 0; |
| @@ -707,6 +707,11 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) · 706 unmodified lines | ||
| 707 | 707 | srb_t *sp; |
| 708 | 708 | int rval; |
| 709 | 709 | |
| 710 | + if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags))) { | |
| 711 | + cmd->result = DID_NO_CONNECT << 16; | |
| 712 | + goto qc24_fail_command; | |
| 713 | + } | |
| 714 | + | |
| 710 | 715 | if (ha->flags.eeh_busy) { |
| 711 | 716 | if (ha->flags.pci_channel_io_perm_failure) { |
| 712 | 717 | ql_dbg(ql_dbg_aer, vha, 0x9010, |
| @@ -1451,6 +1456,15 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) · 738 unmodified lines | ||
| 1451 | 1456 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { |
| 1452 | 1457 | sp = req->outstanding_cmds[cnt]; |
| 1453 | 1458 | if (sp) { |
| 1459 | + /* Get a reference to the sp and drop the lock. | |
| 1460 | + * The reference ensures this sp->done() call | |
| 1461 | + * - and not the call in qla2xxx_eh_abort() - | |
| 1462 | + * ends the SCSI command (with result 'res'). | |
| 1463 | + */ | |
| 1464 | + sp_get(sp); | |
| 1465 | + spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
| 1466 | + qla2xxx_eh_abort(GET_CMD_SP(sp)); | |
| 1467 | + spin_lock_irqsave(&ha->hardware_lock, flags); | |
| 1454 | 1468 | req->outstanding_cmds[cnt] = NULL; |
| 1455 | 1469 | sp->done(vha, sp, res); |
| 1456 | 1470 | } |
| @@ -2341,6 +2355,8 @@ qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) · 884 unmodified lines | ||
| 2341 | 2355 | { |
| 2342 | 2356 | scsi_qla_host_t *vha = shost_priv(shost); |
| 2343 | 2357 | |
| 2358 | + if (test_bit(UNLOADING, &vha->dpc_flags)) | |
| 2359 | + return 1; | |
| 2344 | 2360 | if (!vha->host) |
| 2345 | 2361 | return 1; |
| 2346 | 2362 | if (time > vha->hw->loop_reset_delay * HZ) |
| @@ -793,6 +793,7 @@ static int pvscsi_abort(struct scsi_cmnd *cmd) · 792 unmodified lines | ||
| 793 | 793 | unsigned long flags; |
| 794 | 794 | int result = SUCCESS; |
| 795 | 795 | DECLARE_COMPLETION_ONSTACK(abort_cmp); |
| 796 | + int done; | |
| 796 | 797 | |
| 797 | 798 | scmd_printk(KERN_DEBUG, cmd, "task abort on host %u, %p\n", |
| 798 | 799 | adapter->host->host_no, cmd); |
| @@ -824,10 +825,10 @@ static int pvscsi_abort(struct scsi_cmnd *cmd) · 25 unmodified lines | ||
| 824 | 825 | pvscsi_abort_cmd(adapter, ctx); |
| 825 | 826 | spin_unlock_irqrestore(&adapter->hw_lock, flags); |
| 826 | 827 | /* Wait for 2 secs for the completion. */ |
| 827 | − wait_for_completion_timeout(&abort_cmp, msecs_to_jiffies(2000)); | |
| 828 | + done = wait_for_completion_timeout(&abort_cmp, msecs_to_jiffies(2000)); | |
| 828 | 829 | spin_lock_irqsave(&adapter->hw_lock, flags); |
| 829 | 830 | |
| 830 | − if (!completion_done(&abort_cmp)) { | |
| 831 | + if (!done) { | |
| 831 | 832 | /* |
| 832 | 833 | * Failed to abort the command, unmark the fact that it |
| 833 | 834 | * was requested to be aborted. |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #include <linux/types.h> |
| 28 | 28 | |
| 29 | −#define PVSCSI_DRIVER_VERSION_STRING "1.0.6.0-k" | |
| 29 | +#define PVSCSI_DRIVER_VERSION_STRING "1.0.7.0-k" | |
| 30 | 30 | |
| 31 | 31 | #define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128 |
| 32 | 32 | |
| @@ -207,7 +207,8 @@ static int ni_tio_clock_period_ps(const struct ni_gpct *counter, · 206 unmodified lines | ||
| 207 | 207 | * clock period is specified by user with prescaling |
| 208 | 208 | * already taken into account. |
| 209 | 209 | */ |
| 210 | − return counter->clock_period_ps; | |
| 210 | + *period_ps = counter->clock_period_ps; | |
| 211 | + return 0; | |
| 211 | 212 | } |
| 212 | 213 | |
| 213 | 214 | switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) { |
| @@ -186,6 +186,7 @@ int arche_platform_change_state(enum arche_platform_state state, · 185 unmodified lines | ||
| 186 | 186 | exit: |
| 187 | 187 | spin_unlock_irqrestore(&arche_pdata->wake_lock, flags); |
| 188 | 188 | mutex_unlock(&arche_pdata->platform_state_mutex); |
| 189 | + put_device(&pdev->dev); | |
| 189 | 190 | of_node_put(np); |
| 190 | 191 | return ret; |
| 191 | 192 | } |
| @@ -655,6 +655,7 @@ static void ad5933_work(struct work_struct *work) · 654 unmodified lines | ||
| 655 | 655 | __be16 buf[2]; |
| 656 | 656 | int val[2]; |
| 657 | 657 | unsigned char status; |
| 658 | + int ret; | |
| 658 | 659 | |
| 659 | 660 | mutex_lock(&indio_dev->mlock); |
| 660 | 661 | if (st->state == AD5933_CTRL_INIT_START_FREQ) { |
| @@ -662,19 +663,22 @@ static void ad5933_work(struct work_struct *work) · 1 unmodified line | ||
| 662 | 663 | ad5933_cmd(st, AD5933_CTRL_START_SWEEP); |
| 663 | 664 | st->state = AD5933_CTRL_START_SWEEP; |
| 664 | 665 | schedule_delayed_work(&st->work, st->poll_time_jiffies); |
| 665 | − mutex_unlock(&indio_dev->mlock); | |
| 666 | − return; | |
| 666 | + goto out; | |
| 667 | 667 | } |
| 668 | 668 | |
| 669 | − ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status); | |
| 669 | + ret = ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status); | |
| 670 | + if (ret) | |
| 671 | + goto out; | |
| 670 | 672 | |
| 671 | 673 | if (status & AD5933_STAT_DATA_VALID) { |
| 672 | 674 | int scan_count = bitmap_weight(indio_dev->active_scan_mask, |
| 673 | 675 | indio_dev->masklength); |
| 674 | − ad5933_i2c_read(st->client, | |
| 676 | + ret = ad5933_i2c_read(st->client, | |
| 675 | 677 | test_bit(1, indio_dev->active_scan_mask) ? |
| 676 | 678 | AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA, |
| 677 | 679 | scan_count * 2, (u8 *)buf); |
| 680 | + if (ret) | |
| 681 | + goto out; | |
| 678 | 682 | |
| 679 | 683 | if (scan_count == 2) { |
| 680 | 684 | val[0] = be16_to_cpu(buf[0]); |
| @@ -686,8 +690,7 @@ static void ad5933_work(struct work_struct *work) · 5 unmodified lines | ||
| 686 | 690 | } else { |
| 687 | 691 | /* no data available - try again later */ |
| 688 | 692 | schedule_delayed_work(&st->work, st->poll_time_jiffies); |
| 689 | − mutex_unlock(&indio_dev->mlock); | |
| 690 | − return; | |
| 693 | + goto out; | |
| 691 | 694 | } |
| 692 | 695 | |
| 693 | 696 | if (status & AD5933_STAT_SWEEP_DONE) { |
| @@ -700,7 +703,7 @@ static void ad5933_work(struct work_struct *work) · 6 unmodified lines | ||
| 700 | 703 | ad5933_cmd(st, AD5933_CTRL_INC_FREQ); |
| 701 | 704 | schedule_delayed_work(&st->work, st->poll_time_jiffies); |
| 702 | 705 | } |
| 703 | − | |
| 706 | +out: | |
| 704 | 707 | mutex_unlock(&indio_dev->mlock); |
| 705 | 708 | } |
| 706 | 709 | |
| @@ -106,13 +106,12 @@ static int nvec_mouse_probe(struct platform_device *pdev) · 105 unmodified lines | ||
| 106 | 106 | { |
| 107 | 107 | struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); |
| 108 | 108 | struct serio *ser_dev; |
| 109 | − char mouse_reset[] = { NVEC_PS2, SEND_COMMAND, PSMOUSE_RST, 3 }; | |
| 110 | 109 | |
| 111 | − ser_dev = devm_kzalloc(&pdev->dev, sizeof(struct serio), GFP_KERNEL); | |
| 110 | + ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL); | |
| 112 | 111 | if (!ser_dev) |
| 113 | 112 | return -ENOMEM; |
| 114 | 113 | |
| 115 | − ser_dev->id.type = SERIO_PS_PSTHRU; | |
| 114 | + ser_dev->id.type = SERIO_8042; | |
| 116 | 115 | ser_dev->write = ps2_sendcommand; |
| 117 | 116 | ser_dev->start = ps2_startstreaming; |
| 118 | 117 | ser_dev->stop = ps2_stopstreaming; |
| @@ -127,9 +126,6 @@ static int nvec_mouse_probe(struct platform_device *pdev) · 8 unmodified lines | ||
| 127 | 126 | |
| 128 | 127 | serio_register_port(ser_dev); |
| 129 | 128 | |
| 130 | − /* mouse reset */ | |
| 131 | − nvec_write_async(nvec, mouse_reset, sizeof(mouse_reset)); | |
| 132 | − | |
| 133 | 129 | return 0; |
| 134 | 130 | } |
| 135 | 131 | |
| @@ -601,13 +601,13 @@ · 600 unmodified lines | ||
| 601 | 601 | |
| 602 | 602 | #define PANEL_PLANE_TL 0x08001C |
| 603 | 603 | #define PANEL_PLANE_TL_TOP_SHIFT 16 |
| 604 | −#define PANEL_PLANE_TL_TOP_MASK (0xeff << 16) | |
| 605 | −#define PANEL_PLANE_TL_LEFT_MASK 0xeff | |
| 604 | +#define PANEL_PLANE_TL_TOP_MASK (0x7ff << 16) | |
| 605 | +#define PANEL_PLANE_TL_LEFT_MASK 0x7ff | |
| 606 | 606 | |
| 607 | 607 | #define PANEL_PLANE_BR 0x080020 |
| 608 | 608 | #define PANEL_PLANE_BR_BOTTOM_SHIFT 16 |
| 609 | −#define PANEL_PLANE_BR_BOTTOM_MASK (0xeff << 16) | |
| 610 | −#define PANEL_PLANE_BR_RIGHT_MASK 0xeff | |
| 609 | +#define PANEL_PLANE_BR_BOTTOM_MASK (0x7ff << 16) | |
| 610 | +#define PANEL_PLANE_BR_RIGHT_MASK 0x7ff | |
| 611 | 611 | |
| 612 | 612 | #define PANEL_HORIZONTAL_TOTAL 0x080024 |
| 613 | 613 | #define PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT 16 |
| @@ -932,8 +932,6 @@ static int wait_serial_change(struct acm *acm, unsigned long arg) · 931 unmodified lines | ||
| 932 | 932 | DECLARE_WAITQUEUE(wait, current); |
| 933 | 933 | struct async_icount old, new; |
| 934 | 934 | |
| 935 | − if (arg & (TIOCM_DSR | TIOCM_RI | TIOCM_CD)) | |
| 936 | − return -EINVAL; | |
| 937 | 935 | do { |
| 938 | 936 | spin_lock_irq(&acm->read_lock); |
| 939 | 937 | old = acm->oldcount; |
| @@ -1161,6 +1159,8 @@ static int acm_probe(struct usb_interface *intf, · 221 unmodified lines | ||
| 1161 | 1159 | if (quirks == IGNORE_DEVICE) |
| 1162 | 1160 | return -ENODEV; |
| 1163 | 1161 | |
| 1162 | + memset(&h, 0x00, sizeof(struct usb_cdc_parsed_header)); | |
| 1163 | + | |
| 1164 | 1164 | num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR; |
| 1165 | 1165 | |
| 1166 | 1166 | /* handle quirks deadly to normal probing*/ |
| @@ -769,15 +769,14 @@ static int dwc3_core_init(struct dwc3 *dwc) · 768 unmodified lines | ||
| 769 | 769 | return 0; |
| 770 | 770 | |
| 771 | 771 | err4: |
| 772 | − phy_power_off(dwc->usb2_generic_phy); | |
| 772 | + phy_power_off(dwc->usb3_generic_phy); | |
| 773 | 773 | |
| 774 | 774 | err3: |
| 775 | − phy_power_off(dwc->usb3_generic_phy); | |
| 775 | + phy_power_off(dwc->usb2_generic_phy); | |
| 776 | 776 | |
| 777 | 777 | err2: |
| 778 | 778 | usb_phy_set_suspend(dwc->usb2_phy, 1); |
| 779 | 779 | usb_phy_set_suspend(dwc->usb3_phy, 1); |
| 780 | − dwc3_core_exit(dwc); | |
| 781 | 780 | |
| 782 | 781 | err1: |
| 783 | 782 | usb_phy_shutdown(dwc->usb2_phy); |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <linux/slab.h> |
| 32 | 32 | #include <linux/regmap.h> |
| 33 | 33 | #include <linux/reset.h> |
| 34 | +#include <linux/pinctrl/consumer.h> | |
| 34 | 35 | #include <linux/usb/of.h> |
| 35 | 36 | |
| 36 | 37 | #include "core.h" |
| @@ -588,14 +588,6 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, · 587 unmodified lines | ||
| 588 | 588 | |
| 589 | 589 | req->length = length; |
| 590 | 590 | |
| 591 | − /* throttle high/super speed IRQ rate back slightly */ | |
| 592 | − if (gadget_is_dualspeed(dev->gadget)) | |
| 593 | − req->no_interrupt = (((dev->gadget->speed == USB_SPEED_HIGH || | |
| 594 | − dev->gadget->speed == USB_SPEED_SUPER)) && | |
| 595 | − !list_empty(&dev->tx_reqs)) | |
| 596 | − ? ((atomic_read(&dev->tx_qlen) % dev->qmult) != 0) | |
| 597 | − : 0; | |
| 598 | − | |
| 599 | 591 | retval = usb_ep_queue(in, req, GFP_ATOMIC); |
| 600 | 592 | switch (retval) { |
| 601 | 593 | default: |
| @@ -995,6 +995,14 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) · 994 unmodified lines | ||
| 995 | 995 | } |
| 996 | 996 | val = readl(base + ext_cap_offset); |
| 997 | 997 | |
| 998 | + /* Auto handoff never worked for these devices. Force it and continue */ | |
| 999 | + if ((pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) || | |
| 1000 | + (pdev->vendor == PCI_VENDOR_ID_RENESAS | |
| 1001 | + && pdev->device == 0x0014)) { | |
| 1002 | + val = (val | XHCI_HC_OS_OWNED) & ~XHCI_HC_BIOS_OWNED; | |
| 1003 | + writel(val, base + ext_cap_offset); | |
| 1004 | + } | |
| 1005 | + | |
| 998 | 1006 | /* If the BIOS owns the HC, signal that the OS wants it, and wait */ |
| 999 | 1007 | if (val & XHCI_HC_BIOS_OWNED) { |
| 1000 | 1008 | writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); |
| @@ -479,7 +479,8 @@ static int da8xx_probe(struct platform_device *pdev) · 478 unmodified lines | ||
| 479 | 479 | |
| 480 | 480 | glue->phy = devm_phy_get(&pdev->dev, "usb-phy"); |
| 481 | 481 | if (IS_ERR(glue->phy)) { |
| 482 | − dev_err(&pdev->dev, "failed to get phy\n"); | |
| 482 | + if (PTR_ERR(glue->phy) != -EPROBE_DEFER) | |
| 483 | + dev_err(&pdev->dev, "failed to get phy\n"); | |
| 483 | 484 | return PTR_ERR(glue->phy); |
| 484 | 485 | } |
| 485 | 486 | |
| @@ -2114,11 +2114,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) · 2113 unmodified lines | ||
| 2114 | 2114 | musb->io.ep_offset = musb_flat_ep_offset; |
| 2115 | 2115 | musb->io.ep_select = musb_flat_ep_select; |
| 2116 | 2116 | } |
| 2117 | − /* And override them with platform specific ops if specified. */ | |
| 2118 | − if (musb->ops->ep_offset) | |
| 2119 | − musb->io.ep_offset = musb->ops->ep_offset; | |
| 2120 | − if (musb->ops->ep_select) | |
| 2121 | − musb->io.ep_select = musb->ops->ep_select; | |
| 2122 | 2117 | |
| 2123 | 2118 | /* At least tusb6010 has its own offsets */ |
| 2124 | 2119 | if (musb->ops->ep_offset) |
| @@ -56,8 +56,11 @@ static struct uwb_rc *uwb_rc_find_by_index(int index) · 55 unmodified lines | ||
| 56 | 56 | struct uwb_rc *rc = NULL; |
| 57 | 57 | |
| 58 | 58 | dev = class_find_device(&uwb_rc_class, NULL, &index, uwb_rc_index_match); |
| 59 | − if (dev) | |
| 59 | + if (dev) { | |
| 60 | 60 | rc = dev_get_drvdata(dev); |
| 61 | + put_device(dev); | |
| 62 | + } | |
| 63 | + | |
| 61 | 64 | return rc; |
| 62 | 65 | } |
| 63 | 66 | |
| @@ -467,7 +470,9 @@ struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *target_rc) · 403 unmodified lines | ||
| 467 | 470 | if (dev) { |
| 468 | 471 | rc = dev_get_drvdata(dev); |
| 469 | 472 | __uwb_rc_get(rc); |
| 473 | + put_device(dev); | |
| 470 | 474 | } |
| 475 | + | |
| 471 | 476 | return rc; |
| 472 | 477 | } |
| 473 | 478 | EXPORT_SYMBOL_GPL(__uwb_rc_try_get); |
| @@ -520,8 +525,11 @@ struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *grandpa_dev) · 46 unmodified lines | ||
| 520 | 525 | |
| 521 | 526 | dev = class_find_device(&uwb_rc_class, NULL, grandpa_dev, |
| 522 | 527 | find_rc_grandpa); |
| 523 | − if (dev) | |
| 528 | + if (dev) { | |
| 524 | 529 | rc = dev_get_drvdata(dev); |
| 530 | + put_device(dev); | |
| 531 | + } | |
| 532 | + | |
| 525 | 533 | return rc; |
| 526 | 534 | } |
| 527 | 535 | EXPORT_SYMBOL_GPL(uwb_rc_get_by_grandpa); |
| @@ -553,8 +561,10 @@ struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *addr) · 25 unmodified lines | ||
| 553 | 561 | struct uwb_rc *rc = NULL; |
| 554 | 562 | |
| 555 | 563 | dev = class_find_device(&uwb_rc_class, NULL, addr, find_rc_dev); |
| 556 | − if (dev) | |
| 564 | + if (dev) { | |
| 557 | 565 | rc = dev_get_drvdata(dev); |
| 566 | + put_device(dev); | |
| 567 | + } | |
| 558 | 568 | |
| 559 | 569 | return rc; |
| 560 | 570 | } |
| @@ -97,6 +97,8 @@ static bool uwb_rc_class_device_exists(struct uwb_rc *target_rc) · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | dev = class_find_device(&uwb_rc_class, NULL, target_rc, find_rc); |
| 99 | 99 | |
| 100 | + put_device(dev); | |
| 101 | + | |
| 100 | 102 | return (dev != NULL); |
| 101 | 103 | } |
| 102 | 104 | |
| @@ -526,8 +526,8 @@ int versatile_clcd_init_panel(struct clcd_fb *fb, · 525 unmodified lines | ||
| 526 | 526 | np = of_find_matching_node_and_match(NULL, versatile_clcd_of_match, |
| 527 | 527 | &clcd_id); |
| 528 | 528 | if (!np) { |
| 529 | − dev_err(dev, "no Versatile syscon node\n"); | |
| 530 | − return -ENODEV; | |
| 529 | + /* Vexpress does not have this */ | |
| 530 | + return 0; | |
| 531 | 531 | } |
| 532 | 532 | versatile_clcd_type = (enum versatile_clcd)clcd_id->data; |
| 533 | 533 | |
| @@ -1078,6 +1078,17 @@ static void aio_complete(struct kiocb *kiocb, long res, long res2) · 1077 unmodified lines | ||
| 1078 | 1078 | unsigned tail, pos, head; |
| 1079 | 1079 | unsigned long flags; |
| 1080 | 1080 | |
| 1081 | + if (kiocb->ki_flags & IOCB_WRITE) { | |
| 1082 | + struct file *file = kiocb->ki_filp; | |
| 1083 | + | |
| 1084 | + /* | |
| 1085 | + * Tell lockdep we inherited freeze protection from submission | |
| 1086 | + * thread. | |
| 1087 | + */ | |
| 1088 | + __sb_writers_acquired(file_inode(file)->i_sb, SB_FREEZE_WRITE); | |
| 1089 | + file_end_write(file); | |
| 1090 | + } | |
| 1091 | + | |
| 1081 | 1092 | /* |
| 1082 | 1093 | * Special case handling for sync iocbs: |
| 1083 | 1094 | * - events go directly into the iocb for fast handling |
| @@ -1392,122 +1403,106 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) · 308 unmodified lines | ||
| 1392 | 1403 | return -EINVAL; |
| 1393 | 1404 | } |
| 1394 | 1405 | |
| 1395 | −typedef ssize_t (rw_iter_op)(struct kiocb *, struct iov_iter *); | |
| 1396 | − | |
| 1397 | −static int aio_setup_vectored_rw(int rw, char __user *buf, size_t len, | |
| 1398 | − struct iovec **iovec, | |
| 1399 | − bool compat, | |
| 1400 | − struct iov_iter *iter) | |
| 1406 | +static int aio_setup_rw(int rw, struct iocb *iocb, struct iovec **iovec, | |
| 1407 | + bool vectored, bool compat, struct iov_iter *iter) | |
| 1401 | 1408 | { |
| 1409 | + void __user *buf = (void __user *)(uintptr_t)iocb->aio_buf; | |
| 1410 | + size_t len = iocb->aio_nbytes; | |
| 1411 | + | |
| 1412 | + if (!vectored) { | |
| 1413 | + ssize_t ret = import_single_range(rw, buf, len, *iovec, iter); | |
| 1414 | + *iovec = NULL; | |
| 1415 | + return ret; | |
| 1416 | + } | |
| 1402 | 1417 | #ifdef CONFIG_COMPAT |
| 1403 | 1418 | if (compat) |
| 1404 | − return compat_import_iovec(rw, | |
| 1405 | − (struct compat_iovec __user *)buf, | |
| 1406 | − len, UIO_FASTIOV, iovec, iter); | |
| 1419 | + return compat_import_iovec(rw, buf, len, UIO_FASTIOV, iovec, | |
| 1420 | + iter); | |
| 1407 | 1421 | #endif |
| 1408 | − return import_iovec(rw, (struct iovec __user *)buf, | |
| 1409 | − len, UIO_FASTIOV, iovec, iter); | |
| 1422 | + return import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter); | |
| 1410 | 1423 | } |
| 1411 | 1424 | |
| 1412 | −/* | |
| 1413 | − * aio_run_iocb: | |
| 1414 | − * Performs the initial checks and io submission. | |
| 1415 | − */ | |
| 1416 | −static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, | |
| 1417 | − char __user *buf, size_t len, bool compat) | |
| 1425 | +static inline ssize_t aio_ret(struct kiocb *req, ssize_t ret) | |
| 1426 | +{ | |
| 1427 | + switch (ret) { | |
| 1428 | + case -EIOCBQUEUED: | |
| 1429 | + return ret; | |
| 1430 | + case -ERESTARTSYS: | |
| 1431 | + case -ERESTARTNOINTR: | |
| 1432 | + case -ERESTARTNOHAND: | |
| 1433 | + case -ERESTART_RESTARTBLOCK: | |
| 1434 | + /* | |
| 1435 | + * There's no easy way to restart the syscall since other AIO's | |
| 1436 | + * may be already running. Just fail this IO with EINTR. | |
| 1437 | + */ | |
| 1438 | + ret = -EINTR; | |
| 1439 | + /*FALLTHRU*/ | |
| 1440 | + default: | |
| 1441 | + aio_complete(req, ret, 0); | |
| 1442 | + return 0; | |
| 1443 | + } | |
| 1444 | +} | |
| 1445 | + | |
| 1446 | +static ssize_t aio_read(struct kiocb *req, struct iocb *iocb, bool vectored, | |
| 1447 | + bool compat) | |
| 1418 | 1448 | { |
| 1419 | 1449 | struct file *file = req->ki_filp; |
| 1420 | − ssize_t ret; | |
| 1421 | − int rw; | |
| 1422 | − fmode_t mode; | |
| 1423 | − rw_iter_op *iter_op; | |
| 1424 | 1450 | struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; |
| 1425 | 1451 | struct iov_iter iter; |
| 1452 | + ssize_t ret; | |
| 1426 | 1453 | |
| 1427 | − switch (opcode) { | |
| 1428 | − case IOCB_CMD_PREAD: | |
| 1429 | − case IOCB_CMD_PREADV: | |
| 1430 | − mode = FMODE_READ; | |
| 1431 | − rw = READ; | |
| 1432 | − iter_op = file->f_op->read_iter; | |
| 1433 | − goto rw_common; | |
| 1434 | − | |
| 1435 | − case IOCB_CMD_PWRITE: | |
| 1436 | − case IOCB_CMD_PWRITEV: | |
| 1437 | − mode = FMODE_WRITE; | |
| 1438 | − rw = WRITE; | |
| 1439 | − iter_op = file->f_op->write_iter; | |
| 1440 | − goto rw_common; | |
| 1441 | −rw_common: | |
| 1442 | − if (unlikely(!(file->f_mode & mode))) | |
| 1443 | − return -EBADF; | |
| 1444 | − | |
| 1445 | − if (!iter_op) | |
| 1446 | − return -EINVAL; | |
| 1447 | − | |
| 1448 | − if (opcode == IOCB_CMD_PREADV || opcode == IOCB_CMD_PWRITEV) | |
| 1449 | − ret = aio_setup_vectored_rw(rw, buf, len, | |
| 1450 | − &iovec, compat, &iter); | |
| 1451 | − else { | |
| 1452 | − ret = import_single_range(rw, buf, len, iovec, &iter); | |
| 1453 | − iovec = NULL; | |
| 1454 | − } | |
| 1455 | − if (!ret) | |
| 1456 | − ret = rw_verify_area(rw, file, &req->ki_pos, | |
| 1457 | − iov_iter_count(&iter)); | |
| 1458 | − if (ret < 0) { | |
| 1459 | − kfree(iovec); | |
| 1460 | − return ret; | |
| 1461 | − } | |
| 1462 | − | |
| 1463 | − if (rw == WRITE) | |
| 1464 | − file_start_write(file); | |
| 1465 | − | |
| 1466 | − ret = iter_op(req, &iter); | |
| 1467 | − | |
| 1468 | − if (rw == WRITE) | |
| 1469 | − file_end_write(file); | |
| 1470 | − kfree(iovec); | |
| 1471 | − break; | |
| 1472 | − | |
| 1473 | − case IOCB_CMD_FDSYNC: | |
| 1474 | − if (!file->f_op->aio_fsync) | |
| 1475 | − return -EINVAL; | |
| 1476 | − | |
| 1477 | − ret = file->f_op->aio_fsync(req, 1); | |
| 1478 | − break; | |
| 1454 | + if (unlikely(!(file->f_mode & FMODE_READ))) | |
| 1455 | + return -EBADF; | |
| 1456 | + if (unlikely(!file->f_op->read_iter)) | |
| 1457 | + return -EINVAL; | |
| 1479 | 1458 | |
| 1480 | − case IOCB_CMD_FSYNC: | |
| 1481 | − if (!file->f_op->aio_fsync) | |
| 1482 | − return -EINVAL; | |
| 1459 | + ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter); | |
| 1460 | + if (ret) | |
| 1461 | + return ret; | |
| 1462 | + ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter)); | |
| 1463 | + if (!ret) | |
| 1464 | + ret = aio_ret(req, file->f_op->read_iter(req, &iter)); | |
| 1465 | + kfree(iovec); | |
| 1466 | + return ret; | |
| 1467 | +} | |
| 1483 | 1468 | |
| 1484 | − ret = file->f_op->aio_fsync(req, 0); | |
| 1485 | − break; | |
| 1469 | +static ssize_t aio_write(struct kiocb *req, struct iocb *iocb, bool vectored, | |
| 1470 | + bool compat) | |
| 1471 | +{ | |
| 1472 | + struct file *file = req->ki_filp; | |
| 1473 | + struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs; | |
| 1474 | + struct iov_iter iter; | |
| 1475 | + ssize_t ret; | |
| 1486 | 1476 | |
| 1487 | − default: | |
| 1488 | − pr_debug("EINVAL: no operation provided\n"); | |
| 1477 | + if (unlikely(!(file->f_mode & FMODE_WRITE))) | |
| 1478 | + return -EBADF; | |
| 1479 | + if (unlikely(!file->f_op->write_iter)) | |
| 1489 | 1480 | return -EINVAL; |
| 1490 | − } | |
| 1491 | 1481 | |
| 1492 | − if (ret != -EIOCBQUEUED) { | |
| 1482 | + ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter); | |
| 1483 | + if (ret) | |
| 1484 | + return ret; | |
| 1485 | + ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter)); | |
| 1486 | + if (!ret) { | |
| 1487 | + req->ki_flags |= IOCB_WRITE; | |
| 1488 | + file_start_write(file); | |
| 1489 | + ret = aio_ret(req, file->f_op->write_iter(req, &iter)); | |
| 1493 | 1490 | /* |
| 1494 | − * There's no easy way to restart the syscall since other AIO's | |
| 1495 | − * may be already running. Just fail this IO with EINTR. | |
| 1491 | + * We release freeze protection in aio_complete(). Fool lockdep | |
| 1492 | + * by telling it the lock got released so that it doesn't | |
| 1493 | + * complain about held lock when we return to userspace. | |
| 1496 | 1494 | */ |
| 1497 | − if (unlikely(ret == -ERESTARTSYS || ret == -ERESTARTNOINTR || | |
| 1498 | − ret == -ERESTARTNOHAND || | |
| 1499 | − ret == -ERESTART_RESTARTBLOCK)) | |
| 1500 | − ret = -EINTR; | |
| 1501 | − aio_complete(req, ret, 0); | |
| 1495 | + __sb_writers_release(file_inode(file)->i_sb, SB_FREEZE_WRITE); | |
| 1502 | 1496 | } |
| 1503 | − | |
| 1504 | − return 0; | |
| 1497 | + kfree(iovec); | |
| 1498 | + return ret; | |
| 1505 | 1499 | } |
| 1506 | 1500 | |
| 1507 | 1501 | static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, |
| 1508 | 1502 | struct iocb *iocb, bool compat) |
| 1509 | 1503 | { |
| 1510 | 1504 | struct aio_kiocb *req; |
| 1505 | + struct file *file; | |
| 1511 | 1506 | ssize_t ret; |
| 1512 | 1507 | |
| 1513 | 1508 | /* enforce forwards compatibility on users */ |
| @@ -1530,7 +1525,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, · 16 unmodified lines | ||
| 1530 | 1525 | if (unlikely(!req)) |
| 1531 | 1526 | return -EAGAIN; |
| 1532 | 1527 | |
| 1533 | − req->common.ki_filp = fget(iocb->aio_fildes); | |
| 1528 | + req->common.ki_filp = file = fget(iocb->aio_fildes); | |
| 1534 | 1529 | if (unlikely(!req->common.ki_filp)) { |
| 1535 | 1530 | ret = -EBADF; |
| 1536 | 1531 | goto out_put_req; |
| @@ -1565,13 +1560,29 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, · 28 unmodified lines | ||
| 1565 | 1560 | req->ki_user_iocb = user_iocb; |
| 1566 | 1561 | req->ki_user_data = iocb->aio_data; |
| 1567 | 1562 | |
| 1568 | − ret = aio_run_iocb(&req->common, iocb->aio_lio_opcode, | |
| 1569 | − (char __user *)(unsigned long)iocb->aio_buf, | |
| 1570 | − iocb->aio_nbytes, | |
| 1571 | − compat); | |
| 1572 | − if (ret) | |
| 1573 | − goto out_put_req; | |
| 1563 | + get_file(file); | |
| 1564 | + switch (iocb->aio_lio_opcode) { | |
| 1565 | + case IOCB_CMD_PREAD: | |
| 1566 | + ret = aio_read(&req->common, iocb, false, compat); | |
| 1567 | + break; | |
| 1568 | + case IOCB_CMD_PWRITE: | |
| 1569 | + ret = aio_write(&req->common, iocb, false, compat); | |
| 1570 | + break; | |
| 1571 | + case IOCB_CMD_PREADV: | |
| 1572 | + ret = aio_read(&req->common, iocb, true, compat); | |
| 1573 | + break; | |
| 1574 | + case IOCB_CMD_PWRITEV: | |
| 1575 | + ret = aio_write(&req->common, iocb, true, compat); | |
| 1576 | + break; | |
| 1577 | + default: | |
| 1578 | + pr_debug("invalid aio operation %d\n", iocb->aio_lio_opcode); | |
| 1579 | + ret = -EINVAL; | |
| 1580 | + break; | |
| 1581 | + } | |
| 1582 | + fput(file); | |
| 1574 | 1583 | |
| 1584 | + if (ret && ret != -EIOCBQUEUED) | |
| 1585 | + goto out_put_req; | |
| 1575 | 1586 | return 0; |
| 1576 | 1587 | out_put_req: |
| 1577 | 1588 | put_reqs_available(ctx, 1); |
| @@ -1770,7 +1770,6 @@ const struct file_operations ceph_file_fops = { · 1769 unmodified lines | ||
| 1770 | 1770 | .fsync = ceph_fsync, |
| 1771 | 1771 | .lock = ceph_lock, |
| 1772 | 1772 | .flock = ceph_flock, |
| 1773 | − .splice_read = generic_file_splice_read, | |
| 1774 | 1773 | .splice_write = iter_file_splice_write, |
| 1775 | 1774 | .unlocked_ioctl = ceph_ioctl, |
| 1776 | 1775 | .compat_ioctl = ceph_ioctl, |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | #include <linux/slab.h> |
| 2 | 2 | #include <linux/file.h> |
| 3 | 3 | #include <linux/fdtable.h> |
| 4 | +#include <linux/freezer.h> | |
| 4 | 5 | #include <linux/mm.h> |
| 5 | 6 | #include <linux/stat.h> |
| 6 | 7 | #include <linux/fcntl.h> |
| @@ -423,7 +424,9 @@ static int coredump_wait(int exit_code, struct core_state *core_state) · 416 unmodified lines | ||
| 423 | 424 | if (core_waiters > 0) { |
| 424 | 425 | struct core_thread *ptr; |
| 425 | 426 | |
| 427 | + freezer_do_not_count(); | |
| 426 | 428 | wait_for_completion(&core_state->startup); |
| 429 | + freezer_count(); | |
| 427 | 430 | /* |
| 428 | 431 | * Wait for all the threads to become inactive, so that |
| 429 | 432 | * all the thread context (extended register state, like |
| @@ -39,65 +39,54 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res) · 38 unmodified lines | ||
| 39 | 39 | static int fname_encrypt(struct inode *inode, |
| 40 | 40 | const struct qstr *iname, struct fscrypt_str *oname) |
| 41 | 41 | { |
| 42 | − u32 ciphertext_len; | |
| 43 | 42 | struct skcipher_request *req = NULL; |
| 44 | 43 | DECLARE_FS_COMPLETION_RESULT(ecr); |
| 45 | 44 | struct fscrypt_info *ci = inode->i_crypt_info; |
| 46 | 45 | struct crypto_skcipher *tfm = ci->ci_ctfm; |
| 47 | 46 | int res = 0; |
| 48 | 47 | char iv[FS_CRYPTO_BLOCK_SIZE]; |
| 49 | − struct scatterlist src_sg, dst_sg; | |
| 48 | + struct scatterlist sg; | |
| 50 | 49 | int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK); |
| 51 | − char *workbuf, buf[32], *alloc_buf = NULL; | |
| 52 | − unsigned lim; | |
| 50 | + unsigned int lim; | |
| 51 | + unsigned int cryptlen; | |
| 53 | 52 | |
| 54 | 53 | lim = inode->i_sb->s_cop->max_namelen(inode); |
| 55 | 54 | if (iname->len <= 0 || iname->len > lim) |
| 56 | 55 | return -EIO; |
| 57 | 56 | |
| 58 | − ciphertext_len = max(iname->len, (u32)FS_CRYPTO_BLOCK_SIZE); | |
| 59 | − ciphertext_len = round_up(ciphertext_len, padding); | |
| 60 | − ciphertext_len = min(ciphertext_len, lim); | |
| 57 | + /* | |
| 58 | + * Copy the filename to the output buffer for encrypting in-place and | |
| 59 | + * pad it with the needed number of NUL bytes. | |
| 60 | + */ | |
| 61 | + cryptlen = max_t(unsigned int, iname->len, FS_CRYPTO_BLOCK_SIZE); | |
| 62 | + cryptlen = round_up(cryptlen, padding); | |
| 63 | + cryptlen = min(cryptlen, lim); | |
| 64 | + memcpy(oname->name, iname->name, iname->len); | |
| 65 | + memset(oname->name + iname->len, 0, cryptlen - iname->len); | |
| 61 | 66 | |
| 62 | − if (ciphertext_len <= sizeof(buf)) { | |
| 63 | − workbuf = buf; | |
| 64 | − } else { | |
| 65 | − alloc_buf = kmalloc(ciphertext_len, GFP_NOFS); | |
| 66 | − if (!alloc_buf) | |
| 67 | − return -ENOMEM; | |
| 68 | − workbuf = alloc_buf; | |
| 69 | − } | |
| 67 | + /* Initialize the IV */ | |
| 68 | + memset(iv, 0, FS_CRYPTO_BLOCK_SIZE); | |
| 70 | 69 | |
| 71 | − /* Allocate request */ | |
| 70 | + /* Set up the encryption request */ | |
| 72 | 71 | req = skcipher_request_alloc(tfm, GFP_NOFS); |
| 73 | 72 | if (!req) { |
| 74 | 73 | printk_ratelimited(KERN_ERR |
| 75 | − "%s: crypto_request_alloc() failed\n", __func__); | |
| 76 | − kfree(alloc_buf); | |
| 74 | + "%s: skcipher_request_alloc() failed\n", __func__); | |
| 77 | 75 | return -ENOMEM; |
| 78 | 76 | } |
| 79 | 77 | skcipher_request_set_callback(req, |
| 80 | 78 | CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, |
| 81 | 79 | fname_crypt_complete, &ecr); |
| 80 | + sg_init_one(&sg, oname->name, cryptlen); | |
| 81 | + skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv); | |
| 82 | 82 | |
| 83 | − /* Copy the input */ | |
| 84 | − memcpy(workbuf, iname->name, iname->len); | |
| 85 | − if (iname->len < ciphertext_len) | |
| 86 | − memset(workbuf + iname->len, 0, ciphertext_len - iname->len); | |
| 87 | − | |
| 88 | − /* Initialize IV */ | |
| 89 | − memset(iv, 0, FS_CRYPTO_BLOCK_SIZE); | |
| 90 | − | |
| 91 | − /* Create encryption request */ | |
| 92 | − sg_init_one(&src_sg, workbuf, ciphertext_len); | |
| 93 | − sg_init_one(&dst_sg, oname->name, ciphertext_len); | |
| 94 | − skcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv); | |
| 83 | + /* Do the encryption */ | |
| 95 | 84 | res = crypto_skcipher_encrypt(req); |
| 96 | 85 | if (res == -EINPROGRESS || res == -EBUSY) { |
| 86 | + /* Request is being completed asynchronously; wait for it */ | |
| 97 | 87 | wait_for_completion(&ecr.completion); |
| 98 | 88 | res = ecr.res; |
| 99 | 89 | } |
| 100 | − kfree(alloc_buf); | |
| 101 | 90 | skcipher_request_free(req); |
| 102 | 91 | if (res < 0) { |
| 103 | 92 | printk_ratelimited(KERN_ERR |
| @@ -105,7 +94,7 @@ static int fname_encrypt(struct inode *inode, · 1 unmodified line | ||
| 105 | 94 | return res; |
| 106 | 95 | } |
| 107 | 96 | |
| 108 | − oname->len = ciphertext_len; | |
| 97 | + oname->len = cryptlen; | |
| 109 | 98 | return 0; |
| 110 | 99 | } |
| 111 | 100 | |
| @@ -185,7 +185,7 @@ int get_crypt_info(struct inode *inode) · 184 unmodified lines | ||
| 185 | 185 | struct crypto_skcipher *ctfm; |
| 186 | 186 | const char *cipher_str; |
| 187 | 187 | int keysize; |
| 188 | − u8 raw_key[FS_MAX_KEY_SIZE]; | |
| 188 | + u8 *raw_key = NULL; | |
| 189 | 189 | int res; |
| 190 | 190 | |
| 191 | 191 | res = fscrypt_initialize(); |
| @@ -238,6 +238,15 @@ retry: · 46 unmodified lines | ||
| 238 | 238 | if (res) |
| 239 | 239 | goto out; |
| 240 | 240 | |
| 241 | + /* | |
| 242 | + * This cannot be a stack buffer because it is passed to the scatterlist | |
| 243 | + * crypto API as part of key derivation. | |
| 244 | + */ | |
| 245 | + res = -ENOMEM; | |
| 246 | + raw_key = kmalloc(FS_MAX_KEY_SIZE, GFP_NOFS); | |
| 247 | + if (!raw_key) | |
| 248 | + goto out; | |
| 249 | + | |
| 241 | 250 | if (fscrypt_dummy_context_enabled(inode)) { |
| 242 | 251 | memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE); |
| 243 | 252 | goto got_key; |
| @@ -276,7 +285,8 @@ got_key: · 32 unmodified lines | ||
| 276 | 285 | if (res) |
| 277 | 286 | goto out; |
| 278 | 287 | |
| 279 | − memzero_explicit(raw_key, sizeof(raw_key)); | |
| 288 | + kzfree(raw_key); | |
| 289 | + raw_key = NULL; | |
| 280 | 290 | if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) { |
| 281 | 291 | put_crypt_info(crypt_info); |
| 282 | 292 | goto retry; |
| @@ -287,7 +297,7 @@ out: · 4 unmodified lines | ||
| 287 | 297 | if (res == -ENOKEY) |
| 288 | 298 | res = 0; |
| 289 | 299 | put_crypt_info(crypt_info); |
| 290 | − memzero_explicit(raw_key, sizeof(raw_key)); | |
| 300 | + kzfree(raw_key); | |
| 291 | 301 | return res; |
| 292 | 302 | } |
| 293 | 303 | |
| @@ -235,6 +235,7 @@ struct ext4_io_submit { · 234 unmodified lines | ||
| 235 | 235 | #define EXT4_MAX_BLOCK_SIZE 65536 |
| 236 | 236 | #define EXT4_MIN_BLOCK_LOG_SIZE 10 |
| 237 | 237 | #define EXT4_MAX_BLOCK_LOG_SIZE 16 |
| 238 | +#define EXT4_MAX_CLUSTER_LOG_SIZE 30 | |
| 238 | 239 | #ifdef __KERNEL__ |
| 239 | 240 | # define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) |
| 240 | 241 | #else |
| @@ -3565,7 +3565,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) · 3564 unmodified lines | ||
| 3565 | 3565 | if (blocksize < EXT4_MIN_BLOCK_SIZE || |
| 3566 | 3566 | blocksize > EXT4_MAX_BLOCK_SIZE) { |
| 3567 | 3567 | ext4_msg(sb, KERN_ERR, |
| 3568 | − "Unsupported filesystem blocksize %d", blocksize); | |
| 3568 | + "Unsupported filesystem blocksize %d (%d log_block_size)", | |
| 3569 | + blocksize, le32_to_cpu(es->s_log_block_size)); | |
| 3570 | + goto failed_mount; | |
| 3571 | + } | |
| 3572 | + if (le32_to_cpu(es->s_log_block_size) > | |
| 3573 | + (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { | |
| 3574 | + ext4_msg(sb, KERN_ERR, | |
| 3575 | + "Invalid log block size: %u", | |
| 3576 | + le32_to_cpu(es->s_log_block_size)); | |
| 3569 | 3577 | goto failed_mount; |
| 3570 | 3578 | } |
| 3571 | 3579 | |
| @@ -3697,6 +3705,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) · 125 unmodified lines | ||
| 3697 | 3705 | "block size (%d)", clustersize, blocksize); |
| 3698 | 3706 | goto failed_mount; |
| 3699 | 3707 | } |
| 3708 | + if (le32_to_cpu(es->s_log_cluster_size) > | |
| 3709 | + (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { | |
| 3710 | + ext4_msg(sb, KERN_ERR, | |
| 3711 | + "Invalid log cluster size: %u", | |
| 3712 | + le32_to_cpu(es->s_log_cluster_size)); | |
| 3713 | + goto failed_mount; | |
| 3714 | + } | |
| 3700 | 3715 | sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - |
| 3701 | 3716 | le32_to_cpu(es->s_log_block_size); |
| 3702 | 3717 | sbi->s_clusters_per_group = |
| @@ -286,6 +286,11 @@ const struct dentry_operations fuse_dentry_operations = { · 285 unmodified lines | ||
| 286 | 286 | .d_release = fuse_dentry_release, |
| 287 | 287 | }; |
| 288 | 288 | |
| 289 | +const struct dentry_operations fuse_root_dentry_operations = { | |
| 290 | + .d_init = fuse_dentry_init, | |
| 291 | + .d_release = fuse_dentry_release, | |
| 292 | +}; | |
| 293 | + | |
| 289 | 294 | int fuse_valid_type(int m) |
| 290 | 295 | { |
| 291 | 296 | return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || |
| @@ -1985,6 +1985,10 @@ static int fuse_write_end(struct file *file, struct address_space *mapping, · 1984 unmodified lines | ||
| 1985 | 1985 | { |
| 1986 | 1986 | struct inode *inode = page->mapping->host; |
| 1987 | 1987 | |
| 1988 | + /* Haven't copied anything? Skip zeroing, size extending, dirtying. */ | |
| 1989 | + if (!copied) | |
| 1990 | + goto unlock; | |
| 1991 | + | |
| 1988 | 1992 | if (!PageUptodate(page)) { |
| 1989 | 1993 | /* Zero any unwritten bytes at the end of the page */ |
| 1990 | 1994 | size_t endoff = (pos + copied) & ~PAGE_MASK; |
| @@ -1995,6 +1999,8 @@ static int fuse_write_end(struct file *file, struct address_space *mapping, · 4 unmodified lines | ||
| 1995 | 1999 | |
| 1996 | 2000 | fuse_write_update_size(inode, pos + copied); |
| 1997 | 2001 | set_page_dirty(page); |
| 2002 | + | |
| 2003 | +unlock: | |
| 1998 | 2004 | unlock_page(page); |
| 1999 | 2005 | put_page(page); |
| 2000 | 2006 | |
| @@ -692,6 +692,7 @@ static inline u64 get_node_id(struct inode *inode) · 691 unmodified lines | ||
| 692 | 692 | extern const struct file_operations fuse_dev_operations; |
| 693 | 693 | |
| 694 | 694 | extern const struct dentry_operations fuse_dentry_operations; |
| 695 | +extern const struct dentry_operations fuse_root_dentry_operations; | |
| 695 | 696 | |
| 696 | 697 | /** |
| 697 | 698 | * Inode to nodeid comparison. |
| @@ -1131,10 +1131,11 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) · 1130 unmodified lines | ||
| 1131 | 1131 | |
| 1132 | 1132 | err = -ENOMEM; |
| 1133 | 1133 | root = fuse_get_root_inode(sb, d.rootmode); |
| 1134 | + sb->s_d_op = &fuse_root_dentry_operations; | |
| 1134 | 1135 | root_dentry = d_make_root(root); |
| 1135 | 1136 | if (!root_dentry) |
| 1136 | 1137 | goto err_dev_free; |
| 1137 | − /* only now - we want root dentry with NULL ->d_op */ | |
| 1138 | + /* Root dentry doesn't have .d_revalidate */ | |
| 1138 | 1139 | sb->s_d_op = &fuse_dentry_operations; |
| 1139 | 1140 | |
| 1140 | 1141 | init_req = fuse_request_alloc(0); |
| @@ -314,7 +314,8 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat · 313 unmodified lines | ||
| 314 | 314 | /* Match the full socket address */ |
| 315 | 315 | if (!rpc_cmp_addr_port(sap, clap)) |
| 316 | 316 | /* Match all xprt_switch full socket addresses */ |
| 317 | − if (!rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient, | |
| 317 | + if (IS_ERR(clp->cl_rpcclient) || | |
| 318 | + !rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient, | |
| 318 | 319 | sap)) |
| 319 | 320 | continue; |
| 320 | 321 | |
| @@ -98,7 +98,7 @@ rename_retry: · 97 unmodified lines | ||
| 98 | 98 | return end; |
| 99 | 99 | } |
| 100 | 100 | namelen = strlen(base); |
| 101 | − if (flags & NFS_PATH_CANONICAL) { | |
| 101 | + if (*end == '/') { | |
| 102 | 102 | /* Strip off excess slashes in base string */ |
| 103 | 103 | while (namelen > 0 && base[namelen - 1] == '/') |
| 104 | 104 | namelen--; |
| @@ -178,12 +178,14 @@ static int nfs4_slot_get_seqid(struct nfs4_slot_table *tbl, u32 slotid, · 177 unmodified lines | ||
| 178 | 178 | __must_hold(&tbl->slot_tbl_lock) |
| 179 | 179 | { |
| 180 | 180 | struct nfs4_slot *slot; |
| 181 | + int ret; | |
| 181 | 182 | |
| 182 | 183 | slot = nfs4_lookup_slot(tbl, slotid); |
| 183 | − if (IS_ERR(slot)) | |
| 184 | − return PTR_ERR(slot); | |
| 185 | − *seq_nr = slot->seq_nr; | |
| 186 | − return 0; | |
| 184 | + ret = PTR_ERR_OR_ZERO(slot); | |
| 185 | + if (!ret) | |
| 186 | + *seq_nr = slot->seq_nr; | |
| 187 | + | |
| 188 | + return ret; | |
| 187 | 189 | } |
| 188 | 190 | |
| 189 | 191 | /* |
| @@ -196,7 +198,7 @@ static int nfs4_slot_get_seqid(struct nfs4_slot_table *tbl, u32 slotid, · 6 unmodified lines | ||
| 196 | 198 | static bool nfs4_slot_seqid_in_use(struct nfs4_slot_table *tbl, |
| 197 | 199 | u32 slotid, u32 seq_nr) |
| 198 | 200 | { |
| 199 | − u32 cur_seq; | |
| 201 | + u32 cur_seq = 0; | |
| 200 | 202 | bool ret = false; |
| 201 | 203 | |
| 202 | 204 | spin_lock(&tbl->slot_tbl_lock); |
| @@ -146,6 +146,8 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh, · 145 unmodified lines | ||
| 146 | 146 | u32 id; |
| 147 | 147 | int i; |
| 148 | 148 | |
| 149 | + if (fsinfo->nlayouttypes == 0) | |
| 150 | + goto out_no_driver; | |
| 149 | 151 | if (!(server->nfs_client->cl_exchange_flags & |
| 150 | 152 | (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS))) { |
| 151 | 153 | printk(KERN_ERR "NFS: %s: cl_exchange_flags 0x%x\n", |
| @@ -1544,8 +1544,6 @@ const struct file_operations ntfs_dir_ops = { · 1543 unmodified lines | ||
| 1544 | 1544 | .iterate = ntfs_readdir, /* Read directory contents. */ |
| 1545 | 1545 | #ifdef NTFS_RW |
| 1546 | 1546 | .fsync = ntfs_dir_fsync, /* Sync a directory to disk. */ |
| 1547 | − /*.aio_fsync = ,*/ /* Sync all outstanding async | |
| 1548 | − i/o operations on a kiocb. */ | |
| 1549 | 1547 | #endif /* NTFS_RW */ |
| 1550 | 1548 | /*.ioctl = ,*/ /* Perform function on the |
| 1551 | 1549 | mounted filesystem. */ |
| @@ -3699,7 +3699,7 @@ static void ocfs2_dx_dir_transfer_leaf(struct inode *dir, u32 split_hash, · 3698 unmodified lines | ||
| 3699 | 3699 | static int ocfs2_dx_dir_rebalance_credits(struct ocfs2_super *osb, |
| 3700 | 3700 | struct ocfs2_dx_root_block *dx_root) |
| 3701 | 3701 | { |
| 3702 | − int credits = ocfs2_clusters_to_blocks(osb->sb, 2); | |
| 3702 | + int credits = ocfs2_clusters_to_blocks(osb->sb, 3); | |
| 3703 | 3703 | |
| 3704 | 3704 | credits += ocfs2_calc_extend_credits(osb->sb, &dx_root->dr_list); |
| 3705 | 3705 | credits += ocfs2_quota_trans_credits(osb->sb); |
| @@ -114,6 +114,7 @@ static const struct seq_operations help_debug_ops = { · 113 unmodified lines | ||
| 114 | 114 | }; |
| 115 | 115 | |
| 116 | 116 | const struct file_operations debug_help_fops = { |
| 117 | + .owner = THIS_MODULE, | |
| 117 | 118 | .open = orangefs_debug_help_open, |
| 118 | 119 | .read = seq_read, |
| 119 | 120 | .release = seq_release, |
| @@ -121,6 +122,7 @@ const struct file_operations debug_help_fops = { · 1 unmodified line | ||
| 121 | 122 | }; |
| 122 | 123 | |
| 123 | 124 | static const struct file_operations kernel_debug_fops = { |
| 125 | + .owner = THIS_MODULE, | |
| 124 | 126 | .open = orangefs_debug_open, |
| 125 | 127 | .read = orangefs_debug_read, |
| 126 | 128 | .write = orangefs_debug_write, |
| @@ -299,13 +299,8 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, · 298 unmodified lines | ||
| 299 | 299 | { |
| 300 | 300 | struct iov_iter to; |
| 301 | 301 | struct kiocb kiocb; |
| 302 | − loff_t isize; | |
| 303 | 302 | int idx, ret; |
| 304 | 303 | |
| 305 | − isize = i_size_read(in->f_mapping->host); | |
| 306 | − if (unlikely(*ppos >= isize)) | |
| 307 | − return 0; | |
| 308 | − | |
| 309 | 304 | iov_iter_pipe(&to, ITER_PIPE | READ, pipe, len); |
| 310 | 305 | idx = to.idx; |
| 311 | 306 | init_sync_kiocb(&kiocb, in); |
| @@ -170,7 +170,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, · 169 unmodified lines | ||
| 170 | 170 | const void *value, size_t size, int flags) |
| 171 | 171 | { |
| 172 | 172 | struct inode *inode = dentry->d_inode; |
| 173 | − int error = -EOPNOTSUPP; | |
| 173 | + int error = -EAGAIN; | |
| 174 | 174 | int issec = !strncmp(name, XATTR_SECURITY_PREFIX, |
| 175 | 175 | XATTR_SECURITY_PREFIX_LEN); |
| 176 | 176 | |
| @@ -183,15 +183,21 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, · 6 unmodified lines | ||
| 183 | 183 | security_inode_post_setxattr(dentry, name, value, |
| 184 | 184 | size, flags); |
| 185 | 185 | } |
| 186 | − } else if (issec) { | |
| 187 | − const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; | |
| 188 | − | |
| 186 | + } else { | |
| 189 | 187 | if (unlikely(is_bad_inode(inode))) |
| 190 | 188 | return -EIO; |
| 191 | − error = security_inode_setsecurity(inode, suffix, value, | |
| 192 | − size, flags); | |
| 193 | − if (!error) | |
| 194 | − fsnotify_xattr(dentry); | |
| 189 | + } | |
| 190 | + if (error == -EAGAIN) { | |
| 191 | + error = -EOPNOTSUPP; | |
| 192 | + | |
| 193 | + if (issec) { | |
| 194 | + const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; | |
| 195 | + | |
| 196 | + error = security_inode_setsecurity(inode, suffix, value, | |
| 197 | + size, flags); | |
| 198 | + if (!error) | |
| 199 | + fsnotify_xattr(dentry); | |
| 200 | + } | |
| 195 | 201 | } |
| 196 | 202 | |
| 197 | 203 | return error; |
| @@ -199,9 +199,9 @@ xfs_defer_intake_work( · 198 unmodified lines | ||
| 199 | 199 | struct xfs_defer_pending *dfp; |
| 200 | 200 | |
| 201 | 201 | list_for_each_entry(dfp, &dop->dop_intake, dfp_list) { |
| 202 | − trace_xfs_defer_intake_work(tp->t_mountp, dfp); | |
| 203 | 202 | dfp->dfp_intent = dfp->dfp_type->create_intent(tp, |
| 204 | 203 | dfp->dfp_count); |
| 204 | + trace_xfs_defer_intake_work(tp->t_mountp, dfp); | |
| 205 | 205 | list_sort(tp->t_mountp, &dfp->dfp_work, |
| 206 | 206 | dfp->dfp_type->diff_items); |
| 207 | 207 | list_for_each(li, &dfp->dfp_work) |
| @@ -221,21 +221,14 @@ xfs_defer_trans_abort( · 13 unmodified lines | ||
| 221 | 221 | struct xfs_defer_pending *dfp; |
| 222 | 222 | |
| 223 | 223 | trace_xfs_defer_trans_abort(tp->t_mountp, dop); |
| 224 | − /* | |
| 225 | − * If the transaction was committed, drop the intent reference | |
| 226 | − * since we're bailing out of here. The other reference is | |
| 227 | − * dropped when the intent hits the AIL. If the transaction | |
| 228 | − * was not committed, the intent is freed by the intent item | |
| 229 | − * unlock handler on abort. | |
| 230 | − */ | |
| 231 | − if (!dop->dop_committed) | |
| 232 | − return; | |
| 233 | 224 | |
| 234 | − /* Abort intent items. */ | |
| 225 | + /* Abort intent items that don't have a done item. */ | |
| 235 | 226 | list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { |
| 236 | 227 | trace_xfs_defer_pending_abort(tp->t_mountp, dfp); |
| 237 | − if (!dfp->dfp_done) | |
| 228 | + if (dfp->dfp_intent && !dfp->dfp_done) { | |
| 238 | 229 | dfp->dfp_type->abort_intent(dfp->dfp_intent); |
| 230 | + dfp->dfp_intent = NULL; | |
| 231 | + } | |
| 239 | 232 | } |
| 240 | 233 | |
| 241 | 234 | /* Shut down FS. */ |
| @@ -230,72 +230,62 @@ struct acpi_table_facs { · 229 unmodified lines | ||
| 230 | 230 | /* Fields common to all versions of the FADT */ |
| 231 | 231 | |
| 232 | 232 | struct acpi_table_fadt { |
| 233 | − struct acpi_table_header header; /* [V1] Common ACPI table header */ | |
| 234 | − u32 facs; /* [V1] 32-bit physical address of FACS */ | |
| 235 | − u32 dsdt; /* [V1] 32-bit physical address of DSDT */ | |
| 236 | − u8 model; /* [V1] System Interrupt Model (ACPI 1.0) - not used in ACPI 2.0+ */ | |
| 237 | − u8 preferred_profile; /* [V1] Conveys preferred power management profile to OSPM. */ | |
| 238 | − u16 sci_interrupt; /* [V1] System vector of SCI interrupt */ | |
| 239 | − u32 smi_command; /* [V1] 32-bit Port address of SMI command port */ | |
| 240 | − u8 acpi_enable; /* [V1] Value to write to SMI_CMD to enable ACPI */ | |
| 241 | − u8 acpi_disable; /* [V1] Value to write to SMI_CMD to disable ACPI */ | |
| 242 | − u8 s4_bios_request; /* [V1] Value to write to SMI_CMD to enter S4BIOS state */ | |
| 243 | − u8 pstate_control; /* [V1] Processor performance state control */ | |
| 244 | − u32 pm1a_event_block; /* [V1] 32-bit port address of Power Mgt 1a Event Reg Blk */ | |
| 245 | − u32 pm1b_event_block; /* [V1] 32-bit port address of Power Mgt 1b Event Reg Blk */ | |
| 246 | − u32 pm1a_control_block; /* [V1] 32-bit port address of Power Mgt 1a Control Reg Blk */ | |
| 247 | − u32 pm1b_control_block; /* [V1] 32-bit port address of Power Mgt 1b Control Reg Blk */ | |
| 248 | − u32 pm2_control_block; /* [V1] 32-bit port address of Power Mgt 2 Control Reg Blk */ | |
| 249 | − u32 pm_timer_block; /* [V1] 32-bit port address of Power Mgt Timer Ctrl Reg Blk */ | |
| 250 | − u32 gpe0_block; /* [V1] 32-bit port address of General Purpose Event 0 Reg Blk */ | |
| 251 | − u32 gpe1_block; /* [V1] 32-bit port address of General Purpose Event 1 Reg Blk */ | |
| 252 | − u8 pm1_event_length; /* [V1] Byte Length of ports at pm1x_event_block */ | |
| 253 | − u8 pm1_control_length; /* [V1] Byte Length of ports at pm1x_control_block */ | |
| 254 | − u8 pm2_control_length; /* [V1] Byte Length of ports at pm2_control_block */ | |
| 255 | − u8 pm_timer_length; /* [V1] Byte Length of ports at pm_timer_block */ | |
| 256 | − u8 gpe0_block_length; /* [V1] Byte Length of ports at gpe0_block */ | |
| 257 | − u8 gpe1_block_length; /* [V1] Byte Length of ports at gpe1_block */ | |
| 258 | − u8 gpe1_base; /* [V1] Offset in GPE number space where GPE1 events start */ | |
| 259 | − u8 cst_control; /* [V1] Support for the _CST object and C-States change notification */ | |
| 260 | − u16 c2_latency; /* [V1] Worst case HW latency to enter/exit C2 state */ | |
| 261 | − u16 c3_latency; /* [V1] Worst case HW latency to enter/exit C3 state */ | |
| 262 | − u16 flush_size; /* [V1] Processor memory cache line width, in bytes */ | |
| 263 | − u16 flush_stride; /* [V1] Number of flush strides that need to be read */ | |
| 264 | − u8 duty_offset; /* [V1] Processor duty cycle index in processor P_CNT reg */ | |
| 265 | − u8 duty_width; /* [V1] Processor duty cycle value bit width in P_CNT register */ | |
| 266 | − u8 day_alarm; /* [V1] Index to day-of-month alarm in RTC CMOS RAM */ | |
| 267 | − u8 month_alarm; /* [V1] Index to month-of-year alarm in RTC CMOS RAM */ | |
| 268 | − u8 century; /* [V1] Index to century in RTC CMOS RAM */ | |
| 269 | − u16 boot_flags; /* [V3] IA-PC Boot Architecture Flags (see below for individual flags) */ | |
| 270 | − u8 reserved; /* [V1] Reserved, must be zero */ | |
| 271 | − u32 flags; /* [V1] Miscellaneous flag bits (see below for individual flags) */ | |
| 272 | − /* End of Version 1 FADT fields (ACPI 1.0) */ | |
| 273 | − | |
| 274 | − struct acpi_generic_address reset_register; /* [V3] 64-bit address of the Reset register */ | |
| 275 | − u8 reset_value; /* [V3] Value to write to the reset_register port to reset the system */ | |
| 276 | − u16 arm_boot_flags; /* [V5] ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */ | |
| 277 | − u8 minor_revision; /* [V5] FADT Minor Revision (ACPI 5.1) */ | |
| 278 | − u64 Xfacs; /* [V3] 64-bit physical address of FACS */ | |
| 279 | − u64 Xdsdt; /* [V3] 64-bit physical address of DSDT */ | |
| 280 | − struct acpi_generic_address xpm1a_event_block; /* [V3] 64-bit Extended Power Mgt 1a Event Reg Blk address */ | |
| 281 | − struct acpi_generic_address xpm1b_event_block; /* [V3] 64-bit Extended Power Mgt 1b Event Reg Blk address */ | |
| 282 | − struct acpi_generic_address xpm1a_control_block; /* [V3] 64-bit Extended Power Mgt 1a Control Reg Blk address */ | |
| 283 | − struct acpi_generic_address xpm1b_control_block; /* [V3] 64-bit Extended Power Mgt 1b Control Reg Blk address */ | |
| 284 | − struct acpi_generic_address xpm2_control_block; /* [V3] 64-bit Extended Power Mgt 2 Control Reg Blk address */ | |
| 285 | − struct acpi_generic_address xpm_timer_block; /* [V3] 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ | |
| 286 | − struct acpi_generic_address xgpe0_block; /* [V3] 64-bit Extended General Purpose Event 0 Reg Blk address */ | |
| 287 | − struct acpi_generic_address xgpe1_block; /* [V3] 64-bit Extended General Purpose Event 1 Reg Blk address */ | |
| 288 | − /* End of Version 3 FADT fields (ACPI 2.0) */ | |
| 289 | − | |
| 290 | − struct acpi_generic_address sleep_control; /* [V4] 64-bit Sleep Control register (ACPI 5.0) */ | |
| 291 | − /* End of Version 4 FADT fields (ACPI 3.0 and ACPI 4.0) (Field was originally reserved in ACPI 3.0) */ | |
| 292 | − | |
| 293 | − struct acpi_generic_address sleep_status; /* [V5] 64-bit Sleep Status register (ACPI 5.0) */ | |
| 294 | − /* End of Version 5 FADT fields (ACPI 5.0) */ | |
| 295 | − | |
| 296 | − u64 hypervisor_id; /* [V6] Hypervisor Vendor ID (ACPI 6.0) */ | |
| 297 | − /* End of Version 6 FADT fields (ACPI 6.0) */ | |
| 298 | − | |
| 233 | + struct acpi_table_header header; /* Common ACPI table header */ | |
| 234 | + u32 facs; /* 32-bit physical address of FACS */ | |
| 235 | + u32 dsdt; /* 32-bit physical address of DSDT */ | |
| 236 | + u8 model; /* System Interrupt Model (ACPI 1.0) - not used in ACPI 2.0+ */ | |
| 237 | + u8 preferred_profile; /* Conveys preferred power management profile to OSPM. */ | |
| 238 | + u16 sci_interrupt; /* System vector of SCI interrupt */ | |
| 239 | + u32 smi_command; /* 32-bit Port address of SMI command port */ | |
| 240 | + u8 acpi_enable; /* Value to write to SMI_CMD to enable ACPI */ | |
| 241 | + u8 acpi_disable; /* Value to write to SMI_CMD to disable ACPI */ | |
| 242 | + u8 s4_bios_request; /* Value to write to SMI_CMD to enter S4BIOS state */ | |
| 243 | + u8 pstate_control; /* Processor performance state control */ | |
| 244 | + u32 pm1a_event_block; /* 32-bit port address of Power Mgt 1a Event Reg Blk */ | |
| 245 | + u32 pm1b_event_block; /* 32-bit port address of Power Mgt 1b Event Reg Blk */ | |
| 246 | + u32 pm1a_control_block; /* 32-bit port address of Power Mgt 1a Control Reg Blk */ | |
| 247 | + u32 pm1b_control_block; /* 32-bit port address of Power Mgt 1b Control Reg Blk */ | |
| 248 | + u32 pm2_control_block; /* 32-bit port address of Power Mgt 2 Control Reg Blk */ | |
| 249 | + u32 pm_timer_block; /* 32-bit port address of Power Mgt Timer Ctrl Reg Blk */ | |
| 250 | + u32 gpe0_block; /* 32-bit port address of General Purpose Event 0 Reg Blk */ | |
| 251 | + u32 gpe1_block; /* 32-bit port address of General Purpose Event 1 Reg Blk */ | |
| 252 | + u8 pm1_event_length; /* Byte Length of ports at pm1x_event_block */ | |
| 253 | + u8 pm1_control_length; /* Byte Length of ports at pm1x_control_block */ | |
| 254 | + u8 pm2_control_length; /* Byte Length of ports at pm2_control_block */ | |
| 255 | + u8 pm_timer_length; /* Byte Length of ports at pm_timer_block */ | |
| 256 | + u8 gpe0_block_length; /* Byte Length of ports at gpe0_block */ | |
| 257 | + u8 gpe1_block_length; /* Byte Length of ports at gpe1_block */ | |
| 258 | + u8 gpe1_base; /* Offset in GPE number space where GPE1 events start */ | |
| 259 | + u8 cst_control; /* Support for the _CST object and C-States change notification */ | |
| 260 | + u16 c2_latency; /* Worst case HW latency to enter/exit C2 state */ | |
| 261 | + u16 c3_latency; /* Worst case HW latency to enter/exit C3 state */ | |
| 262 | + u16 flush_size; /* Processor memory cache line width, in bytes */ | |
| 263 | + u16 flush_stride; /* Number of flush strides that need to be read */ | |
| 264 | + u8 duty_offset; /* Processor duty cycle index in processor P_CNT reg */ | |
| 265 | + u8 duty_width; /* Processor duty cycle value bit width in P_CNT register */ | |
| 266 | + u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */ | |
| 267 | + u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */ | |
| 268 | + u8 century; /* Index to century in RTC CMOS RAM */ | |
| 269 | + u16 boot_flags; /* IA-PC Boot Architecture Flags (see below for individual flags) */ | |
| 270 | + u8 reserved; /* Reserved, must be zero */ | |
| 271 | + u32 flags; /* Miscellaneous flag bits (see below for individual flags) */ | |
| 272 | + struct acpi_generic_address reset_register; /* 64-bit address of the Reset register */ | |
| 273 | + u8 reset_value; /* Value to write to the reset_register port to reset the system */ | |
| 274 | + u16 arm_boot_flags; /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */ | |
| 275 | + u8 minor_revision; /* FADT Minor Revision (ACPI 5.1) */ | |
| 276 | + u64 Xfacs; /* 64-bit physical address of FACS */ | |
| 277 | + u64 Xdsdt; /* 64-bit physical address of DSDT */ | |
| 278 | + struct acpi_generic_address xpm1a_event_block; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */ | |
| 279 | + struct acpi_generic_address xpm1b_event_block; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */ | |
| 280 | + struct acpi_generic_address xpm1a_control_block; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */ | |
| 281 | + struct acpi_generic_address xpm1b_control_block; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */ | |
| 282 | + struct acpi_generic_address xpm2_control_block; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */ | |
| 283 | + struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ | |
| 284 | + struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */ | |
| 285 | + struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ | |
| 286 | + struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register (ACPI 5.0) */ | |
| 287 | + struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register (ACPI 5.0) */ | |
| 288 | + u64 hypervisor_id; /* Hypervisor Vendor ID (ACPI 6.0) */ | |
| 299 | 289 | }; |
| 300 | 290 | |
| 301 | 291 | /* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) [Vx]=Introduced in this FADT revision */ |
| @@ -311,8 +301,8 @@ struct acpi_table_fadt { · 9 unmodified lines | ||
| 311 | 301 | |
| 312 | 302 | /* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */ |
| 313 | 303 | |
| 314 | −#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5] PSCI 0.2+ is implemented */ | |
| 315 | −#define ACPI_FADT_PSCI_USE_HVC (1<<1) /* 01: [V5] HVC must be used instead of SMC as the PSCI conduit */ | |
| 304 | +#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is implemented */ | |
| 305 | +#define ACPI_FADT_PSCI_USE_HVC (1<<1) /* 01: [V5+] HVC must be used instead of SMC as the PSCI conduit */ | |
| 316 | 306 | |
| 317 | 307 | /* Masks for FADT flags */ |
| 318 | 308 | |
| @@ -409,34 +399,20 @@ struct acpi_table_desc { · 90 unmodified lines | ||
| 409 | 399 | * match the expected length. In other words, the length of the |
| 410 | 400 | * FADT is the bottom line as to what the version really is. |
| 411 | 401 | * |
| 412 | − * NOTE: There is no officialy released V2 of the FADT. This | |
| 413 | − * version was used only for prototyping and testing during the | |
| 414 | − * 32-bit to 64-bit transition. V3 was the first official 64-bit | |
| 415 | − * version of the FADT. | |
| 416 | − * | |
| 417 | − * Update this list of defines when a new version of the FADT is | |
| 418 | − * added to the ACPI specification. Note that the FADT version is | |
| 419 | − * only incremented when new fields are appended to the existing | |
| 420 | − * version. Therefore, the FADT version is competely independent | |
| 421 | − * from the version of the ACPI specification where it is | |
| 422 | − * defined. | |
| 423 | − * | |
| 424 | − * For reference, the various FADT lengths are as follows: | |
| 425 | − * FADT V1 size: 0x074 ACPI 1.0 | |
| 426 | − * FADT V3 size: 0x0F4 ACPI 2.0 | |
| 427 | − * FADT V4 size: 0x100 ACPI 3.0 and ACPI 4.0 | |
| 428 | − * FADT V5 size: 0x10C ACPI 5.0 | |
| 429 | − * FADT V6 size: 0x114 ACPI 6.0 | |
| 402 | + * For reference, the values below are as follows: | |
| 403 | + * FADT V1 size: 0x074 | |
| 404 | + * FADT V2 size: 0x084 | |
| 405 | + * FADT V3 size: 0x0F4 | |
| 406 | + * FADT V4 size: 0x0F4 | |
| 407 | + * FADT V5 size: 0x10C | |
| 408 | + * FADT V6 size: 0x114 | |
| 430 | 409 | */ |
| 431 | −#define ACPI_FADT_V1_SIZE (u32) (ACPI_FADT_OFFSET (flags) + 4) /* ACPI 1.0 */ | |
| 432 | −#define ACPI_FADT_V3_SIZE (u32) (ACPI_FADT_OFFSET (sleep_control)) /* ACPI 2.0 */ | |
| 433 | −#define ACPI_FADT_V4_SIZE (u32) (ACPI_FADT_OFFSET (sleep_status)) /* ACPI 3.0 and ACPI 4.0 */ | |
| 434 | −#define ACPI_FADT_V5_SIZE (u32) (ACPI_FADT_OFFSET (hypervisor_id)) /* ACPI 5.0 */ | |
| 435 | −#define ACPI_FADT_V6_SIZE (u32) (sizeof (struct acpi_table_fadt)) /* ACPI 6.0 */ | |
| 436 | − | |
| 437 | −/* Update these when new FADT versions are added */ | |
| 410 | +#define ACPI_FADT_V1_SIZE (u32) (ACPI_FADT_OFFSET (flags) + 4) | |
| 411 | +#define ACPI_FADT_V2_SIZE (u32) (ACPI_FADT_OFFSET (minor_revision) + 1) | |
| 412 | +#define ACPI_FADT_V3_SIZE (u32) (ACPI_FADT_OFFSET (sleep_control)) | |
| 413 | +#define ACPI_FADT_V5_SIZE (u32) (ACPI_FADT_OFFSET (hypervisor_id)) | |
| 414 | +#define ACPI_FADT_V6_SIZE (u32) (sizeof (struct acpi_table_fadt)) | |
| 438 | 415 | |
| 439 | −#define ACPI_FADT_MAX_VERSION 6 | |
| 440 | 416 | #define ACPI_FADT_CONFORMANCE "ACPI 6.1 (FADT version 6)" |
| 441 | 417 | |
| 442 | 418 | #endif /* __ACTBL_H__ */ |
| @@ -191,6 +191,9 @@ · 190 unmodified lines | ||
| 191 | 191 | #ifndef __init |
| 192 | 192 | #define __init |
| 193 | 193 | #endif |
| 194 | +#ifndef __iomem | |
| 195 | +#define __iomem | |
| 196 | +#endif | |
| 194 | 197 | |
| 195 | 198 | /* Host-dependent types and defines for user-space ACPICA */ |
| 196 | 199 | |
| @@ -14,6 +14,8 @@ · 13 unmodified lines | ||
| 14 | 14 | * [_sdata, _edata]: contains .data.* sections, may also contain .rodata.* |
| 15 | 15 | * and/or .init.* sections. |
| 16 | 16 | * [__start_rodata, __end_rodata]: contains .rodata.* sections |
| 17 | + * [__start_data_ro_after_init, __end_data_ro_after_init]: | |
| 18 | + * contains data.ro_after_init section | |
| 17 | 19 | * [__init_begin, __init_end]: contains .init.* sections, but .init.text.* |
| 18 | 20 | * may be out of this range on some architectures. |
| 19 | 21 | * [_sinittext, _einittext]: contains .init.text.* sections |
| @@ -31,6 +33,7 @@ extern char _data[], _sdata[], _edata[]; · 11 unmodified lines | ||
| 31 | 33 | extern char __bss_start[], __bss_stop[]; |
| 32 | 34 | extern char __init_begin[], __init_end[]; |
| 33 | 35 | extern char _sinittext[], _einittext[]; |
| 36 | +extern char __start_data_ro_after_init[], __end_data_ro_after_init[]; | |
| 34 | 37 | extern char _end[]; |
| 35 | 38 | extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[]; |
| 36 | 39 | extern char __kprobes_text_start[], __kprobes_text_end[]; |
| @@ -259,7 +259,10 @@ · 258 unmodified lines | ||
| 259 | 259 | * own by defining an empty RO_AFTER_INIT_DATA. |
| 260 | 260 | */ |
| 261 | 261 | #ifndef RO_AFTER_INIT_DATA |
| 262 | −#define RO_AFTER_INIT_DATA *(.data..ro_after_init) | |
| 262 | +#define RO_AFTER_INIT_DATA \ | |
| 263 | + __start_data_ro_after_init = .; \ | |
| 264 | + *(.data..ro_after_init) \ | |
| 265 | + __end_data_ro_after_init = .; | |
| 263 | 266 | #endif |
| 264 | 267 | |
| 265 | 268 | /* |
| @@ -555,7 +555,8 @@ int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *); · 554 unmodified lines | ||
| 555 | 555 | int acpi_device_modalias(struct device *, char *, int); |
| 556 | 556 | void acpi_walk_dep_device_list(acpi_handle handle); |
| 557 | 557 | |
| 558 | −struct platform_device *acpi_create_platform_device(struct acpi_device *); | |
| 558 | +struct platform_device *acpi_create_platform_device(struct acpi_device *, | |
| 559 | + struct property_entry *); | |
| 559 | 560 | #define ACPI_PTR(_ptr) (_ptr) |
| 560 | 561 | |
| 561 | 562 | static inline void acpi_device_set_enumerated(struct acpi_device *adev) |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | * are obviously wrong for any sort of memory access. |
| 15 | 15 | */ |
| 16 | 16 | #define BPF_REGISTER_MAX_RANGE (1024 * 1024 * 1024) |
| 17 | −#define BPF_REGISTER_MIN_RANGE -(1024 * 1024 * 1024) | |
| 17 | +#define BPF_REGISTER_MIN_RANGE -1 | |
| 18 | 18 | |
| 19 | 19 | struct bpf_reg_state { |
| 20 | 20 | enum bpf_reg_type type; |
| @@ -22,7 +22,8 @@ struct bpf_reg_state { · 1 unmodified line | ||
| 22 | 22 | * Used to determine if any memory access using this register will |
| 23 | 23 | * result in a bad access. |
| 24 | 24 | */ |
| 25 | − u64 min_value, max_value; | |
| 25 | + s64 min_value; | |
| 26 | + u64 max_value; | |
| 26 | 27 | union { |
| 27 | 28 | /* valid when type == CONST_IMM | PTR_TO_STACK | UNKNOWN_VALUE */ |
| 28 | 29 | s64 imm; |
| @@ -258,6 +258,8 @@ struct ceph_watch_item { · 257 unmodified lines | ||
| 258 | 258 | struct ceph_entity_addr addr; |
| 259 | 259 | }; |
| 260 | 260 | |
| 261 | +#define CEPH_LINGER_ID_START 0xffff000000000000ULL | |
| 262 | + | |
| 261 | 263 | struct ceph_osd_client { |
| 262 | 264 | struct ceph_client *client; |
| 263 | 265 | |
| @@ -173,12 +173,6 @@ static inline void console_sysfs_notify(void) · 172 unmodified lines | ||
| 173 | 173 | #endif |
| 174 | 174 | extern bool console_suspend_enabled; |
| 175 | 175 | |
| 176 | −#ifdef CONFIG_OF | |
| 177 | −extern void console_set_by_of(void); | |
| 178 | −#else | |
| 179 | −static inline void console_set_by_of(void) {} | |
| 180 | −#endif | |
| 181 | − | |
| 182 | 176 | /* Suspend and resume console messages over PM events */ |
| 183 | 177 | extern void suspend_console(void); |
| 184 | 178 | extern void resume_console(void); |
| @@ -106,8 +106,9 @@ static inline void frontswap_invalidate_area(unsigned type) · 105 unmodified lines | ||
| 106 | 106 | |
| 107 | 107 | static inline void frontswap_init(unsigned type, unsigned long *map) |
| 108 | 108 | { |
| 109 | − if (frontswap_enabled()) | |
| 110 | − __frontswap_init(type, map); | |
| 109 | +#ifdef CONFIG_FRONTSWAP | |
| 110 | + __frontswap_init(type, map); | |
| 111 | +#endif | |
| 111 | 112 | } |
| 112 | 113 | |
| 113 | 114 | #endif /* _LINUX_FRONTSWAP_H */ |
| @@ -321,6 +321,7 @@ struct writeback_control; · 320 unmodified lines | ||
| 321 | 321 | #define IOCB_HIPRI (1 << 3) |
| 322 | 322 | #define IOCB_DSYNC (1 << 4) |
| 323 | 323 | #define IOCB_SYNC (1 << 5) |
| 324 | +#define IOCB_WRITE (1 << 6) | |
| 324 | 325 | |
| 325 | 326 | struct kiocb { |
| 326 | 327 | struct file *ki_filp; |
| @@ -1709,7 +1710,6 @@ struct file_operations { · 1382 unmodified lines | ||
| 1709 | 1710 | int (*flush) (struct file *, fl_owner_t id); |
| 1710 | 1711 | int (*release) (struct inode *, struct file *); |
| 1711 | 1712 | int (*fsync) (struct file *, loff_t, loff_t, int datasync); |
| 1712 | − int (*aio_fsync) (struct kiocb *, int datasync); | |
| 1713 | 1713 | int (*fasync) (int, struct file *, int); |
| 1714 | 1714 | int (*lock) (struct file *, int, struct file_lock *); |
| 1715 | 1715 | ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); |
| @@ -22,7 +22,7 @@ extern int mincore_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, · 21 unmodified lines | ||
| 22 | 22 | unsigned char *vec); |
| 23 | 23 | extern bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr, |
| 24 | 24 | unsigned long new_addr, unsigned long old_end, |
| 25 | − pmd_t *old_pmd, pmd_t *new_pmd); | |
| 25 | + pmd_t *old_pmd, pmd_t *new_pmd, bool *need_flush); | |
| 26 | 26 | extern int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, |
| 27 | 27 | unsigned long addr, pgprot_t newprot, |
| 28 | 28 | int prot_numa); |
| @@ -149,7 +149,7 @@ static inline bool inet6_exact_dif_match(struct net *net, struct sk_buff *skb) · 148 unmodified lines | ||
| 149 | 149 | { |
| 150 | 150 | #if defined(CONFIG_NET_L3_MASTER_DEV) |
| 151 | 151 | if (!net->ipv4.sysctl_tcp_l3mdev_accept && |
| 152 | − ipv6_l3mdev_skb(IP6CB(skb)->flags)) | |
| 152 | + skb && ipv6_l3mdev_skb(IP6CB(skb)->flags)) | |
| 153 | 153 | return true; |
| 154 | 154 | #endif |
| 155 | 155 | return false; |
| @@ -3354,6 +3354,21 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb); · 3353 unmodified lines | ||
| 3354 | 3354 | bool is_skb_forwardable(const struct net_device *dev, |
| 3355 | 3355 | const struct sk_buff *skb); |
| 3356 | 3356 | |
| 3357 | +static __always_inline int ____dev_forward_skb(struct net_device *dev, | |
| 3358 | + struct sk_buff *skb) | |
| 3359 | +{ | |
| 3360 | + if (skb_orphan_frags(skb, GFP_ATOMIC) || | |
| 3361 | + unlikely(!is_skb_forwardable(dev, skb))) { | |
| 3362 | + atomic_long_inc(&dev->rx_dropped); | |
| 3363 | + kfree_skb(skb); | |
| 3364 | + return NET_RX_DROP; | |
| 3365 | + } | |
| 3366 | + | |
| 3367 | + skb_scrub_packet(skb, true); | |
| 3368 | + skb->priority = 0; | |
| 3369 | + return 0; | |
| 3370 | +} | |
| 3371 | + | |
| 3357 | 3372 | void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev); |
| 3358 | 3373 | |
| 3359 | 3374 | extern int netdev_budget; |
| @@ -253,6 +253,13 @@ static inline int phy_set_mode(struct phy *phy, enum phy_mode mode) · 252 unmodified lines | ||
| 253 | 253 | return -ENOSYS; |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | +static inline int phy_reset(struct phy *phy) | |
| 257 | +{ | |
| 258 | + if (!phy) | |
| 259 | + return 0; | |
| 260 | + return -ENOSYS; | |
| 261 | +} | |
| 262 | + | |
| 256 | 263 | static inline int phy_get_bus_width(struct phy *phy) |
| 257 | 264 | { |
| 258 | 265 | return -ENOSYS; |
| @@ -25,6 +25,7 @@ struct svc_xprt_ops { · 24 unmodified lines | ||
| 25 | 25 | void (*xpo_detach)(struct svc_xprt *); |
| 26 | 26 | void (*xpo_free)(struct svc_xprt *); |
| 27 | 27 | int (*xpo_secure_port)(struct svc_rqst *); |
| 28 | + void (*xpo_kill_temp_xprt)(struct svc_xprt *); | |
| 28 | 29 | }; |
| 29 | 30 | |
| 30 | 31 | struct svc_xprt_class { |
| @@ -68,6 +68,9 @@ static inline int gro_cells_init(struct gro_cells *gcells, struct net_device *de · 67 unmodified lines | ||
| 68 | 68 | struct gro_cell *cell = per_cpu_ptr(gcells->cells, i); |
| 69 | 69 | |
| 70 | 70 | __skb_queue_head_init(&cell->napi_skbs); |
| 71 | + | |
| 72 | + set_bit(NAPI_STATE_NO_BUSY_POLL, &cell->napi.state); | |
| 73 | + | |
| 71 | 74 | netif_napi_add(dev, &cell->napi, gro_cell_poll, 64); |
| 72 | 75 | napi_enable(&cell->napi); |
| 73 | 76 | } |
| @@ -47,8 +47,7 @@ struct inet_skb_parm { · 46 unmodified lines | ||
| 47 | 47 | #define IPSKB_REROUTED BIT(4) |
| 48 | 48 | #define IPSKB_DOREDIRECT BIT(5) |
| 49 | 49 | #define IPSKB_FRAG_PMTU BIT(6) |
| 50 | −#define IPSKB_FRAG_SEGS BIT(7) | |
| 51 | −#define IPSKB_L3SLAVE BIT(8) | |
| 50 | +#define IPSKB_L3SLAVE BIT(7) | |
| 52 | 51 | |
| 53 | 52 | u16 frag_max_size; |
| 54 | 53 | }; |
| @@ -146,6 +146,7 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, · 145 unmodified lines | ||
| 146 | 146 | { |
| 147 | 147 | int pkt_len, err; |
| 148 | 148 | |
| 149 | + memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); | |
| 149 | 150 | pkt_len = skb->len - skb_inner_network_offset(skb); |
| 150 | 151 | err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb); |
| 151 | 152 | if (unlikely(net_xmit_eval(err))) |
| @@ -243,6 +243,7 @@ int fib_table_dump(struct fib_table *table, struct sk_buff *skb, · 242 unmodified lines | ||
| 243 | 243 | struct netlink_callback *cb); |
| 244 | 244 | int fib_table_flush(struct net *net, struct fib_table *table); |
| 245 | 245 | struct fib_table *fib_trie_unmerge(struct fib_table *main_tb); |
| 246 | +void fib_table_flush_external(struct fib_table *table); | |
| 246 | 247 | void fib_free_table(struct fib_table *tb); |
| 247 | 248 | |
| 248 | 249 | #ifndef CONFIG_IP_MULTIPLE_TABLES |
| @@ -170,7 +170,7 @@ static inline struct net *copy_net_ns(unsigned long flags, · 169 unmodified lines | ||
| 170 | 170 | extern struct list_head net_namespace_list; |
| 171 | 171 | |
| 172 | 172 | struct net *get_net_ns_by_pid(pid_t pid); |
| 173 | −struct net *get_net_ns_by_fd(int pid); | |
| 173 | +struct net *get_net_ns_by_fd(int fd); | |
| 174 | 174 | |
| 175 | 175 | #ifdef CONFIG_SYSCTL |
| 176 | 176 | void ipx_register_sysctl(void); |
| @@ -30,8 +30,7 @@ static inline struct nf_conn_labels *nf_ct_labels_ext_add(struct nf_conn *ct) · 29 unmodified lines | ||
| 30 | 30 | if (net->ct.labels_used == 0) |
| 31 | 31 | return NULL; |
| 32 | 32 | |
| 33 | − return nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS, | |
| 34 | − sizeof(struct nf_conn_labels), GFP_ATOMIC); | |
| 33 | + return nf_ct_ext_add(ct, NF_CT_EXT_LABELS, GFP_ATOMIC); | |
| 35 | 34 | #else |
| 36 | 35 | return NULL; |
| 37 | 36 | #endif |
| @@ -145,7 +145,7 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) · 144 unmodified lines | ||
| 145 | 145 | return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE; |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | −unsigned int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest); | |
| 148 | +int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest); | |
| 149 | 149 | unsigned int nft_parse_register(const struct nlattr *attr); |
| 150 | 150 | int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg); |
| 151 | 151 | |
| @@ -542,7 +542,8 @@ void *nft_set_elem_init(const struct nft_set *set, · 390 unmodified lines | ||
| 542 | 542 | const struct nft_set_ext_tmpl *tmpl, |
| 543 | 543 | const u32 *key, const u32 *data, |
| 544 | 544 | u64 timeout, gfp_t gfp); |
| 545 | −void nft_set_elem_destroy(const struct nft_set *set, void *elem); | |
| 545 | +void nft_set_elem_destroy(const struct nft_set *set, void *elem, | |
| 546 | + bool destroy_expr); | |
| 546 | 547 | |
| 547 | 548 | /** |
| 548 | 549 | * struct nft_set_gc_batch_head - nf_tables set garbage collection batch |
| @@ -693,7 +694,6 @@ static inline int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src) · 144 unmodified lines | ||
| 693 | 694 | { |
| 694 | 695 | int err; |
| 695 | 696 | |
| 696 | − __module_get(src->ops->type->owner); | |
| 697 | 697 | if (src->ops->clone) { |
| 698 | 698 | dst->ops = src->ops; |
| 699 | 699 | err = src->ops->clone(dst, src); |
| @@ -702,6 +702,8 @@ static inline int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src) · 2 unmodified lines | ||
| 702 | 702 | } else { |
| 703 | 703 | memcpy(dst, src, src->ops->size); |
| 704 | 704 | } |
| 705 | + | |
| 706 | + __module_get(src->ops->type->owner); | |
| 705 | 707 | return 0; |
| 706 | 708 | } |
| 707 | 709 | |
| @@ -152,7 +152,7 @@ void sctp_unhash_endpoint(struct sctp_endpoint *); · 151 unmodified lines | ||
| 152 | 152 | struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *, |
| 153 | 153 | struct sctphdr *, struct sctp_association **, |
| 154 | 154 | struct sctp_transport **); |
| 155 | −void sctp_err_finish(struct sock *, struct sctp_association *); | |
| 155 | +void sctp_err_finish(struct sock *, struct sctp_transport *); | |
| 156 | 156 | void sctp_icmp_frag_needed(struct sock *, struct sctp_association *, |
| 157 | 157 | struct sctp_transport *t, __u32 pmtu); |
| 158 | 158 | void sctp_icmp_redirect(struct sock *, struct sctp_transport *, |
| @@ -1596,11 +1596,11 @@ static inline void sock_put(struct sock *sk) · 1595 unmodified lines | ||
| 1596 | 1596 | void sock_gen_put(struct sock *sk); |
| 1597 | 1597 | |
| 1598 | 1598 | int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested, |
| 1599 | − unsigned int trim_cap); | |
| 1599 | + unsigned int trim_cap, bool refcounted); | |
| 1600 | 1600 | static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb, |
| 1601 | 1601 | const int nested) |
| 1602 | 1602 | { |
| 1603 | − return __sk_receive_skb(sk, skb, nested, 1); | |
| 1603 | + return __sk_receive_skb(sk, skb, nested, 1, true); | |
| 1604 | 1604 | } |
| 1605 | 1605 | |
| 1606 | 1606 | static inline void sk_tx_queue_set(struct sock *sk, int tx_queue) |
| @@ -805,7 +805,7 @@ static inline bool inet_exact_dif_match(struct net *net, struct sk_buff *skb) · 804 unmodified lines | ||
| 805 | 805 | { |
| 806 | 806 | #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) |
| 807 | 807 | if (!net->ipv4.sysctl_tcp_l3mdev_accept && |
| 808 | − ipv4_l3mdev_skb(TCP_SKB_CB(skb)->header.h4.flags)) | |
| 808 | + skb && ipv4_l3mdev_skb(TCP_SKB_CB(skb)->header.h4.flags)) | |
| 809 | 809 | return true; |
| 810 | 810 | #endif |
| 811 | 811 | return false; |
| @@ -1220,6 +1220,7 @@ static inline void tcp_prequeue_init(struct tcp_sock *tp) · 408 unmodified lines | ||
| 1220 | 1220 | |
| 1221 | 1221 | bool tcp_prequeue(struct sock *sk, struct sk_buff *skb); |
| 1222 | 1222 | bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb); |
| 1223 | +int tcp_filter(struct sock *sk, struct sk_buff *skb); | |
| 1223 | 1224 | |
| 1224 | 1225 | #undef STATE_TRACE |
| 1225 | 1226 | |
| @@ -14,7 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #include <linux/atmapi.h> |
| 16 | 16 | #include <linux/atmioc.h> |
| 17 | −#include <linux/time.h> | |
| 18 | 17 | |
| 19 | 18 | #define ZATM_GETPOOL _IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc) |
| 20 | 19 | /* get pool statistics */ |
| @@ -5,9 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * Defines for the BPQETHER pseudo device driver |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | −#ifndef __LINUX_IF_ETHER_H | |
| 9 | 8 | #include <linux/if_ether.h> |
| 10 | −#endif | |
| 11 | 9 | |
| 12 | 10 | #define SIOCSBPQETHOPT (SIOCDEVPRIVATE+0) /* reserved */ |
| 13 | 11 | #define SIOCSBPQETHADDR (SIOCDEVPRIVATE+1) |
| @@ -972,12 +972,19 @@ struct kvm_irqfd { · 971 unmodified lines | ||
| 972 | 972 | __u8 pad[16]; |
| 973 | 973 | }; |
| 974 | 974 | |
| 975 | +/* For KVM_CAP_ADJUST_CLOCK */ | |
| 976 | + | |
| 977 | +/* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags. */ | |
| 978 | +#define KVM_CLOCK_TSC_STABLE 2 | |
| 979 | + | |
| 975 | 980 | struct kvm_clock_data { |
| 976 | 981 | __u64 clock; |
| 977 | 982 | __u32 flags; |
| 978 | 983 | __u32 pad[9]; |
| 979 | 984 | }; |
| 980 | 985 | |
| 986 | +/* For KVM_CAP_SW_TLB */ | |
| 987 | + | |
| 981 | 988 | #define KVM_MMU_FSL_BOOKE_NOHV 0 |
| 982 | 989 | #define KVM_MMU_FSL_BOOKE_HV 1 |
| 983 | 990 | |
| @@ -687,7 +687,8 @@ static void delete_all_elements(struct bpf_htab *htab) · 686 unmodified lines | ||
| 687 | 687 | |
| 688 | 688 | hlist_for_each_entry_safe(l, n, head, hash_node) { |
| 689 | 689 | hlist_del_rcu(&l->hash_node); |
| 690 | − htab_elem_free(htab, l); | |
| 690 | + if (l->state != HTAB_EXTRA_ELEM_USED) | |
| 691 | + htab_elem_free(htab, l); | |
| 691 | 692 | } |
| 692 | 693 | } |
| 693 | 694 | } |
| @@ -194,7 +194,7 @@ static int map_create(union bpf_attr *attr) · 193 unmodified lines | ||
| 194 | 194 | |
| 195 | 195 | err = bpf_map_charge_memlock(map); |
| 196 | 196 | if (err) |
| 197 | − goto free_map; | |
| 197 | + goto free_map_nouncharge; | |
| 198 | 198 | |
| 199 | 199 | err = bpf_map_new_fd(map); |
| 200 | 200 | if (err < 0) |
| @@ -204,6 +204,8 @@ static int map_create(union bpf_attr *attr) · 3 unmodified lines | ||
| 204 | 204 | return err; |
| 205 | 205 | |
| 206 | 206 | free_map: |
| 207 | + bpf_map_uncharge_memlock(map); | |
| 208 | +free_map_nouncharge: | |
| 207 | 209 | map->ops->map_free(map); |
| 208 | 210 | return err; |
| 209 | 211 | } |
| @@ -216,8 +216,8 @@ static void print_verifier_state(struct bpf_verifier_state *state) · 215 unmodified lines | ||
| 216 | 216 | reg->map_ptr->key_size, |
| 217 | 217 | reg->map_ptr->value_size); |
| 218 | 218 | if (reg->min_value != BPF_REGISTER_MIN_RANGE) |
| 219 | − verbose(",min_value=%llu", | |
| 220 | − (unsigned long long)reg->min_value); | |
| 219 | + verbose(",min_value=%lld", | |
| 220 | + (long long)reg->min_value); | |
| 221 | 221 | if (reg->max_value != BPF_REGISTER_MAX_RANGE) |
| 222 | 222 | verbose(",max_value=%llu", |
| 223 | 223 | (unsigned long long)reg->max_value); |
| @@ -758,7 +758,7 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off, · 534 unmodified lines | ||
| 758 | 758 | * index'es we need to make sure that whatever we use |
| 759 | 759 | * will have a set floor within our range. |
| 760 | 760 | */ |
| 761 | − if ((s64)reg->min_value < 0) { | |
| 761 | + if (reg->min_value < 0) { | |
| 762 | 762 | verbose("R%d min value is negative, either use unsigned index or do a if (index >=0) check.\n", |
| 763 | 763 | regno); |
| 764 | 764 | return -EACCES; |
| @@ -1468,7 +1468,8 @@ static void check_reg_overflow(struct bpf_reg_state *reg) · 703 unmodified lines | ||
| 1468 | 1468 | { |
| 1469 | 1469 | if (reg->max_value > BPF_REGISTER_MAX_RANGE) |
| 1470 | 1470 | reg->max_value = BPF_REGISTER_MAX_RANGE; |
| 1471 | − if ((s64)reg->min_value < BPF_REGISTER_MIN_RANGE) | |
| 1471 | + if (reg->min_value < BPF_REGISTER_MIN_RANGE || | |
| 1472 | + reg->min_value > BPF_REGISTER_MAX_RANGE) | |
| 1472 | 1473 | reg->min_value = BPF_REGISTER_MIN_RANGE; |
| 1473 | 1474 | } |
| 1474 | 1475 | |
| @@ -1476,7 +1477,8 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, · 1 unmodified line | ||
| 1476 | 1477 | struct bpf_insn *insn) |
| 1477 | 1478 | { |
| 1478 | 1479 | struct bpf_reg_state *regs = env->cur_state.regs, *dst_reg; |
| 1479 | − u64 min_val = BPF_REGISTER_MIN_RANGE, max_val = BPF_REGISTER_MAX_RANGE; | |
| 1480 | + s64 min_val = BPF_REGISTER_MIN_RANGE; | |
| 1481 | + u64 max_val = BPF_REGISTER_MAX_RANGE; | |
| 1480 | 1482 | bool min_set = false, max_set = false; |
| 1481 | 1483 | u8 opcode = BPF_OP(insn->code); |
| 1482 | 1484 | |
| @@ -1512,22 +1514,43 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, · 29 unmodified lines | ||
| 1512 | 1514 | return; |
| 1513 | 1515 | } |
| 1514 | 1516 | |
| 1517 | + /* If one of our values was at the end of our ranges then we can't just | |
| 1518 | + * do our normal operations to the register, we need to set the values | |
| 1519 | + * to the min/max since they are undefined. | |
| 1520 | + */ | |
| 1521 | + if (min_val == BPF_REGISTER_MIN_RANGE) | |
| 1522 | + dst_reg->min_value = BPF_REGISTER_MIN_RANGE; | |
| 1523 | + if (max_val == BPF_REGISTER_MAX_RANGE) | |
| 1524 | + dst_reg->max_value = BPF_REGISTER_MAX_RANGE; | |
| 1525 | + | |
| 1515 | 1526 | switch (opcode) { |
| 1516 | 1527 | case BPF_ADD: |
| 1517 | − dst_reg->min_value += min_val; | |
| 1518 | − dst_reg->max_value += max_val; | |
| 1528 | + if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) | |
| 1529 | + dst_reg->min_value += min_val; | |
| 1530 | + if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | |
| 1531 | + dst_reg->max_value += max_val; | |
| 1519 | 1532 | break; |
| 1520 | 1533 | case BPF_SUB: |
| 1521 | − dst_reg->min_value -= min_val; | |
| 1522 | − dst_reg->max_value -= max_val; | |
| 1534 | + if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) | |
| 1535 | + dst_reg->min_value -= min_val; | |
| 1536 | + if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | |
| 1537 | + dst_reg->max_value -= max_val; | |
| 1523 | 1538 | break; |
| 1524 | 1539 | case BPF_MUL: |
| 1525 | − dst_reg->min_value *= min_val; | |
| 1526 | − dst_reg->max_value *= max_val; | |
| 1540 | + if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) | |
| 1541 | + dst_reg->min_value *= min_val; | |
| 1542 | + if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | |
| 1543 | + dst_reg->max_value *= max_val; | |
| 1527 | 1544 | break; |
| 1528 | 1545 | case BPF_AND: |
| 1529 | − /* & is special since it could end up with 0 bits set. */ | |
| 1530 | − dst_reg->min_value &= min_val; | |
| 1546 | + /* Disallow AND'ing of negative numbers, ain't nobody got time | |
| 1547 | + * for that. Otherwise the minimum is 0 and the max is the max | |
| 1548 | + * value we could AND against. | |
| 1549 | + */ | |
| 1550 | + if (min_val < 0) | |
| 1551 | + dst_reg->min_value = BPF_REGISTER_MIN_RANGE; | |
| 1552 | + else | |
| 1553 | + dst_reg->min_value = 0; | |
| 1531 | 1554 | dst_reg->max_value = max_val; |
| 1532 | 1555 | break; |
| 1533 | 1556 | case BPF_LSH: |
| @@ -1537,24 +1560,25 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, · 3 unmodified lines | ||
| 1537 | 1560 | */ |
| 1538 | 1561 | if (min_val > ilog2(BPF_REGISTER_MAX_RANGE)) |
| 1539 | 1562 | dst_reg->min_value = BPF_REGISTER_MIN_RANGE; |
| 1540 | − else | |
| 1563 | + else if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) | |
| 1541 | 1564 | dst_reg->min_value <<= min_val; |
| 1542 | 1565 | |
| 1543 | 1566 | if (max_val > ilog2(BPF_REGISTER_MAX_RANGE)) |
| 1544 | 1567 | dst_reg->max_value = BPF_REGISTER_MAX_RANGE; |
| 1545 | − else | |
| 1568 | + else if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | |
| 1546 | 1569 | dst_reg->max_value <<= max_val; |
| 1547 | 1570 | break; |
| 1548 | 1571 | case BPF_RSH: |
| 1549 | − dst_reg->min_value >>= min_val; | |
| 1550 | − dst_reg->max_value >>= max_val; | |
| 1551 | − break; | |
| 1552 | − case BPF_MOD: | |
| 1553 | − /* % is special since it is an unsigned modulus, so the floor | |
| 1554 | − * will always be 0. | |
| 1572 | + /* RSH by a negative number is undefined, and the BPF_RSH is an | |
| 1573 | + * unsigned shift, so make the appropriate casts. | |
| 1555 | 1574 | */ |
| 1556 | − dst_reg->min_value = 0; | |
| 1557 | − dst_reg->max_value = max_val - 1; | |
| 1575 | + if (min_val < 0 || dst_reg->min_value < 0) | |
| 1576 | + dst_reg->min_value = BPF_REGISTER_MIN_RANGE; | |
| 1577 | + else | |
| 1578 | + dst_reg->min_value = | |
| 1579 | + (u64)(dst_reg->min_value) >> min_val; | |
| 1580 | + if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) | |
| 1581 | + dst_reg->max_value >>= max_val; | |
| 1558 | 1582 | break; |
| 1559 | 1583 | default: |
| 1560 | 1584 | reset_reg_range_values(regs, insn->dst_reg); |
| @@ -1341,12 +1341,12 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) · 1340 unmodified lines | ||
| 1341 | 1341 | |
| 1342 | 1342 | } else if (new->flags & IRQF_TRIGGER_MASK) { |
| 1343 | 1343 | unsigned int nmsk = new->flags & IRQF_TRIGGER_MASK; |
| 1344 | − unsigned int omsk = irq_settings_get_trigger_mask(desc); | |
| 1344 | + unsigned int omsk = irqd_get_trigger_type(&desc->irq_data); | |
| 1345 | 1345 | |
| 1346 | 1346 | if (nmsk != omsk) |
| 1347 | 1347 | /* hope the handler works with current trigger mode */ |
| 1348 | 1348 | pr_warn("irq %d uses trigger mode %u; requested %u\n", |
| 1349 | − irq, nmsk, omsk); | |
| 1349 | + irq, omsk, nmsk); | |
| 1350 | 1350 | } |
| 1351 | 1351 | |
| 1352 | 1352 | *old_ptr = new; |
| @@ -45,6 +45,14 @@ enum { · 44 unmodified lines | ||
| 45 | 45 | #define LOCKF_USED_IN_IRQ_READ \ |
| 46 | 46 | (LOCKF_USED_IN_HARDIRQ_READ | LOCKF_USED_IN_SOFTIRQ_READ) |
| 47 | 47 | |
| 48 | +/* | |
| 49 | + * CONFIG_PROVE_LOCKING_SMALL is defined for sparc. Sparc requires .text, | |
| 50 | + * .data and .bss to fit in required 32MB limit for the kernel. With | |
| 51 | + * PROVE_LOCKING we could go over this limit and cause system boot-up problems. | |
| 52 | + * So, reduce the static allocations for lockdeps related structures so that | |
| 53 | + * everything fits in current required size limit. | |
| 54 | + */ | |
| 55 | +#ifdef CONFIG_PROVE_LOCKING_SMALL | |
| 48 | 56 | /* |
| 49 | 57 | * MAX_LOCKDEP_ENTRIES is the maximum number of lock dependencies |
| 50 | 58 | * we track. |
| @@ -54,18 +62,24 @@ enum { · 3 unmodified lines | ||
| 54 | 62 | * table (if it's not there yet), and we check it for lock order |
| 55 | 63 | * conflicts and deadlocks. |
| 56 | 64 | */ |
| 65 | +#define MAX_LOCKDEP_ENTRIES 16384UL | |
| 66 | +#define MAX_LOCKDEP_CHAINS_BITS 15 | |
| 67 | +#define MAX_STACK_TRACE_ENTRIES 262144UL | |
| 68 | +#else | |
| 57 | 69 | #define MAX_LOCKDEP_ENTRIES 32768UL |
| 58 | 70 | |
| 59 | 71 | #define MAX_LOCKDEP_CHAINS_BITS 16 |
| 60 | −#define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS) | |
| 61 | − | |
| 62 | −#define MAX_LOCKDEP_CHAIN_HLOCKS (MAX_LOCKDEP_CHAINS*5) | |
| 63 | 72 | |
| 64 | 73 | /* |
| 65 | 74 | * Stack-trace: tightly packed array of stack backtrace |
| 66 | 75 | * addresses. Protected by the hash_lock. |
| 67 | 76 | */ |
| 68 | 77 | #define MAX_STACK_TRACE_ENTRIES 524288UL |
| 78 | +#endif | |
| 79 | + | |
| 80 | +#define MAX_LOCKDEP_CHAINS (1UL << MAX_LOCKDEP_CHAINS_BITS) | |
| 81 | + | |
| 82 | +#define MAX_LOCKDEP_CHAIN_HLOCKS (MAX_LOCKDEP_CHAINS*5) | |
| 69 | 83 | |
| 70 | 84 | extern struct list_head all_lock_classes; |
| 71 | 85 | extern struct lock_chain lock_chains[]; |
| @@ -203,8 +203,10 @@ static int __init test_suspend(void) · 202 unmodified lines | ||
| 203 | 203 | |
| 204 | 204 | /* RTCs have initialized by now too ... can we use one? */ |
| 205 | 205 | dev = class_find_device(rtc_class, NULL, NULL, has_wakealarm); |
| 206 | − if (dev) | |
| 206 | + if (dev) { | |
| 207 | 207 | rtc = rtc_class_open(dev_name(dev)); |
| 208 | + put_device(dev); | |
| 209 | + } | |
| 208 | 210 | if (!rtc) { |
| 209 | 211 | printk(warn_no_rtc); |
| 210 | 212 | return 0; |
| @@ -253,17 +253,6 @@ static int preferred_console = -1; · 252 unmodified lines | ||
| 253 | 253 | int console_set_on_cmdline; |
| 254 | 254 | EXPORT_SYMBOL(console_set_on_cmdline); |
| 255 | 255 | |
| 256 | −#ifdef CONFIG_OF | |
| 257 | −static bool of_specified_console; | |
| 258 | − | |
| 259 | −void console_set_by_of(void) | |
| 260 | −{ | |
| 261 | − of_specified_console = true; | |
| 262 | −} | |
| 263 | −#else | |
| 264 | −# define of_specified_console false | |
| 265 | −#endif | |
| 266 | − | |
| 267 | 256 | /* Flag: console code may call schedule() */ |
| 268 | 257 | static int console_may_schedule; |
| 269 | 258 | |
| @@ -794,8 +783,6 @@ static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) · 524 unmodified lines | ||
| 794 | 783 | return ret; |
| 795 | 784 | } |
| 796 | 785 | |
| 797 | −static void cont_flush(void); | |
| 798 | − | |
| 799 | 786 | static ssize_t devkmsg_read(struct file *file, char __user *buf, |
| 800 | 787 | size_t count, loff_t *ppos) |
| 801 | 788 | { |
| @@ -811,7 +798,6 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, · 9 unmodified lines | ||
| 811 | 798 | if (ret) |
| 812 | 799 | return ret; |
| 813 | 800 | raw_spin_lock_irq(&logbuf_lock); |
| 814 | − cont_flush(); | |
| 815 | 801 | while (user->seq == log_next_seq) { |
| 816 | 802 | if (file->f_flags & O_NONBLOCK) { |
| 817 | 803 | ret = -EAGAIN; |
| @@ -874,7 +860,6 @@ static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence) · 56 unmodified lines | ||
| 874 | 860 | return -ESPIPE; |
| 875 | 861 | |
| 876 | 862 | raw_spin_lock_irq(&logbuf_lock); |
| 877 | − cont_flush(); | |
| 878 | 863 | switch (whence) { |
| 879 | 864 | case SEEK_SET: |
| 880 | 865 | /* the first record */ |
| @@ -913,7 +898,6 @@ static unsigned int devkmsg_poll(struct file *file, poll_table *wait) · 32 unmodified lines | ||
| 913 | 898 | poll_wait(file, &log_wait, wait); |
| 914 | 899 | |
| 915 | 900 | raw_spin_lock_irq(&logbuf_lock); |
| 916 | − cont_flush(); | |
| 917 | 901 | if (user->seq < log_next_seq) { |
| 918 | 902 | /* return error when data has vanished underneath us */ |
| 919 | 903 | if (user->seq < log_first_seq) |
| @@ -1300,7 +1284,6 @@ static int syslog_print(char __user *buf, int size) · 380 unmodified lines | ||
| 1300 | 1284 | size_t skip; |
| 1301 | 1285 | |
| 1302 | 1286 | raw_spin_lock_irq(&logbuf_lock); |
| 1303 | − cont_flush(); | |
| 1304 | 1287 | if (syslog_seq < log_first_seq) { |
| 1305 | 1288 | /* messages are gone, move to first one */ |
| 1306 | 1289 | syslog_seq = log_first_seq; |
| @@ -1360,7 +1343,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear) · 53 unmodified lines | ||
| 1360 | 1343 | return -ENOMEM; |
| 1361 | 1344 | |
| 1362 | 1345 | raw_spin_lock_irq(&logbuf_lock); |
| 1363 | − cont_flush(); | |
| 1364 | 1346 | if (buf) { |
| 1365 | 1347 | u64 next_seq; |
| 1366 | 1348 | u64 seq; |
| @@ -1522,7 +1504,6 @@ int do_syslog(int type, char __user *buf, int len, int source) · 155 unmodified lines | ||
| 1522 | 1504 | /* Number of chars in the log buffer */ |
| 1523 | 1505 | case SYSLOG_ACTION_SIZE_UNREAD: |
| 1524 | 1506 | raw_spin_lock_irq(&logbuf_lock); |
| 1525 | − cont_flush(); | |
| 1526 | 1507 | if (syslog_seq < log_first_seq) { |
| 1527 | 1508 | /* messages are gone, move to first one */ |
| 1528 | 1509 | syslog_seq = log_first_seq; |
| @@ -2657,7 +2638,7 @@ void register_console(struct console *newcon) · 1128 unmodified lines | ||
| 2657 | 2638 | * didn't select a console we take the first one |
| 2658 | 2639 | * that registers here. |
| 2659 | 2640 | */ |
| 2660 | − if (preferred_console < 0 && !of_specified_console) { | |
| 2641 | + if (preferred_console < 0) { | |
| 2661 | 2642 | if (newcon->index < 0) |
| 2662 | 2643 | newcon->index = 0; |
| 2663 | 2644 | if (newcon->setup == NULL || |
| @@ -3039,7 +3020,6 @@ void kmsg_dump(enum kmsg_dump_reason reason) · 375 unmodified lines | ||
| 3039 | 3020 | dumper->active = true; |
| 3040 | 3021 | |
| 3041 | 3022 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
| 3042 | − cont_flush(); | |
| 3043 | 3023 | dumper->cur_seq = clear_seq; |
| 3044 | 3024 | dumper->cur_idx = clear_idx; |
| 3045 | 3025 | dumper->next_seq = log_next_seq; |
| @@ -3130,7 +3110,6 @@ bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, · 84 unmodified lines | ||
| 3130 | 3110 | bool ret; |
| 3131 | 3111 | |
| 3132 | 3112 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
| 3133 | − cont_flush(); | |
| 3134 | 3113 | ret = kmsg_dump_get_line_nolock(dumper, syslog, line, size, len); |
| 3135 | 3114 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| 3136 | 3115 | |
| @@ -3173,7 +3152,6 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, · 36 unmodified lines | ||
| 3173 | 3152 | goto out; |
| 3174 | 3153 | |
| 3175 | 3154 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
| 3176 | − cont_flush(); | |
| 3177 | 3155 | if (dumper->cur_seq < log_first_seq) { |
| 3178 | 3156 | /* messages are gone, move to first available one */ |
| 3179 | 3157 | dumper->cur_seq = log_first_seq; |
| @@ -54,7 +54,11 @@ static const struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1 · 53 unmodified lines | ||
| 54 | 54 | [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING }, |
| 55 | 55 | [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },}; |
| 56 | 56 | |
| 57 | −static const struct nla_policy cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] = { | |
| 57 | +/* | |
| 58 | + * We have to use TASKSTATS_CMD_ATTR_MAX here, it is the maxattr in the family. | |
| 59 | + * Make sure they are always aligned. | |
| 60 | + */ | |
| 61 | +static const struct nla_policy cgroupstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = { | |
| 58 | 62 | [CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 }, |
| 59 | 63 | }; |
| 60 | 64 | |
| @@ -1862,6 +1862,10 @@ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops, · 1861 unmodified lines | ||
| 1862 | 1862 | |
| 1863 | 1863 | /* Update rec->flags */ |
| 1864 | 1864 | do_for_each_ftrace_rec(pg, rec) { |
| 1865 | + | |
| 1866 | + if (rec->flags & FTRACE_FL_DISABLED) | |
| 1867 | + continue; | |
| 1868 | + | |
| 1865 | 1869 | /* We need to update only differences of filter_hash */ |
| 1866 | 1870 | in_old = !!ftrace_lookup_ip(old_hash, rec->ip); |
| 1867 | 1871 | in_new = !!ftrace_lookup_ip(new_hash, rec->ip); |
| @@ -1884,6 +1888,10 @@ rollback: · 16 unmodified lines | ||
| 1884 | 1888 | |
| 1885 | 1889 | /* Roll back what we did above */ |
| 1886 | 1890 | do_for_each_ftrace_rec(pg, rec) { |
| 1891 | + | |
| 1892 | + if (rec->flags & FTRACE_FL_DISABLED) | |
| 1893 | + continue; | |
| 1894 | + | |
| 1887 | 1895 | if (rec == end) |
| 1888 | 1896 | goto err_out; |
| 1889 | 1897 | |
| @@ -2397,6 +2405,10 @@ void __weak ftrace_replace_code(int enable) · 507 unmodified lines | ||
| 2397 | 2405 | return; |
| 2398 | 2406 | |
| 2399 | 2407 | do_for_each_ftrace_rec(pg, rec) { |
| 2408 | + | |
| 2409 | + if (rec->flags & FTRACE_FL_DISABLED) | |
| 2410 | + continue; | |
| 2411 | + | |
| 2400 | 2412 | failed = __ftrace_replace_code(rec, enable); |
| 2401 | 2413 | if (failed) { |
| 2402 | 2414 | ftrace_bug(failed, rec); |
| @@ -2763,7 +2775,7 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) · 360 unmodified lines | ||
| 2763 | 2775 | struct dyn_ftrace *rec; |
| 2764 | 2776 | |
| 2765 | 2777 | do_for_each_ftrace_rec(pg, rec) { |
| 2766 | − if (FTRACE_WARN_ON_ONCE(rec->flags)) | |
| 2778 | + if (FTRACE_WARN_ON_ONCE(rec->flags & ~FTRACE_FL_DISABLED)) | |
| 2767 | 2779 | pr_warn(" %pS flags:%lx\n", |
| 2768 | 2780 | (void *)rec->ip, rec->flags); |
| 2769 | 2781 | } while_for_each_ftrace_rec(); |
| @@ -3598,6 +3610,10 @@ match_records(struct ftrace_hash *hash, char *func, int len, char *mod) · 828 unmodified lines | ||
| 3598 | 3610 | goto out_unlock; |
| 3599 | 3611 | |
| 3600 | 3612 | do_for_each_ftrace_rec(pg, rec) { |
| 3613 | + | |
| 3614 | + if (rec->flags & FTRACE_FL_DISABLED) | |
| 3615 | + continue; | |
| 3616 | + | |
| 3601 | 3617 | if (ftrace_match_record(rec, &func_g, mod_match, exclude_mod)) { |
| 3602 | 3618 | ret = enter_record(hash, rec, clear_filter); |
| 3603 | 3619 | if (ret < 0) { |
| @@ -3793,6 +3809,9 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, · 189 unmodified lines | ||
| 3793 | 3809 | |
| 3794 | 3810 | do_for_each_ftrace_rec(pg, rec) { |
| 3795 | 3811 | |
| 3812 | + if (rec->flags & FTRACE_FL_DISABLED) | |
| 3813 | + continue; | |
| 3814 | + | |
| 3796 | 3815 | if (!ftrace_match_record(rec, &func_g, NULL, 0)) |
| 3797 | 3816 | continue; |
| 3798 | 3817 | |
| @@ -4685,6 +4704,9 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer) · 886 unmodified lines | ||
| 4685 | 4704 | |
| 4686 | 4705 | do_for_each_ftrace_rec(pg, rec) { |
| 4687 | 4706 | |
| 4707 | + if (rec->flags & FTRACE_FL_DISABLED) | |
| 4708 | + continue; | |
| 4709 | + | |
| 4688 | 4710 | if (ftrace_match_record(rec, &func_g, NULL, 0)) { |
| 4689 | 4711 | /* if it is in the array */ |
| 4690 | 4712 | exists = false; |
| @@ -1085,6 +1085,9 @@ config PROVE_LOCKING · 1084 unmodified lines | ||
| 1085 | 1085 | |
| 1086 | 1086 | For more details, see Documentation/locking/lockdep-design.txt. |
| 1087 | 1087 | |
| 1088 | +config PROVE_LOCKING_SMALL | |
| 1089 | + bool | |
| 1090 | + | |
| 1088 | 1091 | config LOCKDEP |
| 1089 | 1092 | bool |
| 1090 | 1093 | depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT |
| @@ -683,10 +683,11 @@ static void pipe_advance(struct iov_iter *i, size_t size) · 682 unmodified lines | ||
| 683 | 683 | struct pipe_inode_info *pipe = i->pipe; |
| 684 | 684 | struct pipe_buffer *buf; |
| 685 | 685 | int idx = i->idx; |
| 686 | − size_t off = i->iov_offset; | |
| 686 | + size_t off = i->iov_offset, orig_sz; | |
| 687 | 687 | |
| 688 | 688 | if (unlikely(i->count < size)) |
| 689 | 689 | size = i->count; |
| 690 | + orig_sz = size; | |
| 690 | 691 | |
| 691 | 692 | if (size) { |
| 692 | 693 | if (off) /* make it relative to the beginning of buffer */ |
| @@ -713,6 +714,7 @@ static void pipe_advance(struct iov_iter *i, size_t size) · 20 unmodified lines | ||
| 713 | 714 | pipe->nrbufs--; |
| 714 | 715 | } |
| 715 | 716 | } |
| 717 | + i->count -= orig_sz; | |
| 716 | 718 | } |
| 717 | 719 | |
| 718 | 720 | void iov_iter_advance(struct iov_iter *i, size_t size) |
| @@ -192,6 +192,7 @@ void depot_fetch_stack(depot_stack_handle_t handle, struct stack_trace *trace) · 191 unmodified lines | ||
| 192 | 192 | trace->entries = stack->entries; |
| 193 | 193 | trace->skip = 0; |
| 194 | 194 | } |
| 195 | +EXPORT_SYMBOL_GPL(depot_fetch_stack); | |
| 195 | 196 | |
| 196 | 197 | /** |
| 197 | 198 | * depot_save_stack - save stack in a stack depot. |
| @@ -283,3 +284,4 @@ exit: · 85 unmodified lines | ||
| 283 | 284 | fast_exit: |
| 284 | 285 | return retval; |
| 285 | 286 | } |
| 287 | +EXPORT_SYMBOL_GPL(depot_save_stack); | |
| @@ -385,6 +385,9 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align) · 384 unmodified lines | ||
| 385 | 385 | bitmap_maxno = cma_bitmap_maxno(cma); |
| 386 | 386 | bitmap_count = cma_bitmap_pages_to_bits(cma, count); |
| 387 | 387 | |
| 388 | + if (bitmap_count > bitmap_maxno) | |
| 389 | + return NULL; | |
| 390 | + | |
| 388 | 391 | for (;;) { |
| 389 | 392 | mutex_lock(&cma->lock); |
| 390 | 393 | bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap, |
| @@ -1732,6 +1732,9 @@ find_page: · 1731 unmodified lines | ||
| 1732 | 1732 | if (inode->i_blkbits == PAGE_SHIFT || |
| 1733 | 1733 | !mapping->a_ops->is_partially_uptodate) |
| 1734 | 1734 | goto page_not_up_to_date; |
| 1735 | + /* pipes can't handle partially uptodate pages */ | |
| 1736 | + if (unlikely(iter->type & ITER_PIPE)) | |
| 1737 | + goto page_not_up_to_date; | |
| 1735 | 1738 | if (!trylock_page(page)) |
| 1736 | 1739 | goto page_not_up_to_date; |
| 1737 | 1740 | /* Did it get truncated before we got the lock? */ |
| @@ -1426,11 +1426,12 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, · 1425 unmodified lines | ||
| 1426 | 1426 | |
| 1427 | 1427 | bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr, |
| 1428 | 1428 | unsigned long new_addr, unsigned long old_end, |
| 1429 | − pmd_t *old_pmd, pmd_t *new_pmd) | |
| 1429 | + pmd_t *old_pmd, pmd_t *new_pmd, bool *need_flush) | |
| 1430 | 1430 | { |
| 1431 | 1431 | spinlock_t *old_ptl, *new_ptl; |
| 1432 | 1432 | pmd_t pmd; |
| 1433 | 1433 | struct mm_struct *mm = vma->vm_mm; |
| 1434 | + bool force_flush = false; | |
| 1434 | 1435 | |
| 1435 | 1436 | if ((old_addr & ~HPAGE_PMD_MASK) || |
| 1436 | 1437 | (new_addr & ~HPAGE_PMD_MASK) || |
| @@ -1455,6 +1456,8 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr, · 18 unmodified lines | ||
| 1455 | 1456 | new_ptl = pmd_lockptr(mm, new_pmd); |
| 1456 | 1457 | if (new_ptl != old_ptl) |
| 1457 | 1458 | spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING); |
| 1459 | + if (pmd_present(*old_pmd) && pmd_dirty(*old_pmd)) | |
| 1460 | + force_flush = true; | |
| 1458 | 1461 | pmd = pmdp_huge_get_and_clear(mm, old_addr, old_pmd); |
| 1459 | 1462 | VM_BUG_ON(!pmd_none(*new_pmd)); |
| 1460 | 1463 | |
| @@ -1467,6 +1470,10 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr, · 6 unmodified lines | ||
| 1467 | 1470 | set_pmd_at(mm, new_addr, new_pmd, pmd_mksoft_dirty(pmd)); |
| 1468 | 1471 | if (new_ptl != old_ptl) |
| 1469 | 1472 | spin_unlock(new_ptl); |
| 1473 | + if (force_flush) | |
| 1474 | + flush_tlb_range(vma, old_addr, old_addr + PMD_SIZE); | |
| 1475 | + else | |
| 1476 | + *need_flush = true; | |
| 1470 | 1477 | spin_unlock(old_ptl); |
| 1471 | 1478 | return true; |
| 1472 | 1479 | } |
| @@ -1826,11 +1826,17 @@ static void return_unused_surplus_pages(struct hstate *h, · 1825 unmodified lines | ||
| 1826 | 1826 | * is not the case is if a reserve map was changed between calls. It |
| 1827 | 1827 | * is the responsibility of the caller to notice the difference and |
| 1828 | 1828 | * take appropriate action. |
| 1829 | + * | |
| 1830 | + * vma_add_reservation is used in error paths where a reservation must | |
| 1831 | + * be restored when a newly allocated huge page must be freed. It is | |
| 1832 | + * to be called after calling vma_needs_reservation to determine if a | |
| 1833 | + * reservation exists. | |
| 1829 | 1834 | */ |
| 1830 | 1835 | enum vma_resv_mode { |
| 1831 | 1836 | VMA_NEEDS_RESV, |
| 1832 | 1837 | VMA_COMMIT_RESV, |
| 1833 | 1838 | VMA_END_RESV, |
| 1839 | + VMA_ADD_RESV, | |
| 1834 | 1840 | }; |
| 1835 | 1841 | static long __vma_reservation_common(struct hstate *h, |
| 1836 | 1842 | struct vm_area_struct *vma, unsigned long addr, |
| @@ -1856,6 +1862,14 @@ static long __vma_reservation_common(struct hstate *h, · 19 unmodified lines | ||
| 1856 | 1862 | region_abort(resv, idx, idx + 1); |
| 1857 | 1863 | ret = 0; |
| 1858 | 1864 | break; |
| 1865 | + case VMA_ADD_RESV: | |
| 1866 | + if (vma->vm_flags & VM_MAYSHARE) | |
| 1867 | + ret = region_add(resv, idx, idx + 1); | |
| 1868 | + else { | |
| 1869 | + region_abort(resv, idx, idx + 1); | |
| 1870 | + ret = region_del(resv, idx, idx + 1); | |
| 1871 | + } | |
| 1872 | + break; | |
| 1859 | 1873 | default: |
| 1860 | 1874 | BUG(); |
| 1861 | 1875 | } |
| @@ -1903,6 +1917,56 @@ static void vma_end_reservation(struct hstate *h, · 41 unmodified lines | ||
| 1903 | 1917 | (void)__vma_reservation_common(h, vma, addr, VMA_END_RESV); |
| 1904 | 1918 | } |
| 1905 | 1919 | |
| 1920 | +static long vma_add_reservation(struct hstate *h, | |
| 1921 | + struct vm_area_struct *vma, unsigned long addr) | |
| 1922 | +{ | |
| 1923 | + return __vma_reservation_common(h, vma, addr, VMA_ADD_RESV); | |
| 1924 | +} | |
| 1925 | + | |
| 1926 | +/* | |
| 1927 | + * This routine is called to restore a reservation on error paths. In the | |
| 1928 | + * specific error paths, a huge page was allocated (via alloc_huge_page) | |
| 1929 | + * and is about to be freed. If a reservation for the page existed, | |
| 1930 | + * alloc_huge_page would have consumed the reservation and set PagePrivate | |
| 1931 | + * in the newly allocated page. When the page is freed via free_huge_page, | |
| 1932 | + * the global reservation count will be incremented if PagePrivate is set. | |
| 1933 | + * However, free_huge_page can not adjust the reserve map. Adjust the | |
| 1934 | + * reserve map here to be consistent with global reserve count adjustments | |
| 1935 | + * to be made by free_huge_page. | |
| 1936 | + */ | |
| 1937 | +static void restore_reserve_on_error(struct hstate *h, | |
| 1938 | + struct vm_area_struct *vma, unsigned long address, | |
| 1939 | + struct page *page) | |
| 1940 | +{ | |
| 1941 | + if (unlikely(PagePrivate(page))) { | |
| 1942 | + long rc = vma_needs_reservation(h, vma, address); | |
| 1943 | + | |
| 1944 | + if (unlikely(rc < 0)) { | |
| 1945 | + /* | |
| 1946 | + * Rare out of memory condition in reserve map | |
| 1947 | + * manipulation. Clear PagePrivate so that | |
| 1948 | + * global reserve count will not be incremented | |
| 1949 | + * by free_huge_page. This will make it appear | |
| 1950 | + * as though the reservation for this page was | |
| 1951 | + * consumed. This may prevent the task from | |
| 1952 | + * faulting in the page at a later time. This | |
| 1953 | + * is better than inconsistent global huge page | |
| 1954 | + * accounting of reserve counts. | |
| 1955 | + */ | |
| 1956 | + ClearPagePrivate(page); | |
| 1957 | + } else if (rc) { | |
| 1958 | + rc = vma_add_reservation(h, vma, address); | |
| 1959 | + if (unlikely(rc < 0)) | |
| 1960 | + /* | |
| 1961 | + * See above comment about rare out of | |
| 1962 | + * memory condition. | |
| 1963 | + */ | |
| 1964 | + ClearPagePrivate(page); | |
| 1965 | + } else | |
| 1966 | + vma_end_reservation(h, vma, address); | |
| 1967 | + } | |
| 1968 | +} | |
| 1969 | + | |
| 1906 | 1970 | struct page *alloc_huge_page(struct vm_area_struct *vma, |
| 1907 | 1971 | unsigned long addr, int avoid_reserve) |
| 1908 | 1972 | { |
| @@ -3498,6 +3562,7 @@ retry_avoidcopy: · 1589 unmodified lines | ||
| 3498 | 3562 | spin_unlock(ptl); |
| 3499 | 3563 | mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); |
| 3500 | 3564 | out_release_all: |
| 3565 | + restore_reserve_on_error(h, vma, address, new_page); | |
| 3501 | 3566 | put_page(new_page); |
| 3502 | 3567 | out_release_old: |
| 3503 | 3568 | put_page(old_page); |
| @@ -3680,6 +3745,7 @@ backout: · 176 unmodified lines | ||
| 3680 | 3745 | spin_unlock(ptl); |
| 3681 | 3746 | backout_unlocked: |
| 3682 | 3747 | unlock_page(page); |
| 3748 | + restore_reserve_on_error(h, vma, address, page); | |
| 3683 | 3749 | put_page(page); |
| 3684 | 3750 | goto out; |
| 3685 | 3751 | } |
| @@ -1414,6 +1414,7 @@ static void kmemleak_scan(void) · 1413 unmodified lines | ||
| 1414 | 1414 | /* data/bss scanning */ |
| 1415 | 1415 | scan_large_block(_sdata, _edata); |
| 1416 | 1416 | scan_large_block(__bss_start, __bss_stop); |
| 1417 | + scan_large_block(__start_data_ro_after_init, __end_data_ro_after_init); | |
| 1417 | 1418 | |
| 1418 | 1419 | #ifdef CONFIG_SMP |
| 1419 | 1420 | /* per-cpu sections scanning */ |
| @@ -1112,10 +1112,10 @@ int memory_failure(unsigned long pfn, int trapno, int flags) · 1111 unmodified lines | ||
| 1112 | 1112 | } |
| 1113 | 1113 | |
| 1114 | 1114 | if (!PageHuge(p) && PageTransHuge(hpage)) { |
| 1115 | − lock_page(hpage); | |
| 1116 | − if (!PageAnon(hpage) || unlikely(split_huge_page(hpage))) { | |
| 1117 | − unlock_page(hpage); | |
| 1118 | − if (!PageAnon(hpage)) | |
| 1115 | + lock_page(p); | |
| 1116 | + if (!PageAnon(p) || unlikely(split_huge_page(p))) { | |
| 1117 | + unlock_page(p); | |
| 1118 | + if (!PageAnon(p)) | |
| 1119 | 1119 | pr_err("Memory failure: %#lx: non anonymous thp\n", |
| 1120 | 1120 | pfn); |
| 1121 | 1121 | else |
| @@ -1126,9 +1126,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) · 4 unmodified lines | ||
| 1126 | 1126 | put_hwpoison_page(p); |
| 1127 | 1127 | return -EBUSY; |
| 1128 | 1128 | } |
| 1129 | − unlock_page(hpage); | |
| 1130 | − get_hwpoison_page(p); | |
| 1131 | − put_hwpoison_page(hpage); | |
| 1129 | + unlock_page(p); | |
| 1132 | 1130 | VM_BUG_ON_PAGE(!page_count(p), p); |
| 1133 | 1131 | hpage = compound_head(p); |
| 1134 | 1132 | } |
| @@ -104,11 +104,13 @@ static pte_t move_soft_dirty_pte(pte_t pte) · 103 unmodified lines | ||
| 104 | 104 | static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, |
| 105 | 105 | unsigned long old_addr, unsigned long old_end, |
| 106 | 106 | struct vm_area_struct *new_vma, pmd_t *new_pmd, |
| 107 | − unsigned long new_addr, bool need_rmap_locks) | |
| 107 | + unsigned long new_addr, bool need_rmap_locks, bool *need_flush) | |
| 108 | 108 | { |
| 109 | 109 | struct mm_struct *mm = vma->vm_mm; |
| 110 | 110 | pte_t *old_pte, *new_pte, pte; |
| 111 | 111 | spinlock_t *old_ptl, *new_ptl; |
| 112 | + bool force_flush = false; | |
| 113 | + unsigned long len = old_end - old_addr; | |
| 112 | 114 | |
| 113 | 115 | /* |
| 114 | 116 | * When need_rmap_locks is true, we take the i_mmap_rwsem and anon_vma |
| @@ -146,6 +148,14 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, · 31 unmodified lines | ||
| 146 | 148 | new_pte++, new_addr += PAGE_SIZE) { |
| 147 | 149 | if (pte_none(*old_pte)) |
| 148 | 150 | continue; |
| 151 | + | |
| 152 | + /* | |
| 153 | + * We are remapping a dirty PTE, make sure to | |
| 154 | + * flush TLB before we drop the PTL for the | |
| 155 | + * old PTE or we may race with page_mkclean(). | |
| 156 | + */ | |
| 157 | + if (pte_present(*old_pte) && pte_dirty(*old_pte)) | |
| 158 | + force_flush = true; | |
| 149 | 159 | pte = ptep_get_and_clear(mm, old_addr, old_pte); |
| 150 | 160 | pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr); |
| 151 | 161 | pte = move_soft_dirty_pte(pte); |
| @@ -156,6 +166,10 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, · 4 unmodified lines | ||
| 156 | 166 | if (new_ptl != old_ptl) |
| 157 | 167 | spin_unlock(new_ptl); |
| 158 | 168 | pte_unmap(new_pte - 1); |
| 169 | + if (force_flush) | |
| 170 | + flush_tlb_range(vma, old_end - len, old_end); | |
| 171 | + else | |
| 172 | + *need_flush = true; | |
| 159 | 173 | pte_unmap_unlock(old_pte - 1, old_ptl); |
| 160 | 174 | if (need_rmap_locks) |
| 161 | 175 | drop_rmap_locks(vma); |
| @@ -201,13 +215,12 @@ unsigned long move_page_tables(struct vm_area_struct *vma, · 39 unmodified lines | ||
| 201 | 215 | if (need_rmap_locks) |
| 202 | 216 | take_rmap_locks(vma); |
| 203 | 217 | moved = move_huge_pmd(vma, old_addr, new_addr, |
| 204 | − old_end, old_pmd, new_pmd); | |
| 218 | + old_end, old_pmd, new_pmd, | |
| 219 | + &need_flush); | |
| 205 | 220 | if (need_rmap_locks) |
| 206 | 221 | drop_rmap_locks(vma); |
| 207 | − if (moved) { | |
| 208 | − need_flush = true; | |
| 222 | + if (moved) | |
| 209 | 223 | continue; |
| 210 | − } | |
| 211 | 224 | } |
| 212 | 225 | split_huge_pmd(vma, old_pmd, old_addr); |
| 213 | 226 | if (pmd_trans_unstable(old_pmd)) |
| @@ -220,11 +233,10 @@ unsigned long move_page_tables(struct vm_area_struct *vma, · 6 unmodified lines | ||
| 220 | 233 | extent = next - new_addr; |
| 221 | 234 | if (extent > LATENCY_LIMIT) |
| 222 | 235 | extent = LATENCY_LIMIT; |
| 223 | − move_ptes(vma, old_pmd, old_addr, old_addr + extent, | |
| 224 | − new_vma, new_pmd, new_addr, need_rmap_locks); | |
| 225 | − need_flush = true; | |
| 236 | + move_ptes(vma, old_pmd, old_addr, old_addr + extent, new_vma, | |
| 237 | + new_pmd, new_addr, need_rmap_locks, &need_flush); | |
| 226 | 238 | } |
| 227 | − if (likely(need_flush)) | |
| 239 | + if (need_flush) | |
| 228 | 240 | flush_tlb_range(vma, old_end-len, old_addr); |
| 229 | 241 | |
| 230 | 242 | mmu_notifier_invalidate_range_end(vma->vm_mm, mmun_start, mmun_end); |
| @@ -3658,7 +3658,7 @@ retry: · 3657 unmodified lines | ||
| 3658 | 3658 | /* Make sure we know about allocations which stall for too long */ |
| 3659 | 3659 | if (time_after(jiffies, alloc_start + stall_timeout)) { |
| 3660 | 3660 | warn_alloc(gfp_mask, |
| 3661 | − "page alloction stalls for %ums, order:%u\n", | |
| 3661 | + "page allocation stalls for %ums, order:%u", | |
| 3662 | 3662 | jiffies_to_msecs(jiffies-alloc_start), order); |
| 3663 | 3663 | stall_timeout += 10 * HZ; |
| 3664 | 3664 | } |
| @@ -1483,6 +1483,8 @@ static int shmem_replace_page(struct page **pagep, gfp_t gfp, · 1482 unmodified lines | ||
| 1483 | 1483 | copy_highpage(newpage, oldpage); |
| 1484 | 1484 | flush_dcache_page(newpage); |
| 1485 | 1485 | |
| 1486 | + __SetPageLocked(newpage); | |
| 1487 | + __SetPageSwapBacked(newpage); | |
| 1486 | 1488 | SetPageUptodate(newpage); |
| 1487 | 1489 | set_page_private(newpage, swap_index); |
| 1488 | 1490 | SetPageSwapCache(newpage); |
| @@ -533,8 +533,8 @@ void memcg_create_kmem_cache(struct mem_cgroup *memcg, · 532 unmodified lines | ||
| 533 | 533 | |
| 534 | 534 | s = create_cache(cache_name, root_cache->object_size, |
| 535 | 535 | root_cache->size, root_cache->align, |
| 536 | − root_cache->flags, root_cache->ctor, | |
| 537 | − memcg, root_cache); | |
| 536 | + root_cache->flags & CACHE_CREATE_MASK, | |
| 537 | + root_cache->ctor, memcg, root_cache); | |
| 538 | 538 | /* |
| 539 | 539 | * If we could not create a memcg cache, do not complain, because |
| 540 | 540 | * that's not critical at all as we can always proceed with the root |
| @@ -2224,6 +2224,8 @@ static unsigned long read_swap_header(struct swap_info_struct *p, · 2223 unmodified lines | ||
| 2224 | 2224 | swab32s(&swap_header->info.version); |
| 2225 | 2225 | swab32s(&swap_header->info.last_page); |
| 2226 | 2226 | swab32s(&swap_header->info.nr_badpages); |
| 2227 | + if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) | |
| 2228 | + return 0; | |
| 2227 | 2229 | for (i = 0; i < swap_header->info.nr_badpages; i++) |
| 2228 | 2230 | swab32s(&swap_header->info.badpages[i]); |
| 2229 | 2231 | } |
| @@ -652,6 +652,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, · 651 unmodified lines | ||
| 652 | 652 | batadv_softif_destroy_sysfs(hard_iface->soft_iface); |
| 653 | 653 | } |
| 654 | 654 | |
| 655 | + hard_iface->soft_iface = NULL; | |
| 655 | 656 | batadv_hardif_put(hard_iface); |
| 656 | 657 | |
| 657 | 658 | out: |
| @@ -837,6 +837,7 @@ static int batadv_tp_send(void *arg) · 836 unmodified lines | ||
| 837 | 837 | primary_if = batadv_primary_if_get_selected(bat_priv); |
| 838 | 838 | if (unlikely(!primary_if)) { |
| 839 | 839 | err = BATADV_TP_REASON_DST_UNREACHABLE; |
| 840 | + tp_vars->reason = err; | |
| 840 | 841 | goto out; |
| 841 | 842 | } |
| 842 | 843 | |
| @@ -1549,24 +1549,31 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, · 1548 unmodified lines | ||
| 1549 | 1549 | struct sockaddr_can *addr = (struct sockaddr_can *)uaddr; |
| 1550 | 1550 | struct sock *sk = sock->sk; |
| 1551 | 1551 | struct bcm_sock *bo = bcm_sk(sk); |
| 1552 | + int ret = 0; | |
| 1552 | 1553 | |
| 1553 | 1554 | if (len < sizeof(*addr)) |
| 1554 | 1555 | return -EINVAL; |
| 1555 | 1556 | |
| 1556 | − if (bo->bound) | |
| 1557 | − return -EISCONN; | |
| 1557 | + lock_sock(sk); | |
| 1558 | + | |
| 1559 | + if (bo->bound) { | |
| 1560 | + ret = -EISCONN; | |
| 1561 | + goto fail; | |
| 1562 | + } | |
| 1558 | 1563 | |
| 1559 | 1564 | /* bind a device to this socket */ |
| 1560 | 1565 | if (addr->can_ifindex) { |
| 1561 | 1566 | struct net_device *dev; |
| 1562 | 1567 | |
| 1563 | 1568 | dev = dev_get_by_index(&init_net, addr->can_ifindex); |
| 1564 | − if (!dev) | |
| 1565 | − return -ENODEV; | |
| 1566 | − | |
| 1569 | + if (!dev) { | |
| 1570 | + ret = -ENODEV; | |
| 1571 | + goto fail; | |
| 1572 | + } | |
| 1567 | 1573 | if (dev->type != ARPHRD_CAN) { |
| 1568 | 1574 | dev_put(dev); |
| 1569 | − return -ENODEV; | |
| 1575 | + ret = -ENODEV; | |
| 1576 | + goto fail; | |
| 1570 | 1577 | } |
| 1571 | 1578 | |
| 1572 | 1579 | bo->ifindex = dev->ifindex; |
| @@ -1577,17 +1584,24 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, · 4 unmodified lines | ||
| 1577 | 1584 | bo->ifindex = 0; |
| 1578 | 1585 | } |
| 1579 | 1586 | |
| 1580 | − bo->bound = 1; | |
| 1581 | − | |
| 1582 | 1587 | if (proc_dir) { |
| 1583 | 1588 | /* unique socket address as filename */ |
| 1584 | 1589 | sprintf(bo->procname, "%lu", sock_i_ino(sk)); |
| 1585 | 1590 | bo->bcm_proc_read = proc_create_data(bo->procname, 0644, |
| 1586 | 1591 | proc_dir, |
| 1587 | 1592 | &bcm_proc_fops, sk); |
| 1593 | + if (!bo->bcm_proc_read) { | |
| 1594 | + ret = -ENOMEM; | |
| 1595 | + goto fail; | |
| 1596 | + } | |
| 1588 | 1597 | } |
| 1589 | 1598 | |
| 1590 | − return 0; | |
| 1599 | + bo->bound = 1; | |
| 1600 | + | |
| 1601 | +fail: | |
| 1602 | + release_sock(sk); | |
| 1603 | + | |
| 1604 | + return ret; | |
| 1591 | 1605 | } |
| 1592 | 1606 | |
| 1593 | 1607 | static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, |
| @@ -34,7 +34,8 @@ void ceph_file_layout_from_legacy(struct ceph_file_layout *fl, · 33 unmodified lines | ||
| 34 | 34 | fl->stripe_count = le32_to_cpu(legacy->fl_stripe_count); |
| 35 | 35 | fl->object_size = le32_to_cpu(legacy->fl_object_size); |
| 36 | 36 | fl->pool_id = le32_to_cpu(legacy->fl_pg_pool); |
| 37 | − if (fl->pool_id == 0) | |
| 37 | + if (fl->pool_id == 0 && fl->stripe_unit == 0 && | |
| 38 | + fl->stripe_count == 0 && fl->object_size == 0) | |
| 38 | 39 | fl->pool_id = -1; |
| 39 | 40 | } |
| 40 | 41 | EXPORT_SYMBOL(ceph_file_layout_from_legacy); |
| @@ -4094,6 +4094,7 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) · 4093 unmodified lines | ||
| 4094 | 4094 | osd_init(&osdc->homeless_osd); |
| 4095 | 4095 | osdc->homeless_osd.o_osdc = osdc; |
| 4096 | 4096 | osdc->homeless_osd.o_osd = CEPH_HOMELESS_OSD; |
| 4097 | + osdc->last_linger_id = CEPH_LINGER_ID_START; | |
| 4097 | 4098 | osdc->linger_requests = RB_ROOT; |
| 4098 | 4099 | osdc->map_checks = RB_ROOT; |
| 4099 | 4100 | osdc->linger_map_checks = RB_ROOT; |
| @@ -1766,19 +1766,14 @@ EXPORT_SYMBOL_GPL(is_skb_forwardable); · 1765 unmodified lines | ||
| 1766 | 1766 | |
| 1767 | 1767 | int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb) |
| 1768 | 1768 | { |
| 1769 | − if (skb_orphan_frags(skb, GFP_ATOMIC) || | |
| 1770 | − unlikely(!is_skb_forwardable(dev, skb))) { | |
| 1771 | − atomic_long_inc(&dev->rx_dropped); | |
| 1772 | − kfree_skb(skb); | |
| 1773 | − return NET_RX_DROP; | |
| 1774 | − } | |
| 1769 | + int ret = ____dev_forward_skb(dev, skb); | |
| 1775 | 1770 | |
| 1776 | − skb_scrub_packet(skb, true); | |
| 1777 | − skb->priority = 0; | |
| 1778 | − skb->protocol = eth_type_trans(skb, dev); | |
| 1779 | − skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | |
| 1771 | + if (likely(!ret)) { | |
| 1772 | + skb->protocol = eth_type_trans(skb, dev); | |
| 1773 | + skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); | |
| 1774 | + } | |
| 1780 | 1775 | |
| 1781 | − return 0; | |
| 1776 | + return ret; | |
| 1782 | 1777 | } |
| 1783 | 1778 | EXPORT_SYMBOL_GPL(__dev_forward_skb); |
| 1784 | 1779 | |
| @@ -2484,7 +2479,7 @@ int skb_checksum_help(struct sk_buff *skb) · 699 unmodified lines | ||
| 2484 | 2479 | goto out; |
| 2485 | 2480 | } |
| 2486 | 2481 | |
| 2487 | − *(__sum16 *)(skb->data + offset) = csum_fold(csum); | |
| 2482 | + *(__sum16 *)(skb->data + offset) = csum_fold(csum) ?: CSUM_MANGLED_0; | |
| 2488 | 2483 | out_set_summed: |
| 2489 | 2484 | skb->ip_summed = CHECKSUM_NONE; |
| 2490 | 2485 | out: |
| @@ -1628,6 +1628,19 @@ static inline int __bpf_rx_skb(struct net_device *dev, struct sk_buff *skb) · 1627 unmodified lines | ||
| 1628 | 1628 | return dev_forward_skb(dev, skb); |
| 1629 | 1629 | } |
| 1630 | 1630 | |
| 1631 | +static inline int __bpf_rx_skb_no_mac(struct net_device *dev, | |
| 1632 | + struct sk_buff *skb) | |
| 1633 | +{ | |
| 1634 | + int ret = ____dev_forward_skb(dev, skb); | |
| 1635 | + | |
| 1636 | + if (likely(!ret)) { | |
| 1637 | + skb->dev = dev; | |
| 1638 | + ret = netif_rx(skb); | |
| 1639 | + } | |
| 1640 | + | |
| 1641 | + return ret; | |
| 1642 | +} | |
| 1643 | + | |
| 1631 | 1644 | static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb) |
| 1632 | 1645 | { |
| 1633 | 1646 | int ret; |
| @@ -1647,6 +1660,51 @@ static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb) · 13 unmodified lines | ||
| 1647 | 1660 | return ret; |
| 1648 | 1661 | } |
| 1649 | 1662 | |
| 1663 | +static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev, | |
| 1664 | + u32 flags) | |
| 1665 | +{ | |
| 1666 | + /* skb->mac_len is not set on normal egress */ | |
| 1667 | + unsigned int mlen = skb->network_header - skb->mac_header; | |
| 1668 | + | |
| 1669 | + __skb_pull(skb, mlen); | |
| 1670 | + | |
| 1671 | + /* At ingress, the mac header has already been pulled once. | |
| 1672 | + * At egress, skb_pospull_rcsum has to be done in case that | |
| 1673 | + * the skb is originated from ingress (i.e. a forwarded skb) | |
| 1674 | + * to ensure that rcsum starts at net header. | |
| 1675 | + */ | |
| 1676 | + if (!skb_at_tc_ingress(skb)) | |
| 1677 | + skb_postpull_rcsum(skb, skb_mac_header(skb), mlen); | |
| 1678 | + skb_pop_mac_header(skb); | |
| 1679 | + skb_reset_mac_len(skb); | |
| 1680 | + return flags & BPF_F_INGRESS ? | |
| 1681 | + __bpf_rx_skb_no_mac(dev, skb) : __bpf_tx_skb(dev, skb); | |
| 1682 | +} | |
| 1683 | + | |
| 1684 | +static int __bpf_redirect_common(struct sk_buff *skb, struct net_device *dev, | |
| 1685 | + u32 flags) | |
| 1686 | +{ | |
| 1687 | + bpf_push_mac_rcsum(skb); | |
| 1688 | + return flags & BPF_F_INGRESS ? | |
| 1689 | + __bpf_rx_skb(dev, skb) : __bpf_tx_skb(dev, skb); | |
| 1690 | +} | |
| 1691 | + | |
| 1692 | +static int __bpf_redirect(struct sk_buff *skb, struct net_device *dev, | |
| 1693 | + u32 flags) | |
| 1694 | +{ | |
| 1695 | + switch (dev->type) { | |
| 1696 | + case ARPHRD_TUNNEL: | |
| 1697 | + case ARPHRD_TUNNEL6: | |
| 1698 | + case ARPHRD_SIT: | |
| 1699 | + case ARPHRD_IPGRE: | |
| 1700 | + case ARPHRD_VOID: | |
| 1701 | + case ARPHRD_NONE: | |
| 1702 | + return __bpf_redirect_no_mac(skb, dev, flags); | |
| 1703 | + default: | |
| 1704 | + return __bpf_redirect_common(skb, dev, flags); | |
| 1705 | + } | |
| 1706 | +} | |
| 1707 | + | |
| 1650 | 1708 | BPF_CALL_3(bpf_clone_redirect, struct sk_buff *, skb, u32, ifindex, u64, flags) |
| 1651 | 1709 | { |
| 1652 | 1710 | struct net_device *dev; |
| @@ -1675,10 +1733,7 @@ BPF_CALL_3(bpf_clone_redirect, struct sk_buff *, skb, u32, ifindex, u64, flags) · 22 unmodified lines | ||
| 1675 | 1733 | return -ENOMEM; |
| 1676 | 1734 | } |
| 1677 | 1735 | |
| 1678 | − bpf_push_mac_rcsum(clone); | |
| 1679 | − | |
| 1680 | − return flags & BPF_F_INGRESS ? | |
| 1681 | − __bpf_rx_skb(dev, clone) : __bpf_tx_skb(dev, clone); | |
| 1736 | + return __bpf_redirect(clone, dev, flags); | |
| 1682 | 1737 | } |
| 1683 | 1738 | |
| 1684 | 1739 | static const struct bpf_func_proto bpf_clone_redirect_proto = { |
| @@ -1722,10 +1777,7 @@ int skb_do_redirect(struct sk_buff *skb) · 37 unmodified lines | ||
| 1722 | 1777 | return -EINVAL; |
| 1723 | 1778 | } |
| 1724 | 1779 | |
| 1725 | − bpf_push_mac_rcsum(skb); | |
| 1726 | − | |
| 1727 | − return ri->flags & BPF_F_INGRESS ? | |
| 1728 | − __bpf_rx_skb(dev, skb) : __bpf_tx_skb(dev, skb); | |
| 1780 | + return __bpf_redirect(skb, dev, ri->flags); | |
| 1729 | 1781 | } |
| 1730 | 1782 | |
| 1731 | 1783 | static const struct bpf_func_proto bpf_redirect_proto = { |
| @@ -122,7 +122,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb, · 121 unmodified lines | ||
| 122 | 122 | struct flow_dissector_key_keyid *key_keyid; |
| 123 | 123 | bool skip_vlan = false; |
| 124 | 124 | u8 ip_proto = 0; |
| 125 | − bool ret = false; | |
| 125 | + bool ret; | |
| 126 | 126 | |
| 127 | 127 | if (!data) { |
| 128 | 128 | data = skb->data; |
| @@ -549,12 +549,17 @@ ip_proto_again: · 420 unmodified lines | ||
| 549 | 549 | out_good: |
| 550 | 550 | ret = true; |
| 551 | 551 | |
| 552 | −out_bad: | |
| 552 | + key_control->thoff = (u16)nhoff; | |
| 553 | +out: | |
| 553 | 554 | key_basic->n_proto = proto; |
| 554 | 555 | key_basic->ip_proto = ip_proto; |
| 555 | − key_control->thoff = (u16)nhoff; | |
| 556 | 556 | |
| 557 | 557 | return ret; |
| 558 | + | |
| 559 | +out_bad: | |
| 560 | + ret = false; | |
| 561 | + key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen); | |
| 562 | + goto out; | |
| 558 | 563 | } |
| 559 | 564 | EXPORT_SYMBOL(__skb_flow_dissect); |
| 560 | 565 | |
| @@ -219,6 +219,8 @@ int peernet2id_alloc(struct net *net, struct net *peer) · 218 unmodified lines | ||
| 219 | 219 | bool alloc; |
| 220 | 220 | int id; |
| 221 | 221 | |
| 222 | + if (atomic_read(&net->count) == 0) | |
| 223 | + return NETNSA_NSID_NOT_ASSIGNED; | |
| 222 | 224 | spin_lock_irqsave(&net->nsid_lock, flags); |
| 223 | 225 | alloc = atomic_read(&peer->count) == 0 ? false : true; |
| 224 | 226 | id = __peernet2id_alloc(net, peer, &alloc); |
| @@ -275,6 +275,7 @@ int rtnl_unregister(int protocol, int msgtype) · 274 unmodified lines | ||
| 275 | 275 | |
| 276 | 276 | rtnl_msg_handlers[protocol][msgindex].doit = NULL; |
| 277 | 277 | rtnl_msg_handlers[protocol][msgindex].dumpit = NULL; |
| 278 | + rtnl_msg_handlers[protocol][msgindex].calcit = NULL; | |
| 278 | 279 | |
| 279 | 280 | return 0; |
| 280 | 281 | } |
| @@ -839,18 +840,20 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, · 558 unmodified lines | ||
| 839 | 840 | if (dev->dev.parent && dev_is_pci(dev->dev.parent) && |
| 840 | 841 | (ext_filter_mask & RTEXT_FILTER_VF)) { |
| 841 | 842 | int num_vfs = dev_num_vf(dev->dev.parent); |
| 842 | − size_t size = nla_total_size(sizeof(struct nlattr)); | |
| 843 | − size += nla_total_size(num_vfs * sizeof(struct nlattr)); | |
| 843 | + size_t size = nla_total_size(0); | |
| 844 | 844 | size += num_vfs * |
| 845 | − (nla_total_size(sizeof(struct ifla_vf_mac)) + | |
| 846 | − nla_total_size(MAX_VLAN_LIST_LEN * | |
| 847 | − sizeof(struct nlattr)) + | |
| 845 | + (nla_total_size(0) + | |
| 846 | + nla_total_size(sizeof(struct ifla_vf_mac)) + | |
| 847 | + nla_total_size(sizeof(struct ifla_vf_vlan)) + | |
| 848 | + nla_total_size(0) + /* nest IFLA_VF_VLAN_LIST */ | |
| 848 | 849 | nla_total_size(MAX_VLAN_LIST_LEN * |
| 849 | 850 | sizeof(struct ifla_vf_vlan_info)) + |
| 850 | 851 | nla_total_size(sizeof(struct ifla_vf_spoofchk)) + |
| 852 | + nla_total_size(sizeof(struct ifla_vf_tx_rate)) + | |
| 851 | 853 | nla_total_size(sizeof(struct ifla_vf_rate)) + |
| 852 | 854 | nla_total_size(sizeof(struct ifla_vf_link_state)) + |
| 853 | 855 | nla_total_size(sizeof(struct ifla_vf_rss_query_en)) + |
| 856 | + nla_total_size(0) + /* nest IFLA_VF_STATS */ | |
| 854 | 857 | /* IFLA_VF_STATS_RX_PACKETS */ |
| 855 | 858 | nla_total_size_64bit(sizeof(__u64)) + |
| 856 | 859 | /* IFLA_VF_STATS_TX_PACKETS */ |
| @@ -898,7 +901,8 @@ static size_t rtnl_port_size(const struct net_device *dev, · 41 unmodified lines | ||
| 898 | 901 | |
| 899 | 902 | static size_t rtnl_xdp_size(const struct net_device *dev) |
| 900 | 903 | { |
| 901 | − size_t xdp_size = nla_total_size(1); /* XDP_ATTACHED */ | |
| 904 | + size_t xdp_size = nla_total_size(0) + /* nest IFLA_XDP */ | |
| 905 | + nla_total_size(1); /* XDP_ATTACHED */ | |
| 902 | 906 | |
| 903 | 907 | if (!dev->netdev_ops->ndo_xdp) |
| 904 | 908 | return 0; |
| @@ -1605,7 +1609,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) · 700 unmodified lines | ||
| 1605 | 1609 | head = &net->dev_index_head[h]; |
| 1606 | 1610 | hlist_for_each_entry(dev, head, index_hlist) { |
| 1607 | 1611 | if (link_dump_filtered(dev, master_idx, kind_ops)) |
| 1608 | − continue; | |
| 1612 | + goto cont; | |
| 1609 | 1613 | if (idx < s_idx) |
| 1610 | 1614 | goto cont; |
| 1611 | 1615 | err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
| @@ -2848,7 +2852,10 @@ nla_put_failure: · 1236 unmodified lines | ||
| 2848 | 2852 | |
| 2849 | 2853 | static inline size_t rtnl_fdb_nlmsg_size(void) |
| 2850 | 2854 | { |
| 2851 | − return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN); | |
| 2855 | + return NLMSG_ALIGN(sizeof(struct ndmsg)) + | |
| 2856 | + nla_total_size(ETH_ALEN) + /* NDA_LLADDR */ | |
| 2857 | + nla_total_size(sizeof(u16)) + /* NDA_VLAN */ | |
| 2858 | + 0; | |
| 2852 | 2859 | } |
| 2853 | 2860 | |
| 2854 | 2861 | static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type, |
| @@ -453,7 +453,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) · 452 unmodified lines | ||
| 453 | 453 | EXPORT_SYMBOL(sock_queue_rcv_skb); |
| 454 | 454 | |
| 455 | 455 | int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, |
| 456 | − const int nested, unsigned int trim_cap) | |
| 456 | + const int nested, unsigned int trim_cap, bool refcounted) | |
| 457 | 457 | { |
| 458 | 458 | int rc = NET_RX_SUCCESS; |
| 459 | 459 | |
| @@ -487,7 +487,8 @@ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, · 27 unmodified lines | ||
| 487 | 487 | |
| 488 | 488 | bh_unlock_sock(sk); |
| 489 | 489 | out: |
| 490 | − sock_put(sk); | |
| 490 | + if (refcounted) | |
| 491 | + sock_put(sk); | |
| 491 | 492 | return rc; |
| 492 | 493 | discard_and_relse: |
| 493 | 494 | kfree_skb(skb); |
| @@ -1543,6 +1544,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) · 1049 unmodified lines | ||
| 1543 | 1544 | RCU_INIT_POINTER(newsk->sk_reuseport_cb, NULL); |
| 1544 | 1545 | |
| 1545 | 1546 | newsk->sk_err = 0; |
| 1547 | + newsk->sk_err_soft = 0; | |
| 1546 | 1548 | newsk->sk_priority = 0; |
| 1547 | 1549 | newsk->sk_incoming_cpu = raw_smp_processor_id(); |
| 1548 | 1550 | atomic64_set(&newsk->sk_cookie, 0); |
| @@ -235,7 +235,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) · 234 unmodified lines | ||
| 235 | 235 | { |
| 236 | 236 | const struct iphdr *iph = (struct iphdr *)skb->data; |
| 237 | 237 | const u8 offset = iph->ihl << 2; |
| 238 | − const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset); | |
| 238 | + const struct dccp_hdr *dh; | |
| 239 | 239 | struct dccp_sock *dp; |
| 240 | 240 | struct inet_sock *inet; |
| 241 | 241 | const int type = icmp_hdr(skb)->type; |
| @@ -245,11 +245,13 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) · 3 unmodified lines | ||
| 245 | 245 | int err; |
| 246 | 246 | struct net *net = dev_net(skb->dev); |
| 247 | 247 | |
| 248 | − if (skb->len < offset + sizeof(*dh) || | |
| 249 | − skb->len < offset + __dccp_basic_hdr_len(dh)) { | |
| 250 | − __ICMP_INC_STATS(net, ICMP_MIB_INERRORS); | |
| 251 | − return; | |
| 252 | − } | |
| 248 | + /* Only need dccph_dport & dccph_sport which are the first | |
| 249 | + * 4 bytes in dccp header. | |
| 250 | + * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. | |
| 251 | + */ | |
| 252 | + BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); | |
| 253 | + BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); | |
| 254 | + dh = (struct dccp_hdr *)(skb->data + offset); | |
| 253 | 255 | |
| 254 | 256 | sk = __inet_lookup_established(net, &dccp_hashinfo, |
| 255 | 257 | iph->daddr, dh->dccph_dport, |
| @@ -868,7 +870,7 @@ lookup: · 612 unmodified lines | ||
| 868 | 870 | goto discard_and_relse; |
| 869 | 871 | nf_reset(skb); |
| 870 | 872 | |
| 871 | − return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4); | |
| 873 | + return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4, refcounted); | |
| 872 | 874 | |
| 873 | 875 | no_dccp_socket: |
| 874 | 876 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) |
| @@ -70,7 +70,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, · 69 unmodified lines | ||
| 70 | 70 | u8 type, u8 code, int offset, __be32 info) |
| 71 | 71 | { |
| 72 | 72 | const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; |
| 73 | − const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset); | |
| 73 | + const struct dccp_hdr *dh; | |
| 74 | 74 | struct dccp_sock *dp; |
| 75 | 75 | struct ipv6_pinfo *np; |
| 76 | 76 | struct sock *sk; |
| @@ -78,12 +78,13 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, · 1 unmodified line | ||
| 78 | 78 | __u64 seq; |
| 79 | 79 | struct net *net = dev_net(skb->dev); |
| 80 | 80 | |
| 81 | − if (skb->len < offset + sizeof(*dh) || | |
| 82 | − skb->len < offset + __dccp_basic_hdr_len(dh)) { | |
| 83 | − __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), | |
| 84 | − ICMP6_MIB_INERRORS); | |
| 85 | − return; | |
| 86 | − } | |
| 81 | + /* Only need dccph_dport & dccph_sport which are the first | |
| 82 | + * 4 bytes in dccp header. | |
| 83 | + * Our caller (icmpv6_notify()) already pulled 8 bytes for us. | |
| 84 | + */ | |
| 85 | + BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); | |
| 86 | + BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); | |
| 87 | + dh = (struct dccp_hdr *)(skb->data + offset); | |
| 87 | 88 | |
| 88 | 89 | sk = __inet6_lookup_established(net, &dccp_hashinfo, |
| 89 | 90 | &hdr->daddr, dh->dccph_dport, |
| @@ -738,7 +739,8 @@ lookup: · 648 unmodified lines | ||
| 738 | 739 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
| 739 | 740 | goto discard_and_relse; |
| 740 | 741 | |
| 741 | − return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4) ? -1 : 0; | |
| 742 | + return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4, | |
| 743 | + refcounted) ? -1 : 0; | |
| 742 | 744 | |
| 743 | 745 | no_dccp_socket: |
| 744 | 746 | if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) |
| @@ -956,6 +958,7 @@ static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = { · 211 unmodified lines | ||
| 956 | 958 | .getsockopt = ipv6_getsockopt, |
| 957 | 959 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
| 958 | 960 | .sockaddr_len = sizeof(struct sockaddr_in6), |
| 961 | + .bind_conflict = inet6_csk_bind_conflict, | |
| 959 | 962 | #ifdef CONFIG_COMPAT |
| 960 | 963 | .compat_setsockopt = compat_ipv6_setsockopt, |
| 961 | 964 | .compat_getsockopt = compat_ipv6_getsockopt, |
| @@ -1009,6 +1009,10 @@ void dccp_close(struct sock *sk, long timeout) · 1008 unmodified lines | ||
| 1009 | 1009 | __kfree_skb(skb); |
| 1010 | 1010 | } |
| 1011 | 1011 | |
| 1012 | + /* If socket has been already reset kill it. */ | |
| 1013 | + if (sk->sk_state == DCCP_CLOSED) | |
| 1014 | + goto adjudge_to_death; | |
| 1015 | + | |
| 1012 | 1016 | if (data_was_unread) { |
| 1013 | 1017 | /* Unread data was tossed, send an appropriate Reset Code */ |
| 1014 | 1018 | DCCP_WARN("ABORT with %u bytes unread\n", data_was_unread); |
| @@ -533,9 +533,9 @@ EXPORT_SYMBOL(inet_dgram_connect); · 532 unmodified lines | ||
| 533 | 533 | |
| 534 | 534 | static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) |
| 535 | 535 | { |
| 536 | − DEFINE_WAIT(wait); | |
| 536 | + DEFINE_WAIT_FUNC(wait, woken_wake_function); | |
| 537 | 537 | |
| 538 | − prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | |
| 538 | + add_wait_queue(sk_sleep(sk), &wait); | |
| 539 | 539 | sk->sk_write_pending += writebias; |
| 540 | 540 | |
| 541 | 541 | /* Basic assumption: if someone sets sk->sk_err, he _must_ |
| @@ -545,13 +545,12 @@ static long inet_wait_for_connect(struct sock *sk, long timeo, int writebias) · 3 unmodified lines | ||
| 545 | 545 | */ |
| 546 | 546 | while ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { |
| 547 | 547 | release_sock(sk); |
| 548 | − timeo = schedule_timeout(timeo); | |
| 548 | + timeo = wait_woken(&wait, TASK_INTERRUPTIBLE, timeo); | |
| 549 | 549 | lock_sock(sk); |
| 550 | 550 | if (signal_pending(current) || !timeo) |
| 551 | 551 | break; |
| 552 | − prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | |
| 553 | 552 | } |
| 554 | − finish_wait(sk_sleep(sk), &wait); | |
| 553 | + remove_wait_queue(sk_sleep(sk), &wait); | |
| 555 | 554 | sk->sk_write_pending -= writebias; |
| 556 | 555 | return timeo; |
| 557 | 556 | } |
| @@ -151,7 +151,7 @@ static void fib_replace_table(struct net *net, struct fib_table *old, · 150 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | int fib_unmerge(struct net *net) |
| 153 | 153 | { |
| 154 | − struct fib_table *old, *new; | |
| 154 | + struct fib_table *old, *new, *main_table; | |
| 155 | 155 | |
| 156 | 156 | /* attempt to fetch local table if it has been allocated */ |
| 157 | 157 | old = fib_get_table(net, RT_TABLE_LOCAL); |
| @@ -162,11 +162,21 @@ int fib_unmerge(struct net *net) · 4 unmodified lines | ||
| 162 | 162 | if (!new) |
| 163 | 163 | return -ENOMEM; |
| 164 | 164 | |
| 165 | + /* table is already unmerged */ | |
| 166 | + if (new == old) | |
| 167 | + return 0; | |
| 168 | + | |
| 165 | 169 | /* replace merged table with clean table */ |
| 166 | − if (new != old) { | |
| 167 | − fib_replace_table(net, old, new); | |
| 168 | − fib_free_table(old); | |
| 169 | − } | |
| 170 | + fib_replace_table(net, old, new); | |
| 171 | + fib_free_table(old); | |
| 172 | + | |
| 173 | + /* attempt to fetch main table if it has been allocated */ | |
| 174 | + main_table = fib_get_table(net, RT_TABLE_MAIN); | |
| 175 | + if (!main_table) | |
| 176 | + return 0; | |
| 177 | + | |
| 178 | + /* flush local entries from main table */ | |
| 179 | + fib_table_flush_external(main_table); | |
| 170 | 180 | |
| 171 | 181 | return 0; |
| 172 | 182 | } |
| @@ -1743,8 +1743,10 @@ struct fib_table *fib_trie_unmerge(struct fib_table *oldtb) · 1742 unmodified lines | ||
| 1743 | 1743 | local_l = fib_find_node(lt, &local_tp, l->key); |
| 1744 | 1744 | |
| 1745 | 1745 | if (fib_insert_alias(lt, local_tp, local_l, new_fa, |
| 1746 | − NULL, l->key)) | |
| 1746 | + NULL, l->key)) { | |
| 1747 | + kmem_cache_free(fn_alias_kmem, new_fa); | |
| 1747 | 1748 | goto out; |
| 1749 | + } | |
| 1748 | 1750 | } |
| 1749 | 1751 | |
| 1750 | 1752 | /* stop loop if key wrapped back to 0 */ |
| @@ -1760,6 +1762,71 @@ out: · 9 unmodified lines | ||
| 1760 | 1762 | return NULL; |
| 1761 | 1763 | } |
| 1762 | 1764 | |
| 1765 | +/* Caller must hold RTNL */ | |
| 1766 | +void fib_table_flush_external(struct fib_table *tb) | |
| 1767 | +{ | |
| 1768 | + struct trie *t = (struct trie *)tb->tb_data; | |
| 1769 | + struct key_vector *pn = t->kv; | |
| 1770 | + unsigned long cindex = 1; | |
| 1771 | + struct hlist_node *tmp; | |
| 1772 | + struct fib_alias *fa; | |
| 1773 | + | |
| 1774 | + /* walk trie in reverse order */ | |
| 1775 | + for (;;) { | |
| 1776 | + unsigned char slen = 0; | |
| 1777 | + struct key_vector *n; | |
| 1778 | + | |
| 1779 | + if (!(cindex--)) { | |
| 1780 | + t_key pkey = pn->key; | |
| 1781 | + | |
| 1782 | + /* cannot resize the trie vector */ | |
| 1783 | + if (IS_TRIE(pn)) | |
| 1784 | + break; | |
| 1785 | + | |
| 1786 | + /* resize completed node */ | |
| 1787 | + pn = resize(t, pn); | |
| 1788 | + cindex = get_index(pkey, pn); | |
| 1789 | + | |
| 1790 | + continue; | |
| 1791 | + } | |
| 1792 | + | |
| 1793 | + /* grab the next available node */ | |
| 1794 | + n = get_child(pn, cindex); | |
| 1795 | + if (!n) | |
| 1796 | + continue; | |
| 1797 | + | |
| 1798 | + if (IS_TNODE(n)) { | |
| 1799 | + /* record pn and cindex for leaf walking */ | |
| 1800 | + pn = n; | |
| 1801 | + cindex = 1ul << n->bits; | |
| 1802 | + | |
| 1803 | + continue; | |
| 1804 | + } | |
| 1805 | + | |
| 1806 | + hlist_for_each_entry_safe(fa, tmp, &n->leaf, fa_list) { | |
| 1807 | + /* if alias was cloned to local then we just | |
| 1808 | + * need to remove the local copy from main | |
| 1809 | + */ | |
| 1810 | + if (tb->tb_id != fa->tb_id) { | |
| 1811 | + hlist_del_rcu(&fa->fa_list); | |
| 1812 | + alias_free_mem_rcu(fa); | |
| 1813 | + continue; | |
| 1814 | + } | |
| 1815 | + | |
| 1816 | + /* record local slen */ | |
| 1817 | + slen = fa->fa_slen; | |
| 1818 | + } | |
| 1819 | + | |
| 1820 | + /* update leaf slen */ | |
| 1821 | + n->slen = slen; | |
| 1822 | + | |
| 1823 | + if (hlist_empty(&n->leaf)) { | |
| 1824 | + put_child_root(pn, n->key, NULL); | |
| 1825 | + node_free(n); | |
| 1826 | + } | |
| 1827 | + } | |
| 1828 | +} | |
| 1829 | + | |
| 1763 | 1830 | /* Caller must hold RTNL. */ |
| 1764 | 1831 | int fib_table_flush(struct net *net, struct fib_table *tb) |
| 1765 | 1832 | { |
| @@ -2413,22 +2480,19 @@ static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter, · 647 unmodified lines | ||
| 2413 | 2480 | struct key_vector *l, **tp = &iter->tnode; |
| 2414 | 2481 | t_key key; |
| 2415 | 2482 | |
| 2416 | − /* use cache location of next-to-find key */ | |
| 2483 | + /* use cached location of previously found key */ | |
| 2417 | 2484 | if (iter->pos > 0 && pos >= iter->pos) { |
| 2418 | − pos -= iter->pos; | |
| 2419 | 2485 | key = iter->key; |
| 2420 | 2486 | } else { |
| 2421 | − iter->pos = 0; | |
| 2487 | + iter->pos = 1; | |
| 2422 | 2488 | key = 0; |
| 2423 | 2489 | } |
| 2424 | 2490 | |
| 2425 | − while ((l = leaf_walk_rcu(tp, key)) != NULL) { | |
| 2491 | + pos -= iter->pos; | |
| 2492 | + | |
| 2493 | + while ((l = leaf_walk_rcu(tp, key)) && (pos-- > 0)) { | |
| 2426 | 2494 | key = l->key + 1; |
| 2427 | 2495 | iter->pos++; |
| 2428 | − | |
| 2429 | − if (--pos <= 0) | |
| 2430 | − break; | |
| 2431 | − | |
| 2432 | 2496 | l = NULL; |
| 2433 | 2497 | |
| 2434 | 2498 | /* handle unlikely case of a key wrap */ |
| @@ -2437,7 +2501,7 @@ static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter, · 2 unmodified lines | ||
| 2437 | 2501 | } |
| 2438 | 2502 | |
| 2439 | 2503 | if (l) |
| 2440 | − iter->key = key; /* remember it */ | |
| 2504 | + iter->key = l->key; /* remember it */ | |
| 2441 | 2505 | else |
| 2442 | 2506 | iter->pos = 0; /* forget it */ |
| 2443 | 2507 | |
| @@ -2465,7 +2529,7 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos) · 21 unmodified lines | ||
| 2465 | 2529 | return fib_route_get_idx(iter, *pos); |
| 2466 | 2530 | |
| 2467 | 2531 | iter->pos = 0; |
| 2468 | − iter->key = 0; | |
| 2532 | + iter->key = KEY_MAX; | |
| 2469 | 2533 | |
| 2470 | 2534 | return SEQ_START_TOKEN; |
| 2471 | 2535 | } |
| @@ -2474,7 +2538,7 @@ static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) · 2 unmodified lines | ||
| 2474 | 2538 | { |
| 2475 | 2539 | struct fib_route_iter *iter = seq->private; |
| 2476 | 2540 | struct key_vector *l = NULL; |
| 2477 | − t_key key = iter->key; | |
| 2541 | + t_key key = iter->key + 1; | |
| 2478 | 2542 | |
| 2479 | 2543 | ++*pos; |
| 2480 | 2544 | |
| @@ -2483,7 +2547,7 @@ static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) · 2 unmodified lines | ||
| 2483 | 2547 | l = leaf_walk_rcu(&iter->tnode, key); |
| 2484 | 2548 | |
| 2485 | 2549 | if (l) { |
| 2486 | − iter->key = l->key + 1; | |
| 2550 | + iter->key = l->key; | |
| 2487 | 2551 | iter->pos++; |
| 2488 | 2552 | } else { |
| 2489 | 2553 | iter->pos = 0; |
| @@ -477,7 +477,7 @@ static struct rtable *icmp_route_lookup(struct net *net, · 476 unmodified lines | ||
| 477 | 477 | fl4->flowi4_proto = IPPROTO_ICMP; |
| 478 | 478 | fl4->fl4_icmp_type = type; |
| 479 | 479 | fl4->fl4_icmp_code = code; |
| 480 | − fl4->flowi4_oif = l3mdev_master_ifindex(skb_in->dev); | |
| 480 | + fl4->flowi4_oif = l3mdev_master_ifindex(skb_dst(skb_in)->dev); | |
| 481 | 481 | |
| 482 | 482 | security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4)); |
| 483 | 483 | rt = __ip_route_output_key_hash(net, fl4, |
| @@ -502,7 +502,7 @@ static struct rtable *icmp_route_lookup(struct net *net, · 18 unmodified lines | ||
| 502 | 502 | if (err) |
| 503 | 503 | goto relookup_failed; |
| 504 | 504 | |
| 505 | − if (inet_addr_type_dev_table(net, skb_in->dev, | |
| 505 | + if (inet_addr_type_dev_table(net, skb_dst(skb_in)->dev, | |
| 506 | 506 | fl4_dec.saddr) == RTN_LOCAL) { |
| 507 | 507 | rt2 = __ip_route_output_key(net, &fl4_dec); |
| 508 | 508 | if (IS_ERR(rt2)) |
| @@ -162,7 +162,7 @@ static int unsolicited_report_interval(struct in_device *in_dev) · 161 unmodified lines | ||
| 162 | 162 | } |
| 163 | 163 | |
| 164 | 164 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); |
| 165 | −static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); | |
| 165 | +static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list *im); | |
| 166 | 166 | static void igmpv3_clear_delrec(struct in_device *in_dev); |
| 167 | 167 | static int sf_setstate(struct ip_mc_list *pmc); |
| 168 | 168 | static void sf_markstate(struct ip_mc_list *pmc); |
| @@ -1130,10 +1130,15 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im) · 961 unmodified lines | ||
| 1130 | 1130 | spin_unlock_bh(&in_dev->mc_tomb_lock); |
| 1131 | 1131 | } |
| 1132 | 1132 | |
| 1133 | −static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr) | |
| 1133 | +/* | |
| 1134 | + * restore ip_mc_list deleted records | |
| 1135 | + */ | |
| 1136 | +static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list *im) | |
| 1134 | 1137 | { |
| 1135 | 1138 | struct ip_mc_list *pmc, *pmc_prev; |
| 1136 | − struct ip_sf_list *psf, *psf_next; | |
| 1139 | + struct ip_sf_list *psf; | |
| 1140 | + struct net *net = dev_net(in_dev->dev); | |
| 1141 | + __be32 multiaddr = im->multiaddr; | |
| 1137 | 1142 | |
| 1138 | 1143 | spin_lock_bh(&in_dev->mc_tomb_lock); |
| 1139 | 1144 | pmc_prev = NULL; |
| @@ -1149,16 +1154,26 @@ static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr) · 9 unmodified lines | ||
| 1149 | 1154 | in_dev->mc_tomb = pmc->next; |
| 1150 | 1155 | } |
| 1151 | 1156 | spin_unlock_bh(&in_dev->mc_tomb_lock); |
| 1157 | + | |
| 1158 | + spin_lock_bh(&im->lock); | |
| 1152 | 1159 | if (pmc) { |
| 1153 | − for (psf = pmc->tomb; psf; psf = psf_next) { | |
| 1154 | − psf_next = psf->sf_next; | |
| 1155 | − kfree(psf); | |
| 1160 | + im->interface = pmc->interface; | |
| 1161 | + im->crcount = in_dev->mr_qrv ?: net->ipv4.sysctl_igmp_qrv; | |
| 1162 | + im->sfmode = pmc->sfmode; | |
| 1163 | + if (pmc->sfmode == MCAST_INCLUDE) { | |
| 1164 | + im->tomb = pmc->tomb; | |
| 1165 | + im->sources = pmc->sources; | |
| 1166 | + for (psf = im->sources; psf; psf = psf->sf_next) | |
| 1167 | + psf->sf_crcount = im->crcount; | |
| 1156 | 1168 | } |
| 1157 | 1169 | in_dev_put(pmc->interface); |
| 1158 | − kfree(pmc); | |
| 1159 | 1170 | } |
| 1171 | + spin_unlock_bh(&im->lock); | |
| 1160 | 1172 | } |
| 1161 | 1173 | |
| 1174 | +/* | |
| 1175 | + * flush ip_mc_list deleted records | |
| 1176 | + */ | |
| 1162 | 1177 | static void igmpv3_clear_delrec(struct in_device *in_dev) |
| 1163 | 1178 | { |
| 1164 | 1179 | struct ip_mc_list *pmc, *nextpmc; |
| @@ -1366,7 +1381,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr) · 201 unmodified lines | ||
| 1366 | 1381 | ip_mc_hash_add(in_dev, im); |
| 1367 | 1382 | |
| 1368 | 1383 | #ifdef CONFIG_IP_MULTICAST |
| 1369 | − igmpv3_del_delrec(in_dev, im->multiaddr); | |
| 1384 | + igmpv3_del_delrec(in_dev, im); | |
| 1370 | 1385 | #endif |
| 1371 | 1386 | igmp_group_added(im); |
| 1372 | 1387 | if (!in_dev->dead) |
| @@ -1626,8 +1641,12 @@ void ip_mc_remap(struct in_device *in_dev) · 253 unmodified lines | ||
| 1626 | 1641 | |
| 1627 | 1642 | ASSERT_RTNL(); |
| 1628 | 1643 | |
| 1629 | − for_each_pmc_rtnl(in_dev, pmc) | |
| 1644 | + for_each_pmc_rtnl(in_dev, pmc) { | |
| 1645 | +#ifdef CONFIG_IP_MULTICAST | |
| 1646 | + igmpv3_del_delrec(in_dev, pmc); | |
| 1647 | +#endif | |
| 1630 | 1648 | igmp_group_added(pmc); |
| 1649 | + } | |
| 1631 | 1650 | } |
| 1632 | 1651 | |
| 1633 | 1652 | /* Device going down */ |
| @@ -1648,7 +1667,6 @@ void ip_mc_down(struct in_device *in_dev) · 14 unmodified lines | ||
| 1648 | 1667 | in_dev->mr_gq_running = 0; |
| 1649 | 1668 | if (del_timer(&in_dev->mr_gq_timer)) |
| 1650 | 1669 | __in_dev_put(in_dev); |
| 1651 | − igmpv3_clear_delrec(in_dev); | |
| 1652 | 1670 | #endif |
| 1653 | 1671 | |
| 1654 | 1672 | ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS); |
| @@ -1688,8 +1706,12 @@ void ip_mc_up(struct in_device *in_dev) · 33 unmodified lines | ||
| 1688 | 1706 | #endif |
| 1689 | 1707 | ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS); |
| 1690 | 1708 | |
| 1691 | − for_each_pmc_rtnl(in_dev, pmc) | |
| 1709 | + for_each_pmc_rtnl(in_dev, pmc) { | |
| 1710 | +#ifdef CONFIG_IP_MULTICAST | |
| 1711 | + igmpv3_del_delrec(in_dev, pmc); | |
| 1712 | +#endif | |
| 1692 | 1713 | igmp_group_added(pmc); |
| 1714 | + } | |
| 1693 | 1715 | } |
| 1694 | 1716 | |
| 1695 | 1717 | /* |
| @@ -1704,13 +1726,13 @@ void ip_mc_destroy_dev(struct in_device *in_dev) · 8 unmodified lines | ||
| 1704 | 1726 | |
| 1705 | 1727 | /* Deactivate timers */ |
| 1706 | 1728 | ip_mc_down(in_dev); |
| 1729 | +#ifdef CONFIG_IP_MULTICAST | |
| 1730 | + igmpv3_clear_delrec(in_dev); | |
| 1731 | +#endif | |
| 1707 | 1732 | |
| 1708 | 1733 | while ((i = rtnl_dereference(in_dev->mc_list)) != NULL) { |
| 1709 | 1734 | in_dev->mc_list = i->next_rcu; |
| 1710 | 1735 | in_dev->mc_count--; |
| 1711 | − | |
| 1712 | − /* We've dropped the groups in ip_mc_down already */ | |
| 1713 | − ip_mc_clear_src(i); | |
| 1714 | 1736 | ip_ma_put(i); |
| 1715 | 1737 | } |
| 1716 | 1738 | } |
| @@ -117,7 +117,7 @@ int ip_forward(struct sk_buff *skb) · 116 unmodified lines | ||
| 117 | 117 | if (opt->is_strictroute && rt->rt_uses_gateway) |
| 118 | 118 | goto sr_failed; |
| 119 | 119 | |
| 120 | − IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS; | |
| 120 | + IPCB(skb)->flags |= IPSKB_FORWARDED; | |
| 121 | 121 | mtu = ip_dst_mtu_maybe_forward(&rt->dst, true); |
| 122 | 122 | if (ip_exceeds_mtu(skb, mtu)) { |
| 123 | 123 | IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS); |
| @@ -239,19 +239,23 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk, · 238 unmodified lines | ||
| 239 | 239 | struct sk_buff *segs; |
| 240 | 240 | int ret = 0; |
| 241 | 241 | |
| 242 | − /* common case: fragmentation of segments is not allowed, | |
| 243 | − * or seglen is <= mtu | |
| 242 | + /* common case: seglen is <= mtu | |
| 244 | 243 | */ |
| 245 | − if (((IPCB(skb)->flags & IPSKB_FRAG_SEGS) == 0) || | |
| 246 | − skb_gso_validate_mtu(skb, mtu)) | |
| 244 | + if (skb_gso_validate_mtu(skb, mtu)) | |
| 247 | 245 | return ip_finish_output2(net, sk, skb); |
| 248 | 246 | |
| 249 | − /* Slowpath - GSO segment length is exceeding the dst MTU. | |
| 247 | + /* Slowpath - GSO segment length exceeds the egress MTU. | |
| 250 | 248 | * |
| 251 | − * This can happen in two cases: | |
| 252 | − * 1) TCP GRO packet, DF bit not set | |
| 253 | − * 2) skb arrived via virtio-net, we thus get TSO/GSO skbs directly | |
| 254 | − * from host network stack. | |
| 249 | + * This can happen in several cases: | |
| 250 | + * - Forwarding of a TCP GRO skb, when DF flag is not set. | |
| 251 | + * - Forwarding of an skb that arrived on a virtualization interface | |
| 252 | + * (virtio-net/vhost/tap) with TSO/GSO size set by other network | |
| 253 | + * stack. | |
| 254 | + * - Local GSO skb transmitted on an NETIF_F_TSO tunnel stacked over an | |
| 255 | + * interface with a smaller MTU. | |
| 256 | + * - Arriving GRO skb (or GSO skb in a virtualized environment) that is | |
| 257 | + * bridged to a NETIF_F_TSO tunnel stacked over an interface with an | |
| 258 | + * insufficent MTU. | |
| 255 | 259 | */ |
| 256 | 260 | features = netif_skb_features(skb); |
| 257 | 261 | BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET); |
| @@ -1579,7 +1583,8 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb, · 1321 unmodified lines | ||
| 1579 | 1583 | } |
| 1580 | 1584 | |
| 1581 | 1585 | oif = arg->bound_dev_if; |
| 1582 | − oif = oif ? : skb->skb_iif; | |
| 1586 | + if (!oif && netif_index_is_l3_master(net, skb->skb_iif)) | |
| 1587 | + oif = skb->skb_iif; | |
| 1583 | 1588 | |
| 1584 | 1589 | flowi4_init_output(&fl4, oif, |
| 1585 | 1590 | IP4_REPLY_MARK(net, skb->mark), |
| @@ -63,7 +63,6 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, · 62 unmodified lines | ||
| 63 | 63 | int pkt_len = skb->len - skb_inner_network_offset(skb); |
| 64 | 64 | struct net *net = dev_net(rt->dst.dev); |
| 65 | 65 | struct net_device *dev = skb->dev; |
| 66 | − int skb_iif = skb->skb_iif; | |
| 67 | 66 | struct iphdr *iph; |
| 68 | 67 | int err; |
| 69 | 68 | |
| @@ -73,16 +72,6 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, · 3 unmodified lines | ||
| 73 | 72 | skb_dst_set(skb, &rt->dst); |
| 74 | 73 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); |
| 75 | 74 | |
| 76 | − if (skb_iif && !(df & htons(IP_DF))) { | |
| 77 | − /* Arrived from an ingress interface, got encapsulated, with | |
| 78 | − * fragmentation of encapulating frames allowed. | |
| 79 | − * If skb is gso, the resulting encapsulated network segments | |
| 80 | − * may exceed dst mtu. | |
| 81 | − * Allow IP Fragmentation of segments. | |
| 82 | − */ | |
| 83 | − IPCB(skb)->flags |= IPSKB_FRAG_SEGS; | |
| 84 | − } | |
| 85 | − | |
| 86 | 75 | /* Push down and install the IP header. */ |
| 87 | 76 | skb_push(skb, sizeof(struct iphdr)); |
| 88 | 77 | skb_reset_network_header(skb); |
| @@ -1749,7 +1749,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, · 1748 unmodified lines | ||
| 1749 | 1749 | vif->dev->stats.tx_bytes += skb->len; |
| 1750 | 1750 | } |
| 1751 | 1751 | |
| 1752 | − IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS; | |
| 1752 | + IPCB(skb)->flags |= IPSKB_FORWARDED; | |
| 1753 | 1753 | |
| 1754 | 1754 | /* RFC1584 teaches, that DVMRP/PIM router must deliver packets locally |
| 1755 | 1755 | * not only before forwarding, but after forwarding on all output |
| @@ -28,7 +28,7 @@ static void nft_dup_ipv4_eval(const struct nft_expr *expr, · 27 unmodified lines | ||
| 28 | 28 | struct in_addr gw = { |
| 29 | 29 | .s_addr = (__force __be32)regs->data[priv->sreg_addr], |
| 30 | 30 | }; |
| 31 | − int oif = regs->data[priv->sreg_dev]; | |
| 31 | + int oif = priv->sreg_dev ? regs->data[priv->sreg_dev] : -1; | |
| 32 | 32 | |
| 33 | 33 | nf_dup_ipv4(pkt->net, pkt->skb, pkt->hook, &gw, oif); |
| 34 | 34 | } |
| @@ -59,7 +59,9 @@ static int nft_dup_ipv4_dump(struct sk_buff *skb, const struct nft_expr *expr) · 24 unmodified lines | ||
| 59 | 59 | { |
| 60 | 60 | struct nft_dup_ipv4 *priv = nft_expr_priv(expr); |
| 61 | 61 | |
| 62 | − if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr) || | |
| 62 | + if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr)) | |
| 63 | + goto nla_put_failure; | |
| 64 | + if (priv->sreg_dev && | |
| 63 | 65 | nft_dump_register(skb, NFTA_DUP_SREG_DEV, priv->sreg_dev)) |
| 64 | 66 | goto nla_put_failure; |
| 65 | 67 | |
| @@ -753,7 +753,9 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow · 752 unmodified lines | ||
| 753 | 753 | goto reject_redirect; |
| 754 | 754 | } |
| 755 | 755 | |
| 756 | − n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); | |
| 756 | + n = __ipv4_neigh_lookup(rt->dst.dev, new_gw); | |
| 757 | + if (!n) | |
| 758 | + n = neigh_create(&arp_tbl, &new_gw, rt->dst.dev); | |
| 757 | 759 | if (!IS_ERR(n)) { |
| 758 | 760 | if (!(n->nud_state & NUD_VALID)) { |
| 759 | 761 | neigh_event_send(n, NULL); |
| @@ -1164,7 +1164,7 @@ restart: · 1163 unmodified lines | ||
| 1164 | 1164 | |
| 1165 | 1165 | err = -EPIPE; |
| 1166 | 1166 | if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) |
| 1167 | − goto out_err; | |
| 1167 | + goto do_error; | |
| 1168 | 1168 | |
| 1169 | 1169 | sg = !!(sk->sk_route_caps & NETIF_F_SG); |
| 1170 | 1170 | |
| @@ -1241,7 +1241,7 @@ new_segment: · 70 unmodified lines | ||
| 1241 | 1241 | |
| 1242 | 1242 | if (!skb_can_coalesce(skb, i, pfrag->page, |
| 1243 | 1243 | pfrag->offset)) { |
| 1244 | − if (i == sysctl_max_skb_frags || !sg) { | |
| 1244 | + if (i >= sysctl_max_skb_frags || !sg) { | |
| 1245 | 1245 | tcp_mark_push(tp, skb); |
| 1246 | 1246 | goto new_segment; |
| 1247 | 1247 | } |
| @@ -200,8 +200,10 @@ static void tcp_reinit_congestion_control(struct sock *sk, · 199 unmodified lines | ||
| 200 | 200 | icsk->icsk_ca_ops = ca; |
| 201 | 201 | icsk->icsk_ca_setsockopt = 1; |
| 202 | 202 | |
| 203 | − if (sk->sk_state != TCP_CLOSE) | |
| 203 | + if (sk->sk_state != TCP_CLOSE) { | |
| 204 | + memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); | |
| 204 | 205 | tcp_init_congestion_control(sk); |
| 206 | + } | |
| 205 | 207 | } |
| 206 | 208 | |
| 207 | 209 | /* Manage refcounts on socket close. */ |
| @@ -56,6 +56,7 @@ struct dctcp { · 55 unmodified lines | ||
| 56 | 56 | u32 next_seq; |
| 57 | 57 | u32 ce_state; |
| 58 | 58 | u32 delayed_ack_reserved; |
| 59 | + u32 loss_cwnd; | |
| 59 | 60 | }; |
| 60 | 61 | |
| 61 | 62 | static unsigned int dctcp_shift_g __read_mostly = 4; /* g = 1/2^4 */ |
| @@ -96,6 +97,7 @@ static void dctcp_init(struct sock *sk) · 34 unmodified lines | ||
| 96 | 97 | ca->dctcp_alpha = min(dctcp_alpha_on_init, DCTCP_MAX_ALPHA); |
| 97 | 98 | |
| 98 | 99 | ca->delayed_ack_reserved = 0; |
| 100 | + ca->loss_cwnd = 0; | |
| 99 | 101 | ca->ce_state = 0; |
| 100 | 102 | |
| 101 | 103 | dctcp_reset(tp, ca); |
| @@ -111,9 +113,10 @@ static void dctcp_init(struct sock *sk) · 9 unmodified lines | ||
| 111 | 113 | |
| 112 | 114 | static u32 dctcp_ssthresh(struct sock *sk) |
| 113 | 115 | { |
| 114 | − const struct dctcp *ca = inet_csk_ca(sk); | |
| 116 | + struct dctcp *ca = inet_csk_ca(sk); | |
| 115 | 117 | struct tcp_sock *tp = tcp_sk(sk); |
| 116 | 118 | |
| 119 | + ca->loss_cwnd = tp->snd_cwnd; | |
| 117 | 120 | return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->dctcp_alpha) >> 11U), 2U); |
| 118 | 121 | } |
| 119 | 122 | |
| @@ -308,12 +311,20 @@ static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr, · 188 unmodified lines | ||
| 308 | 311 | return 0; |
| 309 | 312 | } |
| 310 | 313 | |
| 314 | +static u32 dctcp_cwnd_undo(struct sock *sk) | |
| 315 | +{ | |
| 316 | + const struct dctcp *ca = inet_csk_ca(sk); | |
| 317 | + | |
| 318 | + return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd); | |
| 319 | +} | |
| 320 | + | |
| 311 | 321 | static struct tcp_congestion_ops dctcp __read_mostly = { |
| 312 | 322 | .init = dctcp_init, |
| 313 | 323 | .in_ack_event = dctcp_update_alpha, |
| 314 | 324 | .cwnd_event = dctcp_cwnd_event, |
| 315 | 325 | .ssthresh = dctcp_ssthresh, |
| 316 | 326 | .cong_avoid = tcp_reno_cong_avoid, |
| 327 | + .undo_cwnd = dctcp_cwnd_undo, | |
| 317 | 328 | .set_state = dctcp_state, |
| 318 | 329 | .get_info = dctcp_get_info, |
| 319 | 330 | .flags = TCP_CONG_NEEDS_ECN, |
| @@ -1564,6 +1564,21 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) · 1563 unmodified lines | ||
| 1564 | 1564 | } |
| 1565 | 1565 | EXPORT_SYMBOL(tcp_add_backlog); |
| 1566 | 1566 | |
| 1567 | +int tcp_filter(struct sock *sk, struct sk_buff *skb) | |
| 1568 | +{ | |
| 1569 | + struct tcphdr *th = (struct tcphdr *)skb->data; | |
| 1570 | + unsigned int eaten = skb->len; | |
| 1571 | + int err; | |
| 1572 | + | |
| 1573 | + err = sk_filter_trim_cap(sk, skb, th->doff * 4); | |
| 1574 | + if (!err) { | |
| 1575 | + eaten -= skb->len; | |
| 1576 | + TCP_SKB_CB(skb)->end_seq -= eaten; | |
| 1577 | + } | |
| 1578 | + return err; | |
| 1579 | +} | |
| 1580 | +EXPORT_SYMBOL(tcp_filter); | |
| 1581 | + | |
| 1567 | 1582 | /* |
| 1568 | 1583 | * From tcp_input.c |
| 1569 | 1584 | */ |
| @@ -1676,8 +1691,10 @@ process: · 106 unmodified lines | ||
| 1676 | 1691 | |
| 1677 | 1692 | nf_reset(skb); |
| 1678 | 1693 | |
| 1679 | − if (sk_filter(sk, skb)) | |
| 1694 | + if (tcp_filter(sk, skb)) | |
| 1680 | 1695 | goto discard_and_relse; |
| 1696 | + th = (const struct tcphdr *)skb->data; | |
| 1697 | + iph = ip_hdr(skb); | |
| 1681 | 1698 | |
| 1682 | 1699 | skb->dev = NULL; |
| 1683 | 1700 | |
| @@ -1652,10 +1652,10 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, · 1651 unmodified lines | ||
| 1652 | 1652 | |
| 1653 | 1653 | if (use_hash2) { |
| 1654 | 1654 | hash2_any = udp4_portaddr_hash(net, htonl(INADDR_ANY), hnum) & |
| 1655 | − udp_table.mask; | |
| 1656 | − hash2 = udp4_portaddr_hash(net, daddr, hnum) & udp_table.mask; | |
| 1655 | + udptable->mask; | |
| 1656 | + hash2 = udp4_portaddr_hash(net, daddr, hnum) & udptable->mask; | |
| 1657 | 1657 | start_lookup: |
| 1658 | − hslot = &udp_table.hash2[hash2]; | |
| 1658 | + hslot = &udptable->hash2[hash2]; | |
| 1659 | 1659 | offset = offsetof(typeof(*sk), __sk_common.skc_portaddr_node); |
| 1660 | 1660 | } |
| 1661 | 1661 | |
| @@ -448,7 +448,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, · 447 unmodified lines | ||
| 448 | 448 | if (__ipv6_addr_needs_scope_id(addr_type)) |
| 449 | 449 | iif = skb->dev->ifindex; |
| 450 | 450 | else |
| 451 | − iif = l3mdev_master_ifindex(skb->dev); | |
| 451 | + iif = l3mdev_master_ifindex(skb_dst(skb)->dev); | |
| 452 | 452 | |
| 453 | 453 | /* |
| 454 | 454 | * Must not send error if the source does not uniquely |
| @@ -1366,7 +1366,7 @@ emsgsize: · 1365 unmodified lines | ||
| 1366 | 1366 | if (((length > mtu) || |
| 1367 | 1367 | (skb && skb_is_gso(skb))) && |
| 1368 | 1368 | (sk->sk_protocol == IPPROTO_UDP) && |
| 1369 | − (rt->dst.dev->features & NETIF_F_UFO) && | |
| 1369 | + (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len && | |
| 1370 | 1370 | (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { |
| 1371 | 1371 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, |
| 1372 | 1372 | hh_len, fragheaderlen, exthdrlen, |
| @@ -1034,6 +1034,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, · 1033 unmodified lines | ||
| 1034 | 1034 | int mtu; |
| 1035 | 1035 | unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen; |
| 1036 | 1036 | unsigned int max_headroom = psh_hlen; |
| 1037 | + bool use_cache = false; | |
| 1037 | 1038 | u8 hop_limit; |
| 1038 | 1039 | int err = -1; |
| 1039 | 1040 | |
| @@ -1066,7 +1067,15 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, · 26 unmodified lines | ||
| 1066 | 1067 | |
| 1067 | 1068 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); |
| 1068 | 1069 | neigh_release(neigh); |
| 1069 | − } else if (!fl6->flowi6_mark) | |
| 1070 | + } else if (!(t->parms.flags & | |
| 1071 | + (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { | |
| 1072 | + /* enable the cache only only if the routing decision does | |
| 1073 | + * not depend on the current inner header value | |
| 1074 | + */ | |
| 1075 | + use_cache = true; | |
| 1076 | + } | |
| 1077 | + | |
| 1078 | + if (use_cache) | |
| 1070 | 1079 | dst = dst_cache_get(&t->dst_cache); |
| 1071 | 1080 | |
| 1072 | 1081 | if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) |
| @@ -1150,7 +1159,7 @@ route_lookup: · 77 unmodified lines | ||
| 1150 | 1159 | if (t->encap.type != TUNNEL_ENCAP_NONE) |
| 1151 | 1160 | goto tx_err_dst_release; |
| 1152 | 1161 | } else { |
| 1153 | − if (!fl6->flowi6_mark && ndst) | |
| 1162 | + if (use_cache && ndst) | |
| 1154 | 1163 | dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr); |
| 1155 | 1164 | } |
| 1156 | 1165 | skb_dst_set(skb, dst); |
| @@ -88,9 +88,6 @@ int udp_tunnel6_xmit_skb(struct dst_entry *dst, struct sock *sk, · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | uh->len = htons(skb->len); |
| 90 | 90 | |
| 91 | − memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | |
| 92 | − IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
| 93 | − | IPSKB_REROUTED); | |
| 94 | 91 | skb_dst_set(skb, dst); |
| 95 | 92 | |
| 96 | 93 | udp6_set_csum(nocheck, skb, saddr, daddr, skb->len); |
| @@ -26,7 +26,7 @@ static void nft_dup_ipv6_eval(const struct nft_expr *expr, · 25 unmodified lines | ||
| 26 | 26 | { |
| 27 | 27 | struct nft_dup_ipv6 *priv = nft_expr_priv(expr); |
| 28 | 28 | struct in6_addr *gw = (struct in6_addr *)®s->data[priv->sreg_addr]; |
| 29 | − int oif = regs->data[priv->sreg_dev]; | |
| 29 | + int oif = priv->sreg_dev ? regs->data[priv->sreg_dev] : -1; | |
| 30 | 30 | |
| 31 | 31 | nf_dup_ipv6(pkt->net, pkt->skb, pkt->hook, gw, oif); |
| 32 | 32 | } |
| @@ -57,7 +57,9 @@ static int nft_dup_ipv6_dump(struct sk_buff *skb, const struct nft_expr *expr) · 24 unmodified lines | ||
| 57 | 57 | { |
| 58 | 58 | struct nft_dup_ipv6 *priv = nft_expr_priv(expr); |
| 59 | 59 | |
| 60 | − if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr) || | |
| 60 | + if (nft_dump_register(skb, NFTA_DUP_SREG_ADDR, priv->sreg_addr)) | |
| 61 | + goto nla_put_failure; | |
| 62 | + if (priv->sreg_dev && | |
| 61 | 63 | nft_dump_register(skb, NFTA_DUP_SREG_DEV, priv->sreg_dev)) |
| 62 | 64 | goto nla_put_failure; |
| 63 | 65 | |
| @@ -1364,6 +1364,9 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, · 1363 unmodified lines | ||
| 1364 | 1364 | if (rt6->rt6i_flags & RTF_LOCAL) |
| 1365 | 1365 | return; |
| 1366 | 1366 | |
| 1367 | + if (dst_metric_locked(dst, RTAX_MTU)) | |
| 1368 | + return; | |
| 1369 | + | |
| 1367 | 1370 | dst_confirm(dst); |
| 1368 | 1371 | mtu = max_t(u32, mtu, IPV6_MIN_MTU); |
| 1369 | 1372 | if (mtu >= dst_mtu(dst)) |
| @@ -2758,6 +2761,7 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg) · 1388 unmodified lines | ||
| 2758 | 2761 | PMTU discouvery. |
| 2759 | 2762 | */ |
| 2760 | 2763 | if (rt->dst.dev == arg->dev && |
| 2764 | + dst_metric_raw(&rt->dst, RTAX_MTU) && | |
| 2761 | 2765 | !dst_metric_locked(&rt->dst, RTAX_MTU)) { |
| 2762 | 2766 | if (rt->rt6i_flags & RTF_CACHE) { |
| 2763 | 2767 | /* For RTF_CACHE with rt6i_pmtu == 0 |
| @@ -818,8 +818,12 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 · 817 unmodified lines | ||
| 818 | 818 | fl6.flowi6_proto = IPPROTO_TCP; |
| 819 | 819 | if (rt6_need_strict(&fl6.daddr) && !oif) |
| 820 | 820 | fl6.flowi6_oif = tcp_v6_iif(skb); |
| 821 | − else | |
| 822 | − fl6.flowi6_oif = oif ? : skb->skb_iif; | |
| 821 | + else { | |
| 822 | + if (!oif && netif_index_is_l3_master(net, skb->skb_iif)) | |
| 823 | + oif = skb->skb_iif; | |
| 824 | + | |
| 825 | + fl6.flowi6_oif = oif; | |
| 826 | + } | |
| 823 | 827 | |
| 824 | 828 | fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark); |
| 825 | 829 | fl6.fl6_dport = t1->dest; |
| @@ -1225,7 +1229,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) · 399 unmodified lines | ||
| 1225 | 1229 | if (skb->protocol == htons(ETH_P_IP)) |
| 1226 | 1230 | return tcp_v4_do_rcv(sk, skb); |
| 1227 | 1231 | |
| 1228 | − if (sk_filter(sk, skb)) | |
| 1232 | + if (tcp_filter(sk, skb)) | |
| 1229 | 1233 | goto discard; |
| 1230 | 1234 | |
| 1231 | 1235 | /* |
| @@ -1453,8 +1457,10 @@ process: · 221 unmodified lines | ||
| 1453 | 1457 | if (tcp_v6_inbound_md5_hash(sk, skb)) |
| 1454 | 1458 | goto discard_and_relse; |
| 1455 | 1459 | |
| 1456 | − if (sk_filter(sk, skb)) | |
| 1460 | + if (tcp_filter(sk, skb)) | |
| 1457 | 1461 | goto discard_and_relse; |
| 1462 | + th = (const struct tcphdr *)skb->data; | |
| 1463 | + hdr = ipv6_hdr(skb); | |
| 1458 | 1464 | |
| 1459 | 1465 | skb->dev = NULL; |
| 1460 | 1466 | |
| @@ -706,10 +706,10 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, · 705 unmodified lines | ||
| 706 | 706 | |
| 707 | 707 | if (use_hash2) { |
| 708 | 708 | hash2_any = udp6_portaddr_hash(net, &in6addr_any, hnum) & |
| 709 | − udp_table.mask; | |
| 710 | − hash2 = udp6_portaddr_hash(net, daddr, hnum) & udp_table.mask; | |
| 709 | + udptable->mask; | |
| 710 | + hash2 = udp6_portaddr_hash(net, daddr, hnum) & udptable->mask; | |
| 711 | 711 | start_lookup: |
| 712 | − hslot = &udp_table.hash2[hash2]; | |
| 712 | + hslot = &udptable->hash2[hash2]; | |
| 713 | 713 | offset = offsetof(typeof(*sk), __sk_common.skc_portaddr_node); |
| 714 | 714 | } |
| 715 | 715 | |
| @@ -97,7 +97,7 @@ static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev) · 96 unmodified lines | ||
| 97 | 97 | unsigned int len = skb->len; |
| 98 | 98 | int ret = l2tp_xmit_skb(session, skb, session->hdr_len); |
| 99 | 99 | |
| 100 | − if (likely(ret == NET_XMIT_SUCCESS)) { | |
| 100 | + if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { | |
| 101 | 101 | atomic_long_add(len, &priv->tx_bytes); |
| 102 | 102 | atomic_long_inc(&priv->tx_packets); |
| 103 | 103 | } else { |
| @@ -251,8 +251,6 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) · 250 unmodified lines | ||
| 251 | 251 | int ret; |
| 252 | 252 | int chk_addr_ret; |
| 253 | 253 | |
| 254 | − if (!sock_flag(sk, SOCK_ZAPPED)) | |
| 255 | − return -EINVAL; | |
| 256 | 254 | if (addr_len < sizeof(struct sockaddr_l2tpip)) |
| 257 | 255 | return -EINVAL; |
| 258 | 256 | if (addr->l2tp_family != AF_INET) |
| @@ -267,6 +265,9 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) · 8 unmodified lines | ||
| 267 | 265 | read_unlock_bh(&l2tp_ip_lock); |
| 268 | 266 | |
| 269 | 267 | lock_sock(sk); |
| 268 | + if (!sock_flag(sk, SOCK_ZAPPED)) | |
| 269 | + goto out; | |
| 270 | + | |
| 270 | 271 | if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip)) |
| 271 | 272 | goto out; |
| 272 | 273 | |
| @@ -269,8 +269,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) · 268 unmodified lines | ||
| 269 | 269 | int addr_type; |
| 270 | 270 | int err; |
| 271 | 271 | |
| 272 | − if (!sock_flag(sk, SOCK_ZAPPED)) | |
| 273 | − return -EINVAL; | |
| 274 | 272 | if (addr->l2tp_family != AF_INET6) |
| 275 | 273 | return -EINVAL; |
| 276 | 274 | if (addr_len < sizeof(*addr)) |
| @@ -296,6 +294,9 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) · 19 unmodified lines | ||
| 296 | 294 | lock_sock(sk); |
| 297 | 295 | |
| 298 | 296 | err = -EINVAL; |
| 297 | + if (!sock_flag(sk, SOCK_ZAPPED)) | |
| 298 | + goto out_unlock; | |
| 299 | + | |
| 299 | 300 | if (sk->sk_state != TCP_CLOSE) |
| 300 | 301 | goto out_unlock; |
| 301 | 302 | |
| @@ -688,7 +688,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending) · 687 unmodified lines | ||
| 688 | 688 | } |
| 689 | 689 | |
| 690 | 690 | /* No need to do anything if the driver does all */ |
| 691 | − if (!local->ops->set_tim) | |
| 691 | + if (ieee80211_hw_check(&local->hw, AP_LINK_PS)) | |
| 692 | 692 | return; |
| 693 | 693 | |
| 694 | 694 | if (sta->dead) |
| @@ -1501,7 +1501,6 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local, · 1500 unmodified lines | ||
| 1501 | 1501 | struct sta_info *sta, |
| 1502 | 1502 | struct sk_buff *skb) |
| 1503 | 1503 | { |
| 1504 | − struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | |
| 1505 | 1504 | struct fq *fq = &local->fq; |
| 1506 | 1505 | struct ieee80211_vif *vif; |
| 1507 | 1506 | struct txq_info *txqi; |
| @@ -1526,8 +1525,6 @@ static bool ieee80211_queue_skb(struct ieee80211_local *local, · 18 unmodified lines | ||
| 1526 | 1525 | if (!txqi) |
| 1527 | 1526 | return false; |
| 1528 | 1527 | |
| 1529 | − info->control.vif = vif; | |
| 1530 | − | |
| 1531 | 1528 | spin_lock_bh(&fq->lock); |
| 1532 | 1529 | ieee80211_txq_enqueue(local, txqi, skb); |
| 1533 | 1530 | spin_unlock_bh(&fq->lock); |
| @@ -3213,7 +3210,6 @@ static void ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata, · 1679 unmodified lines | ||
| 3213 | 3210 | |
| 3214 | 3211 | if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { |
| 3215 | 3212 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
| 3216 | − *ieee80211_get_qos_ctl(hdr) = tid; | |
| 3217 | 3213 | hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); |
| 3218 | 3214 | } else { |
| 3219 | 3215 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
| @@ -3338,6 +3334,11 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, · 118 unmodified lines | ||
| 3338 | 3334 | (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); |
| 3339 | 3335 | info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT; |
| 3340 | 3336 | |
| 3337 | + if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { | |
| 3338 | + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; | |
| 3339 | + *ieee80211_get_qos_ctl(hdr) = tid; | |
| 3340 | + } | |
| 3341 | + | |
| 3341 | 3342 | __skb_queue_head_init(&tx.skbs); |
| 3342 | 3343 | |
| 3343 | 3344 | tx.flags = IEEE80211_TX_UNICAST; |
| @@ -3426,6 +3427,11 @@ begin: · 82 unmodified lines | ||
| 3426 | 3427 | goto begin; |
| 3427 | 3428 | } |
| 3428 | 3429 | |
| 3430 | + if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags)) | |
| 3431 | + info->flags |= IEEE80211_TX_CTL_AMPDU; | |
| 3432 | + else | |
| 3433 | + info->flags &= ~IEEE80211_TX_CTL_AMPDU; | |
| 3434 | + | |
| 3429 | 3435 | if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) { |
| 3430 | 3436 | struct sta_info *sta = container_of(txq->sta, struct sta_info, |
| 3431 | 3437 | sta); |
| @@ -270,6 +270,22 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, · 269 unmodified lines | ||
| 270 | 270 | vht_cap->vht_mcs.tx_mcs_map |= cpu_to_le16(peer_tx << i * 2); |
| 271 | 271 | } |
| 272 | 272 | |
| 273 | + /* | |
| 274 | + * This is a workaround for VHT-enabled STAs which break the spec | |
| 275 | + * and have the VHT-MCS Rx map filled in with value 3 for all eight | |
| 276 | + * spacial streams, an example is AR9462. | |
| 277 | + * | |
| 278 | + * As per spec, in section 22.1.1 Introduction to the VHT PHY | |
| 279 | + * A VHT STA shall support at least single spactial stream VHT-MCSs | |
| 280 | + * 0 to 7 (transmit and receive) in all supported channel widths. | |
| 281 | + */ | |
| 282 | + if (vht_cap->vht_mcs.rx_mcs_map == cpu_to_le16(0xFFFF)) { | |
| 283 | + vht_cap->vht_supported = false; | |
| 284 | + sdata_info(sdata, "Ignoring VHT IE from %pM due to invalid rx_mcs_map\n", | |
| 285 | + sta->addr); | |
| 286 | + return; | |
| 287 | + } | |
| 288 | + | |
| 273 | 289 | /* finally set up the bandwidth */ |
| 274 | 290 | switch (vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) { |
| 275 | 291 | case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: |
| @@ -2845,7 +2845,7 @@ static struct genl_family ip_vs_genl_family = { · 2844 unmodified lines | ||
| 2845 | 2845 | .hdrsize = 0, |
| 2846 | 2846 | .name = IPVS_GENL_NAME, |
| 2847 | 2847 | .version = IPVS_GENL_VERSION, |
| 2848 | − .maxattr = IPVS_CMD_MAX, | |
| 2848 | + .maxattr = IPVS_CMD_ATTR_MAX, | |
| 2849 | 2849 | .netnsok = true, /* Make ipvsadm to work on netns */ |
| 2850 | 2850 | }; |
| 2851 | 2851 | |
| @@ -283,6 +283,7 @@ struct ip_vs_sync_buff { · 282 unmodified lines | ||
| 283 | 283 | */ |
| 284 | 284 | static void ntoh_seq(struct ip_vs_seq *no, struct ip_vs_seq *ho) |
| 285 | 285 | { |
| 286 | + memset(ho, 0, sizeof(*ho)); | |
| 286 | 287 | ho->init_seq = get_unaligned_be32(&no->init_seq); |
| 287 | 288 | ho->delta = get_unaligned_be32(&no->delta); |
| 288 | 289 | ho->previous_delta = get_unaligned_be32(&no->previous_delta); |
| @@ -917,8 +918,10 @@ static void ip_vs_proc_conn(struct netns_ipvs *ipvs, struct ip_vs_conn_param *pa · 628 unmodified lines | ||
| 917 | 918 | kfree(param->pe_data); |
| 918 | 919 | } |
| 919 | 920 | |
| 920 | − if (opt) | |
| 921 | − memcpy(&cp->in_seq, opt, sizeof(*opt)); | |
| 921 | + if (opt) { | |
| 922 | + cp->in_seq = opt->in_seq; | |
| 923 | + cp->out_seq = opt->out_seq; | |
| 924 | + } | |
| 922 | 925 | atomic_set(&cp->in_pkts, sysctl_sync_threshold(ipvs)); |
| 923 | 926 | cp->state = state; |
| 924 | 927 | cp->old_state = cp->state; |
| @@ -76,6 +76,7 @@ struct conntrack_gc_work { · 75 unmodified lines | ||
| 76 | 76 | struct delayed_work dwork; |
| 77 | 77 | u32 last_bucket; |
| 78 | 78 | bool exiting; |
| 79 | + long next_gc_run; | |
| 79 | 80 | }; |
| 80 | 81 | |
| 81 | 82 | static __read_mostly struct kmem_cache *nf_conntrack_cachep; |
| @@ -83,9 +84,11 @@ static __read_mostly spinlock_t nf_conntrack_locks_all_lock; · 1 unmodified line | ||
| 83 | 84 | static __read_mostly DEFINE_SPINLOCK(nf_conntrack_locks_all_lock); |
| 84 | 85 | static __read_mostly bool nf_conntrack_locks_all; |
| 85 | 86 | |
| 87 | +/* every gc cycle scans at most 1/GC_MAX_BUCKETS_DIV part of table */ | |
| 86 | 88 | #define GC_MAX_BUCKETS_DIV 64u |
| 87 | −#define GC_MAX_BUCKETS 8192u | |
| 88 | −#define GC_INTERVAL (5 * HZ) | |
| 89 | +/* upper bound of scan intervals */ | |
| 90 | +#define GC_INTERVAL_MAX (2 * HZ) | |
| 91 | +/* maximum conntracks to evict per gc run */ | |
| 89 | 92 | #define GC_MAX_EVICTS 256u |
| 90 | 93 | |
| 91 | 94 | static struct conntrack_gc_work conntrack_gc_work; |
| @@ -936,13 +939,13 @@ static noinline int early_drop(struct net *net, unsigned int _hash) · 844 unmodified lines | ||
| 936 | 939 | static void gc_worker(struct work_struct *work) |
| 937 | 940 | { |
| 938 | 941 | unsigned int i, goal, buckets = 0, expired_count = 0; |
| 939 | − unsigned long next_run = GC_INTERVAL; | |
| 940 | − unsigned int ratio, scanned = 0; | |
| 941 | 942 | struct conntrack_gc_work *gc_work; |
| 943 | + unsigned int ratio, scanned = 0; | |
| 944 | + unsigned long next_run; | |
| 942 | 945 | |
| 943 | 946 | gc_work = container_of(work, struct conntrack_gc_work, dwork.work); |
| 944 | 947 | |
| 945 | − goal = min(nf_conntrack_htable_size / GC_MAX_BUCKETS_DIV, GC_MAX_BUCKETS); | |
| 948 | + goal = nf_conntrack_htable_size / GC_MAX_BUCKETS_DIV; | |
| 946 | 949 | i = gc_work->last_bucket; |
| 947 | 950 | |
| 948 | 951 | do { |
| @@ -982,17 +985,47 @@ static void gc_worker(struct work_struct *work) · 33 unmodified lines | ||
| 982 | 985 | if (gc_work->exiting) |
| 983 | 986 | return; |
| 984 | 987 | |
| 988 | + /* | |
| 989 | + * Eviction will normally happen from the packet path, and not | |
| 990 | + * from this gc worker. | |
| 991 | + * | |
| 992 | + * This worker is only here to reap expired entries when system went | |
| 993 | + * idle after a busy period. | |
| 994 | + * | |
| 995 | + * The heuristics below are supposed to balance conflicting goals: | |
| 996 | + * | |
| 997 | + * 1. Minimize time until we notice a stale entry | |
| 998 | + * 2. Maximize scan intervals to not waste cycles | |
| 999 | + * | |
| 1000 | + * Normally, expired_count will be 0, this increases the next_run time | |
| 1001 | + * to priorize 2) above. | |
| 1002 | + * | |
| 1003 | + * As soon as a timed-out entry is found, move towards 1) and increase | |
| 1004 | + * the scan frequency. | |
| 1005 | + * In case we have lots of evictions next scan is done immediately. | |
| 1006 | + */ | |
| 985 | 1007 | ratio = scanned ? expired_count * 100 / scanned : 0; |
| 986 | − if (ratio >= 90 || expired_count == GC_MAX_EVICTS) | |
| 1008 | + if (ratio >= 90 || expired_count == GC_MAX_EVICTS) { | |
| 1009 | + gc_work->next_gc_run = 0; | |
| 987 | 1010 | next_run = 0; |
| 1011 | + } else if (expired_count) { | |
| 1012 | + gc_work->next_gc_run /= 2U; | |
| 1013 | + next_run = msecs_to_jiffies(1); | |
| 1014 | + } else { | |
| 1015 | + if (gc_work->next_gc_run < GC_INTERVAL_MAX) | |
| 1016 | + gc_work->next_gc_run += msecs_to_jiffies(1); | |
| 1017 | + | |
| 1018 | + next_run = gc_work->next_gc_run; | |
| 1019 | + } | |
| 988 | 1020 | |
| 989 | 1021 | gc_work->last_bucket = i; |
| 990 | − schedule_delayed_work(&gc_work->dwork, next_run); | |
| 1022 | + queue_delayed_work(system_long_wq, &gc_work->dwork, next_run); | |
| 991 | 1023 | } |
| 992 | 1024 | |
| 993 | 1025 | static void conntrack_gc_work_init(struct conntrack_gc_work *gc_work) |
| 994 | 1026 | { |
| 995 | 1027 | INIT_DELAYED_WORK(&gc_work->dwork, gc_worker); |
| 1028 | + gc_work->next_gc_run = GC_INTERVAL_MAX; | |
| 996 | 1029 | gc_work->exiting = false; |
| 997 | 1030 | } |
| 998 | 1031 | |
| @@ -1885,7 +1918,7 @@ int nf_conntrack_init_start(void) · 886 unmodified lines | ||
| 1885 | 1918 | nf_ct_untracked_status_or(IPS_CONFIRMED | IPS_UNTRACKED); |
| 1886 | 1919 | |
| 1887 | 1920 | conntrack_gc_work_init(&conntrack_gc_work); |
| 1888 | − schedule_delayed_work(&conntrack_gc_work.dwork, GC_INTERVAL); | |
| 1921 | + queue_delayed_work(system_long_wq, &conntrack_gc_work.dwork, GC_INTERVAL_MAX); | |
| 1889 | 1922 | |
| 1890 | 1923 | return 0; |
| 1891 | 1924 | |
| @@ -138,9 +138,14 @@ __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum) · 137 unmodified lines | ||
| 138 | 138 | |
| 139 | 139 | for (i = 0; i < nf_ct_helper_hsize; i++) { |
| 140 | 140 | hlist_for_each_entry_rcu(h, &nf_ct_helper_hash[i], hnode) { |
| 141 | − if (!strcmp(h->name, name) && | |
| 142 | − h->tuple.src.l3num == l3num && | |
| 143 | − h->tuple.dst.protonum == protonum) | |
| 141 | + if (strcmp(h->name, name)) | |
| 142 | + continue; | |
| 143 | + | |
| 144 | + if (h->tuple.src.l3num != NFPROTO_UNSPEC && | |
| 145 | + h->tuple.src.l3num != l3num) | |
| 146 | + continue; | |
| 147 | + | |
| 148 | + if (h->tuple.dst.protonum == protonum) | |
| 144 | 149 | return h; |
| 145 | 150 | } |
| 146 | 151 | } |
| @@ -1436,9 +1436,12 @@ static int process_sip_request(struct sk_buff *skb, unsigned int protoff, · 1435 unmodified lines | ||
| 1436 | 1436 | handler = &sip_handlers[i]; |
| 1437 | 1437 | if (handler->request == NULL) |
| 1438 | 1438 | continue; |
| 1439 | − if (*datalen < handler->len || | |
| 1439 | + if (*datalen < handler->len + 2 || | |
| 1440 | 1440 | strncasecmp(*dptr, handler->method, handler->len)) |
| 1441 | 1441 | continue; |
| 1442 | + if ((*dptr)[handler->len] != ' ' || | |
| 1443 | + !isalpha((*dptr)[handler->len+1])) | |
| 1444 | + continue; | |
| 1442 | 1445 | |
| 1443 | 1446 | if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ, |
| 1444 | 1447 | &matchoff, &matchlen) <= 0) { |
| @@ -2956,12 +2956,14 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, · 2955 unmodified lines | ||
| 2956 | 2956 | |
| 2957 | 2957 | err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set); |
| 2958 | 2958 | if (err < 0) |
| 2959 | − goto err2; | |
| 2959 | + goto err3; | |
| 2960 | 2960 | |
| 2961 | 2961 | list_add_tail_rcu(&set->list, &table->sets); |
| 2962 | 2962 | table->use++; |
| 2963 | 2963 | return 0; |
| 2964 | 2964 | |
| 2965 | +err3: | |
| 2966 | + ops->destroy(set); | |
| 2965 | 2967 | err2: |
| 2966 | 2968 | kfree(set); |
| 2967 | 2969 | err1: |
| @@ -3452,14 +3454,15 @@ void *nft_set_elem_init(const struct nft_set *set, · 484 unmodified lines | ||
| 3452 | 3454 | return elem; |
| 3453 | 3455 | } |
| 3454 | 3456 | |
| 3455 | −void nft_set_elem_destroy(const struct nft_set *set, void *elem) | |
| 3457 | +void nft_set_elem_destroy(const struct nft_set *set, void *elem, | |
| 3458 | + bool destroy_expr) | |
| 3456 | 3459 | { |
| 3457 | 3460 | struct nft_set_ext *ext = nft_set_elem_ext(set, elem); |
| 3458 | 3461 | |
| 3459 | 3462 | nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE); |
| 3460 | 3463 | if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) |
| 3461 | 3464 | nft_data_uninit(nft_set_ext_data(ext), set->dtype); |
| 3462 | − if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) | |
| 3465 | + if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) | |
| 3463 | 3466 | nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext)); |
| 3464 | 3467 | |
| 3465 | 3468 | kfree(elem); |
| @@ -3565,6 +3568,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, · 99 unmodified lines | ||
| 3565 | 3568 | dreg = nft_type_to_reg(set->dtype); |
| 3566 | 3569 | list_for_each_entry(binding, &set->bindings, list) { |
| 3567 | 3570 | struct nft_ctx bind_ctx = { |
| 3571 | + .net = ctx->net, | |
| 3568 | 3572 | .afi = ctx->afi, |
| 3569 | 3573 | .table = ctx->table, |
| 3570 | 3574 | .chain = (struct nft_chain *)binding->chain, |
| @@ -3812,7 +3816,7 @@ void nft_set_gc_batch_release(struct rcu_head *rcu) · 241 unmodified lines | ||
| 3812 | 3816 | |
| 3813 | 3817 | gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu); |
| 3814 | 3818 | for (i = 0; i < gcb->head.cnt; i++) |
| 3815 | − nft_set_elem_destroy(gcb->head.set, gcb->elems[i]); | |
| 3819 | + nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true); | |
| 3816 | 3820 | kfree(gcb); |
| 3817 | 3821 | } |
| 3818 | 3822 | EXPORT_SYMBOL_GPL(nft_set_gc_batch_release); |
| @@ -4030,7 +4034,7 @@ static void nf_tables_commit_release(struct nft_trans *trans) · 211 unmodified lines | ||
| 4030 | 4034 | break; |
| 4031 | 4035 | case NFT_MSG_DELSETELEM: |
| 4032 | 4036 | nft_set_elem_destroy(nft_trans_elem_set(trans), |
| 4033 | − nft_trans_elem(trans).priv); | |
| 4037 | + nft_trans_elem(trans).priv, true); | |
| 4034 | 4038 | break; |
| 4035 | 4039 | } |
| 4036 | 4040 | kfree(trans); |
| @@ -4171,7 +4175,7 @@ static void nf_tables_abort_release(struct nft_trans *trans) · 134 unmodified lines | ||
| 4171 | 4175 | break; |
| 4172 | 4176 | case NFT_MSG_NEWSETELEM: |
| 4173 | 4177 | nft_set_elem_destroy(nft_trans_elem_set(trans), |
| 4174 | − nft_trans_elem(trans).priv); | |
| 4178 | + nft_trans_elem(trans).priv, true); | |
| 4175 | 4179 | break; |
| 4176 | 4180 | } |
| 4177 | 4181 | kfree(trans); |
| @@ -4421,7 +4425,7 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx, · 243 unmodified lines | ||
| 4421 | 4425 | * Otherwise a 0 is returned and the attribute value is stored in the |
| 4422 | 4426 | * destination variable. |
| 4423 | 4427 | */ |
| 4424 | −unsigned int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest) | |
| 4428 | +int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest) | |
| 4425 | 4429 | { |
| 4426 | 4430 | u32 val; |
| 4427 | 4431 | |
| @@ -44,18 +44,22 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr, · 43 unmodified lines | ||
| 44 | 44 | ®s->data[priv->sreg_key], |
| 45 | 45 | ®s->data[priv->sreg_data], |
| 46 | 46 | timeout, GFP_ATOMIC); |
| 47 | − if (elem == NULL) { | |
| 48 | − if (set->size) | |
| 49 | − atomic_dec(&set->nelems); | |
| 50 | − return NULL; | |
| 51 | − } | |
| 47 | + if (elem == NULL) | |
| 48 | + goto err1; | |
| 52 | 49 | |
| 53 | 50 | ext = nft_set_elem_ext(set, elem); |
| 54 | 51 | if (priv->expr != NULL && |
| 55 | 52 | nft_expr_clone(nft_set_ext_expr(ext), priv->expr) < 0) |
| 56 | − return NULL; | |
| 53 | + goto err2; | |
| 57 | 54 | |
| 58 | 55 | return elem; |
| 56 | + | |
| 57 | +err2: | |
| 58 | + nft_set_elem_destroy(set, elem, false); | |
| 59 | +err1: | |
| 60 | + if (set->size) | |
| 61 | + atomic_dec(&set->nelems); | |
| 62 | + return NULL; | |
| 59 | 63 | } |
| 60 | 64 | |
| 61 | 65 | static void nft_dynset_eval(const struct nft_expr *expr, |
| @@ -139,6 +143,9 @@ static int nft_dynset_init(const struct nft_ctx *ctx, · 77 unmodified lines | ||
| 139 | 143 | return PTR_ERR(set); |
| 140 | 144 | } |
| 141 | 145 | |
| 146 | + if (set->ops->update == NULL) | |
| 147 | + return -EOPNOTSUPP; | |
| 148 | + | |
| 142 | 149 | if (set->flags & NFT_SET_CONSTANT) |
| 143 | 150 | return -EBUSY; |
| 144 | 151 | |
| @@ -98,7 +98,7 @@ static bool nft_hash_update(struct nft_set *set, const u32 *key, · 97 unmodified lines | ||
| 98 | 98 | const struct nft_set_ext **ext) |
| 99 | 99 | { |
| 100 | 100 | struct nft_hash *priv = nft_set_priv(set); |
| 101 | − struct nft_hash_elem *he; | |
| 101 | + struct nft_hash_elem *he, *prev; | |
| 102 | 102 | struct nft_hash_cmp_arg arg = { |
| 103 | 103 | .genmask = NFT_GENMASK_ANY, |
| 104 | 104 | .set = set, |
| @@ -112,15 +112,24 @@ static bool nft_hash_update(struct nft_set *set, const u32 *key, · 7 unmodified lines | ||
| 112 | 112 | he = new(set, expr, regs); |
| 113 | 113 | if (he == NULL) |
| 114 | 114 | goto err1; |
| 115 | − if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node, | |
| 116 | − nft_hash_params)) | |
| 115 | + | |
| 116 | + prev = rhashtable_lookup_get_insert_key(&priv->ht, &arg, &he->node, | |
| 117 | + nft_hash_params); | |
| 118 | + if (IS_ERR(prev)) | |
| 117 | 119 | goto err2; |
| 120 | + | |
| 121 | + /* Another cpu may race to insert the element with the same key */ | |
| 122 | + if (prev) { | |
| 123 | + nft_set_elem_destroy(set, he, true); | |
| 124 | + he = prev; | |
| 125 | + } | |
| 126 | + | |
| 118 | 127 | out: |
| 119 | 128 | *ext = &he->ext; |
| 120 | 129 | return true; |
| 121 | 130 | |
| 122 | 131 | err2: |
| 123 | − nft_set_elem_destroy(set, he); | |
| 132 | + nft_set_elem_destroy(set, he, true); | |
| 124 | 133 | err1: |
| 125 | 134 | return false; |
| 126 | 135 | } |
| @@ -332,7 +341,7 @@ static int nft_hash_init(const struct nft_set *set, · 205 unmodified lines | ||
| 332 | 341 | |
| 333 | 342 | static void nft_hash_elem_destroy(void *ptr, void *arg) |
| 334 | 343 | { |
| 335 | − nft_set_elem_destroy((const struct nft_set *)arg, ptr); | |
| 344 | + nft_set_elem_destroy((const struct nft_set *)arg, ptr, true); | |
| 336 | 345 | } |
| 337 | 346 | |
| 338 | 347 | static void nft_hash_destroy(const struct nft_set *set) |
| @@ -266,7 +266,7 @@ static void nft_rbtree_destroy(const struct nft_set *set) · 265 unmodified lines | ||
| 266 | 266 | while ((node = priv->root.rb_node) != NULL) { |
| 267 | 267 | rb_erase(node, &priv->root); |
| 268 | 268 | rbe = rb_entry(node, struct nft_rbtree_elem, node); |
| 269 | − nft_set_elem_destroy(set, rbe); | |
| 269 | + nft_set_elem_destroy(set, rbe, true); | |
| 270 | 270 | } |
| 271 | 271 | } |
| 272 | 272 | |
| @@ -44,7 +44,7 @@ connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) · 43 unmodified lines | ||
| 44 | 44 | u_int32_t newmark; |
| 45 | 45 | |
| 46 | 46 | ct = nf_ct_get(skb, &ctinfo); |
| 47 | − if (ct == NULL) | |
| 47 | + if (ct == NULL || nf_ct_is_untracked(ct)) | |
| 48 | 48 | return XT_CONTINUE; |
| 49 | 49 | |
| 50 | 50 | switch (info->mode) { |
| @@ -97,7 +97,7 @@ connmark_mt(const struct sk_buff *skb, struct xt_action_param *par) · 46 unmodified lines | ||
| 97 | 97 | const struct nf_conn *ct; |
| 98 | 98 | |
| 99 | 99 | ct = nf_ct_get(skb, &ctinfo); |
| 100 | − if (ct == NULL) | |
| 100 | + if (ct == NULL || nf_ct_is_untracked(ct)) | |
| 101 | 101 | return false; |
| 102 | 102 | |
| 103 | 103 | return ((ct->mark & info->mask) == info->mark) ^ info->invert; |
| @@ -178,11 +178,8 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) · 177 unmodified lines | ||
| 178 | 178 | } |
| 179 | 179 | cb->args[1] = i; |
| 180 | 180 | } else { |
| 181 | − if (req->sdiag_protocol >= MAX_LINKS) { | |
| 182 | − read_unlock(&nl_table_lock); | |
| 183 | − rcu_read_unlock(); | |
| 181 | + if (req->sdiag_protocol >= MAX_LINKS) | |
| 184 | 182 | return -ENOENT; |
| 185 | − } | |
| 186 | 183 | |
| 187 | 184 | err = __netlink_diag_dump(skb, cb, req->sdiag_protocol, s_num); |
| 188 | 185 | } |
| @@ -404,7 +404,7 @@ int __genl_register_family(struct genl_family *family) · 403 unmodified lines | ||
| 404 | 404 | |
| 405 | 405 | err = genl_validate_assign_mc_groups(family); |
| 406 | 406 | if (err) |
| 407 | − goto errout_locked; | |
| 407 | + goto errout_free; | |
| 408 | 408 | |
| 409 | 409 | list_add_tail(&family->family_list, genl_family_chain(family->id)); |
| 410 | 410 | genl_unlock_all(); |
| @@ -417,6 +417,8 @@ int __genl_register_family(struct genl_family *family) · 6 unmodified lines | ||
| 417 | 417 | |
| 418 | 418 | return 0; |
| 419 | 419 | |
| 420 | +errout_free: | |
| 421 | + kfree(family->attrbuf); | |
| 420 | 422 | errout_locked: |
| 421 | 423 | genl_unlock_all(); |
| 422 | 424 | errout: |
| @@ -112,7 +112,7 @@ static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, · 111 unmodified lines | ||
| 112 | 112 | |
| 113 | 113 | for (it_chain = chain; (tp = rtnl_dereference(*it_chain)) != NULL; |
| 114 | 114 | it_chain = &tp->next) |
| 115 | − tfilter_notify(net, oskb, n, tp, 0, event, false); | |
| 115 | + tfilter_notify(net, oskb, n, tp, n->nlmsg_flags, event, false); | |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | /* Select new prio value from the range, managed by kernel. */ |
| @@ -430,7 +430,8 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, · 311 unmodified lines | ||
| 430 | 430 | if (!skb) |
| 431 | 431 | return -ENOBUFS; |
| 432 | 432 | |
| 433 | − if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, 0, event) <= 0) { | |
| 433 | + if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, | |
| 434 | + n->nlmsg_flags, event) <= 0) { | |
| 434 | 435 | kfree_skb(skb); |
| 435 | 436 | return -EINVAL; |
| 436 | 437 | } |
| @@ -181,9 +181,10 @@ int sctp_rcv(struct sk_buff *skb) · 180 unmodified lines | ||
| 181 | 181 | * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB |
| 182 | 182 | */ |
| 183 | 183 | if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) { |
| 184 | − if (asoc) { | |
| 185 | − sctp_association_put(asoc); | |
| 184 | + if (transport) { | |
| 185 | + sctp_transport_put(transport); | |
| 186 | 186 | asoc = NULL; |
| 187 | + transport = NULL; | |
| 187 | 188 | } else { |
| 188 | 189 | sctp_endpoint_put(ep); |
| 189 | 190 | ep = NULL; |
| @@ -269,8 +270,8 @@ int sctp_rcv(struct sk_buff *skb) · 79 unmodified lines | ||
| 269 | 270 | bh_unlock_sock(sk); |
| 270 | 271 | |
| 271 | 272 | /* Release the asoc/ep ref we took in the lookup calls. */ |
| 272 | − if (asoc) | |
| 273 | − sctp_association_put(asoc); | |
| 273 | + if (transport) | |
| 274 | + sctp_transport_put(transport); | |
| 274 | 275 | else |
| 275 | 276 | sctp_endpoint_put(ep); |
| 276 | 277 | |
| @@ -283,8 +284,8 @@ discard_it: · 6 unmodified lines | ||
| 283 | 284 | |
| 284 | 285 | discard_release: |
| 285 | 286 | /* Release the asoc/ep ref we took in the lookup calls. */ |
| 286 | − if (asoc) | |
| 287 | − sctp_association_put(asoc); | |
| 287 | + if (transport) | |
| 288 | + sctp_transport_put(transport); | |
| 288 | 289 | else |
| 289 | 290 | sctp_endpoint_put(ep); |
| 290 | 291 | |
| @@ -300,6 +301,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) · 9 unmodified lines | ||
| 300 | 301 | { |
| 301 | 302 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; |
| 302 | 303 | struct sctp_inq *inqueue = &chunk->rcvr->inqueue; |
| 304 | + struct sctp_transport *t = chunk->transport; | |
| 303 | 305 | struct sctp_ep_common *rcvr = NULL; |
| 304 | 306 | int backloged = 0; |
| 305 | 307 | |
| @@ -351,7 +353,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) · 45 unmodified lines | ||
| 351 | 353 | done: |
| 352 | 354 | /* Release the refs we took in sctp_add_backlog */ |
| 353 | 355 | if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) |
| 354 | − sctp_association_put(sctp_assoc(rcvr)); | |
| 356 | + sctp_transport_put(t); | |
| 355 | 357 | else if (SCTP_EP_TYPE_SOCKET == rcvr->type) |
| 356 | 358 | sctp_endpoint_put(sctp_ep(rcvr)); |
| 357 | 359 | else |
| @@ -363,6 +365,7 @@ done: · 5 unmodified lines | ||
| 363 | 365 | static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) |
| 364 | 366 | { |
| 365 | 367 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; |
| 368 | + struct sctp_transport *t = chunk->transport; | |
| 366 | 369 | struct sctp_ep_common *rcvr = chunk->rcvr; |
| 367 | 370 | int ret; |
| 368 | 371 | |
| @@ -373,7 +376,7 @@ static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) · 4 unmodified lines | ||
| 373 | 376 | * from us |
| 374 | 377 | */ |
| 375 | 378 | if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) |
| 376 | − sctp_association_hold(sctp_assoc(rcvr)); | |
| 379 | + sctp_transport_hold(t); | |
| 377 | 380 | else if (SCTP_EP_TYPE_SOCKET == rcvr->type) |
| 378 | 381 | sctp_endpoint_hold(sctp_ep(rcvr)); |
| 379 | 382 | else |
| @@ -537,15 +540,15 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, · 157 unmodified lines | ||
| 537 | 540 | return sk; |
| 538 | 541 | |
| 539 | 542 | out: |
| 540 | − sctp_association_put(asoc); | |
| 543 | + sctp_transport_put(transport); | |
| 541 | 544 | return NULL; |
| 542 | 545 | } |
| 543 | 546 | |
| 544 | 547 | /* Common cleanup code for icmp/icmpv6 error handler. */ |
| 545 | −void sctp_err_finish(struct sock *sk, struct sctp_association *asoc) | |
| 548 | +void sctp_err_finish(struct sock *sk, struct sctp_transport *t) | |
| 546 | 549 | { |
| 547 | 550 | bh_unlock_sock(sk); |
| 548 | − sctp_association_put(asoc); | |
| 551 | + sctp_transport_put(t); | |
| 549 | 552 | } |
| 550 | 553 | |
| 551 | 554 | /* |
| @@ -641,7 +644,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) · 89 unmodified lines | ||
| 641 | 644 | } |
| 642 | 645 | |
| 643 | 646 | out_unlock: |
| 644 | − sctp_err_finish(sk, asoc); | |
| 647 | + sctp_err_finish(sk, transport); | |
| 645 | 648 | } |
| 646 | 649 | |
| 647 | 650 | /* |
| @@ -952,11 +955,8 @@ static struct sctp_association *__sctp_lookup_association( · 304 unmodified lines | ||
| 952 | 955 | goto out; |
| 953 | 956 | |
| 954 | 957 | asoc = t->asoc; |
| 955 | − sctp_association_hold(asoc); | |
| 956 | 958 | *pt = t; |
| 957 | 959 | |
| 958 | − sctp_transport_put(t); | |
| 959 | − | |
| 960 | 960 | out: |
| 961 | 961 | return asoc; |
| 962 | 962 | } |
| @@ -986,7 +986,7 @@ int sctp_has_association(struct net *net, · 23 unmodified lines | ||
| 986 | 986 | struct sctp_transport *transport; |
| 987 | 987 | |
| 988 | 988 | if ((asoc = sctp_lookup_association(net, laddr, paddr, &transport))) { |
| 989 | − sctp_association_put(asoc); | |
| 989 | + sctp_transport_put(transport); | |
| 990 | 990 | return 1; |
| 991 | 991 | } |
| 992 | 992 | |
| @@ -1021,7 +1021,6 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, · 28 unmodified lines | ||
| 1021 | 1021 | struct sctphdr *sh = sctp_hdr(skb); |
| 1022 | 1022 | union sctp_params params; |
| 1023 | 1023 | sctp_init_chunk_t *init; |
| 1024 | − struct sctp_transport *transport; | |
| 1025 | 1024 | struct sctp_af *af; |
| 1026 | 1025 | |
| 1027 | 1026 | /* |
| @@ -1052,7 +1051,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, · 24 unmodified lines | ||
| 1052 | 1051 | |
| 1053 | 1052 | af->from_addr_param(paddr, params.addr, sh->source, 0); |
| 1054 | 1053 | |
| 1055 | − asoc = __sctp_lookup_association(net, laddr, paddr, &transport); | |
| 1054 | + asoc = __sctp_lookup_association(net, laddr, paddr, transportp); | |
| 1056 | 1055 | if (asoc) |
| 1057 | 1056 | return asoc; |
| 1058 | 1057 | } |
| @@ -198,7 +198,7 @@ static void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, · 197 unmodified lines | ||
| 198 | 198 | } |
| 199 | 199 | |
| 200 | 200 | out_unlock: |
| 201 | − sctp_err_finish(sk, asoc); | |
| 201 | + sctp_err_finish(sk, transport); | |
| 202 | 202 | out: |
| 203 | 203 | if (likely(idev != NULL)) |
| 204 | 204 | in6_dev_put(idev); |
| @@ -1214,9 +1214,12 @@ static int __sctp_connect(struct sock *sk, · 1213 unmodified lines | ||
| 1214 | 1214 | |
| 1215 | 1215 | timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK); |
| 1216 | 1216 | |
| 1217 | − err = sctp_wait_for_connect(asoc, &timeo); | |
| 1218 | − if ((err == 0 || err == -EINPROGRESS) && assoc_id) | |
| 1217 | + if (assoc_id) | |
| 1219 | 1218 | *assoc_id = asoc->assoc_id; |
| 1219 | + err = sctp_wait_for_connect(asoc, &timeo); | |
| 1220 | + /* Note: the asoc may be freed after the return of | |
| 1221 | + * sctp_wait_for_connect. | |
| 1222 | + */ | |
| 1220 | 1223 | |
| 1221 | 1224 | /* Don't free association on exit. */ |
| 1222 | 1225 | asoc = NULL; |
| @@ -4282,19 +4285,18 @@ static void sctp_shutdown(struct sock *sk, int how) · 3059 unmodified lines | ||
| 4282 | 4285 | { |
| 4283 | 4286 | struct net *net = sock_net(sk); |
| 4284 | 4287 | struct sctp_endpoint *ep; |
| 4285 | − struct sctp_association *asoc; | |
| 4286 | 4288 | |
| 4287 | 4289 | if (!sctp_style(sk, TCP)) |
| 4288 | 4290 | return; |
| 4289 | 4291 | |
| 4290 | − if (how & SEND_SHUTDOWN) { | |
| 4292 | + ep = sctp_sk(sk)->ep; | |
| 4293 | + if (how & SEND_SHUTDOWN && !list_empty(&ep->asocs)) { | |
| 4294 | + struct sctp_association *asoc; | |
| 4295 | + | |
| 4291 | 4296 | sk->sk_state = SCTP_SS_CLOSING; |
| 4292 | − ep = sctp_sk(sk)->ep; | |
| 4293 | − if (!list_empty(&ep->asocs)) { | |
| 4294 | − asoc = list_entry(ep->asocs.next, | |
| 4295 | − struct sctp_association, asocs); | |
| 4296 | − sctp_primitive_SHUTDOWN(net, asoc, NULL); | |
| 4297 | − } | |
| 4297 | + asoc = list_entry(ep->asocs.next, | |
| 4298 | + struct sctp_association, asocs); | |
| 4299 | + sctp_primitive_SHUTDOWN(net, asoc, NULL); | |
| 4298 | 4300 | } |
| 4299 | 4301 | } |
| 4300 | 4302 | |
| @@ -4480,12 +4482,9 @@ int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *), · 179 unmodified lines | ||
| 4480 | 4482 | if (!transport || !sctp_transport_hold(transport)) |
| 4481 | 4483 | goto out; |
| 4482 | 4484 | |
| 4483 | − sctp_association_hold(transport->asoc); | |
| 4484 | − sctp_transport_put(transport); | |
| 4485 | − | |
| 4486 | 4485 | rcu_read_unlock(); |
| 4487 | 4486 | err = cb(transport, p); |
| 4488 | − sctp_association_put(transport->asoc); | |
| 4487 | + sctp_transport_put(transport); | |
| 4489 | 4488 | |
| 4490 | 4489 | out: |
| 4491 | 4490 | return err; |
| @@ -341,8 +341,23 @@ static const struct xattr_handler sockfs_xattr_handler = { · 340 unmodified lines | ||
| 341 | 341 | .get = sockfs_xattr_get, |
| 342 | 342 | }; |
| 343 | 343 | |
| 344 | +static int sockfs_security_xattr_set(const struct xattr_handler *handler, | |
| 345 | + struct dentry *dentry, struct inode *inode, | |
| 346 | + const char *suffix, const void *value, | |
| 347 | + size_t size, int flags) | |
| 348 | +{ | |
| 349 | + /* Handled by LSM. */ | |
| 350 | + return -EAGAIN; | |
| 351 | +} | |
| 352 | + | |
| 353 | +static const struct xattr_handler sockfs_security_xattr_handler = { | |
| 354 | + .prefix = XATTR_SECURITY_PREFIX, | |
| 355 | + .set = sockfs_security_xattr_set, | |
| 356 | +}; | |
| 357 | + | |
| 344 | 358 | static const struct xattr_handler *sockfs_xattr_handlers[] = { |
| 345 | 359 | &sockfs_xattr_handler, |
| 360 | + &sockfs_security_xattr_handler, | |
| 346 | 361 | NULL |
| 347 | 362 | }; |
| 348 | 363 | |
| @@ -2038,6 +2053,8 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, · 1689 unmodified lines | ||
| 2038 | 2053 | if (err) |
| 2039 | 2054 | break; |
| 2040 | 2055 | ++datagrams; |
| 2056 | + if (msg_data_left(&msg_sys)) | |
| 2057 | + break; | |
| 2041 | 2058 | cond_resched(); |
| 2042 | 2059 | } |
| 2043 | 2060 | |
| @@ -2753,14 +2753,18 @@ EXPORT_SYMBOL_GPL(rpc_cap_max_reconnect_timeout); · 2752 unmodified lines | ||
| 2753 | 2753 | |
| 2754 | 2754 | void rpc_clnt_xprt_switch_put(struct rpc_clnt *clnt) |
| 2755 | 2755 | { |
| 2756 | + rcu_read_lock(); | |
| 2756 | 2757 | xprt_switch_put(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); |
| 2758 | + rcu_read_unlock(); | |
| 2757 | 2759 | } |
| 2758 | 2760 | EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_put); |
| 2759 | 2761 | |
| 2760 | 2762 | void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt) |
| 2761 | 2763 | { |
| 2764 | + rcu_read_lock(); | |
| 2762 | 2765 | rpc_xprt_switch_add_xprt(rcu_dereference(clnt->cl_xpi.xpi_xpswitch), |
| 2763 | 2766 | xprt); |
| 2767 | + rcu_read_unlock(); | |
| 2764 | 2768 | } |
| 2765 | 2769 | EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_add_xprt); |
| 2766 | 2770 | |
| @@ -2770,9 +2774,8 @@ bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt, · 3 unmodified lines | ||
| 2770 | 2774 | struct rpc_xprt_switch *xps; |
| 2771 | 2775 | bool ret; |
| 2772 | 2776 | |
| 2773 | − xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch); | |
| 2774 | − | |
| 2775 | 2777 | rcu_read_lock(); |
| 2778 | + xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch); | |
| 2776 | 2779 | ret = rpc_xprt_switch_has_addr(xps, sap); |
| 2777 | 2780 | rcu_read_unlock(); |
| 2778 | 2781 | return ret; |
| @@ -1002,14 +1002,8 @@ static void svc_age_temp_xprts(unsigned long closure) · 1001 unmodified lines | ||
| 1002 | 1002 | void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr) |
| 1003 | 1003 | { |
| 1004 | 1004 | struct svc_xprt *xprt; |
| 1005 | − struct svc_sock *svsk; | |
| 1006 | − struct socket *sock; | |
| 1007 | 1005 | struct list_head *le, *next; |
| 1008 | 1006 | LIST_HEAD(to_be_closed); |
| 1009 | − struct linger no_linger = { | |
| 1010 | − .l_onoff = 1, | |
| 1011 | − .l_linger = 0, | |
| 1012 | − }; | |
| 1013 | 1007 | |
| 1014 | 1008 | spin_lock_bh(&serv->sv_lock); |
| 1015 | 1009 | list_for_each_safe(le, next, &serv->sv_tempsocks) { |
| @@ -1027,10 +1021,7 @@ void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr) · 11 unmodified lines | ||
| 1027 | 1021 | list_del_init(le); |
| 1028 | 1022 | xprt = list_entry(le, struct svc_xprt, xpt_list); |
| 1029 | 1023 | dprintk("svc_age_temp_xprts_now: closing %p\n", xprt); |
| 1030 | − svsk = container_of(xprt, struct svc_sock, sk_xprt); | |
| 1031 | − sock = svsk->sk_sock; | |
| 1032 | − kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER, | |
| 1033 | − (char *)&no_linger, sizeof(no_linger)); | |
| 1024 | + xprt->xpt_ops->xpo_kill_temp_xprt(xprt); | |
| 1034 | 1025 | svc_close_xprt(xprt); |
| 1035 | 1026 | } |
| 1036 | 1027 | } |
| @@ -438,6 +438,21 @@ static int svc_tcp_has_wspace(struct svc_xprt *xprt) · 437 unmodified lines | ||
| 438 | 438 | return !test_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); |
| 439 | 439 | } |
| 440 | 440 | |
| 441 | +static void svc_tcp_kill_temp_xprt(struct svc_xprt *xprt) | |
| 442 | +{ | |
| 443 | + struct svc_sock *svsk; | |
| 444 | + struct socket *sock; | |
| 445 | + struct linger no_linger = { | |
| 446 | + .l_onoff = 1, | |
| 447 | + .l_linger = 0, | |
| 448 | + }; | |
| 449 | + | |
| 450 | + svsk = container_of(xprt, struct svc_sock, sk_xprt); | |
| 451 | + sock = svsk->sk_sock; | |
| 452 | + kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER, | |
| 453 | + (char *)&no_linger, sizeof(no_linger)); | |
| 454 | +} | |
| 455 | + | |
| 441 | 456 | /* |
| 442 | 457 | * See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo |
| 443 | 458 | */ |
| @@ -648,6 +663,10 @@ static struct svc_xprt *svc_udp_accept(struct svc_xprt *xprt) · 204 unmodified lines | ||
| 648 | 663 | return NULL; |
| 649 | 664 | } |
| 650 | 665 | |
| 666 | +static void svc_udp_kill_temp_xprt(struct svc_xprt *xprt) | |
| 667 | +{ | |
| 668 | +} | |
| 669 | + | |
| 651 | 670 | static struct svc_xprt *svc_udp_create(struct svc_serv *serv, |
| 652 | 671 | struct net *net, |
| 653 | 672 | struct sockaddr *sa, int salen, |
| @@ -667,6 +686,7 @@ static struct svc_xprt_ops svc_udp_ops = { · 13 unmodified lines | ||
| 667 | 686 | .xpo_has_wspace = svc_udp_has_wspace, |
| 668 | 687 | .xpo_accept = svc_udp_accept, |
| 669 | 688 | .xpo_secure_port = svc_sock_secure_port, |
| 689 | + .xpo_kill_temp_xprt = svc_udp_kill_temp_xprt, | |
| 670 | 690 | }; |
| 671 | 691 | |
| 672 | 692 | static struct svc_xprt_class svc_udp_class = { |
| @@ -1242,6 +1262,7 @@ static struct svc_xprt_ops svc_tcp_ops = { · 569 unmodified lines | ||
| 1242 | 1262 | .xpo_has_wspace = svc_tcp_has_wspace, |
| 1243 | 1263 | .xpo_accept = svc_tcp_accept, |
| 1244 | 1264 | .xpo_secure_port = svc_sock_secure_port, |
| 1265 | + .xpo_kill_temp_xprt = svc_tcp_kill_temp_xprt, | |
| 1245 | 1266 | }; |
| 1246 | 1267 | |
| 1247 | 1268 | static struct svc_xprt_class svc_tcp_class = { |
| @@ -44,18 +44,20 @@ · 43 unmodified lines | ||
| 44 | 44 | * being done. |
| 45 | 45 | * |
| 46 | 46 | * When the underlying transport disconnects, MRs are left in one of |
| 47 | − * three states: | |
| 47 | + * four states: | |
| 48 | 48 | * |
| 49 | 49 | * INVALID: The MR was not in use before the QP entered ERROR state. |
| 50 | − * (Or, the LOCAL_INV WR has not completed or flushed yet). | |
| 51 | − * | |
| 52 | − * STALE: The MR was being registered or unregistered when the QP | |
| 53 | − * entered ERROR state, and the pending WR was flushed. | |
| 54 | 50 | * |
| 55 | 51 | * VALID: The MR was registered before the QP entered ERROR state. |
| 56 | 52 | * |
| 57 | − * When frwr_op_map encounters STALE and VALID MRs, they are recovered | |
| 58 | − * with ib_dereg_mr and then are re-initialized. Beause MR recovery | |
| 53 | + * FLUSHED_FR: The MR was being registered when the QP entered ERROR | |
| 54 | + * state, and the pending WR was flushed. | |
| 55 | + * | |
| 56 | + * FLUSHED_LI: The MR was being invalidated when the QP entered ERROR | |
| 57 | + * state, and the pending WR was flushed. | |
| 58 | + * | |
| 59 | + * When frwr_op_map encounters FLUSHED and VALID MRs, they are recovered | |
| 60 | + * with ib_dereg_mr and then are re-initialized. Because MR recovery | |
| 59 | 61 | * allocates fresh resources, it is deferred to a workqueue, and the |
| 60 | 62 | * recovered MRs are placed back on the rb_mws list when recovery is |
| 61 | 63 | * complete. frwr_op_map allocates another MR for the current RPC while |
| @@ -177,12 +179,15 @@ __frwr_reset_mr(struct rpcrdma_ia *ia, struct rpcrdma_mw *r) · 115 unmodified lines | ||
| 177 | 179 | static void |
| 178 | 180 | frwr_op_recover_mr(struct rpcrdma_mw *mw) |
| 179 | 181 | { |
| 182 | + enum rpcrdma_frmr_state state = mw->frmr.fr_state; | |
| 180 | 183 | struct rpcrdma_xprt *r_xprt = mw->mw_xprt; |
| 181 | 184 | struct rpcrdma_ia *ia = &r_xprt->rx_ia; |
| 182 | 185 | int rc; |
| 183 | 186 | |
| 184 | 187 | rc = __frwr_reset_mr(ia, mw); |
| 185 | − ib_dma_unmap_sg(ia->ri_device, mw->mw_sg, mw->mw_nents, mw->mw_dir); | |
| 188 | + if (state != FRMR_FLUSHED_LI) | |
| 189 | + ib_dma_unmap_sg(ia->ri_device, | |
| 190 | + mw->mw_sg, mw->mw_nents, mw->mw_dir); | |
| 186 | 191 | if (rc) |
| 187 | 192 | goto out_release; |
| 188 | 193 | |
| @@ -262,10 +267,8 @@ frwr_op_maxpages(struct rpcrdma_xprt *r_xprt) · 73 unmodified lines | ||
| 262 | 267 | } |
| 263 | 268 | |
| 264 | 269 | static void |
| 265 | −__frwr_sendcompletion_flush(struct ib_wc *wc, struct rpcrdma_frmr *frmr, | |
| 266 | − const char *wr) | |
| 270 | +__frwr_sendcompletion_flush(struct ib_wc *wc, const char *wr) | |
| 267 | 271 | { |
| 268 | − frmr->fr_state = FRMR_IS_STALE; | |
| 269 | 272 | if (wc->status != IB_WC_WR_FLUSH_ERR) |
| 270 | 273 | pr_err("rpcrdma: %s: %s (%u/0x%x)\n", |
| 271 | 274 | wr, ib_wc_status_msg(wc->status), |
| @@ -288,7 +291,8 @@ frwr_wc_fastreg(struct ib_cq *cq, struct ib_wc *wc) · 16 unmodified lines | ||
| 288 | 291 | if (wc->status != IB_WC_SUCCESS) { |
| 289 | 292 | cqe = wc->wr_cqe; |
| 290 | 293 | frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe); |
| 291 | − __frwr_sendcompletion_flush(wc, frmr, "fastreg"); | |
| 294 | + frmr->fr_state = FRMR_FLUSHED_FR; | |
| 295 | + __frwr_sendcompletion_flush(wc, "fastreg"); | |
| 292 | 296 | } |
| 293 | 297 | } |
| 294 | 298 | |
| @@ -308,7 +312,8 @@ frwr_wc_localinv(struct ib_cq *cq, struct ib_wc *wc) · 13 unmodified lines | ||
| 308 | 312 | if (wc->status != IB_WC_SUCCESS) { |
| 309 | 313 | cqe = wc->wr_cqe; |
| 310 | 314 | frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe); |
| 311 | − __frwr_sendcompletion_flush(wc, frmr, "localinv"); | |
| 315 | + frmr->fr_state = FRMR_FLUSHED_LI; | |
| 316 | + __frwr_sendcompletion_flush(wc, "localinv"); | |
| 312 | 317 | } |
| 313 | 318 | } |
| 314 | 319 | |
| @@ -328,8 +333,10 @@ frwr_wc_localinv_wake(struct ib_cq *cq, struct ib_wc *wc) · 13 unmodified lines | ||
| 328 | 333 | /* WARNING: Only wr_cqe and status are reliable at this point */ |
| 329 | 334 | cqe = wc->wr_cqe; |
| 330 | 335 | frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe); |
| 331 | − if (wc->status != IB_WC_SUCCESS) | |
| 332 | − __frwr_sendcompletion_flush(wc, frmr, "localinv"); | |
| 336 | + if (wc->status != IB_WC_SUCCESS) { | |
| 337 | + frmr->fr_state = FRMR_FLUSHED_LI; | |
| 338 | + __frwr_sendcompletion_flush(wc, "localinv"); | |
| 339 | + } | |
| 333 | 340 | complete(&frmr->fr_linv_done); |
| 334 | 341 | } |
| 335 | 342 | |
| @@ -67,6 +67,7 @@ static void svc_rdma_detach(struct svc_xprt *xprt); · 66 unmodified lines | ||
| 67 | 67 | static void svc_rdma_free(struct svc_xprt *xprt); |
| 68 | 68 | static int svc_rdma_has_wspace(struct svc_xprt *xprt); |
| 69 | 69 | static int svc_rdma_secure_port(struct svc_rqst *); |
| 70 | +static void svc_rdma_kill_temp_xprt(struct svc_xprt *); | |
| 70 | 71 | |
| 71 | 72 | static struct svc_xprt_ops svc_rdma_ops = { |
| 72 | 73 | .xpo_create = svc_rdma_create, |
| @@ -79,6 +80,7 @@ static struct svc_xprt_ops svc_rdma_ops = { · 6 unmodified lines | ||
| 79 | 80 | .xpo_has_wspace = svc_rdma_has_wspace, |
| 80 | 81 | .xpo_accept = svc_rdma_accept, |
| 81 | 82 | .xpo_secure_port = svc_rdma_secure_port, |
| 83 | + .xpo_kill_temp_xprt = svc_rdma_kill_temp_xprt, | |
| 82 | 84 | }; |
| 83 | 85 | |
| 84 | 86 | struct svc_xprt_class svc_rdma_class = { |
| @@ -1317,6 +1319,10 @@ static int svc_rdma_secure_port(struct svc_rqst *rqstp) · 1232 unmodified lines | ||
| 1317 | 1319 | return 1; |
| 1318 | 1320 | } |
| 1319 | 1321 | |
| 1322 | +static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt) | |
| 1323 | +{ | |
| 1324 | +} | |
| 1325 | + | |
| 1320 | 1326 | int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr) |
| 1321 | 1327 | { |
| 1322 | 1328 | struct ib_send_wr *bad_wr, *n_wr; |
| @@ -216,7 +216,8 @@ struct rpcrdma_rep { · 215 unmodified lines | ||
| 216 | 216 | enum rpcrdma_frmr_state { |
| 217 | 217 | FRMR_IS_INVALID, /* ready to be used */ |
| 218 | 218 | FRMR_IS_VALID, /* in use */ |
| 219 | − FRMR_IS_STALE, /* failed completion */ | |
| 219 | + FRMR_FLUSHED_FR, /* flushed FASTREG WR */ | |
| 220 | + FRMR_FLUSHED_LI, /* flushed LOCALINV WR */ | |
| 220 | 221 | }; |
| 221 | 222 | |
| 222 | 223 | struct rpcrdma_frmr { |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * net/tipc/socket.c: TIPC socket API |
| 3 | 3 | * |
| 4 | − * Copyright (c) 2001-2007, 2012-2015, Ericsson AB | |
| 4 | + * Copyright (c) 2001-2007, 2012-2016, Ericsson AB | |
| 5 | 5 | * Copyright (c) 2004-2008, 2010-2013, Wind River Systems |
| 6 | 6 | * All rights reserved. |
| 7 | 7 | * |
| @@ -129,54 +129,8 @@ static const struct proto_ops packet_ops; · 121 unmodified lines | ||
| 129 | 129 | static const struct proto_ops stream_ops; |
| 130 | 130 | static const struct proto_ops msg_ops; |
| 131 | 131 | static struct proto tipc_proto; |
| 132 | − | |
| 133 | 132 | static const struct rhashtable_params tsk_rht_params; |
| 134 | 133 | |
| 135 | −/* | |
| 136 | − * Revised TIPC socket locking policy: | |
| 137 | − * | |
| 138 | − * Most socket operations take the standard socket lock when they start | |
| 139 | − * and hold it until they finish (or until they need to sleep). Acquiring | |
| 140 | − * this lock grants the owner exclusive access to the fields of the socket | |
| 141 | − * data structures, with the exception of the backlog queue. A few socket | |
| 142 | − * operations can be done without taking the socket lock because they only | |
| 143 | − * read socket information that never changes during the life of the socket. | |
| 144 | − * | |
| 145 | − * Socket operations may acquire the lock for the associated TIPC port if they | |
| 146 | − * need to perform an operation on the port. If any routine needs to acquire | |
| 147 | − * both the socket lock and the port lock it must take the socket lock first | |
| 148 | − * to avoid the risk of deadlock. | |
| 149 | − * | |
| 150 | − * The dispatcher handling incoming messages cannot grab the socket lock in | |
| 151 | − * the standard fashion, since invoked it runs at the BH level and cannot block. | |
| 152 | − * Instead, it checks to see if the socket lock is currently owned by someone, | |
| 153 | − * and either handles the message itself or adds it to the socket's backlog | |
| 154 | − * queue; in the latter case the queued message is processed once the process | |
| 155 | − * owning the socket lock releases it. | |
| 156 | − * | |
| 157 | − * NOTE: Releasing the socket lock while an operation is sleeping overcomes | |
| 158 | − * the problem of a blocked socket operation preventing any other operations | |
| 159 | − * from occurring. However, applications must be careful if they have | |
| 160 | − * multiple threads trying to send (or receive) on the same socket, as these | |
| 161 | − * operations might interfere with each other. For example, doing a connect | |
| 162 | − * and a receive at the same time might allow the receive to consume the | |
| 163 | − * ACK message meant for the connect. While additional work could be done | |
| 164 | − * to try and overcome this, it doesn't seem to be worthwhile at the present. | |
| 165 | − * | |
| 166 | − * NOTE: Releasing the socket lock while an operation is sleeping also ensures | |
| 167 | − * that another operation that must be performed in a non-blocking manner is | |
| 168 | − * not delayed for very long because the lock has already been taken. | |
| 169 | − * | |
| 170 | − * NOTE: This code assumes that certain fields of a port/socket pair are | |
| 171 | − * constant over its lifetime; such fields can be examined without taking | |
| 172 | − * the socket lock and/or port lock, and do not need to be re-read even | |
| 173 | − * after resuming processing after waiting. These fields include: | |
| 174 | − * - socket type | |
| 175 | − * - pointer to socket sk structure (aka tipc_sock structure) | |
| 176 | − * - pointer to port structure | |
| 177 | − * - port reference | |
| 178 | − */ | |
| 179 | − | |
| 180 | 134 | static u32 tsk_own_node(struct tipc_sock *tsk) |
| 181 | 135 | { |
| 182 | 136 | return msg_prevnode(&tsk->phdr); |
| @@ -2199,7 +2199,8 @@ out: · 2198 unmodified lines | ||
| 2199 | 2199 | * Sleep until more data has arrived. But check for races.. |
| 2200 | 2200 | */ |
| 2201 | 2201 | static long unix_stream_data_wait(struct sock *sk, long timeo, |
| 2202 | − struct sk_buff *last, unsigned int last_len) | |
| 2202 | + struct sk_buff *last, unsigned int last_len, | |
| 2203 | + bool freezable) | |
| 2203 | 2204 | { |
| 2204 | 2205 | struct sk_buff *tail; |
| 2205 | 2206 | DEFINE_WAIT(wait); |
| @@ -2220,7 +2221,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, · 14 unmodified lines | ||
| 2220 | 2221 | |
| 2221 | 2222 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
| 2222 | 2223 | unix_state_unlock(sk); |
| 2223 | − timeo = freezable_schedule_timeout(timeo); | |
| 2224 | + if (freezable) | |
| 2225 | + timeo = freezable_schedule_timeout(timeo); | |
| 2226 | + else | |
| 2227 | + timeo = schedule_timeout(timeo); | |
| 2224 | 2228 | unix_state_lock(sk); |
| 2225 | 2229 | |
| 2226 | 2230 | if (sock_flag(sk, SOCK_DEAD)) |
| @@ -2250,7 +2254,8 @@ struct unix_stream_read_state { · 23 unmodified lines | ||
| 2250 | 2254 | unsigned int splice_flags; |
| 2251 | 2255 | }; |
| 2252 | 2256 | |
| 2253 | −static int unix_stream_read_generic(struct unix_stream_read_state *state) | |
| 2257 | +static int unix_stream_read_generic(struct unix_stream_read_state *state, | |
| 2258 | + bool freezable) | |
| 2254 | 2259 | { |
| 2255 | 2260 | struct scm_cookie scm; |
| 2256 | 2261 | struct socket *sock = state->socket; |
| @@ -2330,7 +2335,7 @@ again: · 73 unmodified lines | ||
| 2330 | 2335 | mutex_unlock(&u->iolock); |
| 2331 | 2336 | |
| 2332 | 2337 | timeo = unix_stream_data_wait(sk, timeo, last, |
| 2333 | − last_len); | |
| 2338 | + last_len, freezable); | |
| 2334 | 2339 | |
| 2335 | 2340 | if (signal_pending(current)) { |
| 2336 | 2341 | err = sock_intr_errno(timeo); |
| @@ -2472,7 +2477,7 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, · 135 unmodified lines | ||
| 2472 | 2477 | .flags = flags |
| 2473 | 2478 | }; |
| 2474 | 2479 | |
| 2475 | − return unix_stream_read_generic(&state); | |
| 2480 | + return unix_stream_read_generic(&state, true); | |
| 2476 | 2481 | } |
| 2477 | 2482 | |
| 2478 | 2483 | static int unix_stream_splice_actor(struct sk_buff *skb, |
| @@ -2503,7 +2508,7 @@ static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos, · 24 unmodified lines | ||
| 2503 | 2508 | flags & SPLICE_F_NONBLOCK) |
| 2504 | 2509 | state.flags = MSG_DONTWAIT; |
| 2505 | 2510 | |
| 2506 | − return unix_stream_read_generic(&state); | |
| 2511 | + return unix_stream_read_generic(&state, false); | |
| 2507 | 2512 | } |
| 2508 | 2513 | |
| 2509 | 2514 | static int unix_shutdown(struct socket *sock, int mode) |
| @@ -2812,7 +2817,8 @@ static int unix_seq_show(struct seq_file *seq, void *v) · 302 unmodified lines | ||
| 2812 | 2817 | i++; |
| 2813 | 2818 | } |
| 2814 | 2819 | for ( ; i < len; i++) |
| 2815 | − seq_putc(seq, u->addr->name->sun_path[i]); | |
| 2820 | + seq_putc(seq, u->addr->name->sun_path[i] ?: | |
| 2821 | + '@'); | |
| 2816 | 2822 | } |
| 2817 | 2823 | unix_state_unlock(s); |
| 2818 | 2824 | seq_putc(seq, '\n'); |
| @@ -71,6 +71,7 @@ struct cfg80211_registered_device { · 70 unmodified lines | ||
| 71 | 71 | struct list_head bss_list; |
| 72 | 72 | struct rb_root bss_tree; |
| 73 | 73 | u32 bss_generation; |
| 74 | + u32 bss_entries; | |
| 74 | 75 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ |
| 75 | 76 | struct sk_buff *scan_msg; |
| 76 | 77 | struct cfg80211_sched_scan_request __rcu *sched_scan_req; |
| @@ -57,6 +57,19 @@ · 56 unmodified lines | ||
| 57 | 57 | * also linked into the probe response struct. |
| 58 | 58 | */ |
| 59 | 59 | |
| 60 | +/* | |
| 61 | + * Limit the number of BSS entries stored in mac80211. Each one is | |
| 62 | + * a bit over 4k at most, so this limits to roughly 4-5M of memory. | |
| 63 | + * If somebody wants to really attack this though, they'd likely | |
| 64 | + * use small beacons, and only one type of frame, limiting each of | |
| 65 | + * the entries to a much smaller size (in order to generate more | |
| 66 | + * entries in total, so overhead is bigger.) | |
| 67 | + */ | |
| 68 | +static int bss_entries_limit = 1000; | |
| 69 | +module_param(bss_entries_limit, int, 0644); | |
| 70 | +MODULE_PARM_DESC(bss_entries_limit, | |
| 71 | + "limit to number of scan BSS entries (per wiphy, default 1000)"); | |
| 72 | + | |
| 60 | 73 | #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ) |
| 61 | 74 | |
| 62 | 75 | static void bss_free(struct cfg80211_internal_bss *bss) |
| @@ -137,6 +150,10 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev, · 74 unmodified lines | ||
| 137 | 150 | |
| 138 | 151 | list_del_init(&bss->list); |
| 139 | 152 | rb_erase(&bss->rbn, &rdev->bss_tree); |
| 153 | + rdev->bss_entries--; | |
| 154 | + WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list), | |
| 155 | + "rdev bss entries[%d]/list[empty:%d] corruption\n", | |
| 156 | + rdev->bss_entries, list_empty(&rdev->bss_list)); | |
| 140 | 157 | bss_ref_put(rdev, bss); |
| 141 | 158 | return true; |
| 142 | 159 | } |
| @@ -163,6 +180,40 @@ static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev, · 20 unmodified lines | ||
| 163 | 180 | rdev->bss_generation++; |
| 164 | 181 | } |
| 165 | 182 | |
| 183 | +static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev) | |
| 184 | +{ | |
| 185 | + struct cfg80211_internal_bss *bss, *oldest = NULL; | |
| 186 | + bool ret; | |
| 187 | + | |
| 188 | + lockdep_assert_held(&rdev->bss_lock); | |
| 189 | + | |
| 190 | + list_for_each_entry(bss, &rdev->bss_list, list) { | |
| 191 | + if (atomic_read(&bss->hold)) | |
| 192 | + continue; | |
| 193 | + | |
| 194 | + if (!list_empty(&bss->hidden_list) && | |
| 195 | + !bss->pub.hidden_beacon_bss) | |
| 196 | + continue; | |
| 197 | + | |
| 198 | + if (oldest && time_before(oldest->ts, bss->ts)) | |
| 199 | + continue; | |
| 200 | + oldest = bss; | |
| 201 | + } | |
| 202 | + | |
| 203 | + if (WARN_ON(!oldest)) | |
| 204 | + return false; | |
| 205 | + | |
| 206 | + /* | |
| 207 | + * The callers make sure to increase rdev->bss_generation if anything | |
| 208 | + * gets removed (and a new entry added), so there's no need to also do | |
| 209 | + * it here. | |
| 210 | + */ | |
| 211 | + | |
| 212 | + ret = __cfg80211_unlink_bss(rdev, oldest); | |
| 213 | + WARN_ON(!ret); | |
| 214 | + return ret; | |
| 215 | +} | |
| 216 | + | |
| 166 | 217 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, |
| 167 | 218 | bool send_message) |
| 168 | 219 | { |
| @@ -689,6 +740,7 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev, · 520 unmodified lines | ||
| 689 | 740 | const u8 *ie; |
| 690 | 741 | int i, ssidlen; |
| 691 | 742 | u8 fold = 0; |
| 743 | + u32 n_entries = 0; | |
| 692 | 744 | |
| 693 | 745 | ies = rcu_access_pointer(new->pub.beacon_ies); |
| 694 | 746 | if (WARN_ON(!ies)) |
| @@ -712,6 +764,12 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev, · 17 unmodified lines | ||
| 712 | 764 | /* This is the bad part ... */ |
| 713 | 765 | |
| 714 | 766 | list_for_each_entry(bss, &rdev->bss_list, list) { |
| 767 | + /* | |
| 768 | + * we're iterating all the entries anyway, so take the | |
| 769 | + * opportunity to validate the list length accounting | |
| 770 | + */ | |
| 771 | + n_entries++; | |
| 772 | + | |
| 715 | 773 | if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid)) |
| 716 | 774 | continue; |
| 717 | 775 | if (bss->pub.channel != new->pub.channel) |
| @@ -740,6 +798,10 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev, · 22 unmodified lines | ||
| 740 | 798 | new->pub.beacon_ies); |
| 741 | 799 | } |
| 742 | 800 | |
| 801 | + WARN_ONCE(n_entries != rdev->bss_entries, | |
| 802 | + "rdev bss entries[%d]/list[len:%d] corruption\n", | |
| 803 | + rdev->bss_entries, n_entries); | |
| 804 | + | |
| 743 | 805 | return true; |
| 744 | 806 | } |
| 745 | 807 | |
| @@ -894,7 +956,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, · 148 unmodified lines | ||
| 894 | 956 | } |
| 895 | 957 | } |
| 896 | 958 | |
| 959 | + if (rdev->bss_entries >= bss_entries_limit && | |
| 960 | + !cfg80211_bss_expire_oldest(rdev)) { | |
| 961 | + kfree(new); | |
| 962 | + goto drop; | |
| 963 | + } | |
| 964 | + | |
| 897 | 965 | list_add_tail(&new->list, &rdev->bss_list); |
| 966 | + rdev->bss_entries++; | |
| 898 | 967 | rb_insert_bss(rdev, new); |
| 899 | 968 | found = new; |
| 900 | 969 | } |
| @@ -1158,7 +1158,8 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate) · 1157 unmodified lines | ||
| 1158 | 1158 | 58500000, |
| 1159 | 1159 | 65000000, |
| 1160 | 1160 | 78000000, |
| 1161 | − 0, | |
| 1161 | + /* not in the spec, but some devices use this: */ | |
| 1162 | + 86500000, | |
| 1162 | 1163 | }, |
| 1163 | 1164 | { 13500000, |
| 1164 | 1165 | 27000000, |
| @@ -27,6 +27,7 @@ hostprogs-y += xdp2 · 26 unmodified lines | ||
| 27 | 27 | hostprogs-y += test_current_task_under_cgroup |
| 28 | 28 | hostprogs-y += trace_event |
| 29 | 29 | hostprogs-y += sampleip |
| 30 | +hostprogs-y += tc_l2_redirect | |
| 30 | 31 | |
| 31 | 32 | test_verifier-objs := test_verifier.o libbpf.o |
| 32 | 33 | test_maps-objs := test_maps.o libbpf.o |
| @@ -56,6 +57,7 @@ test_current_task_under_cgroup-objs := bpf_load.o libbpf.o \ · 23 unmodified lines | ||
| 56 | 57 | test_current_task_under_cgroup_user.o |
| 57 | 58 | trace_event-objs := bpf_load.o libbpf.o trace_event_user.o |
| 58 | 59 | sampleip-objs := bpf_load.o libbpf.o sampleip_user.o |
| 60 | +tc_l2_redirect-objs := bpf_load.o libbpf.o tc_l2_redirect_user.o | |
| 59 | 61 | |
| 60 | 62 | # Tell kbuild to always build the programs |
| 61 | 63 | always := $(hostprogs-y) |
| @@ -72,6 +74,7 @@ always += test_probe_write_user_kern.o · 10 unmodified lines | ||
| 72 | 74 | always += trace_output_kern.o |
| 73 | 75 | always += tcbpf1_kern.o |
| 74 | 76 | always += tcbpf2_kern.o |
| 77 | +always += tc_l2_redirect_kern.o | |
| 75 | 78 | always += lathist_kern.o |
| 76 | 79 | always += offwaketime_kern.o |
| 77 | 80 | always += spintest_kern.o |
| @@ -111,6 +114,7 @@ HOSTLOADLIBES_xdp2 += -lelf · 33 unmodified lines | ||
| 111 | 114 | HOSTLOADLIBES_test_current_task_under_cgroup += -lelf |
| 112 | 115 | HOSTLOADLIBES_trace_event += -lelf |
| 113 | 116 | HOSTLOADLIBES_sampleip += -lelf |
| 117 | +HOSTLOADLIBES_tc_l2_redirect += -l elf | |
| 114 | 118 | |
| 115 | 119 | # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: |
| 116 | 120 | # make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang |
| @@ -0,0 +1,173 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | + | |
| 3 | +[[ -z $TC ]] && TC='tc' | |
| 4 | +[[ -z $IP ]] && IP='ip' | |
| 5 | + | |
| 6 | +REDIRECT_USER='./tc_l2_redirect' | |
| 7 | +REDIRECT_BPF='./tc_l2_redirect_kern.o' | |
| 8 | + | |
| 9 | +RP_FILTER=$(< /proc/sys/net/ipv4/conf/all/rp_filter) | |
| 10 | +IPV6_FORWARDING=$(< /proc/sys/net/ipv6/conf/all/forwarding) | |
| 11 | + | |
| 12 | +function config_common { | |
| 13 | + local tun_type=$1 | |
| 14 | + | |
| 15 | + $IP netns add ns1 | |
| 16 | + $IP netns add ns2 | |
| 17 | + $IP link add ve1 type veth peer name vens1 | |
| 18 | + $IP link add ve2 type veth peer name vens2 | |
| 19 | + $IP link set dev ve1 up | |
| 20 | + $IP link set dev ve2 up | |
| 21 | + $IP link set dev ve1 mtu 1500 | |
| 22 | + $IP link set dev ve2 mtu 1500 | |
| 23 | + $IP link set dev vens1 netns ns1 | |
| 24 | + $IP link set dev vens2 netns ns2 | |
| 25 | + | |
| 26 | + $IP -n ns1 link set dev lo up | |
| 27 | + $IP -n ns1 link set dev vens1 up | |
| 28 | + $IP -n ns1 addr add 10.1.1.101/24 dev vens1 | |
| 29 | + $IP -n ns1 addr add 2401:db01::65/64 dev vens1 nodad | |
| 30 | + $IP -n ns1 route add default via 10.1.1.1 dev vens1 | |
| 31 | + $IP -n ns1 route add default via 2401:db01::1 dev vens1 | |
| 32 | + | |
| 33 | + $IP -n ns2 link set dev lo up | |
| 34 | + $IP -n ns2 link set dev vens2 up | |
| 35 | + $IP -n ns2 addr add 10.2.1.102/24 dev vens2 | |
| 36 | + $IP -n ns2 addr add 2401:db02::66/64 dev vens2 nodad | |
| 37 | + $IP -n ns2 addr add 10.10.1.102 dev lo | |
| 38 | + $IP -n ns2 addr add 2401:face::66/64 dev lo nodad | |
| 39 | + $IP -n ns2 link add ipt2 type ipip local 10.2.1.102 remote 10.2.1.1 | |
| 40 | + $IP -n ns2 link add ip6t2 type ip6tnl mode any local 2401:db02::66 remote 2401:db02::1 | |
| 41 | + $IP -n ns2 link set dev ipt2 up | |
| 42 | + $IP -n ns2 link set dev ip6t2 up | |
| 43 | + $IP netns exec ns2 $TC qdisc add dev vens2 clsact | |
| 44 | + $IP netns exec ns2 $TC filter add dev vens2 ingress bpf da obj $REDIRECT_BPF sec drop_non_tun_vip | |
| 45 | + if [[ $tun_type == "ipip" ]]; then | |
| 46 | + $IP -n ns2 route add 10.1.1.0/24 dev ipt2 | |
| 47 | + $IP netns exec ns2 sysctl -q -w net.ipv4.conf.all.rp_filter=0 | |
| 48 | + $IP netns exec ns2 sysctl -q -w net.ipv4.conf.ipt2.rp_filter=0 | |
| 49 | + else | |
| 50 | + $IP -n ns2 route add 10.1.1.0/24 dev ip6t2 | |
| 51 | + $IP -n ns2 route add 2401:db01::/64 dev ip6t2 | |
| 52 | + $IP netns exec ns2 sysctl -q -w net.ipv4.conf.all.rp_filter=0 | |
| 53 | + $IP netns exec ns2 sysctl -q -w net.ipv4.conf.ip6t2.rp_filter=0 | |
| 54 | + fi | |
| 55 | + | |
| 56 | + $IP addr add 10.1.1.1/24 dev ve1 | |
| 57 | + $IP addr add 2401:db01::1/64 dev ve1 nodad | |
| 58 | + $IP addr add 10.2.1.1/24 dev ve2 | |
| 59 | + $IP addr add 2401:db02::1/64 dev ve2 nodad | |
| 60 | + | |
| 61 | + $TC qdisc add dev ve2 clsact | |
| 62 | + $TC filter add dev ve2 ingress bpf da obj $REDIRECT_BPF sec l2_to_iptun_ingress_forward | |
| 63 | + | |
| 64 | + sysctl -q -w net.ipv4.conf.all.rp_filter=0 | |
| 65 | + sysctl -q -w net.ipv6.conf.all.forwarding=1 | |
| 66 | +} | |
| 67 | + | |
| 68 | +function cleanup { | |
| 69 | + set +e | |
| 70 | + [[ -z $DEBUG ]] || set +x | |
| 71 | + $IP netns delete ns1 >& /dev/null | |
| 72 | + $IP netns delete ns2 >& /dev/null | |
| 73 | + $IP link del ve1 >& /dev/null | |
| 74 | + $IP link del ve2 >& /dev/null | |
| 75 | + $IP link del ipt >& /dev/null | |
| 76 | + $IP link del ip6t >& /dev/null | |
| 77 | + sysctl -q -w net.ipv4.conf.all.rp_filter=$RP_FILTER | |
| 78 | + sysctl -q -w net.ipv6.conf.all.forwarding=$IPV6_FORWARDING | |
| 79 | + rm -f /sys/fs/bpf/tc/globals/tun_iface | |
| 80 | + [[ -z $DEBUG ]] || set -x | |
| 81 | + set -e | |
| 82 | +} | |
| 83 | + | |
| 84 | +function l2_to_ipip { | |
| 85 | + echo -n "l2_to_ipip $1: " | |
| 86 | + | |
| 87 | + local dir=$1 | |
| 88 | + | |
| 89 | + config_common ipip | |
| 90 | + | |
| 91 | + $IP link add ipt type ipip external | |
| 92 | + $IP link set dev ipt up | |
| 93 | + sysctl -q -w net.ipv4.conf.ipt.rp_filter=0 | |
| 94 | + sysctl -q -w net.ipv4.conf.ipt.forwarding=1 | |
| 95 | + | |
| 96 | + if [[ $dir == "egress" ]]; then | |
| 97 | + $IP route add 10.10.1.0/24 via 10.2.1.102 dev ve2 | |
| 98 | + $TC filter add dev ve2 egress bpf da obj $REDIRECT_BPF sec l2_to_iptun_ingress_redirect | |
| 99 | + sysctl -q -w net.ipv4.conf.ve1.forwarding=1 | |
| 100 | + else | |
| 101 | + $TC qdisc add dev ve1 clsact | |
| 102 | + $TC filter add dev ve1 ingress bpf da obj $REDIRECT_BPF sec l2_to_iptun_ingress_redirect | |
| 103 | + fi | |
| 104 | + | |
| 105 | + $REDIRECT_USER -U /sys/fs/bpf/tc/globals/tun_iface -i $(< /sys/class/net/ipt/ifindex) | |
| 106 | + | |
| 107 | + $IP netns exec ns1 ping -c1 10.10.1.102 >& /dev/null | |
| 108 | + | |
| 109 | + if [[ $dir == "egress" ]]; then | |
| 110 | + # test direct egress to ve2 (i.e. not forwarding from | |
| 111 | + # ve1 to ve2). | |
| 112 | + ping -c1 10.10.1.102 >& /dev/null | |
| 113 | + fi | |
| 114 | + | |
| 115 | + cleanup | |
| 116 | + | |
| 117 | + echo "OK" | |
| 118 | +} | |
| 119 | + | |
| 120 | +function l2_to_ip6tnl { | |
| 121 | + echo -n "l2_to_ip6tnl $1: " | |
| 122 | + | |
| 123 | + local dir=$1 | |
| 124 | + | |
| 125 | + config_common ip6tnl | |
| 126 | + | |
| 127 | + $IP link add ip6t type ip6tnl mode any external | |
| 128 | + $IP link set dev ip6t up | |
| 129 | + sysctl -q -w net.ipv4.conf.ip6t.rp_filter=0 | |
| 130 | + sysctl -q -w net.ipv4.conf.ip6t.forwarding=1 | |
| 131 | + | |
| 132 | + if [[ $dir == "egress" ]]; then | |
| 133 | + $IP route add 10.10.1.0/24 via 10.2.1.102 dev ve2 | |
| 134 | + $IP route add 2401:face::/64 via 2401:db02::66 dev ve2 | |
| 135 | + $TC filter add dev ve2 egress bpf da obj $REDIRECT_BPF sec l2_to_ip6tun_ingress_redirect | |
| 136 | + sysctl -q -w net.ipv4.conf.ve1.forwarding=1 | |
| 137 | + else | |
| 138 | + $TC qdisc add dev ve1 clsact | |
| 139 | + $TC filter add dev ve1 ingress bpf da obj $REDIRECT_BPF sec l2_to_ip6tun_ingress_redirect | |
| 140 | + fi | |
| 141 | + | |
| 142 | + $REDIRECT_USER -U /sys/fs/bpf/tc/globals/tun_iface -i $(< /sys/class/net/ip6t/ifindex) | |
| 143 | + | |
| 144 | + $IP netns exec ns1 ping -c1 10.10.1.102 >& /dev/null | |
| 145 | + $IP netns exec ns1 ping -6 -c1 2401:face::66 >& /dev/null | |
| 146 | + | |
| 147 | + if [[ $dir == "egress" ]]; then | |
| 148 | + # test direct egress to ve2 (i.e. not forwarding from | |
| 149 | + # ve1 to ve2). | |
| 150 | + ping -c1 10.10.1.102 >& /dev/null | |
| 151 | + ping -6 -c1 2401:face::66 >& /dev/null | |
| 152 | + fi | |
| 153 | + | |
| 154 | + cleanup | |
| 155 | + | |
| 156 | + echo "OK" | |
| 157 | +} | |
| 158 | + | |
| 159 | +cleanup | |
| 160 | +test_names="l2_to_ipip l2_to_ip6tnl" | |
| 161 | +test_dirs="ingress egress" | |
| 162 | +if [[ $# -ge 2 ]]; then | |
| 163 | + test_names=$1 | |
| 164 | + test_dirs=$2 | |
| 165 | +elif [[ $# -ge 1 ]]; then | |
| 166 | + test_names=$1 | |
| 167 | +fi | |
| 168 | + | |
| 169 | +for t in $test_names; do | |
| 170 | + for d in $test_dirs; do | |
| 171 | + $t $d | |
| 172 | + done | |
| 173 | +done | |
| @@ -0,0 +1,236 @@ | ||
| 1 | +/* Copyright (c) 2016 Facebook | |
| 2 | + * | |
| 3 | + * This program is free software; you can redistribute it and/or | |
| 4 | + * modify it under the terms of version 2 of the GNU General Public | |
| 5 | + * License as published by the Free Software Foundation. | |
| 6 | + */ | |
| 7 | +#include <uapi/linux/bpf.h> | |
| 8 | +#include <uapi/linux/if_ether.h> | |
| 9 | +#include <uapi/linux/if_packet.h> | |
| 10 | +#include <uapi/linux/ip.h> | |
| 11 | +#include <uapi/linux/ipv6.h> | |
| 12 | +#include <uapi/linux/in.h> | |
| 13 | +#include <uapi/linux/tcp.h> | |
| 14 | +#include <uapi/linux/filter.h> | |
| 15 | +#include <uapi/linux/pkt_cls.h> | |
| 16 | +#include <net/ipv6.h> | |
| 17 | +#include "bpf_helpers.h" | |
| 18 | + | |
| 19 | +#define _htonl __builtin_bswap32 | |
| 20 | + | |
| 21 | +#define PIN_GLOBAL_NS 2 | |
| 22 | +struct bpf_elf_map { | |
| 23 | + __u32 type; | |
| 24 | + __u32 size_key; | |
| 25 | + __u32 size_value; | |
| 26 | + __u32 max_elem; | |
| 27 | + __u32 flags; | |
| 28 | + __u32 id; | |
| 29 | + __u32 pinning; | |
| 30 | +}; | |
| 31 | + | |
| 32 | +/* copy of 'struct ethhdr' without __packed */ | |
| 33 | +struct eth_hdr { | |
| 34 | + unsigned char h_dest[ETH_ALEN]; | |
| 35 | + unsigned char h_source[ETH_ALEN]; | |
| 36 | + unsigned short h_proto; | |
| 37 | +}; | |
| 38 | + | |
| 39 | +struct bpf_elf_map SEC("maps") tun_iface = { | |
| 40 | + .type = BPF_MAP_TYPE_ARRAY, | |
| 41 | + .size_key = sizeof(int), | |
| 42 | + .size_value = sizeof(int), | |
| 43 | + .pinning = PIN_GLOBAL_NS, | |
| 44 | + .max_elem = 1, | |
| 45 | +}; | |
| 46 | + | |
| 47 | +static __always_inline bool is_vip_addr(__be16 eth_proto, __be32 daddr) | |
| 48 | +{ | |
| 49 | + if (eth_proto == htons(ETH_P_IP)) | |
| 50 | + return (_htonl(0xffffff00) & daddr) == _htonl(0x0a0a0100); | |
| 51 | + else if (eth_proto == htons(ETH_P_IPV6)) | |
| 52 | + return (daddr == _htonl(0x2401face)); | |
| 53 | + | |
| 54 | + return false; | |
| 55 | +} | |
| 56 | + | |
| 57 | +SEC("l2_to_iptun_ingress_forward") | |
| 58 | +int _l2_to_iptun_ingress_forward(struct __sk_buff *skb) | |
| 59 | +{ | |
| 60 | + struct bpf_tunnel_key tkey = {}; | |
| 61 | + void *data = (void *)(long)skb->data; | |
| 62 | + struct eth_hdr *eth = data; | |
| 63 | + void *data_end = (void *)(long)skb->data_end; | |
| 64 | + int key = 0, *ifindex; | |
| 65 | + | |
| 66 | + int ret; | |
| 67 | + | |
| 68 | + if (data + sizeof(*eth) > data_end) | |
| 69 | + return TC_ACT_OK; | |
| 70 | + | |
| 71 | + ifindex = bpf_map_lookup_elem(&tun_iface, &key); | |
| 72 | + if (!ifindex) | |
| 73 | + return TC_ACT_OK; | |
| 74 | + | |
| 75 | + if (eth->h_proto == htons(ETH_P_IP)) { | |
| 76 | + char fmt4[] = "ingress forward to ifindex:%d daddr4:%x\n"; | |
| 77 | + struct iphdr *iph = data + sizeof(*eth); | |
| 78 | + | |
| 79 | + if (data + sizeof(*eth) + sizeof(*iph) > data_end) | |
| 80 | + return TC_ACT_OK; | |
| 81 | + | |
| 82 | + if (iph->protocol != IPPROTO_IPIP) | |
| 83 | + return TC_ACT_OK; | |
| 84 | + | |
| 85 | + bpf_trace_printk(fmt4, sizeof(fmt4), *ifindex, | |
| 86 | + _htonl(iph->daddr)); | |
| 87 | + return bpf_redirect(*ifindex, BPF_F_INGRESS); | |
| 88 | + } else if (eth->h_proto == htons(ETH_P_IPV6)) { | |
| 89 | + char fmt6[] = "ingress forward to ifindex:%d daddr6:%x::%x\n"; | |
| 90 | + struct ipv6hdr *ip6h = data + sizeof(*eth); | |
| 91 | + | |
| 92 | + if (data + sizeof(*eth) + sizeof(*ip6h) > data_end) | |
| 93 | + return TC_ACT_OK; | |
| 94 | + | |
| 95 | + if (ip6h->nexthdr != IPPROTO_IPIP && | |
| 96 | + ip6h->nexthdr != IPPROTO_IPV6) | |
| 97 | + return TC_ACT_OK; | |
| 98 | + | |
| 99 | + bpf_trace_printk(fmt6, sizeof(fmt6), *ifindex, | |
| 100 | + _htonl(ip6h->daddr.s6_addr32[0]), | |
| 101 | + _htonl(ip6h->daddr.s6_addr32[3])); | |
| 102 | + return bpf_redirect(*ifindex, BPF_F_INGRESS); | |
| 103 | + } | |
| 104 | + | |
| 105 | + return TC_ACT_OK; | |
| 106 | +} | |
| 107 | + | |
| 108 | +SEC("l2_to_iptun_ingress_redirect") | |
| 109 | +int _l2_to_iptun_ingress_redirect(struct __sk_buff *skb) | |
| 110 | +{ | |
| 111 | + struct bpf_tunnel_key tkey = {}; | |
| 112 | + void *data = (void *)(long)skb->data; | |
| 113 | + struct eth_hdr *eth = data; | |
| 114 | + void *data_end = (void *)(long)skb->data_end; | |
| 115 | + int key = 0, *ifindex; | |
| 116 | + | |
| 117 | + int ret; | |
| 118 | + | |
| 119 | + if (data + sizeof(*eth) > data_end) | |
| 120 | + return TC_ACT_OK; | |
| 121 | + | |
| 122 | + ifindex = bpf_map_lookup_elem(&tun_iface, &key); | |
| 123 | + if (!ifindex) | |
| 124 | + return TC_ACT_OK; | |
| 125 | + | |
| 126 | + if (eth->h_proto == htons(ETH_P_IP)) { | |
| 127 | + char fmt4[] = "e/ingress redirect daddr4:%x to ifindex:%d\n"; | |
| 128 | + struct iphdr *iph = data + sizeof(*eth); | |
| 129 | + __be32 daddr = iph->daddr; | |
| 130 | + | |
| 131 | + if (data + sizeof(*eth) + sizeof(*iph) > data_end) | |
| 132 | + return TC_ACT_OK; | |
| 133 | + | |
| 134 | + if (!is_vip_addr(eth->h_proto, daddr)) | |
| 135 | + return TC_ACT_OK; | |
| 136 | + | |
| 137 | + bpf_trace_printk(fmt4, sizeof(fmt4), _htonl(daddr), *ifindex); | |
| 138 | + } else { | |
| 139 | + return TC_ACT_OK; | |
| 140 | + } | |
| 141 | + | |
| 142 | + tkey.tunnel_id = 10000; | |
| 143 | + tkey.tunnel_ttl = 64; | |
| 144 | + tkey.remote_ipv4 = 0x0a020166; /* 10.2.1.102 */ | |
| 145 | + bpf_skb_set_tunnel_key(skb, &tkey, sizeof(tkey), 0); | |
| 146 | + return bpf_redirect(*ifindex, 0); | |
| 147 | +} | |
| 148 | + | |
| 149 | +SEC("l2_to_ip6tun_ingress_redirect") | |
| 150 | +int _l2_to_ip6tun_ingress_redirect(struct __sk_buff *skb) | |
| 151 | +{ | |
| 152 | + struct bpf_tunnel_key tkey = {}; | |
| 153 | + void *data = (void *)(long)skb->data; | |
| 154 | + struct eth_hdr *eth = data; | |
| 155 | + void *data_end = (void *)(long)skb->data_end; | |
| 156 | + int key = 0, *ifindex; | |
| 157 | + | |
| 158 | + if (data + sizeof(*eth) > data_end) | |
| 159 | + return TC_ACT_OK; | |
| 160 | + | |
| 161 | + ifindex = bpf_map_lookup_elem(&tun_iface, &key); | |
| 162 | + if (!ifindex) | |
| 163 | + return TC_ACT_OK; | |
| 164 | + | |
| 165 | + if (eth->h_proto == htons(ETH_P_IP)) { | |
| 166 | + char fmt4[] = "e/ingress redirect daddr4:%x to ifindex:%d\n"; | |
| 167 | + struct iphdr *iph = data + sizeof(*eth); | |
| 168 | + | |
| 169 | + if (data + sizeof(*eth) + sizeof(*iph) > data_end) | |
| 170 | + return TC_ACT_OK; | |
| 171 | + | |
| 172 | + if (!is_vip_addr(eth->h_proto, iph->daddr)) | |
| 173 | + return TC_ACT_OK; | |
| 174 | + | |
| 175 | + bpf_trace_printk(fmt4, sizeof(fmt4), _htonl(iph->daddr), | |
| 176 | + *ifindex); | |
| 177 | + } else if (eth->h_proto == htons(ETH_P_IPV6)) { | |
| 178 | + char fmt6[] = "e/ingress redirect daddr6:%x to ifindex:%d\n"; | |
| 179 | + struct ipv6hdr *ip6h = data + sizeof(*eth); | |
| 180 | + | |
| 181 | + if (data + sizeof(*eth) + sizeof(*ip6h) > data_end) | |
| 182 | + return TC_ACT_OK; | |
| 183 | + | |
| 184 | + if (!is_vip_addr(eth->h_proto, ip6h->daddr.s6_addr32[0])) | |
| 185 | + return TC_ACT_OK; | |
| 186 | + | |
| 187 | + bpf_trace_printk(fmt6, sizeof(fmt6), | |
| 188 | + _htonl(ip6h->daddr.s6_addr32[0]), *ifindex); | |
| 189 | + } else { | |
| 190 | + return TC_ACT_OK; | |
| 191 | + } | |
| 192 | + | |
| 193 | + tkey.tunnel_id = 10000; | |
| 194 | + tkey.tunnel_ttl = 64; | |
| 195 | + /* 2401:db02:0:0:0:0:0:66 */ | |
| 196 | + tkey.remote_ipv6[0] = _htonl(0x2401db02); | |
| 197 | + tkey.remote_ipv6[1] = 0; | |
| 198 | + tkey.remote_ipv6[2] = 0; | |
| 199 | + tkey.remote_ipv6[3] = _htonl(0x00000066); | |
| 200 | + bpf_skb_set_tunnel_key(skb, &tkey, sizeof(tkey), BPF_F_TUNINFO_IPV6); | |
| 201 | + return bpf_redirect(*ifindex, 0); | |
| 202 | +} | |
| 203 | + | |
| 204 | +SEC("drop_non_tun_vip") | |
| 205 | +int _drop_non_tun_vip(struct __sk_buff *skb) | |
| 206 | +{ | |
| 207 | + struct bpf_tunnel_key tkey = {}; | |
| 208 | + void *data = (void *)(long)skb->data; | |
| 209 | + struct eth_hdr *eth = data; | |
| 210 | + void *data_end = (void *)(long)skb->data_end; | |
| 211 | + | |
| 212 | + if (data + sizeof(*eth) > data_end) | |
| 213 | + return TC_ACT_OK; | |
| 214 | + | |
| 215 | + if (eth->h_proto == htons(ETH_P_IP)) { | |
| 216 | + struct iphdr *iph = data + sizeof(*eth); | |
| 217 | + | |
| 218 | + if (data + sizeof(*eth) + sizeof(*iph) > data_end) | |
| 219 | + return TC_ACT_OK; | |
| 220 | + | |
| 221 | + if (is_vip_addr(eth->h_proto, iph->daddr)) | |
| 222 | + return TC_ACT_SHOT; | |
| 223 | + } else if (eth->h_proto == htons(ETH_P_IPV6)) { | |
| 224 | + struct ipv6hdr *ip6h = data + sizeof(*eth); | |
| 225 | + | |
| 226 | + if (data + sizeof(*eth) + sizeof(*ip6h) > data_end) | |
| 227 | + return TC_ACT_OK; | |
| 228 | + | |
| 229 | + if (is_vip_addr(eth->h_proto, ip6h->daddr.s6_addr32[0])) | |
| 230 | + return TC_ACT_SHOT; | |
| 231 | + } | |
| 232 | + | |
| 233 | + return TC_ACT_OK; | |
| 234 | +} | |
| 235 | + | |
| 236 | +char _license[] SEC("license") = "GPL"; | |
| @@ -0,0 +1,73 @@ | ||
| 1 | +/* Copyright (c) 2016 Facebook | |
| 2 | + * | |
| 3 | + * This program is free software; you can redistribute it and/or | |
| 4 | + * modify it under the terms of version 2 of the GNU General Public | |
| 5 | + * License as published by the Free Software Foundation. | |
| 6 | + */ | |
| 7 | +#include <linux/unistd.h> | |
| 8 | +#include <linux/bpf.h> | |
| 9 | + | |
| 10 | +#include <stdlib.h> | |
| 11 | +#include <stdio.h> | |
| 12 | +#include <unistd.h> | |
| 13 | +#include <string.h> | |
| 14 | +#include <errno.h> | |
| 15 | + | |
| 16 | +#include "libbpf.h" | |
| 17 | + | |
| 18 | +static void usage(void) | |
| 19 | +{ | |
| 20 | + printf("Usage: tc_l2_ipip_redirect [...]\n"); | |
| 21 | + printf(" -U <file> Update an already pinned BPF array\n"); | |
| 22 | + printf(" -i <ifindex> Interface index\n"); | |
| 23 | + printf(" -h Display this help\n"); | |
| 24 | +} | |
| 25 | + | |
| 26 | +int main(int argc, char **argv) | |
| 27 | +{ | |
| 28 | + const char *pinned_file = NULL; | |
| 29 | + int ifindex = -1; | |
| 30 | + int array_key = 0; | |
| 31 | + int array_fd = -1; | |
| 32 | + int ret = -1; | |
| 33 | + int opt; | |
| 34 | + | |
| 35 | + while ((opt = getopt(argc, argv, "F:U:i:")) != -1) { | |
| 36 | + switch (opt) { | |
| 37 | + /* General args */ | |
| 38 | + case 'U': | |
| 39 | + pinned_file = optarg; | |
| 40 | + break; | |
| 41 | + case 'i': | |
| 42 | + ifindex = atoi(optarg); | |
| 43 | + break; | |
| 44 | + default: | |
| 45 | + usage(); | |
| 46 | + goto out; | |
| 47 | + } | |
| 48 | + } | |
| 49 | + | |
| 50 | + if (ifindex < 0 || !pinned_file) { | |
| 51 | + usage(); | |
| 52 | + goto out; | |
| 53 | + } | |
| 54 | + | |
| 55 | + array_fd = bpf_obj_get(pinned_file); | |
| 56 | + if (array_fd < 0) { | |
| 57 | + fprintf(stderr, "bpf_obj_get(%s): %s(%d)\n", | |
| 58 | + pinned_file, strerror(errno), errno); | |
| 59 | + goto out; | |
| 60 | + } | |
| 61 | + | |
| 62 | + /* bpf_tunnel_key.remote_ipv4 expects host byte orders */ | |
| 63 | + ret = bpf_update_elem(array_fd, &array_key, &ifindex, 0); | |
| 64 | + if (ret) { | |
| 65 | + perror("bpf_update_elem"); | |
| 66 | + goto out; | |
| 67 | + } | |
| 68 | + | |
| 69 | +out: | |
| 70 | + if (array_fd != -1) | |
| 71 | + close(array_fd); | |
| 72 | + return ret; | |
| 73 | +} | |
| @@ -159,7 +159,8 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< · 158 unmodified lines | ||
| 159 | 159 | $(obj)/%.i: $(src)/%.c FORCE |
| 160 | 160 | $(call if_changed_dep,cpp_i_c) |
| 161 | 161 | |
| 162 | −cmd_gensymtypes = \ | |
| 162 | +# These mirror gensymtypes_S and co below, keep them in synch. | |
| 163 | +cmd_gensymtypes_c = \ | |
| 163 | 164 | $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ |
| 164 | 165 | $(GENKSYMS) $(if $(1), -T $(2)) \ |
| 165 | 166 | $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \ |
| @@ -169,7 +170,7 @@ cmd_gensymtypes = \ · 3 unmodified lines | ||
| 169 | 170 | quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ |
| 170 | 171 | cmd_cc_symtypes_c = \ |
| 171 | 172 | set -e; \ |
| 172 | − $(call cmd_gensymtypes,true,$@) >/dev/null; \ | |
| 173 | + $(call cmd_gensymtypes_c,true,$@) >/dev/null; \ | |
| 173 | 174 | test -s $@ || rm -f $@ |
| 174 | 175 | |
| 175 | 176 | $(obj)/%.symtypes : $(src)/%.c FORCE |
| @@ -198,9 +199,10 @@ else · 22 unmodified lines | ||
| 198 | 199 | # the actual value of the checksum generated by genksyms |
| 199 | 200 | |
| 200 | 201 | cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< |
| 201 | −cmd_modversions = \ | |
| 202 | + | |
| 203 | +cmd_modversions_c = \ | |
| 202 | 204 | if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ |
| 203 | − $(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ | |
| 205 | + $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ | |
| 204 | 206 | > $(@D)/.tmp_$(@F:.o=.ver); \ |
| 205 | 207 | \ |
| 206 | 208 | $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ |
| @@ -268,13 +270,14 @@ endif # CONFIG_STACK_VALIDATION · 61 unmodified lines | ||
| 268 | 270 | define rule_cc_o_c |
| 269 | 271 | $(call echo-cmd,checksrc) $(cmd_checksrc) \ |
| 270 | 272 | $(call cmd_and_fixdep,cc_o_c) \ |
| 271 | − $(cmd_modversions) \ | |
| 273 | + $(cmd_modversions_c) \ | |
| 272 | 274 | $(cmd_objtool) \ |
| 273 | 275 | $(call echo-cmd,record_mcount) $(cmd_record_mcount) |
| 274 | 276 | endef |
| 275 | 277 | |
| 276 | 278 | define rule_as_o_S |
| 277 | 279 | $(call cmd_and_fixdep,as_o_S) \ |
| 280 | + $(cmd_modversions_S) \ | |
| 278 | 281 | $(cmd_objtool) |
| 279 | 282 | endef |
| 280 | 283 | |
| @@ -314,6 +317,39 @@ modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) · 33 unmodified lines | ||
| 314 | 317 | $(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) |
| 315 | 318 | $(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) |
| 316 | 319 | |
| 320 | +# .S file exports must have their C prototypes defined in asm/asm-prototypes.h | |
| 321 | +# or a file that it includes, in order to get versioned symbols. We build a | |
| 322 | +# dummy C file that includes asm-prototypes and the EXPORT_SYMBOL lines from | |
| 323 | +# the .S file (with trailing ';'), and run genksyms on that, to extract vers. | |
| 324 | +# | |
| 325 | +# This is convoluted. The .S file must first be preprocessed to run guards and | |
| 326 | +# expand names, then the resulting exports must be constructed into plain | |
| 327 | +# EXPORT_SYMBOL(symbol); to build our dummy C file, and that gets preprocessed | |
| 328 | +# to make the genksyms input. | |
| 329 | +# | |
| 330 | +# These mirror gensymtypes_c and co above, keep them in synch. | |
| 331 | +cmd_gensymtypes_S = \ | |
| 332 | + (echo "\#include <linux/kernel.h>" ; \ | |
| 333 | + echo "\#include <asm/asm-prototypes.h>" ; \ | |
| 334 | + $(CPP) $(a_flags) $< | \ | |
| 335 | + grep "\<___EXPORT_SYMBOL\>" | \ | |
| 336 | + sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ) | \ | |
| 337 | + $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \ | |
| 338 | + $(GENKSYMS) $(if $(1), -T $(2)) \ | |
| 339 | + $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \ | |
| 340 | + $(if $(KBUILD_PRESERVE),-p) \ | |
| 341 | + -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) | |
| 342 | + | |
| 343 | +quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ | |
| 344 | +cmd_cc_symtypes_S = \ | |
| 345 | + set -e; \ | |
| 346 | + $(call cmd_gensymtypes_S,true,$@) >/dev/null; \ | |
| 347 | + test -s $@ || rm -f $@ | |
| 348 | + | |
| 349 | +$(obj)/%.symtypes : $(src)/%.S FORCE | |
| 350 | + $(call cmd,cc_symtypes_S) | |
| 351 | + | |
| 352 | + | |
| 317 | 353 | quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@ |
| 318 | 354 | cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< |
| 319 | 355 | |
| @@ -321,7 +357,37 @@ $(obj)/%.s: $(src)/%.S FORCE · 1 unmodified line | ||
| 321 | 357 | $(call if_changed_dep,cpp_s_S) |
| 322 | 358 | |
| 323 | 359 | quiet_cmd_as_o_S = AS $(quiet_modtag) $@ |
| 324 | −cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< | |
| 360 | + | |
| 361 | +ifndef CONFIG_MODVERSIONS | |
| 362 | +cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< | |
| 363 | + | |
| 364 | +else | |
| 365 | + | |
| 366 | +ASM_PROTOTYPES := $(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/asm-prototypes.h) | |
| 367 | + | |
| 368 | +ifeq ($(ASM_PROTOTYPES),) | |
| 369 | +cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< | |
| 370 | + | |
| 371 | +else | |
| 372 | + | |
| 373 | +# versioning matches the C process described above, with difference that | |
| 374 | +# we parse asm-prototypes.h C header to get function definitions. | |
| 375 | + | |
| 376 | +cmd_as_o_S = $(CC) $(a_flags) -c -o $(@D)/.tmp_$(@F) $< | |
| 377 | + | |
| 378 | +cmd_modversions_S = \ | |
| 379 | + if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ | |
| 380 | + $(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ | |
| 381 | + > $(@D)/.tmp_$(@F:.o=.ver); \ | |
| 382 | + \ | |
| 383 | + $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ | |
| 384 | + -T $(@D)/.tmp_$(@F:.o=.ver); \ | |
| 385 | + rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ | |
| 386 | + else \ | |
| 387 | + mv -f $(@D)/.tmp_$(@F) $@; \ | |
| 388 | + fi; | |
| 389 | +endif | |
| 390 | +endif | |
| 325 | 391 | |
| 326 | 392 | $(obj)/%.o: $(src)/%.S $(objtool_obj) FORCE |
| 327 | 393 | $(call if_changed_rule,as_o_S) |
| @@ -430,6 +496,9 @@ cmd_export_list = $(OBJDUMP) -h $< | \ · 102 unmodified lines | ||
| 430 | 496 | |
| 431 | 497 | $(obj)/lib-ksyms.o: $(lib-target) FORCE |
| 432 | 498 | $(call if_changed,export_list) |
| 499 | + | |
| 500 | +targets += $(obj)/lib-ksyms.o | |
| 501 | + | |
| 433 | 502 | endif |
| 434 | 503 | |
| 435 | 504 | # |
| @@ -36,6 +36,7 @@ warning-2 += -Wshadow · 35 unmodified lines | ||
| 36 | 36 | warning-2 += $(call cc-option, -Wlogical-op) |
| 37 | 37 | warning-2 += $(call cc-option, -Wmissing-field-initializers) |
| 38 | 38 | warning-2 += $(call cc-option, -Wsign-compare) |
| 39 | +warning-2 += $(call cc-option, -Wmaybe-uninitialized) | |
| 39 | 40 | |
| 40 | 41 | warning-3 := -Wbad-function-cast |
| 41 | 42 | warning-3 += -Wcast-qual |
| @@ -17,4 +17,8 @@ endif · 16 unmodified lines | ||
| 17 | 17 | ifdef CONFIG_UBSAN_NULL |
7 more lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.